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:
Katsushi Kobayashi 2002-09-13 12:31:56 +00:00
parent c51f3753df
commit 3c60ba66c4
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=103285
26 changed files with 12176 additions and 0 deletions

89
share/man/man4/firewire.4 Normal file
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

565
sys/dev/firewire/firewire.h Normal file
View 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

View 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

View 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;
};

View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

View 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);

View 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

View 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));

View 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;
};

View 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
View 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);

View 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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,8 @@
# $FreeBSD$
SUBDIR =
SUBDIR += firewire
SUBDIR += sbp
#SUBDIR += fwe
.include <bsd.subdir.mk>

View 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>

View 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>

View 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>