Initial import for IEEE1394 OHCI chipdet device driver and SBP-2 (Serial
Bus Protocol 2:SCSI over IEEE1394) support for CAM.
This commit is contained in:
parent
c51f3753df
commit
3c60ba66c4
89
share/man/man4/firewire.4
Normal file
89
share/man/man4/firewire.4
Normal file
@ -0,0 +1,89 @@
|
||||
.\" Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. All advertising materials mentioning features or use of this software
|
||||
.\" must display the acknowledgement as bellow:
|
||||
.\"
|
||||
.\" This product includes software developed by K. Kobayashi and H. Shimokawa
|
||||
.\"
|
||||
.\" 4. The name of the author may not be used to endorse or promote products
|
||||
.\" derived from this software without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
.\" DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
.\" POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd May 23, 2002
|
||||
.Dt FIREWIRE 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm firewire
|
||||
.Nd IEEE1394 High-performance Serial Bus
|
||||
.Sh SYNOPSIS
|
||||
.Cd "device firewire"
|
||||
.Pp
|
||||
.In dev/firewire/firewire.h
|
||||
.Sh DESCRIPTION
|
||||
.Fx
|
||||
provides machine-independent bus support and row drivers for
|
||||
.Tn firewire
|
||||
interfaces.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
driver consists of two layers: the controller and the
|
||||
bus layer.
|
||||
The controller attaches to a physical bus
|
||||
(like
|
||||
.Xr pci 4 ) .
|
||||
The
|
||||
.Tn firewire
|
||||
bus attaches to the controller. And the additional driver can be
|
||||
attached to the bus.
|
||||
.Pp
|
||||
Up to 63 devices, including the host itself, can be attached to
|
||||
a firewire bus. The root node is dynamically assigned with PHY
|
||||
device function. Also, the other firewire bus specific parameters
|
||||
e.g. node id, cycle master, isochronous resource manager and bus
|
||||
manager, are dynamically assigned, after bus rest is initiated.
|
||||
On firewire bus, every device is identified with EUI 64 address.
|
||||
|
||||
.Pp
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr fwohci 4 ,
|
||||
.Xr pci 4 ,
|
||||
.Xr sbp 4 ,
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
driver first appeared in
|
||||
.Fx 5.0 .
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
driver was written by
|
||||
.An Katsushi Kobayashi
|
||||
and
|
||||
.An Hidetoshi Shimokawa
|
||||
for the
|
||||
.Nx
|
||||
project.
|
73
share/man/man4/fwohci.4
Normal file
73
share/man/man4/fwohci.4
Normal file
@ -0,0 +1,73 @@
|
||||
.\" Copyright (c) 1998,1999,2000 Katsushi Kobayashi and Hidetoshi Shimokawa
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. All advertising materials mentioning features or use of this software
|
||||
.\" must display the acknowledgement as bellow:
|
||||
.\"
|
||||
.\" This product includes software developed by K. Kobayashi and H. Shimokawa
|
||||
.\"
|
||||
.\" 4. The name of the author may not be used to endorse or promote products
|
||||
.\" derived from this software without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
.\" DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
.\" POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.\"
|
||||
.Dd April 10, 2000
|
||||
.Dt FWOHCI 4
|
||||
.Os FreeBSD
|
||||
.Sh NAME
|
||||
.Nm fwohci
|
||||
.Nd
|
||||
OHCI firewire chipset device driver
|
||||
.Sh SYNOPSIS
|
||||
.Cd "device fwohci"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
driver provides support for PCI firewire interface cards.
|
||||
The driver supports following OHCI chipsets.
|
||||
.Pp
|
||||
.Bl -tag -width xxxxxxxxxxxxxxxxxxxx
|
||||
.It uPD72861
|
||||
.It TI TSB12LV22,LV23,26 and TSB43AA22
|
||||
.It Sony CX3022
|
||||
.It VIA VT6306
|
||||
.It Ricoh R5C552
|
||||
.Pp
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr firewire 8 ,
|
||||
.Xr sbp 4
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
device driver first appeared in
|
||||
.Fx 5.0 .
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
device driver was written by
|
||||
.An Katsushi Kobayashi .
|
||||
.Pp
|
||||
This manual page was written by
|
||||
.An Katsushi Kobayashi .
|
86
share/man/man4/sbp.4
Normal file
86
share/man/man4/sbp.4
Normal file
@ -0,0 +1,86 @@
|
||||
.\" Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. All advertising materials mentioning features or use of this software
|
||||
.\" must display the acknowledgement as bellow:
|
||||
.\"
|
||||
.\" This product includes software developed by K. Kobayashi
|
||||
.\"
|
||||
.\" 4. The name of the author may not be used to endorse or promote products
|
||||
.\" derived from this software without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
.\" DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
.\" POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.\"
|
||||
.Dd May 20, 2002
|
||||
.Dt SBP 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm sbp
|
||||
.Nd Serial Bus Protocol 2 (SBP-2) Mass Storage Devices driver
|
||||
.Sh SYNOPSIS
|
||||
.Cd "device sbp"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
driver provides support for SBP-2 devices that attach to the firewire (IEEE1394)
|
||||
port.
|
||||
Verified are
|
||||
.Pp
|
||||
.Bl -tag -compact -width xxxxxx
|
||||
.It Apple Macintosh G4 (target mode)
|
||||
.It Apple iPod
|
||||
.El
|
||||
.Pp
|
||||
.Nm firewire
|
||||
and
|
||||
.Nm fwohci
|
||||
must be configured in the kernel as well.
|
||||
Last but not least, support for
|
||||
SCSI drives,
|
||||
.Nm da
|
||||
.Sh EXAMPLES
|
||||
.Dl device sbp
|
||||
.Dl device scbus
|
||||
.Dl device da
|
||||
.Dl device pass
|
||||
.Pp
|
||||
Add the
|
||||
.Nm
|
||||
driver to the kernel.
|
||||
.Pp
|
||||
.Dl camcontrol rescan 0
|
||||
.Pp
|
||||
Rescan a SCSI drive that was added after boot.
|
||||
.\".Sh HISTORY
|
||||
.Sh AUTHORS
|
||||
.An -nosplit
|
||||
The
|
||||
.Nm
|
||||
driver was written by
|
||||
.An Katsushi Kobayashi
|
||||
and
|
||||
.An Hidetoshi Shimokawa .
|
||||
.Pp
|
||||
This manual page was written by
|
||||
.An Katsushi Kobayashi .
|
155
sys/dev/firewire/00README
Normal file
155
sys/dev/firewire/00README
Normal file
@ -0,0 +1,155 @@
|
||||
$FreeBSD$
|
||||
|
||||
IEEE 1394 support for FreeBSD-5.X and 4.X.
|
||||
|
||||
1. Introduction
|
||||
|
||||
This tarball contains IEEE1394(FireWire) driver which is first
|
||||
written by Katsushi Kobayashi[1] <ikob@koganei.wide.ad.jp> and
|
||||
modified by Hidetoshi Shimokawa <simokawa@freebsd.org>.
|
||||
Please note this driver is still under development.
|
||||
You can find latest snapshots under:
|
||||
http://people.freebsd.org/~simokawa/
|
||||
named firewire-2002XXXX.tar.gz
|
||||
|
||||
The driver consists of 6 parts:
|
||||
|
||||
- fwohci.c/fwohci_pci.c
|
||||
OHCI[2] driver
|
||||
- IEEE1394 link/phy chip control
|
||||
- firewire.c
|
||||
Chip independent driver
|
||||
- CSR
|
||||
- Transaction
|
||||
- Character devices for userland
|
||||
- fwmem.c
|
||||
/dev/fwmem0: physical memory of a remote node.
|
||||
- sbp.c
|
||||
SBP-II[3] (a.k.a. SCSI over FireWire) driver
|
||||
|
||||
- if_fwe.c
|
||||
NON-Standard implementation of Ethernet over FireWire.
|
||||
|
||||
- bus_mgm.c (userland)
|
||||
Bus management function for user.
|
||||
show topology map, change gap count, bus reset, etc.
|
||||
|
||||
2. Installation
|
||||
|
||||
Suppose you have kernel source at /sys.
|
||||
|
||||
- Extract tarball at root directory.
|
||||
- cd /sys/dev/firewire
|
||||
- make
|
||||
- make install
|
||||
- make load
|
||||
|
||||
For FreeBSD-4 user:
|
||||
|
||||
- ./MAKEDEV
|
||||
|
||||
3. SBP-II support (sbp)
|
||||
|
||||
- You need CAM(SCSI) support in your kernel.
|
||||
If you are using FreeBSD-5 before 2002/03/23 or FreeBSD-4 before
|
||||
2002/4/8, you need to apply CAM-patch in this archive
|
||||
to handle HDD's(T_RBC or T_DIRECT which doesn't support READ_6).
|
||||
|
||||
- If you connect a few firewire devices only, try the following to
|
||||
reduce gap overhead.
|
||||
|
||||
- ./bus_mgm -g 8
|
||||
|
||||
4. Ethernet over FireWire (if_fwe)
|
||||
|
||||
This is a sample driver for ethernet emulation. Please note this
|
||||
does NOT conform to any standards like IP over FireWire(RFC2734[4]).
|
||||
It just sends ethernet frames encapsulated in asynchronous stream
|
||||
packets. It doesn't scale because it does something like unicast over multicast, but it's easy to be implemented and you can use any
|
||||
facilities what ethernet can do. (ipv6, bridging, vlan etc.)
|
||||
|
||||
It also has DEVICE_POLLING[5] support. To enable it, edit your
|
||||
kernel config file and Makefile.fwe then rebuild kernel and if_fwe.ko.
|
||||
Note this driver checks kern.polling.enable only when enabling the
|
||||
interface. When you enable polling after the interface is up,
|
||||
try 'ifconfig fwe0 down;ifconfig fwe0 up'.
|
||||
|
||||
5. FireWire for Kernel Hackers
|
||||
|
||||
As you know, IEEE1394 is a bus and OHCI supports physical access
|
||||
to the host memory. This means that you can access the remote
|
||||
host over firewire without software support at the remote host.
|
||||
In other words, you can investigate remote host's physical memory
|
||||
whether its OS is alive or crashed or hangs up.
|
||||
|
||||
You need to apply KVMLIB-patch and rebuild libkvm then rebuild ps,
|
||||
dmesg and gdb those are statically linked.
|
||||
You may want to apply GDB-patch in this archive to get same behavior
|
||||
as gdb with /dev/mem or want to insert savectx(&dumppcb) into panic(),
|
||||
breakpoint() and so on to emulation crash dump.
|
||||
|
||||
You have to determine target node_id manually at this point.
|
||||
(guess using bus_mgm -t or dmesg)
|
||||
(Targets should be specified by EUI64 in the future)
|
||||
|
||||
# sysctl kern.firewire.fwmem_node=[node_id]
|
||||
|
||||
# ps -agx -M /dev/fwmem0 -N /sys/i386/compile/GENERIC/kernel
|
||||
# dmesg -M /dev/fwmem0 -N /sys/i386/compile/GENERIC/kernel
|
||||
# gdb -k -c /dev/fwmem0 /sys/i386/compile/GENERIC/kernel.debug
|
||||
# dd if=/dev/fwmem0 of=vmcore bs=1m count=[phys. memory in MB]
|
||||
|
||||
remote gdb at 400,000,000 bps :-)
|
||||
|
||||
|
||||
6. DV
|
||||
I have not tested yet.
|
||||
|
||||
7. Tested HW
|
||||
|
||||
OS
|
||||
- FreeBSD-4/i386
|
||||
- FreeBSD-4/alpha
|
||||
- FreeBSD-5/i386
|
||||
|
||||
* Not tested on SMP.
|
||||
* Not tested on big-endian machine...
|
||||
|
||||
OHCI
|
||||
- Texas Instruments TSB12LV26 (PCI)
|
||||
- Texas Instruments TSB43AA22 (PCI/Cardbus)
|
||||
|
||||
* There might be phy probing problem but most of the OHCI
|
||||
chips should work.
|
||||
* Tested with multiple firewire buses.
|
||||
|
||||
SBP-II
|
||||
- HDD: Logitec USB/FireWire LHD-P30FU
|
||||
- HDD: Yano A-dish 120GB
|
||||
- HDD: Yano B-Max 320GB
|
||||
The repository of cvsup2.jp.freebsd.org is on this device.
|
||||
- HDD: Personal Storage 3000XT 160GB
|
||||
The last sector of this drive cannot be accessed..
|
||||
- DVD-RAM: Panasonic LF-D340JD
|
||||
- SCSI-FireWire converter: Yano FWSCSI-01
|
||||
We can recognize only 1 device/lun at this point
|
||||
- HDD: iPod, PowerBook G4 (target mode)
|
||||
Reported by ikob
|
||||
- Scanner: Epson GT-9700F
|
||||
Now works!!
|
||||
Sane-backend needs a patch(SANE-patch in this archive).
|
||||
|
||||
if_fwe
|
||||
- IPv4, IPv6, bridging, vlan.
|
||||
- You need at least two FreeBSD machines with this driver to use.
|
||||
|
||||
References:
|
||||
[1] ftp://ftp.uec.ac.jp/pub/firewire/beta/
|
||||
[2] http://developer.intel.com/technology/1394/download/ohci_11.htm
|
||||
[3] http://www.t10.org/scsi-3.htm
|
||||
[4] http://www.faqs.org/rfcs/rfc2734.html
|
||||
[5] http://info.iet.unipi.it/~luigi/polling/
|
||||
|
||||
|
||||
Hidetoshi Shimokawa
|
||||
simokawa@freebsd.org
|
456
sys/dev/firewire/bus_mgm.c
Normal file
456
sys/dev/firewire/bus_mgm.c
Normal file
@ -0,0 +1,456 @@
|
||||
/*
|
||||
* Copyright (C) 2002
|
||||
* Hidetoshi Shimokawa. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
*
|
||||
* This product includes software developed by Hidetoshi Shimokawa.
|
||||
*
|
||||
* 4. Neither the name of the author nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/errno.h>
|
||||
#include <dev/firewire/firewire.h>
|
||||
#include <dev/firewire/iec13213.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <err.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
printf("bus_mgm [-g gap_count] [-b pri_req] [-c node]"
|
||||
" [-r] [-t] [-s]\n");
|
||||
printf("\t-g: broadcast gap_count by phy_config packet\n");
|
||||
printf("\t-b: set PRIORITY_BUDGET register on all supported nodes\n");
|
||||
printf("\t-c: read configuration ROM\n");
|
||||
printf("\t-r: bus reset\n");
|
||||
printf("\t-t: read topology map\n");
|
||||
printf("\t-s: read speed map\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void
|
||||
get_num_of_dev(int fd, struct fw_devlstreq *data)
|
||||
{
|
||||
int i;
|
||||
data->n = 64;
|
||||
if( ioctl(fd, FW_GDEVLST, data) < 0) {
|
||||
err(1, "ioctl");
|
||||
}
|
||||
#if 1
|
||||
printf("%d devices\n", data->n);
|
||||
for (i = 0; i < data->n; i++) {
|
||||
printf("%d node %d eui:%08x%08x status:%d\n",
|
||||
i,
|
||||
data->dst[i],
|
||||
data->eui[i].hi,
|
||||
data->eui[i].lo,
|
||||
data->status[i]
|
||||
);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
u_int32_t
|
||||
read_write_quad(int fd, struct fw_eui64 eui, u_int32_t addr_lo, int read, u_int32_t data)
|
||||
{
|
||||
struct fw_asyreq *asyreq;
|
||||
u_int32_t *qld, res;
|
||||
|
||||
asyreq = (struct fw_asyreq *)malloc(sizeof(struct fw_asyreq_t) + 16);
|
||||
asyreq->req.len = 16;
|
||||
asyreq->req.type = FWASREQEUI;
|
||||
asyreq->req.dst.eui = eui;
|
||||
#if 0
|
||||
asyreq->pkt.mode.rreqq.dst = htons(FWLOCALBUS | node);
|
||||
#endif
|
||||
asyreq->pkt.mode.rreqq.tlrt = 0;
|
||||
if (read)
|
||||
asyreq->pkt.mode.rreqq.tcode = FWTCODE_RREQQ;
|
||||
else
|
||||
asyreq->pkt.mode.rreqq.tcode = FWTCODE_WREQQ;
|
||||
|
||||
asyreq->pkt.mode.rreqq.dest_hi = htons(0xffff);
|
||||
asyreq->pkt.mode.rreqq.dest_lo = htonl(addr_lo);
|
||||
|
||||
qld = (u_int32_t *)&asyreq->pkt;
|
||||
if (!read)
|
||||
asyreq->pkt.mode.wreqq.data = data;
|
||||
|
||||
if (ioctl(fd, FW_ASYREQ, asyreq) < 0) {
|
||||
err(1, "ioctl");
|
||||
}
|
||||
res = qld[3];
|
||||
free(asyreq);
|
||||
if (read)
|
||||
return ntohl(res);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
void
|
||||
send_phy_config(int fd, int root_node, int gap_count)
|
||||
{
|
||||
struct fw_asyreq *asyreq;
|
||||
|
||||
asyreq = (struct fw_asyreq *)malloc(sizeof(struct fw_asyreq_t) + 12);
|
||||
asyreq->req.len = 12;
|
||||
asyreq->req.type = FWASREQNODE;
|
||||
asyreq->pkt.mode.ld[0] = 0;
|
||||
asyreq->pkt.mode.ld[1] = 0;
|
||||
asyreq->pkt.mode.common.tcode = FWTCODE_PHY;
|
||||
if (root_node >= 0)
|
||||
asyreq->pkt.mode.ld[1] |= htonl((root_node & 0x3f) << 24 | 1 << 23);
|
||||
if (gap_count >= 0)
|
||||
asyreq->pkt.mode.ld[1] |= htonl(1 << 22 | (gap_count & 0x3f) << 16);
|
||||
asyreq->pkt.mode.ld[2] = ~asyreq->pkt.mode.ld[1];
|
||||
|
||||
printf("send phy_config root_node=%d gap_count=%d\n",
|
||||
root_node, gap_count);
|
||||
|
||||
if (ioctl(fd, FW_ASYREQ, asyreq) < 0) {
|
||||
err(1, "ioctl");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
set_pri_req(int fd, int pri_req)
|
||||
{
|
||||
struct fw_devlstreq data;
|
||||
u_int32_t max, reg, old;
|
||||
int i;
|
||||
|
||||
get_num_of_dev(fd, &data);
|
||||
#define BUGET_REG 0xf0000218
|
||||
for (i = 0; i < data.n; i++) {
|
||||
if (!data.status[i])
|
||||
continue;
|
||||
reg = read_write_quad(fd, data.eui[i], BUGET_REG, 1, 0);
|
||||
printf("%d %08x:%08x, %08x",
|
||||
data.dst[i], data.eui[i].hi, data.eui[i].lo, reg);
|
||||
if (reg > 0 && pri_req >= 0) {
|
||||
old = (reg & 0x3f);
|
||||
max = (reg & 0x3f00) >> 8;
|
||||
if (pri_req > max)
|
||||
pri_req = max;
|
||||
printf(" 0x%x -> 0x%x\n", old, pri_req);
|
||||
read_write_quad(fd, data.eui[i], BUGET_REG, 0, pri_req);
|
||||
} else {
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
parse_text(struct csrtext *textleaf)
|
||||
{
|
||||
char buf[256];
|
||||
u_int32_t *bp;
|
||||
int i, len;
|
||||
|
||||
bp = (u_int32_t *)&buf[0];
|
||||
len = textleaf->crc_len - 2;
|
||||
for (i = 0; i < len; i ++) {
|
||||
*bp++ = ntohl(textleaf->text[i]);
|
||||
}
|
||||
*bp = 0;
|
||||
printf("'%s'", buf);
|
||||
}
|
||||
|
||||
void
|
||||
parse_crom(struct csrdirectory *dir, int depth)
|
||||
{
|
||||
int i, j;
|
||||
struct csrreg *reg;
|
||||
|
||||
printf(" len=0x%04x(%d) crc=0x%04x\n",
|
||||
dir->crc_len, dir->crc_len, dir->crc);
|
||||
if (dir->crc_len > 0xff) {
|
||||
printf(" too long!\n");
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < dir->crc_len; i ++) {
|
||||
for (j = 0; j < depth; j++)
|
||||
printf("\t");
|
||||
reg = &dir->entry[i];
|
||||
printf("0x%02x 0x%06x ", reg->key, reg->val);
|
||||
switch (reg->key) {
|
||||
case 0x03:
|
||||
printf("module_vendor_ID");
|
||||
break;
|
||||
case 0x04:
|
||||
printf("XXX");
|
||||
break;
|
||||
case 0x0c:
|
||||
printf("node_capabilities");
|
||||
break;
|
||||
case 0x12:
|
||||
printf("unit_spec_ID");
|
||||
break;
|
||||
case 0x13:
|
||||
printf("unit_sw_version");
|
||||
break;
|
||||
case 0x14:
|
||||
printf("logical_unit_number");
|
||||
break;
|
||||
case 0x17:
|
||||
printf("model_ID");
|
||||
break;
|
||||
case 0x38:
|
||||
printf("command_set_spec_ID");
|
||||
break;
|
||||
case 0x39:
|
||||
printf("command_set");
|
||||
break;
|
||||
case 0x3a:
|
||||
printf("unit_characteristics");
|
||||
break;
|
||||
case 0x3b:
|
||||
printf("command_set_revision");
|
||||
break;
|
||||
case 0x3c:
|
||||
printf("firmware_revision");
|
||||
break;
|
||||
case 0x3d:
|
||||
printf("reconnect_timeout");
|
||||
break;
|
||||
case 0x54:
|
||||
printf("management_agent");
|
||||
break;
|
||||
case 0x81:
|
||||
printf("text_leaf: ");
|
||||
parse_text((struct csrtext *)(reg + reg->val));
|
||||
break;
|
||||
case 0xd1:
|
||||
printf("unit_directory");
|
||||
parse_crom((struct csrdirectory *)(reg + reg->val),
|
||||
depth + 1);
|
||||
break;
|
||||
default:
|
||||
printf("uknown");
|
||||
break;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void parse_bus_info_block(u_int32_t *p, int info_len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < info_len; i++) {
|
||||
printf("bus_info: 0x%08x\n", *p++);
|
||||
}
|
||||
}
|
||||
void
|
||||
show_crom(int fd, int node)
|
||||
{
|
||||
struct fw_devlstreq data;
|
||||
struct fw_crom_buf buf;
|
||||
struct csrhdr *hdr;
|
||||
u_int32_t *p;
|
||||
int i;
|
||||
|
||||
get_num_of_dev(fd, &data);
|
||||
for (i = 0; i < data.n; i++) {
|
||||
if (data.dst[i] == node && data.eui[i].lo != 0)
|
||||
break;
|
||||
}
|
||||
if (i != data.n) {
|
||||
printf("node: %d\n", node);
|
||||
buf.eui = data.eui[i];
|
||||
} else {
|
||||
printf("no such node: %d\n", node);
|
||||
return;
|
||||
}
|
||||
|
||||
buf.len = 256 * 4;
|
||||
buf.ptr = malloc(buf.len);
|
||||
if (ioctl(fd, FW_GCROM, &buf) < 0) {
|
||||
err(1, "ioctl");
|
||||
}
|
||||
p = (u_int32_t *)buf.ptr;
|
||||
printf("first quad: 0x%08x\n", *p);
|
||||
hdr = (struct csrhdr *)p;
|
||||
if (hdr->info_len == 1) {
|
||||
/* minimum ROM */
|
||||
struct csrreg *reg;
|
||||
reg = (struct csrreg *)p;
|
||||
printf("verndor ID: 0x%06x\n", reg->val);
|
||||
return;
|
||||
}
|
||||
printf("len: %d\n", hdr->crc_len);
|
||||
parse_bus_info_block(p+1, hdr->info_len);
|
||||
p += 1 + hdr->info_len;
|
||||
printf("root_directory");
|
||||
parse_crom((struct csrdirectory *)p, 0);
|
||||
}
|
||||
static void
|
||||
show_topology_map(int fd)
|
||||
{
|
||||
struct fw_topology_map *tmap;
|
||||
union fw_self_id sid;
|
||||
int i;
|
||||
static char *port_status[] = {" ", "-", "P", "C"};
|
||||
static char *pwr_class[] = {" 0W", "15W", "30W", "45W",
|
||||
"-1W", "-2W", "-5W", "-9W"};
|
||||
static char *speed[] = {"S100", "S200", "S400", "S800"};
|
||||
tmap = malloc(sizeof(struct fw_topology_map));
|
||||
if (tmap == NULL)
|
||||
return;
|
||||
if (ioctl(fd, FW_GTPMAP, tmap) < 0) {
|
||||
err(1, "ioctl");
|
||||
}
|
||||
printf("crc_len: %d generation:%d node_count:%d sid_count:%d\n",
|
||||
tmap->crc_len, tmap->generation,
|
||||
tmap->node_count, tmap->self_id_count);
|
||||
printf("id link gap_cnt speed delay cIRM power port0 port1 port2"
|
||||
" ini more\n");
|
||||
for (i = 0; i < tmap->crc_len - 2; i++) {
|
||||
sid = tmap->self_id[i];
|
||||
if (sid.p0.sequel) {
|
||||
printf("%02d sequel packet\n", sid.p0.phy_id);
|
||||
continue;
|
||||
}
|
||||
printf("%02d %2d %d %4s %d %d %3s"
|
||||
" %s %s %s %d %d\n",
|
||||
sid.p0.phy_id,
|
||||
sid.p0.link_active,
|
||||
sid.p0.gap_count,
|
||||
speed[sid.p0.phy_speed],
|
||||
sid.p0.phy_delay,
|
||||
sid.p0.contender,
|
||||
pwr_class[sid.p0.power_class],
|
||||
port_status[sid.p0.port0],
|
||||
port_status[sid.p0.port1],
|
||||
port_status[sid.p0.port2],
|
||||
sid.p0.initiated_reset,
|
||||
sid.p0.more_packets
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
show_speed_map(int fd)
|
||||
{
|
||||
struct fw_speed_map *smap;
|
||||
int i,j;
|
||||
|
||||
smap = malloc(sizeof(struct fw_speed_map));
|
||||
if (smap == NULL)
|
||||
return;
|
||||
if (ioctl(fd, FW_GSPMAP, &smap) < 0) {
|
||||
err(1, "ioctl");
|
||||
}
|
||||
printf("crc_len: %d generation:%d\n", smap->crc_len, smap->generation);
|
||||
for (i = 0; i < 64; i ++) {
|
||||
for (j = 0; j < 64; j ++)
|
||||
printf("%d", smap->speed[i][j]);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
char devname[] = "/dev/fw1";
|
||||
int fd, tmp;
|
||||
|
||||
if ((fd = open(devname, O_RDWR)) < 0)
|
||||
err(1, "open");
|
||||
|
||||
if (argc < 2) {
|
||||
usage();
|
||||
}
|
||||
|
||||
argv++;
|
||||
argc--;
|
||||
while (argc > 0) {
|
||||
if (strcmp(*argv, "-g") == 0) {
|
||||
/* gap count */
|
||||
argv++;
|
||||
argc--;
|
||||
if (argc > 0) {
|
||||
tmp = strtoul(*argv, (char **)NULL, 0);
|
||||
argv++;
|
||||
argc--;
|
||||
send_phy_config(fd, -1, tmp);
|
||||
} else {
|
||||
usage();
|
||||
}
|
||||
} else if (strcmp(*argv, "-b") == 0) {
|
||||
argv++;
|
||||
argc--;
|
||||
tmp = -1;
|
||||
if (argc > 0) {
|
||||
tmp = strtoul(*argv, (char **)NULL, 0);
|
||||
argv++;
|
||||
argc--;
|
||||
} else {
|
||||
usage();
|
||||
}
|
||||
set_pri_req(fd, tmp);
|
||||
} else if (strcmp(*argv, "-r") == 0) {
|
||||
argv++;
|
||||
argc--;
|
||||
/* bus reset */
|
||||
if(ioctl(fd, FW_IBUSRST, &tmp) < 0) {
|
||||
err(1, "ioctl");
|
||||
}
|
||||
} else if (strcmp(*argv, "-t") == 0) {
|
||||
argv++;
|
||||
argc--;
|
||||
show_topology_map(fd);
|
||||
} else if (strcmp(*argv, "-s") == 0) {
|
||||
argv++;
|
||||
argc--;
|
||||
show_speed_map(fd);
|
||||
} else if (strcmp(*argv, "-c") == 0) {
|
||||
argv++;
|
||||
argc--;
|
||||
if (argc > 0) {
|
||||
tmp = strtoul(*argv, (char **)NULL, 0);
|
||||
argv++;
|
||||
argc--;
|
||||
} else {
|
||||
usage();
|
||||
}
|
||||
show_crom(fd, tmp);
|
||||
} else
|
||||
usage();
|
||||
}
|
||||
return 0;
|
||||
}
|
3245
sys/dev/firewire/firewire.c
Normal file
3245
sys/dev/firewire/firewire.c
Normal file
File diff suppressed because it is too large
Load Diff
565
sys/dev/firewire/firewire.h
Normal file
565
sys/dev/firewire/firewire.h
Normal file
@ -0,0 +1,565 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the acknowledgement as bellow:
|
||||
*
|
||||
* This product includes software developed by K. Kobayashi and H. Shimokawa
|
||||
*
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _FIREWIRE_H
|
||||
#define _FIREWIRE_H 1
|
||||
|
||||
#define DEV_DEF 0
|
||||
#define DEV_DV 2
|
||||
|
||||
struct dv_data{
|
||||
u_int32_t n_write;
|
||||
u_int32_t a_write;
|
||||
u_int32_t k_write;
|
||||
u_int32_t write_done;
|
||||
u_int32_t write_len[16];
|
||||
u_int32_t write_off[16];
|
||||
u_int32_t n_read;
|
||||
u_int32_t a_read;
|
||||
u_int32_t k_read;
|
||||
u_int32_t read_done;
|
||||
u_int32_t read_len[16];
|
||||
u_int32_t read_off[16];
|
||||
};
|
||||
|
||||
struct dv_data_req_t {
|
||||
unsigned long index;
|
||||
unsigned long len;
|
||||
unsigned long off;
|
||||
};
|
||||
|
||||
struct fw_isochreq {
|
||||
unsigned char ch:6,
|
||||
tag:2;
|
||||
};
|
||||
|
||||
struct fw_isobufreq {
|
||||
struct {
|
||||
unsigned int nchunk;
|
||||
unsigned int npacket;
|
||||
unsigned int psize;
|
||||
} tx, rx;
|
||||
};
|
||||
|
||||
struct fw_addr{
|
||||
unsigned long hi;
|
||||
unsigned long lo;
|
||||
};
|
||||
|
||||
struct fw_asybindreq {
|
||||
struct fw_addr start;
|
||||
unsigned long len;
|
||||
};
|
||||
|
||||
struct fw_reg_req_t{
|
||||
unsigned long addr;
|
||||
unsigned long data;
|
||||
};
|
||||
|
||||
#define FWPMAX_S400 (2048 + 20) /* MAXREC plus space for control data */
|
||||
#define FWMAXQUEUE 128
|
||||
|
||||
#define FWLOCALBUS 0xffc0
|
||||
|
||||
#define FWTCODE_WREQQ 0
|
||||
#define FWTCODE_WREQB 1
|
||||
#define FWTCODE_WRES 2
|
||||
#define FWTCODE_RREQQ 4
|
||||
#define FWTCODE_RREQB 5
|
||||
#define FWTCODE_RRESQ 6
|
||||
#define FWTCODE_RRESB 7
|
||||
#define FWTCODE_CYCS 8
|
||||
#define FWTCODE_LREQ 9
|
||||
#define FWTCODE_STREAM 0xa
|
||||
#define FWTCODE_LRES 0xb
|
||||
#define FWTCODE_PHY 0xe
|
||||
|
||||
#define FWRETRY_1 0
|
||||
#define FWRETRY_X 1
|
||||
#define FWRETRY_A 2
|
||||
#define FWRETRY_B 3
|
||||
|
||||
#define FWRCODE_COMPLETE 0
|
||||
#define FWRCODE_ER_CONFL 4
|
||||
#define FWRCODE_ER_DATA 5
|
||||
#define FWRCODE_ER_TYPE 6
|
||||
#define FWRCODE_ER_ADDR 7
|
||||
|
||||
#define FWSPD_S100 0
|
||||
#define FWSPD_S200 1
|
||||
#define FWSPD_S400 2
|
||||
|
||||
#define FWP_TL_VALID (1 << 7)
|
||||
|
||||
struct fw_isohdr{
|
||||
u_int32_t hdr[1];
|
||||
};
|
||||
struct fw_asyhdr{
|
||||
u_int32_t hdr[4];
|
||||
};
|
||||
#define FWPHYSIDSUBS(SID) (((SID) >> 23) & 1)
|
||||
#define FWPHYSIDNODE(SID) (((SID) >> 24) & 0x3f)
|
||||
#define FWPHYSIDLINK(SID) (((SID) >> 22) & 1)
|
||||
#define FWPHYSIDGAP(SID) (((SID) >> 16) & 0x3f)
|
||||
#define FWPHYSIDSPD(SID) (((SID) >> 14) & 0x3)
|
||||
#define FWPHYSIDDEL(SID) (((SID) >> 12) & 0x3)
|
||||
#define FWPHYSIDCON(SID) (((SID) >> 11) & 1)
|
||||
#define FWPHYSIDPWR(SID) (((SID) >> 8) & 0x7)
|
||||
#define FWPHYSIDP0(SID) (((SID) >> 6) & 0x3)
|
||||
#define FWPHYSIDP1(SID) (((SID) >> 4) & 0x3)
|
||||
#define FWPHYSIDP2(SID) (((SID) >> 2) & 0x3)
|
||||
#define FWPHYSIDIR(SID) (((SID) >> 1) & 1)
|
||||
#define FWPHYSIDMORE(SID) ((SID) & 1)
|
||||
#define FWPHYSIDSEQ(SID) (((SID) >> 20) & 0x7)
|
||||
#define FWPHYSIDPA(SID) (((SID) >> 16) & 0x3)
|
||||
#define FWPHYSIDPB(SID) (((SID) >> 14) & 0x3)
|
||||
#define FWPHYSIDPC(SID) (((SID) >> 12) & 0x3)
|
||||
#define FWPHYSIDPD(SID) (((SID) >> 10) & 0x3)
|
||||
#define FWPHYSIDPE(SID) (((SID) >> 8) & 0x3)
|
||||
#define FWPHYSIDPF(SID) (((SID) >> 6) & 0x3)
|
||||
#define FWPHYSIDPG(SID) (((SID) >> 4) & 0x3)
|
||||
#define FWPHYSIDPH(SID) (((SID) >> 2) & 0x3)
|
||||
struct fw_pkt{
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
union{
|
||||
u_int32_t ld[0];
|
||||
struct {
|
||||
u_int32_t :28,
|
||||
tcode:4;
|
||||
}common;
|
||||
struct {
|
||||
u_int16_t len;
|
||||
u_int8_t chtag;
|
||||
u_int8_t sy:4,
|
||||
tcode:4;
|
||||
u_int32_t payload[0];
|
||||
}stream;
|
||||
struct {
|
||||
u_int16_t dst;
|
||||
u_int8_t tlrt;
|
||||
u_int8_t pri:4,
|
||||
tcode:4;
|
||||
u_int16_t src;
|
||||
}hdr;
|
||||
struct {
|
||||
u_int16_t dst;
|
||||
u_int8_t tlrt;
|
||||
u_int8_t pri:4,
|
||||
tcode:4;
|
||||
u_int16_t src;
|
||||
u_int16_t dest_hi;
|
||||
u_int32_t dest_lo;
|
||||
}rreqq;
|
||||
struct {
|
||||
u_int16_t dst;
|
||||
u_int8_t tlrt;
|
||||
u_int8_t pri:4,
|
||||
tcode:4;
|
||||
u_int16_t src;
|
||||
u_int16_t res1:4,
|
||||
rtcode:4,
|
||||
res2:8;
|
||||
u_int32_t res3;
|
||||
}wres;
|
||||
struct {
|
||||
u_int16_t dst;
|
||||
u_int8_t tlrt;
|
||||
u_int8_t pri:4,
|
||||
tcode:4;
|
||||
u_int16_t src;
|
||||
u_int16_t dest_hi;
|
||||
u_int32_t dest_lo;
|
||||
u_int16_t len;
|
||||
u_int16_t extcode:16;
|
||||
}rreqb;
|
||||
struct {
|
||||
u_int16_t dst;
|
||||
u_int8_t tlrt;
|
||||
u_int8_t pri:4,
|
||||
tcode:4;
|
||||
u_int16_t src;
|
||||
u_int16_t dest_hi:16;
|
||||
u_int32_t dest_lo;
|
||||
u_int32_t data;
|
||||
}wreqq;
|
||||
struct {
|
||||
u_int16_t dst;
|
||||
u_int8_t tlrt;
|
||||
u_int8_t pri:4,
|
||||
tcode:4;
|
||||
u_int16_t src;
|
||||
u_int16_t dest_hi;
|
||||
u_int32_t dest_lo;
|
||||
u_int32_t data;
|
||||
}cyc;
|
||||
struct {
|
||||
u_int16_t dst;
|
||||
u_int8_t tlrt;
|
||||
u_int8_t pri:4,
|
||||
tcode:4;
|
||||
u_int16_t src;
|
||||
u_int16_t res1:4,
|
||||
rtcode:4,
|
||||
res2:8;
|
||||
u_int32_t res3;
|
||||
u_int32_t data;
|
||||
}rresq;
|
||||
struct {
|
||||
u_int16_t dst;
|
||||
u_int8_t tlrt;
|
||||
u_int8_t pri:4,
|
||||
tcode:4;
|
||||
u_int16_t src;
|
||||
u_int16_t dest_hi;
|
||||
u_int32_t dest_lo;
|
||||
u_int16_t len;
|
||||
u_int16_t extcode;
|
||||
u_int32_t payload[0];
|
||||
}wreqb;
|
||||
struct {
|
||||
u_int16_t dst;
|
||||
u_int8_t tlrt;
|
||||
u_int8_t pri:4,
|
||||
tcode:4;
|
||||
u_int16_t src;
|
||||
u_int16_t dest_hi;
|
||||
u_int32_t dest_lo;
|
||||
u_int16_t len;
|
||||
u_int16_t extcode;
|
||||
#define FW_LREQ_MSKSWAP 1
|
||||
#define FW_LREQ_CMPSWAP 2
|
||||
#define FW_LREQ_FTADD 3
|
||||
#define FW_LREQ_LTADD 4
|
||||
#define FW_LREQ_BDADD 5
|
||||
#define FW_LREQ_WRADD 6
|
||||
u_int32_t payload[0];
|
||||
}lreq;
|
||||
struct {
|
||||
u_int16_t dst;
|
||||
u_int8_t tlrt;
|
||||
u_int8_t pri:4,
|
||||
tcode:4;
|
||||
u_int16_t src;
|
||||
u_int16_t res1:4,
|
||||
rtcode:4,
|
||||
res2:8;
|
||||
u_int32_t res3;
|
||||
u_int16_t len;
|
||||
u_int16_t extcode;
|
||||
u_int32_t payload[0];
|
||||
}rresb;
|
||||
struct {
|
||||
u_int16_t dst;
|
||||
u_int8_t tlrt;
|
||||
u_int8_t pri:4,
|
||||
tcode:4;
|
||||
u_int16_t src;
|
||||
u_int16_t res1:4,
|
||||
rtcode:4,
|
||||
res2:8;
|
||||
u_int32_t res3;
|
||||
u_int16_t len;
|
||||
u_int16_t extcode;
|
||||
u_int32_t payload[0];
|
||||
}lres;
|
||||
}mode;
|
||||
#else
|
||||
union{
|
||||
u_int32_t ld[0];
|
||||
struct {
|
||||
u_int32_t :4,
|
||||
tcode:4,
|
||||
:24;
|
||||
}common;
|
||||
struct {
|
||||
u_int8_t sy:4,
|
||||
tcode:4;
|
||||
u_int8_t chtag;
|
||||
u_int16_t len;
|
||||
u_int32_t payload[0];
|
||||
}stream;
|
||||
struct {
|
||||
u_int32_t pri:4,
|
||||
tcode:4,
|
||||
tlrt:8,
|
||||
dst:16;
|
||||
u_int32_t :16,
|
||||
src:16;
|
||||
}hdr;
|
||||
struct {
|
||||
u_int8_t pri:4,
|
||||
tcode:4;
|
||||
u_int8_t tlrt;
|
||||
u_int16_t dst;
|
||||
u_int16_t dest_hi;
|
||||
u_int16_t src;
|
||||
u_int32_t dest_lo;
|
||||
}rreqq;
|
||||
struct {
|
||||
u_int8_t pri:4,
|
||||
tcode:4;
|
||||
u_int8_t tlrt;
|
||||
u_int16_t dst;
|
||||
u_int16_t res1:12,
|
||||
rtcode:4;
|
||||
u_int16_t src;
|
||||
u_int32_t res3;
|
||||
}wres;
|
||||
struct {
|
||||
u_int8_t pri:4,
|
||||
tcode:4;
|
||||
u_int8_t tlrt;
|
||||
u_int16_t dst;
|
||||
u_int16_t dest_hi;
|
||||
u_int16_t src;
|
||||
u_int32_t dest_lo;
|
||||
u_int16_t extcode:16;
|
||||
u_int16_t len;
|
||||
}rreqb;
|
||||
struct {
|
||||
u_int8_t pri:4,
|
||||
tcode:4;
|
||||
u_int8_t tlrt;
|
||||
u_int16_t dst;
|
||||
u_int16_t dest_hi:16;
|
||||
u_int16_t src;
|
||||
u_int32_t dest_lo;
|
||||
u_int32_t data;
|
||||
}wreqq;
|
||||
struct {
|
||||
u_int8_t pri:4,
|
||||
tcode:4;
|
||||
u_int8_t tlrt;
|
||||
u_int16_t dst;
|
||||
u_int16_t dest_hi;
|
||||
u_int16_t src;
|
||||
u_int32_t dest_lo;
|
||||
u_int32_t data;
|
||||
}cyc;
|
||||
struct {
|
||||
u_int8_t pri:4,
|
||||
tcode:4;
|
||||
u_int8_t tlrt;
|
||||
u_int16_t dst;
|
||||
u_int16_t res1:12,
|
||||
rtcode:4;
|
||||
u_int16_t src;
|
||||
u_int32_t res3;
|
||||
u_int32_t data;
|
||||
}rresq;
|
||||
struct {
|
||||
u_int8_t pri:4,
|
||||
tcode:4;
|
||||
u_int8_t tlrt;
|
||||
u_int16_t dst;
|
||||
u_int16_t dest_hi;
|
||||
u_int16_t src;
|
||||
u_int32_t dest_lo;
|
||||
u_int16_t extcode;
|
||||
u_int16_t len;
|
||||
u_int32_t payload[0];
|
||||
}wreqb;
|
||||
struct {
|
||||
u_int8_t pri:4,
|
||||
tcode:4;
|
||||
u_int8_t tlrt;
|
||||
u_int16_t dst;
|
||||
u_int16_t dest_hi;
|
||||
u_int16_t src;
|
||||
u_int32_t dest_lo;
|
||||
u_int16_t extcode;
|
||||
u_int16_t len;
|
||||
u_int32_t payload[0];
|
||||
}lreq;
|
||||
struct {
|
||||
u_int8_t pri:4,
|
||||
tcode:4;
|
||||
u_int8_t tlrt;
|
||||
u_int16_t dst;
|
||||
u_int16_t res1:12,
|
||||
rtcode:4;
|
||||
u_int16_t src;
|
||||
u_int32_t res3;
|
||||
u_int16_t extcode;
|
||||
u_int16_t len;
|
||||
u_int32_t payload[0];
|
||||
}rresb;
|
||||
struct {
|
||||
u_int8_t pri:4,
|
||||
tcode:4;
|
||||
u_int8_t tlrt;
|
||||
u_int16_t dst;
|
||||
u_int16_t res1:12,
|
||||
rtcode:4;
|
||||
u_int16_t src;
|
||||
u_int32_t res3;
|
||||
u_int16_t extcode;
|
||||
u_int16_t len;
|
||||
u_int32_t payload[0];
|
||||
}lres;
|
||||
}mode;
|
||||
#endif
|
||||
};
|
||||
struct fw_eui64 {
|
||||
u_int32_t hi, lo;
|
||||
};
|
||||
struct fw_asyreq {
|
||||
struct fw_asyreq_t{
|
||||
unsigned char sped;
|
||||
unsigned int type;
|
||||
#define FWASREQNODE 0
|
||||
#define FWASREQEUI 1
|
||||
#define FWASRESTL 2
|
||||
#define FWASREQSTREAM 3
|
||||
unsigned short len;
|
||||
union {
|
||||
struct fw_eui64 eui;
|
||||
}dst;
|
||||
}req;
|
||||
struct fw_pkt pkt;
|
||||
u_int32_t data[512];
|
||||
};
|
||||
struct fw_devlstreq {
|
||||
int n;
|
||||
struct fw_eui64 eui[64];
|
||||
u_int16_t dst[64];
|
||||
u_int16_t status[64];
|
||||
};
|
||||
#define FW_SELF_ID_PORT_CONNECTED_TO_CHILD 3
|
||||
#define FW_SELF_ID_PORT_CONNECTED_TO_PARENT 2
|
||||
#define FW_SELF_ID_PORT_NOT_CONNECTED 1
|
||||
#define FW_SELF_ID_PORT_NOT_EXISTS 0
|
||||
union fw_self_id {
|
||||
struct {
|
||||
u_int32_t more_packets:1,
|
||||
initiated_reset:1,
|
||||
port2:2,
|
||||
port1:2,
|
||||
port0:2,
|
||||
power_class:3,
|
||||
contender:1,
|
||||
phy_delay:2,
|
||||
phy_speed:2,
|
||||
gap_count:6,
|
||||
link_active:1,
|
||||
sequel:1,
|
||||
phy_id:6,
|
||||
id:2;
|
||||
} p0;
|
||||
struct {
|
||||
u_int32_t more_packets:1,
|
||||
reserved1:1,
|
||||
porth:2,
|
||||
portg:2,
|
||||
portf:2,
|
||||
porte:2,
|
||||
portd:2,
|
||||
portc:2,
|
||||
portb:2,
|
||||
porta:2,
|
||||
reserved2:2,
|
||||
sequence_num:3,
|
||||
sequel:1,
|
||||
phy_id:6,
|
||||
id:2;
|
||||
} p1;
|
||||
};
|
||||
struct fw_topology_map {
|
||||
u_int32_t crc:16,
|
||||
crc_len:16;
|
||||
u_int32_t generation;
|
||||
u_int32_t self_id_count:16,
|
||||
node_count:16;
|
||||
union fw_self_id self_id[4*64];
|
||||
};
|
||||
struct fw_speed_map {
|
||||
u_int32_t crc:16,
|
||||
crc_len:16;
|
||||
u_int32_t generation;
|
||||
u_int8_t speed[64][64];
|
||||
};
|
||||
struct fw_map_buf {
|
||||
int len;
|
||||
void *ptr;
|
||||
};
|
||||
struct fw_crom_buf {
|
||||
struct fw_eui64 eui;
|
||||
int len;
|
||||
void *ptr;
|
||||
};
|
||||
#define FWSTMAXCHUNK 16
|
||||
/*
|
||||
* Firewire specific system requests.
|
||||
*/
|
||||
#define FW_SSTDV _IOWR('S', 85, unsigned int)
|
||||
#define FW_SSTBUF _IOWR('S', 86, struct fw_isobufreq)
|
||||
#define FW_GSTBUF _IOWR('S', 87, struct fw_isobufreq)
|
||||
#define FW_SRSTREAM _IOWR('S', 88, struct fw_isochreq)
|
||||
#define FW_GRSTREAM _IOWR('S', 89, struct fw_isochreq)
|
||||
#define FW_STSTREAM _IOWR('S', 90, struct fw_isochreq)
|
||||
#define FW_GTSTREAM _IOWR('S', 91, struct fw_isochreq)
|
||||
|
||||
#define FW_ASYREQ _IOWR('S', 92, struct fw_asyreq)
|
||||
#define FW_IBUSRST _IOR('S', 1, unsigned int)
|
||||
#define FW_GDEVLST _IOWR('S', 2, struct fw_devlstreq)
|
||||
#define FW_SBINDADDR _IOWR('S', 3, struct fw_asybindreq)
|
||||
#define FW_CBINDADDR _IOWR('S', 4, struct fw_asybindreq)
|
||||
#define FW_GTPMAP _IOR('S', 5, struct fw_topology_map)
|
||||
#define FW_GSPMAP _IOW('S', 6, struct fw_speed_map *)
|
||||
#define FW_GCROM _IOWR('S', 7, struct fw_crom_buf)
|
||||
|
||||
#define FWOHCI_RDREG _IOWR('S', 80, struct fw_reg_req_t)
|
||||
#define FWOHCI_WRREG _IOWR('S', 81, struct fw_reg_req_t)
|
||||
|
||||
#define DUMPDMA _IOWR('S', 82, u_int32_t)
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#define FWMAXNDMA 0x100 /* 8 bits DMA channel id. in device No. */
|
||||
|
||||
#if __FreeBSD_version < 500000
|
||||
#define dev2unit(x) ((minor(x) & 0xff) | (minor(x) >> 8))
|
||||
#define unit2minor(x) (((x) & 0xff) | (((x) << 8) & ~0xffff))
|
||||
#endif
|
||||
|
||||
#define UNIT2MIN(x) (((x) & 0xff) << 8)
|
||||
#define DEV2UNIT(x) ((dev2unit(x) & 0xff00) >> 8)
|
||||
#define DEV2DMACH(x) (dev2unit(x) & 0xff)
|
||||
|
||||
#define FWMEM_FLAG 0x10000
|
||||
#define DEV_FWMEM(x) (dev2unit(x) & FWMEM_FLAG)
|
||||
#endif
|
||||
#endif
|
87
sys/dev/firewire/firewire_phy.h
Normal file
87
sys/dev/firewire/firewire_phy.h
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the acknowledgement as bellow:
|
||||
*
|
||||
* This product includes software developed by K. Kobayashi and H. Shimokawa
|
||||
*
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
*/
|
||||
|
||||
#define FW_PHY_PHYSID_REG 0x00
|
||||
#define FW_PHY_PHYSID (63<<2)
|
||||
#define FW_PHY_ROOT_REG 0x00
|
||||
#define FW_PHY_ROOT (1<<1)
|
||||
#define FW_PHY_CPS_REG 0x00
|
||||
#define FW_PHY_CPS (1<<0)
|
||||
|
||||
#define FW_PHY_RHB_REG 0x01
|
||||
#define FW_PHY_RHB (1<<7)
|
||||
#define FW_PHY_IBR_REG 0x01
|
||||
#define FW_PHY_IBR (1<<6)
|
||||
#define FW_PHY_ISBR_REG 0x05
|
||||
#define FW_PHY_ISBR (1<<6)
|
||||
#define FW_PHY_GC_REG 0x01
|
||||
|
||||
#define FW_PHY_SPD_REG 0x02
|
||||
#define FW_PHY_SPD (3<<6)
|
||||
#define FW_PHY_REV_REG 0x02
|
||||
#define FW_PHY_REV (3<<4)
|
||||
#define FW_PHY_NP_REG 0x02
|
||||
#define FW_PHY_NP (15<<0)
|
||||
|
||||
#define FW_PHY_P1_REG 0x03
|
||||
#define FW_PHY_P2_REG 0x04
|
||||
#define FW_PHY_P3_REG 0x05
|
||||
|
||||
#define FW_PHY_P_ASTAT (3<<6)
|
||||
#define FW_PHY_P_BSTAT (3<<4)
|
||||
#define FW_PHY_P_CH (1<<3)
|
||||
#define FW_PHY_P_CON (1<<2)
|
||||
|
||||
#define FW_PHY_LOOPINT_REG 0x06
|
||||
#define FW_PHY_LOOPINT (1<<7)
|
||||
#define FW_PHY_CPSINT_REG 0x06
|
||||
#define FW_PHY_CPSNT (1<<6)
|
||||
/*
|
||||
#define FW_PHY_CPS_REG 0x06
|
||||
#define FW_PHY_CPS (1<<5)
|
||||
*/
|
||||
#define FW_PHY_IR_REG 0x06
|
||||
#define FW_PHY_IR (1<<4)
|
||||
#define FW_PHY_C_REG 0x06
|
||||
#define FW_PHY_C (1<<0)
|
||||
|
||||
#define FW_PHY_ESPD_REG 0x03
|
||||
#define FW_PHY_ESPD (7<<5)
|
||||
|
||||
#define FW_PHY_EDEL_REG 0x03
|
||||
#define FW_PHY_EDEL 15<<0
|
||||
|
||||
|
38
sys/dev/firewire/firewirebusreg.h
Normal file
38
sys/dev/firewire/firewirebusreg.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the acknowledgement as bellow:
|
||||
*
|
||||
* This product includes software developed by K. Kobayashi and H. Shimokawa
|
||||
*
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
*/
|
||||
struct firewire_bus{
|
||||
device_t bdev;
|
||||
};
|
349
sys/dev/firewire/firewirereg.h
Normal file
349
sys/dev/firewire/firewirereg.h
Normal file
@ -0,0 +1,349 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the acknowledgement as bellow:
|
||||
*
|
||||
* This product includes software developed by K. Kobayashi and H. Shimokawa
|
||||
*
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
*/
|
||||
|
||||
#if __FreeBSD_version >= 500000
|
||||
typedef struct thread fw_proc;
|
||||
#include <sys/selinfo.h>
|
||||
#else
|
||||
typedef struct proc fw_proc;
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#define splfw splimp
|
||||
|
||||
struct fw_device{
|
||||
u_int16_t dst;
|
||||
struct fw_eui64 eui;
|
||||
u_int32_t spec;
|
||||
u_int32_t ver;
|
||||
u_int8_t speed;
|
||||
u_int8_t maxrec;
|
||||
u_int8_t nport;
|
||||
u_int8_t power;
|
||||
#define CSRROMOFF 0x400
|
||||
#define CSRROMSIZE 0x400
|
||||
int rommax; /* offset from 0xffff f000 0000 */
|
||||
u_int32_t csrrom[CSRROMSIZE/4];
|
||||
int rcnt;
|
||||
device_t dev;
|
||||
u_int32_t status;
|
||||
#define FWDEVINIT 1
|
||||
#define FWDEVATTACHED 2
|
||||
#define FWDEVINVAL 3
|
||||
TAILQ_ENTRY(fw_device) link;
|
||||
LIST_HEAD(, fw_xfer) txqueue;
|
||||
LIST_HEAD(, fw_xfer) rxqueue;
|
||||
};
|
||||
struct firewire_softc {
|
||||
#if __FreeBSD_version >= 500000
|
||||
dev_t dev;
|
||||
#else
|
||||
dev_t dev[FWMAXNDMA+1];
|
||||
#endif
|
||||
struct firewire_comm *fc;
|
||||
};
|
||||
#define FW_MAX_DMACH 0x20
|
||||
#define FW_MAX_DEVCH FW_MAX_DMACH
|
||||
#define FW_XFERTIMEOUT 1
|
||||
struct firewire_dev_comm {
|
||||
device_t dev;
|
||||
struct firewire_comm *fc;
|
||||
void (*post_explore) __P((void *));
|
||||
};
|
||||
|
||||
struct tcode_info {
|
||||
u_char hdr_len; /* IEEE1394 header length */
|
||||
u_char flag;
|
||||
#define FWTI_REQ (1 << 0)
|
||||
#define FWTI_RES (1 << 1)
|
||||
#define FWTI_TLABEL (1 << 2)
|
||||
#define FWTI_BLOCK_STR (1 << 3)
|
||||
#define FWTI_BLOCK_ASY (1 << 4)
|
||||
};
|
||||
|
||||
struct firewire_comm{
|
||||
device_t dev;
|
||||
device_t bdev;
|
||||
u_int16_t busid:10,
|
||||
nodeid:6;
|
||||
u_int mode;
|
||||
u_int nport;
|
||||
u_int speed;
|
||||
u_int maxrec;
|
||||
u_int irm;
|
||||
u_int max_node;
|
||||
u_int max_hop;
|
||||
u_int max_asyretry;
|
||||
#define FWPHYASYST (1 << 0)
|
||||
u_int retry_count;
|
||||
u_int32_t ongobus:10,
|
||||
ongonode:6,
|
||||
ongoaddr:16;
|
||||
struct fw_device *ongodev;
|
||||
struct fw_eui64 ongoeui;
|
||||
#define FWMAXCSRDIR 16
|
||||
SLIST_HEAD(, csrdir) ongocsr;
|
||||
SLIST_HEAD(, csrdir) csrfree;
|
||||
struct csrdir{
|
||||
u_int32_t ongoaddr;
|
||||
u_int32_t off;
|
||||
SLIST_ENTRY(csrdir) link;
|
||||
};
|
||||
u_int32_t status;
|
||||
#define FWBUSRESET 0
|
||||
#define FWBUSINIT 1
|
||||
#define FWBUSCYMELECT 2
|
||||
#define FWBUSMGRELECT 3
|
||||
#define FWBUSMGRDONE 4
|
||||
#define FWBUSEXPLORE 5
|
||||
#define FWBUSPHYCONF 6
|
||||
#define FWBUSEXPDONE 7
|
||||
#define FWBUSCOMPLETION 10
|
||||
int nisodma;
|
||||
u_int8_t eui[8];
|
||||
STAILQ_HEAD(fw_queue, fw_xfer);
|
||||
struct fw_xferq {
|
||||
int flag;
|
||||
#define FWXFERQ_CHTAGMASK 0xff
|
||||
#define FWXFERQ_RUNNING (1 << 8)
|
||||
#define FWXFERQ_STREAM (1 << 9)
|
||||
|
||||
#define FWXFERQ_PACKET (1 << 10)
|
||||
#define FWXFERQ_BULK (1 << 11)
|
||||
#define FWXFERQ_DV (1 << 12)
|
||||
#define FWXFERQ_MODEMASK (7 << 10)
|
||||
|
||||
#define FWXFERQ_EXTBUF (1 << 13)
|
||||
#define FWXFERQ_OPEN (1 << 14)
|
||||
|
||||
#define FWXFERQ_HANDLER (1 << 16)
|
||||
#define FWXFERQ_WAKEUP (1 << 17)
|
||||
|
||||
void (*start) __P((struct firewire_comm*));
|
||||
void (*drain) __P((struct firewire_comm*, struct fw_xfer*));
|
||||
struct fw_queue q;
|
||||
u_int queued;
|
||||
u_int maxq;
|
||||
u_int psize;
|
||||
u_int packets;
|
||||
u_int error;
|
||||
STAILQ_HEAD(, fw_bind) binds;
|
||||
caddr_t buf;
|
||||
u_int bnchunk;
|
||||
u_int bnpacket;
|
||||
u_int btpacket;
|
||||
struct fw_bulkxfer *bulkxfer;
|
||||
STAILQ_HEAD(, fw_bulkxfer) stvalid;
|
||||
STAILQ_HEAD(, fw_bulkxfer) stfree;
|
||||
struct fw_bulkxfer *stdma;
|
||||
struct fw_bulkxfer *stdma2;
|
||||
struct fw_bulkxfer *stproc;
|
||||
u_int procptr;
|
||||
int dvdbc, dvdiff, dvsync;
|
||||
struct fw_dvbuf *dvbuf;
|
||||
STAILQ_HEAD(, fw_dvbuf) dvvalid;
|
||||
STAILQ_HEAD(, fw_dvbuf) dvfree;
|
||||
struct fw_dvbuf *dvdma;
|
||||
struct fw_dvbuf *dvproc;
|
||||
u_int dvptr;
|
||||
u_int dvpacket;
|
||||
u_int need_wakeup;
|
||||
struct selinfo rsel;
|
||||
caddr_t sc;
|
||||
void (*hand) __P((struct fw_xferq *));
|
||||
};
|
||||
struct fw_xferq
|
||||
*arq, *atq, *ars, *ats, *it[FW_MAX_DMACH],*ir[FW_MAX_DMACH];
|
||||
struct fw_bulkxfer{
|
||||
u_int32_t flag;
|
||||
caddr_t buf;
|
||||
STAILQ_ENTRY(fw_bulkxfer) link;
|
||||
caddr_t start;
|
||||
caddr_t end;
|
||||
u_int npacket;
|
||||
};
|
||||
struct fw_dvbuf{
|
||||
caddr_t buf;
|
||||
STAILQ_ENTRY(fw_dvbuf) link;
|
||||
};
|
||||
struct tlabel{
|
||||
struct fw_xfer *xfer;
|
||||
STAILQ_ENTRY(tlabel) link;
|
||||
};
|
||||
STAILQ_HEAD(, tlabel) tlabels[0x40];
|
||||
struct fw_bind{
|
||||
u_int32_t start_hi, start_lo, addrlen;
|
||||
struct fw_xfer* xfer;
|
||||
STAILQ_ENTRY(fw_bind) fclist;
|
||||
STAILQ_ENTRY(fw_bind) chlist;
|
||||
};
|
||||
STAILQ_HEAD(, fw_bind) binds;
|
||||
TAILQ_HEAD(, fw_device) devices;
|
||||
STAILQ_HEAD(, fw_xfer) pending;
|
||||
volatile u_int32_t *sid_buf;
|
||||
u_int sid_cnt;
|
||||
#define CSRSIZE 0x4000
|
||||
u_int32_t csr_arc[CSRSIZE/4];
|
||||
#define CROMSIZE 0x400
|
||||
u_int32_t *config_rom;
|
||||
struct fw_topology_map *topology_map;
|
||||
struct fw_speed_map *speed_map;
|
||||
struct callout_handle tlhandle;
|
||||
struct callout_handle bmrhandle;
|
||||
struct callout_handle timeouthandle;
|
||||
struct callout_handle retry_probe_handle;
|
||||
u_int32_t (*cyctimer) __P((struct firewire_comm *));
|
||||
void (*ibr) __P((struct firewire_comm *));
|
||||
u_int32_t (*set_bmr) __P((struct firewire_comm *, u_int32_t));
|
||||
int (*ioctl) __P((dev_t, u_long, caddr_t, int, fw_proc *));
|
||||
int (*irx_enable) __P((struct firewire_comm *, int));
|
||||
int (*irx_disable) __P((struct firewire_comm *, int));
|
||||
int (*itx_enable) __P((struct firewire_comm *, int));
|
||||
int (*itx_disable) __P((struct firewire_comm *, int));
|
||||
void (*timeout) __P((void *));
|
||||
void (*poll) __P((struct firewire_comm *, int, int));
|
||||
void (*set_intr) __P((struct firewire_comm *, int));
|
||||
void (*irx_post) __P((struct firewire_comm *, u_int32_t *));
|
||||
void (*itx_post) __P((struct firewire_comm *, u_int32_t *));
|
||||
struct tcode_info *tcode;
|
||||
};
|
||||
#define CSRARC(sc, offset) ((sc)->csr_arc[(offset)/4])
|
||||
|
||||
|
||||
struct fw_xfer{
|
||||
caddr_t sc;
|
||||
struct firewire_comm *fc;
|
||||
struct fw_xferq *q;
|
||||
struct callout_handle ch;
|
||||
time_t time;
|
||||
struct fw_tlabel *tlabel;
|
||||
u_int8_t spd;
|
||||
u_int8_t tcode;
|
||||
int resp;
|
||||
#define FWXF_INIT 0
|
||||
#define FWXF_INQ 1
|
||||
#define FWXF_START 2
|
||||
#define FWXF_SENT 3
|
||||
#define FWXF_SENTERR 4
|
||||
#define FWXF_BUSY 8
|
||||
#define FWXF_RCVD 10
|
||||
int state;
|
||||
u_int8_t retry;
|
||||
u_int8_t tl;
|
||||
int sub;
|
||||
int32_t dst;
|
||||
u_int8_t act_type;
|
||||
#define FWACT_NULL 0
|
||||
#define FWACT_XFER 2
|
||||
#define FWACT_CH 3
|
||||
void (*retry_req) __P((struct fw_xfer *));
|
||||
union{
|
||||
void (*hand) __P((struct fw_xfer *));
|
||||
|
||||
} act;
|
||||
union{
|
||||
struct {
|
||||
struct fw_device *device;
|
||||
} req;
|
||||
struct {
|
||||
struct stch *channel;
|
||||
} stream;
|
||||
} mode;
|
||||
struct {
|
||||
u_int16_t len, off;
|
||||
caddr_t buf;
|
||||
} send, recv;
|
||||
struct mbuf *mbuf;
|
||||
STAILQ_ENTRY(fw_xfer) link;
|
||||
};
|
||||
void fw_sidrcv __P((struct firewire_comm *, caddr_t, u_int, u_int));
|
||||
void fw_rcv __P((struct firewire_comm *, caddr_t, u_int, u_int, u_int, u_int));
|
||||
void fw_xfer_free __P(( struct fw_xfer*));
|
||||
struct fw_xfer *fw_xfer_alloc __P((void));
|
||||
void fw_init __P((struct firewire_comm *));
|
||||
int fw_tbuf_update __P((struct firewire_comm *, int, int));
|
||||
int fw_rbuf_update __P((struct firewire_comm *, int, int));
|
||||
int fw_readreqq __P((struct firewire_comm *, u_int32_t, u_int32_t, u_int32_t *));
|
||||
int fw_writereqb __P((struct firewire_comm *, u_int32_t, u_int32_t, u_int32_t, u_int32_t *));
|
||||
int fw_readresb __P((struct firewire_comm *, u_int32_t, u_int32_t, u_int32_t, u_int32_t*));
|
||||
int fw_writeres __P((struct firewire_comm *, u_int32_t, u_int32_t));
|
||||
u_int32_t getcsrdata __P((struct fw_device *, u_int8_t));
|
||||
void fw_asybusy __P((struct fw_xfer *));
|
||||
int fw_bindadd __P((struct firewire_comm *, struct fw_bind *));
|
||||
int fw_bindremove __P((struct firewire_comm *, struct fw_bind *));
|
||||
int fw_asyreq __P((struct firewire_comm *, int, struct fw_xfer*));
|
||||
void fw_busreset __P((struct firewire_comm *));
|
||||
u_int16_t fw_crc16 __P((u_int32_t *, u_int32_t));
|
||||
void fw_xfer_timeout __P((void *));
|
||||
void fw_xfer_done __P((struct fw_xfer *));
|
||||
void fw_asy_callback __P((struct fw_xfer *));
|
||||
|
||||
extern int firewire_debug;
|
||||
extern devclass_t firewire_devclass;
|
||||
|
||||
#define DV_BROADCAST_ON (1<<30)
|
||||
#define IP_CHANNELS 0x0234
|
||||
|
||||
#define STATE_CLEAR 0x0000
|
||||
#define STATE_SET 0x0004
|
||||
#define NODE_IDS 0x0008
|
||||
#define RESET_START 0x000c
|
||||
#define SPLIT_TIMEOUT_HI 0x0018
|
||||
#define SPLIT_TIMEOUT_LO 0x001c
|
||||
#define CYCLE_TIME 0x0200
|
||||
#define BUS_TIME 0x0210
|
||||
#define BUS_MGR_ID 0x021c
|
||||
#define BANDWIDTH_AV 0x0220
|
||||
#define CHANNELS_AV_HI 0x0224
|
||||
#define CHANNELS_AV_LO 0x0228
|
||||
|
||||
#define CONF_ROM 0x0400
|
||||
|
||||
#define TOPO_MAP 0x1000
|
||||
#define SPED_MAP 0x2000
|
||||
|
||||
#define oMPR 0x900
|
||||
#define oPCR 0x904
|
||||
|
||||
#define iMPR 0x980
|
||||
#define iPCR 0x984
|
||||
|
||||
#define FWPRI ((PZERO+8)|PCATCH)
|
||||
|
||||
#ifdef __alpha__
|
||||
#undef vtophys
|
||||
#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)(va))
|
||||
#endif /* __alpha__ */
|
219
sys/dev/firewire/fw_tap.c
Normal file
219
sys/dev/firewire/fw_tap.c
Normal file
@ -0,0 +1,219 @@
|
||||
/*
|
||||
* Copyright (C) 2002
|
||||
* Hidetoshi Shimokawa. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
*
|
||||
* This product includes software developed by Hidetoshi Shimokawa.
|
||||
*
|
||||
* 4. Neither the name of the author nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/poll.h>
|
||||
#include <dev/firewire/firewire.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <err.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
struct fwinfo {
|
||||
int fd;
|
||||
struct fw_asyreq *asyreq;
|
||||
} fw;
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
printf("fw_tap [-f fwdev] [-t tapdev] channel\n");
|
||||
exit(0);
|
||||
}
|
||||
static struct fwinfo
|
||||
init_fw(char *fwdev, int ch)
|
||||
{
|
||||
struct fw_isochreq chreq;
|
||||
struct fw_asyreq *asyreq;
|
||||
int fd;
|
||||
struct fwinfo fw;
|
||||
|
||||
if ((fd = open(fwdev, O_RDWR)) < 0)
|
||||
err(1, "open");
|
||||
|
||||
printf("ch=%d\n", ch);
|
||||
chreq.ch = ch;
|
||||
chreq.tag = 0;
|
||||
if (ioctl(fd, FW_SRSTREAM, &chreq) < 0)
|
||||
err(1, "ioctl");
|
||||
|
||||
asyreq = (struct fw_asyreq *)malloc(sizeof(struct fw_asyreq));
|
||||
asyreq->req.type = FWASREQSTREAM;
|
||||
asyreq->req.sped = 2; /* S400 */
|
||||
asyreq->pkt.mode.stream.tcode = FWTCODE_STREAM;
|
||||
asyreq->pkt.mode.stream.sy = 0;
|
||||
asyreq->pkt.mode.stream.chtag = ch;
|
||||
|
||||
fw.asyreq = asyreq;
|
||||
fw.fd = fd;
|
||||
|
||||
return fw;
|
||||
}
|
||||
|
||||
static int
|
||||
init_tap(char *tapdev)
|
||||
{
|
||||
int fd;
|
||||
|
||||
if ((fd = open(tapdev, O_RDWR)) < 0)
|
||||
err(1, "open");
|
||||
/*
|
||||
* XXX We need to make it be promiscuous mode to discard packets
|
||||
* which upper layer shouldn't see in ether_demux() of if_ethersub.c.
|
||||
* use netgraph?
|
||||
*/
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
send_stream(struct fwinfo *fw, int len)
|
||||
{
|
||||
struct fw_asyreq *asyreq;
|
||||
|
||||
asyreq = fw->asyreq;
|
||||
asyreq->req.len = len + 4;
|
||||
asyreq->pkt.mode.stream.len = htons(len);
|
||||
if (ioctl(fw->fd, FW_ASYREQ, asyreq) < 0)
|
||||
err(1, "ioctl");
|
||||
}
|
||||
|
||||
|
||||
#define MTU 2048
|
||||
#define HDR 4
|
||||
static void
|
||||
fw2tap(struct fwinfo fw, int tapd)
|
||||
{
|
||||
int res, size;
|
||||
struct pollfd pfd[2];
|
||||
char *buf, *fwbuf;
|
||||
int fwd;
|
||||
|
||||
fwd = fw.fd;
|
||||
pfd[0].fd = fwd;
|
||||
pfd[0].events = POLLIN;
|
||||
pfd[1].fd = tapd;
|
||||
pfd[1].events = POLLIN;
|
||||
fwbuf = (char *)&fw.asyreq->pkt.mode.stream.payload[0];
|
||||
if ((buf = malloc(MTU + HDR)) == NULL)
|
||||
err(1, "malloc");
|
||||
|
||||
|
||||
while (1) {
|
||||
res = poll(pfd, 2, -1);
|
||||
if (pfd[0].revents & POLLIN) {
|
||||
size = read(fwd, buf, MTU + HDR);
|
||||
#if 0
|
||||
printf("in %5d bytes\n", size - HDR);
|
||||
#endif
|
||||
write(tapd, buf + HDR, size - HDR);
|
||||
}
|
||||
if (pfd[1].revents & POLLIN) {
|
||||
size = read(tapd, fwbuf, MTU);
|
||||
#if 0
|
||||
printf("out %5d bytes\n", size);
|
||||
#endif
|
||||
send_stream(&fw, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int ch;
|
||||
int tapd;
|
||||
struct fwinfo fw;
|
||||
char *fwdev, *tapdev;
|
||||
|
||||
if (argc < 2) {
|
||||
usage();
|
||||
}
|
||||
|
||||
fwdev = "/dev/fw2";
|
||||
tapdev = "/dev/tap0";
|
||||
ch = 0;
|
||||
|
||||
argv++;
|
||||
argc--;
|
||||
while (argc > 0) {
|
||||
if (strcmp(*argv, "-f") == 0) {
|
||||
/* fw device */
|
||||
argv++;
|
||||
argc--;
|
||||
if (argc > 0) {
|
||||
fwdev = *argv;
|
||||
argv++;
|
||||
argc--;
|
||||
} else {
|
||||
usage();
|
||||
}
|
||||
} else if (strcmp(*argv, "-t") == 0) {
|
||||
/* tap device */
|
||||
argv++;
|
||||
argc--;
|
||||
if (argc > 0) {
|
||||
tapdev = *argv;
|
||||
argv++;
|
||||
argc--;
|
||||
} else {
|
||||
usage();
|
||||
}
|
||||
} else if (argc > 0) {
|
||||
ch = strtoul(*argv, (char **)NULL, 0);
|
||||
argv++;
|
||||
argc--;
|
||||
} else {
|
||||
usage();
|
||||
}
|
||||
}
|
||||
fw = init_fw(fwdev, ch);
|
||||
tapd = init_tap(tapdev);
|
||||
fw2tap(fw, tapd);
|
||||
return 0;
|
||||
}
|
254
sys/dev/firewire/fwmem.c
Normal file
254
sys/dev/firewire/fwmem.c
Normal file
@ -0,0 +1,254 @@
|
||||
/*
|
||||
* Copyright (C) 2002
|
||||
* Hidetoshi Shimokawa. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
*
|
||||
* This product includes software developed by Hidetoshi Shimokawa.
|
||||
*
|
||||
* 4. Neither the name of the author nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <sys/bus.h>
|
||||
|
||||
#include <sys/signal.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/ioccom.h>
|
||||
|
||||
#include <dev/firewire/firewire.h>
|
||||
#include <dev/firewire/firewirereg.h>
|
||||
#include <dev/firewire/fwmem.h>
|
||||
|
||||
static int fwmem_node=0, fwmem_speed=2, fwmem_debug=0;
|
||||
SYSCTL_DECL(_hw_firewire);
|
||||
SYSCTL_NODE(_hw_firewire, OID_AUTO, fwmem, CTLFLAG_RD, 0,
|
||||
"Firewire Memory Access");
|
||||
SYSCTL_INT(_hw_firewire_fwmem, OID_AUTO, node, CTLFLAG_RW, &fwmem_node, 0,
|
||||
"Fwmem target node");
|
||||
SYSCTL_INT(_hw_firewire_fwmem, OID_AUTO, speed, CTLFLAG_RW, &fwmem_speed, 0,
|
||||
"Fwmem link speed");
|
||||
SYSCTL_INT(_debug, OID_AUTO, fwmem_debug, CTLFLAG_RW, &fwmem_debug, 0,
|
||||
"Fwmem driver debug flag");
|
||||
|
||||
struct fw_xfer *
|
||||
fwmem_read_quad(
|
||||
struct firewire_comm *fc,
|
||||
int dst,
|
||||
u_int16_t dst_hi,
|
||||
u_int32_t dst_lo
|
||||
)
|
||||
{
|
||||
struct fw_xfer *xfer;
|
||||
struct fw_pkt *fp;
|
||||
int err = 0;
|
||||
|
||||
xfer = fw_xfer_alloc();
|
||||
if (xfer == NULL) {
|
||||
err = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
xfer->fc = fc;
|
||||
xfer->dst = FWLOCALBUS | dst;
|
||||
xfer->spd = fwmem_speed; /* XXX */
|
||||
xfer->send.len = 12;
|
||||
xfer->send.buf = malloc(xfer->send.len, M_DEVBUF, M_NOWAIT | M_ZERO);
|
||||
if (xfer->send.buf == NULL) {
|
||||
err = ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
xfer->send.off = 0;
|
||||
xfer->act.hand = fw_asy_callback;
|
||||
xfer->retry_req = fw_asybusy;
|
||||
xfer->sc = NULL;
|
||||
|
||||
fp = (struct fw_pkt *)xfer->send.buf;
|
||||
fp->mode.rreqq.tcode = FWTCODE_RREQQ;
|
||||
fp->mode.rreqq.dst = htons(xfer->dst);
|
||||
fp->mode.rreqq.dest_hi = htons(dst_hi);
|
||||
fp->mode.rreqq.dest_lo = htonl(dst_lo);
|
||||
|
||||
if (fwmem_debug)
|
||||
printf("fwmem: %d %04x:%08x\n", dst, dst_hi, dst_lo);
|
||||
err = fw_asyreq(fc, -1, xfer);
|
||||
if (err)
|
||||
goto error;
|
||||
err = tsleep((caddr_t)xfer, FWPRI, "fwmem", hz);
|
||||
if (err == 0) {
|
||||
return xfer;
|
||||
}
|
||||
error:
|
||||
fw_xfer_free(xfer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct fw_xfer *
|
||||
fwmem_read_block(
|
||||
struct firewire_comm *fc,
|
||||
int dst,
|
||||
u_int16_t dst_hi,
|
||||
u_int32_t dst_lo,
|
||||
int len
|
||||
)
|
||||
{
|
||||
struct fw_xfer *xfer;
|
||||
struct fw_pkt *fp;
|
||||
int err = 0;
|
||||
|
||||
xfer = fw_xfer_alloc();
|
||||
if (xfer == NULL) {
|
||||
err = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
xfer->fc = fc;
|
||||
xfer->dst = FWLOCALBUS | dst;
|
||||
xfer->spd = fwmem_speed; /* XXX */
|
||||
xfer->send.len = 16;
|
||||
xfer->send.buf = malloc(xfer->send.len, M_DEVBUF, M_NOWAIT | M_ZERO);
|
||||
if (xfer->send.buf == NULL) {
|
||||
err = ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
xfer->send.off = 0;
|
||||
xfer->act.hand = fw_asy_callback;
|
||||
xfer->retry_req = fw_asybusy;
|
||||
xfer->sc = NULL;
|
||||
|
||||
fp = (struct fw_pkt *)xfer->send.buf;
|
||||
fp->mode.rreqb.tcode = FWTCODE_RREQB;
|
||||
fp->mode.rreqb.dst = htons(xfer->dst);
|
||||
fp->mode.rreqb.dest_hi = htons(dst_hi);
|
||||
fp->mode.rreqb.dest_lo = htonl(dst_lo);
|
||||
fp->mode.rreqb.len = htons(len);
|
||||
|
||||
if (fwmem_debug)
|
||||
printf("fwmem: %d %04x:%08x %d\n", dst, dst_hi, dst_lo, len);
|
||||
err = fw_asyreq(fc, -1, xfer);
|
||||
if (err)
|
||||
goto error;
|
||||
err = tsleep((caddr_t)xfer, FWPRI, "fwmem", hz);
|
||||
if (err == 0) {
|
||||
return xfer;
|
||||
}
|
||||
error:
|
||||
fw_xfer_free(xfer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
fwmem_open (dev_t dev, int flags, int fmt, fw_proc *td)
|
||||
{
|
||||
int err = 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
fwmem_close (dev_t dev, int flags, int fmt, fw_proc *td)
|
||||
{
|
||||
int err = 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
#define MAXLEN 2048
|
||||
#define USE_QUAD 0
|
||||
int
|
||||
fwmem_read (dev_t dev, struct uio *uio, int ioflag)
|
||||
{
|
||||
struct firewire_softc *sc;
|
||||
struct firewire_comm *fc;
|
||||
struct fw_xfer *xfer;
|
||||
int err = 0, pad;
|
||||
int unit = DEV2UNIT(dev);
|
||||
u_int16_t dst_hi;
|
||||
u_int32_t dst_lo;
|
||||
off_t offset;
|
||||
int len;
|
||||
|
||||
sc = devclass_get_softc(firewire_devclass, unit);
|
||||
fc = sc->fc;
|
||||
|
||||
pad = uio->uio_offset % 4;
|
||||
if (fwmem_debug && pad != 0)
|
||||
printf("unaligned\n");
|
||||
while(uio->uio_resid > 0) {
|
||||
offset = uio->uio_offset;
|
||||
offset -= pad;
|
||||
dst_hi = (offset >> 32) & 0xffff;
|
||||
dst_lo = offset & 0xffffffff;
|
||||
#if USE_QUAD
|
||||
xfer = fwmem_read_quad(fc, fwmem_node, dst_hi, dst_lo);
|
||||
if (xfer == NULL || xfer->resp != 0 || xfer->recv.buf == NULL)
|
||||
return EINVAL; /* XXX */
|
||||
err = uiomove(xfer->recv.buf + xfer->recv.off + 4*3 + pad,
|
||||
4 - pad, uio);
|
||||
#else
|
||||
len = uio->uio_resid;
|
||||
if (len > MAXLEN)
|
||||
len = MAXLEN;
|
||||
xfer = fwmem_read_block(fc, fwmem_node, dst_hi, dst_lo, len);
|
||||
if (xfer == NULL || xfer->resp != 0 || xfer->recv.buf == NULL)
|
||||
return EINVAL; /* XXX */
|
||||
err = uiomove(xfer->recv.buf + xfer->recv.off + 4*4 + pad,
|
||||
len - pad, uio);
|
||||
#endif
|
||||
if (err)
|
||||
return err;
|
||||
fw_xfer_free(xfer);
|
||||
pad = 0;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
int
|
||||
fwmem_write (dev_t dev, struct uio *uio, int ioflag)
|
||||
{
|
||||
return EINVAL;
|
||||
}
|
||||
int
|
||||
fwmem_ioctl (dev_t dev, u_long cmd, caddr_t data, int flag, fw_proc *td)
|
||||
{
|
||||
return EINVAL;
|
||||
}
|
||||
int
|
||||
fwmem_poll (dev_t dev, int events, fw_proc *td)
|
||||
{
|
||||
return EINVAL;
|
||||
}
|
||||
int
|
||||
fwmem_mmap (dev_t dev, vm_offset_t offset, int nproto)
|
||||
{
|
||||
return EINVAL;
|
||||
}
|
47
sys/dev/firewire/fwmem.h
Normal file
47
sys/dev/firewire/fwmem.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2002
|
||||
* Hidetoshi Shimokawa. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
*
|
||||
* This product includes software developed by Hidetoshi Shimokawa.
|
||||
*
|
||||
* 4. Neither the name of the author nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
struct fw_xfer * fwmem_read_quad(struct firewire_comm *,
|
||||
int, u_int16_t, u_int32_t);
|
||||
struct fw_xfer * fwmem_read_block(struct firewire_comm *,
|
||||
int, u_int16_t, u_int32_t, int);
|
||||
d_open_t fwmem_open;
|
||||
d_close_t fwmem_close;
|
||||
d_ioctl_t fwmem_ioctl;
|
||||
d_read_t fwmem_read;
|
||||
d_write_t fwmem_write;
|
||||
d_poll_t fwmem_poll;
|
||||
d_mmap_t fwmem_mmap;
|
2649
sys/dev/firewire/fwohci.c
Normal file
2649
sys/dev/firewire/fwohci.c
Normal file
File diff suppressed because it is too large
Load Diff
294
sys/dev/firewire/fwohci_pci.c
Normal file
294
sys/dev/firewire/fwohci_pci.c
Normal file
@ -0,0 +1,294 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the acknowledgement as bellow:
|
||||
*
|
||||
* This product includes software developed by K. Kobayashi and H. SHimokawa
|
||||
*
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
*/
|
||||
#include "opt_bus.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/queue.h>
|
||||
#include <machine/bus.h>
|
||||
#include <sys/rman.h>
|
||||
#include <machine/resource.h>
|
||||
|
||||
#include <pci/pcivar.h>
|
||||
#include <pci/pcireg.h>
|
||||
|
||||
#include <dev/firewire/firewire.h>
|
||||
#include <dev/firewire/firewirebusreg.h>
|
||||
#include <dev/firewire/firewirereg.h>
|
||||
|
||||
#include <dev/firewire/fwohcireg.h>
|
||||
#include <dev/firewire/fwohcivar.h>
|
||||
|
||||
static int fwohci_pci_attach(device_t self);
|
||||
static int fwohci_pci_detach(device_t self);
|
||||
|
||||
/*
|
||||
* The probe routine.
|
||||
*/
|
||||
static int
|
||||
fwohci_pci_probe( device_t dev )
|
||||
{
|
||||
#if 1
|
||||
if ((pci_get_vendor(dev) == FW_VENDORID_NEC) &&
|
||||
(pci_get_device(dev) == FW_DEVICE_UPD861)) {
|
||||
device_set_desc(dev, "NEC uPD72861");
|
||||
return 0;
|
||||
}
|
||||
if ((pci_get_vendor(dev) == FW_VENDORID_TI) &&
|
||||
(pci_get_device(dev) == FW_DEVICE_TITSB22)) {
|
||||
device_set_desc(dev, "Texas Instruments TSB12LV22");
|
||||
return 0;
|
||||
}
|
||||
if ((pci_get_vendor(dev) == FW_VENDORID_TI) &&
|
||||
(pci_get_device(dev) == FW_DEVICE_TITSB23)) {
|
||||
device_set_desc(dev, "Texas Instruments TSB12LV23");
|
||||
return 0;
|
||||
}
|
||||
if ((pci_get_vendor(dev) == FW_VENDORID_TI) &&
|
||||
(pci_get_device(dev) == FW_DEVICE_TITSB26)) {
|
||||
device_set_desc(dev, "Texas Instruments TSB12LV26");
|
||||
return 0;
|
||||
}
|
||||
if ((pci_get_vendor(dev) == FW_VENDORID_TI) &&
|
||||
(pci_get_device(dev) == FW_DEVICE_TITSB43)) {
|
||||
device_set_desc(dev, "Texas Instruments TSB43AA22");
|
||||
return 0;
|
||||
}
|
||||
if ((pci_get_vendor(dev) == FW_VENDORID_SONY) &&
|
||||
(pci_get_device(dev) == FW_DEVICE_CX3022)) {
|
||||
device_set_desc(dev, "SONY CX3022");
|
||||
return 0;
|
||||
}
|
||||
if ((pci_get_vendor(dev) == FW_VENDORID_VIA) &&
|
||||
(pci_get_device(dev) == FW_DEVICE_VT6306)) {
|
||||
device_set_desc(dev, "VIA VT6306");
|
||||
return 0;
|
||||
}
|
||||
if ((pci_get_vendor(dev) == FW_VENDORID_RICOH) &&
|
||||
(pci_get_device(dev) == FW_DEVICE_R5C552)) {
|
||||
device_set_desc(dev, "Ricoh R5C552");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if (pci_get_class(dev) == PCIC_SERIALBUS
|
||||
&& pci_get_subclass(dev) == PCIS_SERIALBUS_FW
|
||||
&& pci_get_progif(dev) == PCI_INTERFACE_OHCI) {
|
||||
device_set_desc(dev, "1394 Open Host Controller Interface");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ENXIO;
|
||||
}
|
||||
|
||||
#if __FreeBSD_version < 500000
|
||||
static void
|
||||
fwohci_dummy_intr(void *arg)
|
||||
{
|
||||
/* XXX do nothing */
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
fwohci_pci_attach(device_t self)
|
||||
{
|
||||
fwohci_softc_t *sc = device_get_softc(self);
|
||||
int err;
|
||||
int rid;
|
||||
int intr;
|
||||
int latency, cache_line;
|
||||
u_int16_t cmd;
|
||||
/* For the moment, put in a message stating what is wrong */
|
||||
intr = pci_read_config(self, PCIR_INTLINE, 1);
|
||||
if (intr == 0 || intr == 255) {
|
||||
device_printf(self, "Invalid irq %d\n", intr);
|
||||
#ifdef __i386__
|
||||
device_printf(self, "Please switch PNP-OS to 'No' in BIOS\n");
|
||||
#endif
|
||||
return ENXIO;
|
||||
}
|
||||
|
||||
cmd = pci_read_config(self, PCIR_COMMAND, 2);
|
||||
cmd |= PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN | PCIM_CMD_MWRICEN;
|
||||
pci_write_config(self, PCIR_COMMAND, cmd, 2);
|
||||
|
||||
latency = pci_read_config(self, PCIR_LATTIMER, 1);
|
||||
#define DEF_LATENCY 250 /* Derived from Max Bulk Transfer size 512 Bytes*/
|
||||
if( latency < DEF_LATENCY ) {
|
||||
latency = DEF_LATENCY;
|
||||
device_printf(self, "PCI bus latency was changing to");
|
||||
pci_write_config(self, PCIR_LATTIMER,latency, 1);
|
||||
} else
|
||||
{
|
||||
device_printf(self, "PCI bus latency is");
|
||||
}
|
||||
printf(" %d.\n", (int) latency);
|
||||
cache_line = pci_read_config(self, PCIR_CACHELNSZ, 1);
|
||||
#if 0
|
||||
#define DEF_CACHE_LINE 0xc
|
||||
cache_line = DEF_CACHE_LINE;
|
||||
pci_write_config(self, PCIR_CACHELNSZ, cache_line, 1);
|
||||
#endif
|
||||
printf("cache size %d.\n", (int) cache_line);
|
||||
/**/
|
||||
rid = PCI_CBMEM;
|
||||
sc->bsr = bus_alloc_resource(self, SYS_RES_MEMORY, &rid,
|
||||
0, ~0, 1, RF_ACTIVE);
|
||||
if (!sc->bsr) {
|
||||
device_printf(self, "Could not map memory\n");
|
||||
return ENXIO;
|
||||
}
|
||||
|
||||
sc->bst = rman_get_bustag(sc->bsr);
|
||||
sc->bsh = rman_get_bushandle(sc->bsr);
|
||||
|
||||
rid = 0;
|
||||
sc->irq_res = bus_alloc_resource(self, SYS_RES_IRQ, &rid, 0, ~0, 1,
|
||||
RF_SHAREABLE | RF_ACTIVE);
|
||||
if (sc->irq_res == NULL) {
|
||||
device_printf(self, "Could not allocate irq\n");
|
||||
fwohci_pci_detach(self);
|
||||
return ENXIO;
|
||||
}
|
||||
|
||||
sc->fc.bdev = device_add_child(self, "firewire", -1);
|
||||
if (!sc->fc.bdev) {
|
||||
device_printf(self, "Could not add firewire device\n");
|
||||
fwohci_pci_detach(self);
|
||||
return ENOMEM;
|
||||
}
|
||||
device_set_ivars(sc->fc.bdev, sc);
|
||||
|
||||
err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_NET,
|
||||
(driver_intr_t *) fwohci_intr, sc, &sc->ih);
|
||||
#if __FreeBSD_version < 500000
|
||||
/* XXX splcam() should mask this irq for sbp.c*/
|
||||
err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_CAM,
|
||||
(driver_intr_t *) fwohci_dummy_intr, sc, &sc->ih_cam);
|
||||
#endif
|
||||
if (err) {
|
||||
device_printf(self, "Could not setup irq, %d\n", err);
|
||||
fwohci_pci_detach(self);
|
||||
return ENXIO;
|
||||
}
|
||||
|
||||
err = fwohci_init(sc, self);
|
||||
|
||||
if (!err)
|
||||
err = device_probe_and_attach(sc->fc.bdev);
|
||||
|
||||
if (err) {
|
||||
device_printf(self, "Firewire init failed\n");
|
||||
fwohci_pci_detach(self);
|
||||
return EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
fwohci_pci_detach(device_t self)
|
||||
{
|
||||
fwohci_softc_t *sc = device_get_softc(self);
|
||||
int s;
|
||||
|
||||
|
||||
s = splfw();
|
||||
bus_generic_detach(self);
|
||||
|
||||
/* disable interrupts that might have been switched on */
|
||||
if (sc->bst && sc->bsh)
|
||||
bus_space_write_4(sc->bst, sc->bsh,
|
||||
FWOHCI_INTMASKCLR, OHCI_INT_EN);
|
||||
|
||||
if (sc->irq_res) {
|
||||
int err = bus_teardown_intr(self, sc->irq_res, sc->ih);
|
||||
if (err)
|
||||
/* XXX or should we panic? */
|
||||
device_printf(self, "Could not tear down irq, %d\n",
|
||||
err);
|
||||
#if __FreeBSD_version < 500000
|
||||
err = bus_teardown_intr(self, sc->irq_res, sc->ih_cam);
|
||||
#endif
|
||||
sc->ih = NULL;
|
||||
}
|
||||
|
||||
if (sc->fc.bdev) {
|
||||
device_delete_child(self, sc->fc.bdev);
|
||||
sc->fc.bdev = NULL;
|
||||
}
|
||||
|
||||
if (sc->irq_res) {
|
||||
bus_release_resource(self, SYS_RES_IRQ, 0, sc->irq_res);
|
||||
sc->irq_res = NULL;
|
||||
}
|
||||
|
||||
if (sc->bsr) {
|
||||
bus_release_resource(self, SYS_RES_MEMORY,PCI_CBMEM,sc->bsr);
|
||||
sc->bsr = NULL;
|
||||
sc->bst = 0;
|
||||
sc->bsh = 0;
|
||||
}
|
||||
splx(s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static device_method_t fwohci_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, fwohci_pci_probe),
|
||||
DEVMETHOD(device_attach, fwohci_pci_attach),
|
||||
DEVMETHOD(device_detach, fwohci_pci_detach),
|
||||
DEVMETHOD(device_shutdown, bus_generic_shutdown),
|
||||
|
||||
/* Bus interface */
|
||||
DEVMETHOD(bus_print_child, bus_generic_print_child),
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static driver_t fwohci_driver = {
|
||||
"fwohci",
|
||||
fwohci_methods,
|
||||
sizeof(fwohci_softc_t),
|
||||
};
|
||||
|
||||
static devclass_t fwohci_devclass;
|
||||
|
||||
DRIVER_MODULE(fwohci, pci, fwohci_driver, fwohci_devclass, 0, 0);
|
||||
DRIVER_MODULE(fwohci, cardbus, fwohci_driver, fwohci_devclass, 0, 0);
|
394
sys/dev/firewire/fwohcireg.h
Normal file
394
sys/dev/firewire/fwohcireg.h
Normal file
@ -0,0 +1,394 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2001 Katsushi Kobayashi and Hidetoshi Shimokawa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the acknowledgement as bellow:
|
||||
*
|
||||
* This product includes software developed by K. Kobayashi and H. Shimokawa
|
||||
*
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
*/
|
||||
#define PCI_CBMEM 0x10
|
||||
|
||||
#define FW_VENDORID_NEC 0x1033
|
||||
#define FW_VENDORID_TI 0x104c
|
||||
#define FW_VENDORID_SONY 0x104d
|
||||
#define FW_VENDORID_VIA 0x1106
|
||||
#define FW_VENDORID_RICOH 0x1180
|
||||
|
||||
#define FW_DEVICE_UPD861 0x0063
|
||||
#define FW_DEVICE_TITSB22 0x8009
|
||||
#define FW_DEVICE_TITSB23 0x8019
|
||||
#define FW_DEVICE_TITSB26 0x8020
|
||||
#define FW_DEVICE_TITSB43 0x8021
|
||||
#define FW_DEVICE_CX3022 0x8039
|
||||
#define FW_DEVICE_VT6306 0x3044
|
||||
#define FW_DEVICE_R5C552 0x1180
|
||||
|
||||
#define PCI_INTERFACE_OHCI 0x10
|
||||
|
||||
#define FW_OHCI_BASE_REG 0x10
|
||||
|
||||
#define OHCI_DMA_ITCH 0x20
|
||||
#define OHCI_DMA_IRCH 0x20
|
||||
|
||||
#define OHCI_MAX_DMA_CH (0x4 + OHCI_DMA_ITCH + OHCI_DMA_IRCH)
|
||||
|
||||
|
||||
typedef volatile u_int32_t fwohcireg_t;
|
||||
|
||||
struct fwohcidb {
|
||||
union {
|
||||
struct {
|
||||
volatile u_int32_t cmd;
|
||||
volatile u_int32_t addr;
|
||||
volatile u_int32_t depend;
|
||||
volatile u_int32_t count:16,
|
||||
status:16;
|
||||
} desc;
|
||||
volatile u_int32_t immed[4];
|
||||
} db;
|
||||
#define OHCI_OUTPUT_MORE (0 << 28)
|
||||
#define OHCI_OUTPUT_LAST (1 << 28)
|
||||
#define OHCI_INPUT_MORE (2 << 28)
|
||||
#define OHCI_INPUT_LAST (3 << 28)
|
||||
#define OHCI_STORE_QUAD (4 << 28)
|
||||
#define OHCI_LOAD_QUAD (5 << 28)
|
||||
#define OHCI_NOP (6 << 28)
|
||||
#define OHCI_STOP (7 << 28)
|
||||
#define OHCI_STORE (8 << 28)
|
||||
#define OHCI_CMD_MASK (0xf << 28)
|
||||
|
||||
#define OHCI_UPDATE (1 << 27)
|
||||
|
||||
#define OHCI_KEY_ST0 (0 << 24)
|
||||
#define OHCI_KEY_ST1 (1 << 24)
|
||||
#define OHCI_KEY_ST2 (2 << 24)
|
||||
#define OHCI_KEY_ST3 (3 << 24)
|
||||
#define OHCI_KEY_REGS (5 << 24)
|
||||
#define OHCI_KEY_SYS (6 << 24)
|
||||
#define OHCI_KEY_DEVICE (7 << 24)
|
||||
#define OHCI_KEY_MASK (7 << 24)
|
||||
|
||||
#define OHCI_INTERRUPT_NEVER (0 << 20)
|
||||
#define OHCI_INTERRUPT_TRUE (1 << 20)
|
||||
#define OHCI_INTERRUPT_FALSE (2 << 20)
|
||||
#define OHCI_INTERRUPT_ALWAYS (3 << 20)
|
||||
|
||||
#define OHCI_BRANCH_NEVER (0 << 18)
|
||||
#define OHCI_BRANCH_TRUE (1 << 18)
|
||||
#define OHCI_BRANCH_FALSE (2 << 18)
|
||||
#define OHCI_BRANCH_ALWAYS (3 << 18)
|
||||
#define OHCI_BRANCH_MASK (3 << 18)
|
||||
|
||||
#define OHCI_WAIT_NEVER (0 << 16)
|
||||
#define OHCI_WAIT_TRUE (1 << 16)
|
||||
#define OHCI_WAIT_FALSE (2 << 16)
|
||||
#define OHCI_WAIT_ALWAYS (3 << 16)
|
||||
};
|
||||
|
||||
#define OHCI_SPD_S100 0x4
|
||||
#define OHCI_SPD_S200 0x1
|
||||
#define OHCI_SPD_S400 0x2
|
||||
|
||||
|
||||
#define FWOHCIEV_NOSTAT 0
|
||||
#define FWOHCIEV_LONGP 2
|
||||
#define FWOHCIEV_MISSACK 3
|
||||
#define FWOHCIEV_UNDRRUN 4
|
||||
#define FWOHCIEV_OVRRUN 5
|
||||
#define FWOHCIEV_DESCERR 6
|
||||
#define FWOHCIEV_DTRDERR 7
|
||||
#define FWOHCIEV_DTWRERR 8
|
||||
#define FWOHCIEV_BUSRST 9
|
||||
#define FWOHCIEV_TIMEOUT 0xa
|
||||
#define FWOHCIEV_TCODERR 0xb
|
||||
#define FWOHCIEV_UNKNOWN 0xe
|
||||
#define FWOHCIEV_FLUSHED 0xf
|
||||
#define FWOHCIEV_ACKCOMPL 0x11
|
||||
#define FWOHCIEV_ACKPEND 0x12
|
||||
#define FWOHCIEV_ACKBSX 0x14
|
||||
#define FWOHCIEV_ACKBSA 0x15
|
||||
#define FWOHCIEV_ACKBSB 0x16
|
||||
#define FWOHCIEV_ACKTARD 0x1b
|
||||
#define FWOHCIEV_ACKDERR 0x1d
|
||||
#define FWOHCIEV_ACKTERR 0x1e
|
||||
|
||||
#define FWOHCIEV_MASK 0x1f
|
||||
|
||||
struct ohci_registers {
|
||||
fwohcireg_t ver; /* Version No. 0x0 */
|
||||
fwohcireg_t guid; /* GUID_ROM No. 0x4 */
|
||||
fwohcireg_t retry; /* AT retries 0x8 */
|
||||
#define FWOHCI_RETRY 0x8
|
||||
fwohcireg_t csr_data; /* CSR data 0xc */
|
||||
fwohcireg_t csr_cmp; /* CSR compare 0x10 */
|
||||
fwohcireg_t csr_cntl; /* CSR compare 0x14 */
|
||||
fwohcireg_t rom_hdr; /* config ROM ptr. 0x18 */
|
||||
fwohcireg_t bus_id; /* BUS_ID 0x1c */
|
||||
fwohcireg_t bus_opt; /* BUS option 0x20 */
|
||||
#define FWOHCIGUID_H 0x24
|
||||
#define FWOHCIGUID_L 0x28
|
||||
fwohcireg_t guid_hi; /* GUID hi 0x24 */
|
||||
fwohcireg_t guid_lo; /* GUID lo 0x28 */
|
||||
fwohcireg_t dummy0[2]; /* dummy 0x2c-0x30 */
|
||||
fwohcireg_t config_rom; /* config ROM map 0x34 */
|
||||
fwohcireg_t post_wr_lo; /* post write addr lo 0x38 */
|
||||
fwohcireg_t post_wr_hi; /* post write addr hi 0x3c */
|
||||
fwohcireg_t vender; /* vender ID 0x40 */
|
||||
fwohcireg_t dummy1[3]; /* dummy 0x44-0x4c */
|
||||
fwohcireg_t hcc_cntl_set; /* HCC control set 0x50 */
|
||||
fwohcireg_t hcc_cntl_clr; /* HCC control clr 0x54 */
|
||||
#define OHCI_HCC_BIGEND (1 << 30)
|
||||
#define OHCI_HCC_PRPHY (1 << 23)
|
||||
#define OHCI_HCC_PHYEN (1 << 22)
|
||||
#define OHCI_HCC_LPS (1 << 19)
|
||||
#define OHCI_HCC_POSTWR (1 << 18)
|
||||
#define OHCI_HCC_LINKEN (1 << 17)
|
||||
#define OHCI_HCC_RESET (1 << 16)
|
||||
fwohcireg_t dummy2[2]; /* dummy 0x58-0x5c */
|
||||
fwohcireg_t dummy3[1]; /* dummy 0x60 */
|
||||
fwohcireg_t sid_buf; /* self id buffer 0x64 */
|
||||
fwohcireg_t sid_cnt; /* self id count 0x68 */
|
||||
fwohcireg_t dummy4[1]; /* dummy 0x6c */
|
||||
fwohcireg_t ir_mask_hi_set; /* ir mask hi set 0x70 */
|
||||
fwohcireg_t ir_mask_hi_clr; /* ir mask hi set 0x74 */
|
||||
fwohcireg_t ir_mask_lo_set; /* ir mask hi set 0x78 */
|
||||
fwohcireg_t ir_mask_lo_clr; /* ir mask hi set 0x7c */
|
||||
#define FWOHCI_INTSTAT 0x80
|
||||
#define FWOHCI_INTSTATCLR 0x84
|
||||
#define FWOHCI_INTMASK 0x88
|
||||
#define FWOHCI_INTMASKCLR 0x8c
|
||||
fwohcireg_t int_stat; /* 0x80 */
|
||||
fwohcireg_t int_clear; /* 0x84 */
|
||||
fwohcireg_t int_mask; /* 0x88 */
|
||||
fwohcireg_t int_mask_clear; /* 0x8c */
|
||||
fwohcireg_t it_int_stat; /* 0x90 */
|
||||
fwohcireg_t it_int_clear; /* 0x94 */
|
||||
fwohcireg_t it_int_mask; /* 0x98 */
|
||||
fwohcireg_t it_mask_clear; /* 0x9c */
|
||||
fwohcireg_t ir_int_stat; /* 0xa0 */
|
||||
fwohcireg_t ir_int_clear; /* 0xa4 */
|
||||
fwohcireg_t ir_int_mask; /* 0xa8 */
|
||||
fwohcireg_t ir_mask_clear; /* 0xac */
|
||||
fwohcireg_t dummy5[11]; /* dummy 0xb0-d8 */
|
||||
fwohcireg_t fairness; /* fairness control 0xdc */
|
||||
fwohcireg_t link_cntl; /* Chip control 0xe0*/
|
||||
fwohcireg_t link_cntl_clr; /* Chip control clear 0xe4*/
|
||||
#define FWOHCI_NODEID 0xe8
|
||||
fwohcireg_t node; /* Node ID 0xe8 */
|
||||
#define OHCI_NODE_VALID (1 << 31)
|
||||
#define OHCI_NODE_ROOT (1 << 30)
|
||||
|
||||
#define OHCI_ASYSRCBUS 1
|
||||
|
||||
fwohcireg_t phy_access; /* PHY cntl 0xec */
|
||||
#define PHYDEV_RDDONE (1<<31)
|
||||
#define PHYDEV_RDCMD (1<<15)
|
||||
#define PHYDEV_WRCMD (1<<14)
|
||||
#define PHYDEV_REGADDR 8
|
||||
#define PHYDEV_WRDATA 0
|
||||
#define PHYDEV_RDADDR 24
|
||||
#define PHYDEV_RDDATA 16
|
||||
|
||||
fwohcireg_t cycle_timer; /* Cycle Timer 0xf0 */
|
||||
fwohcireg_t dummy6[3]; /* dummy 0xf4-fc */
|
||||
fwohcireg_t areq_hi; /* Async req. filter hi 0x100 */
|
||||
fwohcireg_t areq_hi_clr; /* Async req. filter hi 0x104 */
|
||||
fwohcireg_t areq_lo; /* Async req. filter lo 0x108 */
|
||||
fwohcireg_t areq_lo_clr; /* Async req. filter lo 0x10c */
|
||||
fwohcireg_t preq_hi; /* Async req. filter hi 0x110 */
|
||||
fwohcireg_t preq_hi_clr; /* Async req. filter hi 0x114 */
|
||||
fwohcireg_t preq_lo; /* Async req. filter lo 0x118 */
|
||||
fwohcireg_t preq_lo_clr; /* Async req. filter lo 0x11c */
|
||||
|
||||
fwohcireg_t pys_upper; /* Physical Upper bound 0x120 */
|
||||
|
||||
fwohcireg_t dummy7[23]; /* dummy 0x124-0x17c */
|
||||
|
||||
struct ohci_dma{
|
||||
fwohcireg_t cntl;
|
||||
|
||||
#define OHCI_CNTL_CYCMATCH_S (0x1 << 31)
|
||||
|
||||
#define OHCI_CNTL_BUFFIL (0x1 << 31)
|
||||
#define OHCI_CNTL_ISOHDR (0x1 << 30)
|
||||
#define OHCI_CNTL_CYCMATCH_R (0x1 << 29)
|
||||
#define OHCI_CNTL_MULTICH (0x1 << 28)
|
||||
|
||||
#define OHCI_CNTL_DMA_RUN (0x1 << 15)
|
||||
#define OHCI_CNTL_DMA_WAKE (0x1 << 12)
|
||||
#define OHCI_CNTL_DMA_DEAD (0x1 << 11)
|
||||
#define OHCI_CNTL_DMA_ACTIVE (0x1 << 10)
|
||||
#define OHCI_CNTL_DMA_BT (0x1 << 8)
|
||||
#define OHCI_CNTL_DMA_BAD (0x1 << 7)
|
||||
#define OHCI_CNTL_DMA_STAT (0xff)
|
||||
|
||||
fwohcireg_t cntl_clr;
|
||||
fwohcireg_t dummy0;
|
||||
fwohcireg_t cmd;
|
||||
fwohcireg_t match;
|
||||
fwohcireg_t dummy1;
|
||||
fwohcireg_t dummy2;
|
||||
fwohcireg_t dummy3;
|
||||
};
|
||||
/* 0x180, 0x184, 0x188, 0x18c */
|
||||
/* 0x190, 0x194, 0x198, 0x19c */
|
||||
/* 0x1a0, 0x1a4, 0x1a8, 0x1ac */
|
||||
/* 0x1b0, 0x1b4, 0x1b8, 0x1bc */
|
||||
/* 0x1c0, 0x1c4, 0x1c8, 0x1cc */
|
||||
/* 0x1d0, 0x1d4, 0x1d8, 0x1dc */
|
||||
/* 0x1e0, 0x1e4, 0x1e8, 0x1ec */
|
||||
/* 0x1f0, 0x1f4, 0x1f8, 0x1fc */
|
||||
struct ohci_dma dma_ch[0x4];
|
||||
|
||||
/* 0x200, 0x204, 0x208, 0x20c */
|
||||
/* 0x210, 0x204, 0x208, 0x20c */
|
||||
struct ohci_itdma{
|
||||
fwohcireg_t cntl;
|
||||
fwohcireg_t cntl_clr;
|
||||
fwohcireg_t dummy0;
|
||||
fwohcireg_t cmd;
|
||||
};
|
||||
struct ohci_itdma dma_itch[0x20];
|
||||
|
||||
/* 0x400, 0x404, 0x408, 0x40c */
|
||||
/* 0x410, 0x404, 0x408, 0x40c */
|
||||
|
||||
struct ohci_dma dma_irch[0x20];
|
||||
};
|
||||
|
||||
struct fwohcidb_tr{
|
||||
STAILQ_ENTRY(fwohcidb_tr) link;
|
||||
struct fw_xfer *xfer;
|
||||
volatile struct fwohcidb *db;
|
||||
caddr_t buf;
|
||||
caddr_t dummy;
|
||||
int dbcnt;
|
||||
};
|
||||
|
||||
/*
|
||||
* OHCI info structure.
|
||||
*/
|
||||
#if 0
|
||||
struct fwohci_softc {
|
||||
struct fw_softc fc;
|
||||
volatile struct ohci_registers *base;
|
||||
int init;
|
||||
#define SIDPHASE 1
|
||||
u_int32_t flags;
|
||||
struct fwohcidb_tr *db_tr[OHCI_MAX_DMA_CH];
|
||||
struct fwohcidb_tr *db_first[OHCI_MAX_DMA_CH];
|
||||
struct fwohcidb_tr *db_last[OHCI_MAX_DMA_CH];
|
||||
struct {
|
||||
int tail;
|
||||
struct fwohcidb_tr *db_tr;
|
||||
struct fwohcidb *db;
|
||||
}dbdvtx[MAX_DVFRAME], dbdvrx[MAX_DVFRAME];
|
||||
int ndb[OHCI_MAX_DMA_CH];
|
||||
u_int32_t isohdr[OHCI_MAX_DMA_CH];
|
||||
int queued[OHCI_MAX_DMA_CH];
|
||||
int dma_ch[OHCI_MAX_DMA_CH];
|
||||
};
|
||||
#endif
|
||||
struct fwohci_txpkthdr{
|
||||
union{
|
||||
u_int32_t ld[4];
|
||||
struct {
|
||||
u_int32_t res3:4,
|
||||
tcode:4,
|
||||
res2:8,
|
||||
spd:3,
|
||||
res1:13;
|
||||
}common;
|
||||
struct {
|
||||
u_int32_t res3:4,
|
||||
tcode:4,
|
||||
tlrt:8,
|
||||
spd:3,
|
||||
res2:4,
|
||||
srcbus:1,
|
||||
res1:8;
|
||||
u_int32_t res4:16,
|
||||
dst:16;
|
||||
}asycomm;
|
||||
struct {
|
||||
u_int32_t sy:4,
|
||||
tcode:4,
|
||||
chtag:8,
|
||||
spd:3,
|
||||
res1:13;
|
||||
u_int32_t res2:16,
|
||||
len:16;
|
||||
}stream;
|
||||
}mode;
|
||||
};
|
||||
struct fwohci_trailer{
|
||||
u_int32_t time:16,
|
||||
stat:16;
|
||||
};
|
||||
|
||||
#define OHCI_CNTL_CYCSRC (0x1 << 22)
|
||||
#define OHCI_CNTL_CYCMTR (0x1 << 21)
|
||||
#define OHCI_CNTL_CYCTIMER (0x1 << 20)
|
||||
#define OHCI_CNTL_PHYPKT (0x1 << 10)
|
||||
#define OHCI_CNTL_SID (0x1 << 9)
|
||||
|
||||
#define OHCI_INT_DMA_ATRQ (0x1 << 0)
|
||||
#define OHCI_INT_DMA_ATRS (0x1 << 1)
|
||||
#define OHCI_INT_DMA_ARRQ (0x1 << 2)
|
||||
#define OHCI_INT_DMA_ARRS (0x1 << 3)
|
||||
#define OHCI_INT_DMA_PRRQ (0x1 << 4)
|
||||
#define OHCI_INT_DMA_PRRS (0x1 << 5)
|
||||
#define OHCI_INT_DMA_IT (0x1 << 6)
|
||||
#define OHCI_INT_DMA_IR (0x1 << 7)
|
||||
#define OHCI_INT_PW_ERR (0x1 << 8)
|
||||
#define OHCI_INT_LR_ERR (0x1 << 9)
|
||||
|
||||
#define OHCI_INT_PHY_SID (0x1 << 16)
|
||||
#define OHCI_INT_PHY_BUS_R (0x1 << 17)
|
||||
|
||||
#define OHCI_INT_PHY_INT (0x1 << 19)
|
||||
#define OHCI_INT_CYC_START (0x1 << 20)
|
||||
#define OHCI_INT_CYC_64SECOND (0x1 << 21)
|
||||
#define OHCI_INT_CYC_LOST (0x1 << 22)
|
||||
#define OHCI_INT_CYC_ERR (0x1 << 23)
|
||||
|
||||
#define OHCI_INT_ERR (0x1 << 24)
|
||||
#define OHCI_INT_CYC_LONG (0x1 << 25)
|
||||
#define OHCI_INT_PHY_REG (0x1 << 26)
|
||||
|
||||
#define OHCI_INT_EN (0x1 << 31)
|
||||
|
||||
#define IP_CHANNELS 0x0234
|
||||
#define FWOHCI_MAXREC 2048
|
||||
|
||||
#define OHCI_ISORA 0x02
|
||||
#define OHCI_ISORB 0x04
|
||||
|
||||
#define FWOHCITCODE_PHY 0xe
|
70
sys/dev/firewire/fwohcivar.h
Normal file
70
sys/dev/firewire/fwohcivar.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi SHimokawa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the acknowledgement as bellow:
|
||||
*
|
||||
* This product includes software developed by K. Kobayashi and H. Shimokawa
|
||||
*
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
*/
|
||||
typedef struct fwohci_softc {
|
||||
struct firewire_comm fc;
|
||||
bus_space_tag_t bst;
|
||||
bus_space_handle_t bsh;
|
||||
void *ih;
|
||||
#if __FreeBSD_version < 500000
|
||||
void *ih_cam;
|
||||
#endif
|
||||
|
||||
struct resource *bsr;
|
||||
struct resource *irq_res;
|
||||
struct fwohci_dbch{
|
||||
u_int ndb;
|
||||
u_int ndesc;
|
||||
caddr_t dummy;
|
||||
STAILQ_HEAD(, fwohcidb_tr) db_trq;
|
||||
struct fwohcidb_tr *top, *bottom, *pdb_tr;
|
||||
struct fw_xferq xferq;
|
||||
struct {
|
||||
int len;
|
||||
int hlen;
|
||||
int plen;
|
||||
caddr_t buf;
|
||||
} frag;
|
||||
int flags;
|
||||
#define FWOHCI_DBCH_FULL (1<<1)
|
||||
int buf_offset;
|
||||
} arrq, arrs, atrq, atrs, it[OHCI_MAX_DMA_CH], ir[OHCI_MAX_DMA_CH];
|
||||
u_int maxrec;
|
||||
u_int32_t *cromptr;
|
||||
u_int32_t intmask;
|
||||
} fwohci_softc_t;
|
||||
void fwohci_intr __P((void *arg));
|
||||
int fwohci_init __P((struct fwohci_softc *, device_t));
|
||||
int fwohci_shutdown __P((device_t dev));
|
92
sys/dev/firewire/iec13213.h
Normal file
92
sys/dev/firewire/iec13213.h
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the acknowledgement as bellow:
|
||||
*
|
||||
* This product includes software developed by K. Kobayashi and H. Shimokawa
|
||||
*
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
*/
|
||||
#define CSRKEY_MVID 0x3
|
||||
#define CSRKEY_NCAP 0xc
|
||||
#define CSRKEY_NUNQ 0x8d
|
||||
#define CSRKEY_NPWR 0x30
|
||||
#define CSRKEY_SPEC 0x12
|
||||
#define CSRVAL_1394TA 0x00a02d
|
||||
#define CSRVAL_ANSIT10 0x00609e
|
||||
#define CSRKEY_VER 0x13
|
||||
#define CSR_PROTAVC 0x010001
|
||||
#define CSR_PROTCAL 0x010002
|
||||
#define CSR_PROTEHS 0x010004
|
||||
#define CSR_PROTHAVI 0x010008
|
||||
#define CSR_PROTCAM104 0x000100
|
||||
#define CSR_PROTCAM120 0x000101
|
||||
#define CSR_PROTCAM130 0x000102
|
||||
#define CSR_PROTDPP 0x0a6be2
|
||||
#define CSR_PROTIICP 0x4b661f
|
||||
|
||||
#define CSRVAL_T10SBP2 0x010483
|
||||
|
||||
struct csrreg {
|
||||
u_int32_t val:24,
|
||||
key:8;
|
||||
};
|
||||
struct csrhdr {
|
||||
u_int32_t crc:16,
|
||||
crc_len:8,
|
||||
info_len:8;
|
||||
};
|
||||
struct csrdirectory {
|
||||
u_int32_t crc:16,
|
||||
crc_len:16;
|
||||
struct csrreg entry[0];
|
||||
};
|
||||
struct csrtext {
|
||||
u_int32_t crc:16,
|
||||
crc_len:16;
|
||||
u_int32_t spec_id:16,
|
||||
spec_type:16;
|
||||
u_int32_t lang_id;
|
||||
u_int32_t text[0];
|
||||
};
|
||||
struct businfo {
|
||||
u_int32_t crc:16,
|
||||
crc_len:8,
|
||||
:12,
|
||||
max_rec:4,
|
||||
clk_acc:8,
|
||||
:4,
|
||||
bmc:1,
|
||||
isc:1,
|
||||
cmc:1,
|
||||
irmc:1;
|
||||
u_int32_t c_id_hi:8,
|
||||
v_id:24;
|
||||
u_int32_t c_id_lo;
|
||||
};
|
74
sys/dev/firewire/iec68113.h
Normal file
74
sys/dev/firewire/iec68113.h
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2001 Katsushi Kobayashi and Hidetoshi Shimokawa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the acknowledgement as bellow:
|
||||
*
|
||||
* This product includes software developed by K. Kobayashi and H. Shimokawa
|
||||
*
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
*/
|
||||
struct ciphdr {
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
u_int32_t src:8,
|
||||
len:8,
|
||||
dummy:8,
|
||||
dbc:8;
|
||||
u_int32_t :16,
|
||||
cyc:16;
|
||||
#else
|
||||
u_int32_t dbc:8,
|
||||
dummy:8,
|
||||
len:8,
|
||||
src:8;
|
||||
u_int32_t cyc:16,
|
||||
:16;
|
||||
#endif
|
||||
};
|
||||
struct dvdbc{
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
u_int32_t :8,
|
||||
dbn:8,
|
||||
rsv0:3,
|
||||
z:1,
|
||||
dseq:4,
|
||||
seq:4,
|
||||
rsv1:1,
|
||||
sct:3;
|
||||
#else
|
||||
u_int32_t seq:4,
|
||||
:1,
|
||||
sct:3,
|
||||
:3,
|
||||
z:1,
|
||||
dseq:4,
|
||||
dbn:8,
|
||||
:8;
|
||||
#endif
|
||||
u_int32_t ld[19];
|
||||
};
|
597
sys/dev/firewire/if_fwe.c
Normal file
597
sys/dev/firewire/if_fwe.c
Normal file
@ -0,0 +1,597 @@
|
||||
/*
|
||||
* Copyright (C) 2002
|
||||
* Hidetoshi Shimokawa. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
*
|
||||
* This product includes software developed by Hidetoshi Shimokawa.
|
||||
*
|
||||
* 4. Neither the name of the author nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "opt_inet.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#include <net/bpf.h>
|
||||
#include <net/ethernet.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/if_vlan_var.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <dev/firewire/firewire.h>
|
||||
#include <dev/firewire/firewirereg.h>
|
||||
#include <dev/firewire/if_fwevar.h>
|
||||
|
||||
#define FWEDEBUG if (fwedebug) printf
|
||||
#define MAX_QUEUED IFQ_MAXLEN /* 50 */
|
||||
|
||||
/* network interface */
|
||||
static void fwe_start __P((struct ifnet *));
|
||||
static int fwe_ioctl __P((struct ifnet *, u_long, caddr_t));
|
||||
static void fwe_init __P((void *));
|
||||
|
||||
static void fwe_as_output __P((struct fwe_softc *, struct ifnet *));
|
||||
static void fwe_as_input __P((struct fw_xferq *));
|
||||
|
||||
static int fwedebug = 0;
|
||||
static int stream_ch = 1;
|
||||
|
||||
MALLOC_DECLARE(M_FWE);
|
||||
MALLOC_DEFINE(M_FWE, "if_fwe", "Ethernet over Firewire interface");
|
||||
SYSCTL_INT(_debug, OID_AUTO, if_fwe_debug, CTLFLAG_RW, &fwedebug, 0, "");
|
||||
SYSCTL_DECL(_hw_firewire);
|
||||
SYSCTL_NODE(_hw_firewire, OID_AUTO, fwe, CTLFLAG_RD, 0,
|
||||
"Ethernet Emulation Subsystem");
|
||||
SYSCTL_INT(_hw_firewire_fwe, OID_AUTO, stream_ch, CTLFLAG_RW, &stream_ch, 0,
|
||||
"Stream channel to use");
|
||||
|
||||
#ifdef DEVICE_POLLING
|
||||
#define FWE_POLL_REGISTER(func, fwe, ifp) \
|
||||
if (ether_poll_register(func, ifp)) { \
|
||||
struct firewire_comm *fc = (fwe)->fd.fc; \
|
||||
fc->set_intr(fc, 0); \
|
||||
}
|
||||
|
||||
#define FWE_POLL_DEREGISTER(fwe, ifp) \
|
||||
do { \
|
||||
struct firewire_comm *fc = (fwe)->fd.fc; \
|
||||
ether_poll_deregister(ifp); \
|
||||
fc->set_intr(fc, 1); \
|
||||
} while(0) \
|
||||
|
||||
static poll_handler_t fwe_poll;
|
||||
|
||||
static void
|
||||
fwe_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
|
||||
{
|
||||
struct fwe_softc *fwe;
|
||||
struct firewire_comm *fc;
|
||||
|
||||
fwe = ((struct fwe_eth_softc *)ifp->if_softc)->fwe;
|
||||
fc = fwe->fd.fc;
|
||||
if (cmd == POLL_DEREGISTER) {
|
||||
/* enable interrupts */
|
||||
fc->set_intr(fc, 1);
|
||||
return;
|
||||
}
|
||||
fc->poll(fc, (cmd == POLL_AND_CHECK_STATUS)?0:1, count);
|
||||
}
|
||||
#else
|
||||
#define FWE_POLL_REGISTER(func, fwe, ifp)
|
||||
#define FWE_POLL_DEREGISTER(fwe, ifp)
|
||||
#endif
|
||||
static void
|
||||
fwe_identify(driver_t *driver, device_t parent)
|
||||
{
|
||||
BUS_ADD_CHILD(parent, 0, "if_fwe", device_get_unit(parent));
|
||||
}
|
||||
|
||||
static int
|
||||
fwe_probe(device_t dev)
|
||||
{
|
||||
device_t pa;
|
||||
|
||||
pa = device_get_parent(dev);
|
||||
if(device_get_unit(dev) != device_get_unit(pa)){
|
||||
return(ENXIO);
|
||||
}
|
||||
|
||||
device_set_desc(dev, "Ethernet over Firewire");
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
fwe_attach(device_t dev)
|
||||
{
|
||||
struct fwe_softc *fwe;
|
||||
struct ifnet *ifp;
|
||||
int unit, s;
|
||||
u_char *eaddr;
|
||||
|
||||
fwe = ((struct fwe_softc *)device_get_softc(dev));
|
||||
unit = device_get_unit(dev);
|
||||
|
||||
bzero(fwe, sizeof(struct fwe_softc));
|
||||
/* XXX */
|
||||
fwe->stream_ch = stream_ch;
|
||||
fwe->dma_ch = -1;
|
||||
|
||||
fwe->fd.fc = device_get_ivars(dev);
|
||||
fwe->fd.dev = dev;
|
||||
fwe->fd.post_explore = NULL;
|
||||
fwe->eth_softc.fwe = fwe;
|
||||
|
||||
fwe->pkt_hdr.mode.stream.tcode = FWTCODE_STREAM;
|
||||
fwe->pkt_hdr.mode.stream.sy = 0;
|
||||
fwe->pkt_hdr.mode.stream.chtag = fwe->stream_ch;
|
||||
|
||||
/* generate fake MAC address: first and last 3bytes from eui64 */
|
||||
#define LOCAL (0x02)
|
||||
#define GROUP (0x01)
|
||||
eaddr = &fwe->eth_softc.arpcom.ac_enaddr[0];
|
||||
eaddr[0] = (fwe->fd.fc->eui[0] | LOCAL) & ~GROUP;
|
||||
eaddr[1] = fwe->fd.fc->eui[1];
|
||||
eaddr[2] = fwe->fd.fc->eui[2];
|
||||
eaddr[3] = fwe->fd.fc->eui[5];
|
||||
eaddr[4] = fwe->fd.fc->eui[6];
|
||||
eaddr[5] = fwe->fd.fc->eui[7];
|
||||
printf("if_fwe%d: %02x:%02x:%02x:%02x:%02x:%02x\n", unit,
|
||||
eaddr[0], eaddr[1], eaddr[2], eaddr[3], eaddr[4], eaddr[5]);
|
||||
|
||||
/* fill the rest and attach interface */
|
||||
ifp = &fwe->fwe_if;
|
||||
ifp->if_softc = &fwe->eth_softc;
|
||||
|
||||
ifp->if_unit = unit;
|
||||
ifp->if_name = "fwe";
|
||||
ifp->if_init = fwe_init;
|
||||
ifp->if_output = ether_output;
|
||||
ifp->if_start = fwe_start;
|
||||
ifp->if_ioctl = fwe_ioctl;
|
||||
ifp->if_mtu = ETHERMTU;
|
||||
ifp->if_flags = (IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST);
|
||||
ifp->if_snd.ifq_maxlen = FWMAXQUEUE - 1;
|
||||
|
||||
s = splimp();
|
||||
ether_ifattach(ifp, 1);
|
||||
splx(s);
|
||||
|
||||
/* Tell the upper layer(s) we support long frames. */
|
||||
ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
|
||||
|
||||
ifp->if_snd.ifq_maxlen = MAX_QUEUED - 1;
|
||||
|
||||
FWEDEBUG("interface %s%d created.\n", ifp->if_name, ifp->if_unit);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
fwe_stop(struct fwe_softc *fwe)
|
||||
{
|
||||
struct firewire_comm *fc;
|
||||
struct fw_xferq *xferq;
|
||||
struct ifnet *ifp = &fwe->fwe_if;
|
||||
|
||||
fc = fwe->fd.fc;
|
||||
|
||||
FWE_POLL_DEREGISTER(fwe, ifp);
|
||||
|
||||
if (fwe->dma_ch >= 0) {
|
||||
xferq = fc->ir[fwe->dma_ch];
|
||||
|
||||
if (xferq->flag & FWXFERQ_RUNNING)
|
||||
fc->irx_disable(fc, fwe->dma_ch);
|
||||
xferq->flag &=
|
||||
~(FWXFERQ_MODEMASK | FWXFERQ_OPEN | FWXFERQ_HANDLER);
|
||||
/* XXX dequeue xferq->q */
|
||||
fwe->dma_ch = -1;
|
||||
}
|
||||
|
||||
ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
|
||||
}
|
||||
|
||||
static int
|
||||
fwe_detach(device_t dev)
|
||||
{
|
||||
struct fwe_softc *fwe;
|
||||
int s;
|
||||
|
||||
fwe = (struct fwe_softc *)device_get_softc(dev);
|
||||
s = splimp();
|
||||
|
||||
fwe_stop(fwe);
|
||||
ether_ifdetach(&fwe->fwe_if, 1);
|
||||
|
||||
splx(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
fwe_init(void *arg)
|
||||
{
|
||||
struct fwe_softc *fwe = ((struct fwe_eth_softc *)arg)->fwe;
|
||||
struct firewire_comm *fc;
|
||||
struct ifnet *ifp = &fwe->fwe_if;
|
||||
struct fw_xferq *xferq;
|
||||
int i;
|
||||
|
||||
FWEDEBUG("initializing %s%d\n", ifp->if_name, ifp->if_unit);
|
||||
|
||||
/* XXX keep promiscoud mode */
|
||||
ifp->if_flags |= IFF_PROMISC;
|
||||
|
||||
fc = fwe->fd.fc;
|
||||
#define START 0
|
||||
if (fwe->dma_ch < 0) {
|
||||
xferq = NULL;
|
||||
for (i = START; i < fc->nisodma; i ++) {
|
||||
xferq = fc->ir[i];
|
||||
if ((xferq->flag & FWXFERQ_OPEN) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (xferq == NULL) {
|
||||
printf("no free dma channel\n");
|
||||
return;
|
||||
}
|
||||
fwe->dma_ch = i;
|
||||
fwe->stream_ch = stream_ch;
|
||||
fwe->pkt_hdr.mode.stream.chtag = fwe->stream_ch;
|
||||
/* allocate DMA channel and init packet mode */
|
||||
xferq->flag |= FWXFERQ_OPEN | FWXFERQ_PACKET;
|
||||
xferq->flag |= fwe->stream_ch & 0xff;
|
||||
/* register fwe_input handler */
|
||||
xferq->sc = (caddr_t) fwe;
|
||||
xferq->hand = fwe_as_input;
|
||||
xferq->flag |= FWXFERQ_HANDLER;
|
||||
} else
|
||||
xferq = fc->ir[fwe->dma_ch];
|
||||
|
||||
|
||||
/* start dma */
|
||||
if ((xferq->flag & FWXFERQ_RUNNING) == 0)
|
||||
fc->irx_enable(fc, fwe->dma_ch);
|
||||
|
||||
ifp->if_flags |= IFF_RUNNING;
|
||||
ifp->if_flags &= ~IFF_OACTIVE;
|
||||
|
||||
FWE_POLL_REGISTER(fwe_poll, fwe, ifp);
|
||||
#if 0
|
||||
/* attempt to start output */
|
||||
fwe_start(ifp);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
fwe_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
{
|
||||
struct fwe_softc *fwe = ((struct fwe_eth_softc *)ifp->if_softc)->fwe;
|
||||
struct ifstat *ifs = NULL;
|
||||
int s, error, len;
|
||||
|
||||
switch (cmd) {
|
||||
case SIOCSIFADDR:
|
||||
case SIOCGIFADDR:
|
||||
case SIOCSIFMTU:
|
||||
s = splimp();
|
||||
error = ether_ioctl(ifp, cmd, data);
|
||||
splx(s);
|
||||
return (error);
|
||||
case SIOCSIFFLAGS:
|
||||
s = splimp();
|
||||
if (ifp->if_flags & IFF_UP) {
|
||||
if (!(ifp->if_flags & IFF_RUNNING))
|
||||
fwe_init(&fwe->eth_softc);
|
||||
} else {
|
||||
if (ifp->if_flags & IFF_RUNNING)
|
||||
fwe_stop(fwe);
|
||||
}
|
||||
/* XXX keep promiscoud mode */
|
||||
ifp->if_flags |= IFF_PROMISC;
|
||||
splx(s);
|
||||
break;
|
||||
case SIOCADDMULTI:
|
||||
case SIOCDELMULTI:
|
||||
break;
|
||||
|
||||
case SIOCGIFSTATUS:
|
||||
s = splimp();
|
||||
ifs = (struct ifstat *)data;
|
||||
len = strlen(ifs->ascii);
|
||||
if (len < sizeof(ifs->ascii))
|
||||
snprintf(ifs->ascii + len,
|
||||
sizeof(ifs->ascii) - len,
|
||||
"\tch %d dma %d\n",
|
||||
fwe->stream_ch, fwe->dma_ch);
|
||||
splx(s);
|
||||
break;
|
||||
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
fwe_start(struct ifnet *ifp)
|
||||
{
|
||||
struct fwe_softc *fwe = ((struct fwe_eth_softc *)ifp->if_softc)->fwe;
|
||||
int s;
|
||||
|
||||
#if 1
|
||||
FWEDEBUG("%s%d starting\n", ifp->if_name, ifp->if_unit);
|
||||
|
||||
if (fwe->dma_ch < 0) {
|
||||
struct mbuf *m = NULL;
|
||||
|
||||
FWEDEBUG("%s%d not ready.\n", ifp->if_name, ifp->if_unit);
|
||||
|
||||
s = splimp();
|
||||
do {
|
||||
IF_DEQUEUE(&ifp->if_snd, m);
|
||||
if (m != NULL)
|
||||
m_freem(m);
|
||||
ifp->if_oerrors ++;
|
||||
} while (m != NULL);
|
||||
splx(s);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
s = splimp();
|
||||
ifp->if_flags |= IFF_OACTIVE;
|
||||
|
||||
if (ifp->if_snd.ifq_len != 0)
|
||||
fwe_as_output(fwe, ifp);
|
||||
|
||||
ifp->if_flags &= ~IFF_OACTIVE;
|
||||
splx(s);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
fwe_output_callback(struct fw_xfer *xfer)
|
||||
{
|
||||
struct fwe_softc *fwe;
|
||||
struct ifnet *ifp;
|
||||
|
||||
fwe = (struct fwe_softc *)xfer->sc;
|
||||
/* XXX error check */
|
||||
FWEDEBUG("resp = %d\n", xfer->resp);
|
||||
m_freem(xfer->mbuf);
|
||||
xfer->send.buf = NULL;
|
||||
fw_xfer_free(xfer);
|
||||
#if 1
|
||||
/* XXX for queue full */
|
||||
ifp = &fwe->fwe_if;
|
||||
if (ifp->if_snd.ifq_head != NULL)
|
||||
fwe_start(ifp);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define HDR_LEN 4
|
||||
#define ALIGN_PAD 2
|
||||
/* Async. stream output */
|
||||
static void
|
||||
fwe_as_output(struct fwe_softc *fwe, struct ifnet *ifp)
|
||||
{
|
||||
struct mbuf *m;
|
||||
struct fw_xfer *xfer;
|
||||
struct fw_xferq *xferq;
|
||||
struct fw_pkt *fp;
|
||||
int i = 0;
|
||||
|
||||
xfer = NULL;
|
||||
xferq = fwe->fd.fc->atq;
|
||||
while (xferq->queued < xferq->maxq) {
|
||||
IF_DEQUEUE(&ifp->if_snd, m);
|
||||
if (m == NULL)
|
||||
break;
|
||||
xfer = fw_xfer_alloc();
|
||||
if (xfer == NULL) {
|
||||
return;
|
||||
}
|
||||
if (ifp->if_bpf != NULL)
|
||||
bpf_mtap(ifp, m);
|
||||
|
||||
xfer->send.off = 0;
|
||||
xfer->spd = 2;
|
||||
xfer->fc = fwe->fd.fc;
|
||||
xfer->retry_req = fw_asybusy;
|
||||
xfer->sc = (caddr_t)fwe;
|
||||
xfer->act.hand = fwe_output_callback;
|
||||
|
||||
/* keep ip packet alignment for alpha */
|
||||
M_PREPEND(m, ALIGN_PAD, M_DONTWAIT);
|
||||
fp = (struct fw_pkt *)&xfer->dst; /* XXX */
|
||||
xfer->dst = *((int32_t *)&fwe->pkt_hdr);
|
||||
fp->mode.stream.len = htons(m->m_pkthdr.len);
|
||||
xfer->send.buf = (caddr_t) fp;
|
||||
xfer->mbuf = m;
|
||||
xfer->send.len = m->m_pkthdr.len + HDR_LEN;
|
||||
|
||||
i++;
|
||||
if (fw_asyreq(xfer->fc, -1, xfer) != 0) {
|
||||
/* error */
|
||||
ifp->if_oerrors ++;
|
||||
/* XXX set error code */
|
||||
fwe_output_callback(xfer);
|
||||
} else {
|
||||
ifp->if_opackets ++;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
if (i > 1)
|
||||
printf("%d queued\n", i);
|
||||
#endif
|
||||
if (xfer != NULL)
|
||||
xferq->start(xfer->fc);
|
||||
}
|
||||
|
||||
#if __FreeBSD_version >= 500000
|
||||
static void
|
||||
fwe_free(void *buf, void *args)
|
||||
{
|
||||
FWEDEBUG("fwe_free:\n");
|
||||
free(buf, M_DEVBUF);
|
||||
}
|
||||
|
||||
#else
|
||||
static void
|
||||
fwe_free(caddr_t buf, u_int size)
|
||||
{
|
||||
int *p;
|
||||
FWEDEBUG("fwe_free:\n");
|
||||
p = (int *)buf;
|
||||
(*p) --;
|
||||
if (*p < 1)
|
||||
free(buf, M_DEVBUF);
|
||||
}
|
||||
|
||||
static void
|
||||
fwe_ref(caddr_t buf, u_int size)
|
||||
{
|
||||
int *p;
|
||||
|
||||
FWEDEBUG("fwe_ref: called\n");
|
||||
p = (int *)buf;
|
||||
(*p) ++;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Async. stream output */
|
||||
static void
|
||||
fwe_as_input(struct fw_xferq *xferq)
|
||||
{
|
||||
struct mbuf *m;
|
||||
struct ether_header *eh;
|
||||
struct ifnet *ifp;
|
||||
struct fw_xfer *xfer;
|
||||
struct fwe_softc *fwe;
|
||||
u_char *c;
|
||||
int len;
|
||||
caddr_t p;
|
||||
|
||||
fwe = (struct fwe_softc *)xferq->sc;
|
||||
ifp = &fwe->fwe_if;
|
||||
#if 0
|
||||
FWE_POLL_REGISTER(fwe_poll, fwe, ifp);
|
||||
#endif
|
||||
while ((xfer = STAILQ_FIRST(&xferq->q)) != NULL) {
|
||||
STAILQ_REMOVE_HEAD(&xferq->q, link);
|
||||
xferq->queued --;
|
||||
MGETHDR(m, M_DONTWAIT, MT_DATA);
|
||||
if (m == NULL) {
|
||||
printf("MGETHDR failed\n");
|
||||
fw_xfer_free(xfer);
|
||||
return;
|
||||
}
|
||||
len = xfer->recv.off + xfer->recv.len;
|
||||
FWEDEBUG("fwe_as_input len=%d\n", len);
|
||||
#if __FreeBSD_version >= 500000
|
||||
MEXTADD(m, xfer->recv.buf, len, fwe_free, NULL, 0, EXT_NET_DRV);
|
||||
#else
|
||||
m->m_flags |= M_EXT;
|
||||
m->m_ext.ext_buf = xfer->recv.buf;
|
||||
m->m_ext.ext_size = len;
|
||||
m->m_ext.ext_free = fwe_free;
|
||||
m->m_ext.ext_ref = fwe_ref;
|
||||
*((int *)m->m_ext.ext_buf) = 1; /* XXX refcount */
|
||||
#endif
|
||||
p = xfer->recv.buf + xfer->recv.off + HDR_LEN + ALIGN_PAD;
|
||||
eh = (struct ether_header *)p;
|
||||
p += sizeof(struct ether_header);
|
||||
len -= xfer->recv.off + HDR_LEN + ALIGN_PAD
|
||||
+ sizeof(struct ether_header);
|
||||
m->m_data = p;
|
||||
m->m_len = m->m_pkthdr.len = len;
|
||||
m->m_pkthdr.rcvif = ifp;
|
||||
c = (char *)eh;
|
||||
#if 0
|
||||
FWEDEBUG("%02x %02x %02x %02x %02x %02x\n"
|
||||
"%02x %02x %02x %02x %02x %02x\n"
|
||||
"%02x %02x %02x %02x\n"
|
||||
"%02x %02x %02x %02x\n"
|
||||
"%02x %02x %02x %02x\n"
|
||||
"%02x %02x %02x %02x\n",
|
||||
c[0], c[1], c[2], c[3], c[4], c[5],
|
||||
c[6], c[7], c[8], c[9], c[10], c[11],
|
||||
c[12], c[13], c[14], c[15],
|
||||
c[16], c[17], c[18], c[19],
|
||||
c[20], c[21], c[22], c[23],
|
||||
c[20], c[21], c[22], c[23]
|
||||
);
|
||||
#endif
|
||||
ether_input(ifp, eh, m);
|
||||
ifp->if_ipackets ++;
|
||||
|
||||
xfer->recv.buf = NULL;
|
||||
fw_xfer_free(xfer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static devclass_t fwe_devclass;
|
||||
|
||||
static device_method_t fwe_methods[] = {
|
||||
/* device interface */
|
||||
DEVMETHOD(device_identify, fwe_identify),
|
||||
DEVMETHOD(device_probe, fwe_probe),
|
||||
DEVMETHOD(device_attach, fwe_attach),
|
||||
DEVMETHOD(device_detach, fwe_detach),
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static driver_t fwe_driver = {
|
||||
"if_fwe",
|
||||
fwe_methods,
|
||||
sizeof(struct fwe_softc),
|
||||
};
|
||||
|
||||
|
||||
DRIVER_MODULE(if_fwe, firewire, fwe_driver, fwe_devclass, 0, 0);
|
||||
MODULE_VERSION(if_fwe, 1);
|
||||
MODULE_DEPEND(if_fwe, firewire, 1, 1, 1);
|
53
sys/dev/firewire/if_fwevar.h
Normal file
53
sys/dev/firewire/if_fwevar.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2002
|
||||
* Hidetoshi Shimokawa. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
*
|
||||
* This product includes software developed by Hidetoshi Shimokawa.
|
||||
*
|
||||
* 4. Neither the name of the author nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _NET_IF_FWEVAR_H_
|
||||
#define _NET_IF_FWEVAR_H_
|
||||
|
||||
struct fwe_softc {
|
||||
/* XXX this must be first for fd.post_explore() */
|
||||
struct firewire_dev_comm fd;
|
||||
short stream_ch;
|
||||
short dma_ch;
|
||||
struct fw_pkt pkt_hdr;
|
||||
struct fwe_eth_softc {
|
||||
/* XXX this must be first for if_ethersub.c */
|
||||
struct arpcom arpcom; /* ethernet common data */
|
||||
#define fwe_if eth_softc.arpcom.ac_if
|
||||
struct fwe_softc *fwe;
|
||||
} eth_softc;
|
||||
};
|
||||
#endif /* !_NET_IF_FWEVAR_H_ */
|
2214
sys/dev/firewire/sbp.c
Normal file
2214
sys/dev/firewire/sbp.c
Normal file
File diff suppressed because it is too large
Load Diff
8
sys/modules/firewire/Makefile
Normal file
8
sys/modules/firewire/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
# $FreeBSD$
|
||||
|
||||
SUBDIR =
|
||||
SUBDIR += firewire
|
||||
SUBDIR += sbp
|
||||
#SUBDIR += fwe
|
||||
|
||||
.include <bsd.subdir.mk>
|
29
sys/modules/firewire/firewire/Makefile
Normal file
29
sys/modules/firewire/firewire/Makefile
Normal file
@ -0,0 +1,29 @@
|
||||
# $FreeBSD$
|
||||
|
||||
# Makefile for the IEEE1394 OHCI chipset
|
||||
|
||||
.PATH: ${.CURDIR}/../../../dev/firewire
|
||||
|
||||
KMOD= firewire
|
||||
SRCS = bus_if.h device_if.h pci_if.h \
|
||||
opt_bus.h opt_firewire.h \
|
||||
firewire.c firewire.h firewire_phy.h firewirebusreg.h firewirereg.h \
|
||||
fwohci.c fwohci_pci.c fwohcireg.h fwohcivar.h \
|
||||
iec13213.h iec68113.h \
|
||||
fwmem.c fwmem.h
|
||||
|
||||
opt_firewire.h:
|
||||
echo "#define FIREWIRE_FREEBSD_MODULE 1" > opt_firewire.h
|
||||
|
||||
#EXPORT_SYMS= fw_asybusy \
|
||||
# fw_asyreq \
|
||||
# fw_bindadd \
|
||||
# fw_bindremove \
|
||||
# getcsrdata \
|
||||
# fw_xfer_alloc \
|
||||
# fw_xfer_free \
|
||||
|
||||
EXPORT_SYMS= YES
|
||||
|
||||
.include <bsd.kmod.mk>
|
||||
|
19
sys/modules/firewire/fwe/Makefile
Normal file
19
sys/modules/firewire/fwe/Makefile
Normal file
@ -0,0 +1,19 @@
|
||||
# $FreeBSD$
|
||||
|
||||
# Makefile for the SBP-II (Serial Bus Protocol 2/SCSI over IEEE1394)
|
||||
|
||||
.PATH: ${.CURDIR}/../../../dev/firewire
|
||||
|
||||
CFLAGS+= -g
|
||||
|
||||
KMOD = if_fwe
|
||||
SRCS = bus_if.h device_if.h\
|
||||
opt_bus.h opt_firewire.h opt_inet.h\
|
||||
if_fwe.c if_fwevar.h\
|
||||
firewire.h firewirereg.h
|
||||
|
||||
opt_fwe.h:
|
||||
echo "#define FIREWIRE_ETHEREMU_FREEBSD 1" > opt_fwe.h
|
||||
|
||||
.include <bsd.kmod.mk>
|
||||
|
20
sys/modules/firewire/sbp/Makefile
Normal file
20
sys/modules/firewire/sbp/Makefile
Normal file
@ -0,0 +1,20 @@
|
||||
# $FreeBSD$
|
||||
|
||||
# Makefile for the SBP-II (Serial Bus Protocol 2/SCSI over IEEE1394)
|
||||
|
||||
.PATH: ${.CURDIR}/../../../dev/firewire
|
||||
|
||||
CFLAGS+= -g
|
||||
|
||||
KMOD = sbp
|
||||
SRCS = bus_if.h device_if.h\
|
||||
opt_bus.h opt_firewire.h opt_cam.h opt_scsi.h\
|
||||
sbp.c \
|
||||
firewire.h firewirereg.h \
|
||||
iec13213.h
|
||||
|
||||
opt_sbp.h:
|
||||
echo "#define SBP2_FREEBSD_MODULE 1" > opt_sbp.h
|
||||
|
||||
.include <bsd.kmod.mk>
|
||||
|
Loading…
Reference in New Issue
Block a user