Patch by JiSheng Zhang: Update the FireWire stack and tools to the current
FreeBSD version (r188928). Note to JiSheng: I did have to fix fwcontrol.c line 111, looked like a last minute change to me. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29752 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -103,9 +103,16 @@ struct fw_reg_req_t {
|
||||
#define FWRCODE_ER_TYPE 6
|
||||
#define FWRCODE_ER_ADDR 7
|
||||
|
||||
/*
|
||||
* Defined 1394a-2000
|
||||
* Table 5B-1
|
||||
*/
|
||||
#define FWSPD_S100 0
|
||||
#define FWSPD_S200 1
|
||||
#define FWSPD_S400 2
|
||||
#define FWSPD_S800 3
|
||||
#define FWSPD_S1600 4
|
||||
#define FWSPD_S3200 5
|
||||
|
||||
#define FWP_TL_VALID (1 << 7)
|
||||
|
||||
@@ -281,10 +288,18 @@ struct fw_devlstreq {
|
||||
struct fw_devinfo dev[FW_MAX_DEVLST];
|
||||
};
|
||||
|
||||
/*
|
||||
* Defined in IEEE 1394a-2000
|
||||
* 4.3.4.1
|
||||
*/
|
||||
#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
|
||||
|
||||
#define FW_SELF_ID_PAGE0 0
|
||||
#define FW_SELF_ID_PAGE1 1
|
||||
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
union fw_self_id {
|
||||
struct {
|
||||
@@ -294,7 +309,7 @@ union fw_self_id {
|
||||
link_active:1,
|
||||
gap_count:6,
|
||||
phy_speed:2,
|
||||
phy_delay:2,
|
||||
reserved:2,
|
||||
contender:1,
|
||||
power_class:3,
|
||||
port0:2,
|
||||
@@ -309,18 +324,32 @@ union fw_self_id {
|
||||
phy_id:6,
|
||||
sequel:1,
|
||||
sequence_num:3,
|
||||
:2,
|
||||
porta:2,
|
||||
portb:2,
|
||||
portc:2,
|
||||
portd:2,
|
||||
porte:2,
|
||||
portf:2,
|
||||
portg:2,
|
||||
porth:2,
|
||||
:1,
|
||||
reserved2:2,
|
||||
port3:2,
|
||||
port4:2,
|
||||
port5:2,
|
||||
port6:2,
|
||||
port7:2,
|
||||
port8:2,
|
||||
port9:2,
|
||||
port10:2,
|
||||
reserved1:1,
|
||||
more_packets:1;
|
||||
} p1;
|
||||
struct {
|
||||
uint32_t
|
||||
id:2,
|
||||
phy_id:6,
|
||||
sequel:1,
|
||||
sequence_num:3,
|
||||
:2,
|
||||
port11:2,
|
||||
port12:2,
|
||||
port13:2,
|
||||
port14:2,
|
||||
port15:2,
|
||||
:8;
|
||||
} p2;
|
||||
};
|
||||
#else
|
||||
union fw_self_id {
|
||||
@@ -332,7 +361,7 @@ union fw_self_id {
|
||||
port0:2,
|
||||
power_class:3,
|
||||
contender:1,
|
||||
phy_delay:2,
|
||||
reserved:2,
|
||||
phy_speed:2,
|
||||
gap_count:6,
|
||||
link_active:1,
|
||||
@@ -343,20 +372,34 @@ union fw_self_id {
|
||||
struct {
|
||||
uint32_t more_packets:1,
|
||||
reserved1:1,
|
||||
porth:2,
|
||||
portg:2,
|
||||
portf:2,
|
||||
porte:2,
|
||||
portd:2,
|
||||
portc:2,
|
||||
portb:2,
|
||||
porta:2,
|
||||
port10:2,
|
||||
port9:2,
|
||||
port8:2,
|
||||
port7:2,
|
||||
port6:2,
|
||||
port5:2,
|
||||
port4:2,
|
||||
port3:2,
|
||||
reserved2:2,
|
||||
sequence_num:3,
|
||||
sequel:1,
|
||||
phy_id:6,
|
||||
id:2;
|
||||
} p1;
|
||||
struct {
|
||||
uint32_t
|
||||
reserved3:8,
|
||||
port15:2,
|
||||
port14:2,
|
||||
port13:2,
|
||||
port12:2,
|
||||
port11:2,
|
||||
reserved4:2,
|
||||
sequence_num:3,
|
||||
sequel:1,
|
||||
phy_id:6,
|
||||
id:2;
|
||||
} p2;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -422,7 +465,7 @@ struct fw_crom_buf {
|
||||
#endif
|
||||
|
||||
#define MAKEMINOR(f, u, s) \
|
||||
unit2minor((f) | (((u) & 0xff) << 8) | (s & 0xff))
|
||||
((f) | (((u) & 0xff) << 8) | (s & 0xff))
|
||||
#define DEV2UNIT(x) ((dev2unit(x) & 0xff00) >> 8)
|
||||
#define DEV2SUB(x) (dev2unit(x) & 0xff)
|
||||
|
||||
|
||||
@@ -34,6 +34,10 @@
|
||||
* $FreeBSD: src/sys/dev/firewire/fwphyreg.h,v 1.3 2005/01/06 01:42:41 imp Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* IEEE 1394a
|
||||
* Figure 5B - 1
|
||||
*/
|
||||
struct phyreg_base {
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
uint8_t phy_id:6,
|
||||
@@ -100,6 +104,10 @@ struct phyreg_base {
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* IEEE 1394a
|
||||
* Figure 5B - 2
|
||||
*/
|
||||
struct phyreg_page0 {
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
uint8_t astat:2,
|
||||
@@ -160,6 +168,10 @@ struct phyreg_page0 {
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* IEEE 1394a
|
||||
* Figure 5B - 3
|
||||
*/
|
||||
struct phyreg_page1 {
|
||||
uint8_t compliance;
|
||||
uint8_t :8;
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
|
||||
#define PROBE_THREAD_PRIORITY 80
|
||||
|
||||
int firewire_debug=1, try_bmr=1, hold_count=3;
|
||||
int firewire_debug=1, try_bmr=1, hold_count=0;
|
||||
|
||||
#define FW_MAXASYRTY 4
|
||||
|
||||
@@ -435,6 +435,31 @@ firewire_attach(struct firewire_comm *fc, struct firewire_softc *sc)
|
||||
|
||||
// fwdev_makedev(sc);
|
||||
|
||||
fc->crom_src_buf = (struct crom_src_buf *)malloc(
|
||||
sizeof(struct crom_src_buf));
|
||||
if (fc->crom_src_buf == NULL) {
|
||||
device_printf(fc->dev, "%s: Malloc Failure crom src buff\n", __func__);
|
||||
return ENOMEM;
|
||||
}
|
||||
memset(fc->crom_src_buf, 0, sizeof(struct crom_src_buf));
|
||||
fc->topology_map = (struct fw_topology_map *)malloc(
|
||||
sizeof(struct fw_topology_map));
|
||||
if (fc->topology_map == NULL) {
|
||||
device_printf(fc->dev, "%s: Malloc Failure topology map\n", __func__);
|
||||
free(fc->crom_src_buf);
|
||||
return ENOMEM;
|
||||
}
|
||||
memset(fc->topology_map, 0, sizeof(struct fw_topology_map));
|
||||
fc->speed_map = (struct fw_speed_map *)malloc(
|
||||
sizeof(struct fw_speed_map));
|
||||
if (fc->speed_map == NULL) {
|
||||
device_printf(fc->dev, "%s: Malloc Failure speed map\n", __func__);
|
||||
free(fc->crom_src_buf);
|
||||
free(fc->topology_map);
|
||||
return ENOMEM;
|
||||
}
|
||||
memset(fc->speed_map, 0, sizeof(struct fw_speed_map));
|
||||
|
||||
mtx_init(&fc->wait_lock, "fwwait", NULL, MTX_DEF);
|
||||
mtx_init(&fc->tlabel_lock, "fwtlabel", NULL, MTX_DEF);
|
||||
// CALLOUT_INIT(&fc->timeout_callout);
|
||||
@@ -448,7 +473,7 @@ firewire_attach(struct firewire_comm *fc, struct firewire_softc *sc)
|
||||
hz/WATCHDOG_HZ, B_PERIODIC_TIMER);
|
||||
|
||||
/* create thread */
|
||||
// kthread_create(fw_bus_probe_thread, (void *)fc, &fc->probe_thread,
|
||||
// kproc_create(fw_bus_probe_thread, (void *)fc, &fc->probe_thread,
|
||||
// 0, 0, "fw%d_probe", unit);
|
||||
fc->probe_thread = spawn_kernel_thread(fw_bus_probe_thread,
|
||||
"fw_probe", PROBE_THREAD_PRIORITY, fc);
|
||||
@@ -468,7 +493,9 @@ firewire_attach(struct firewire_comm *fc, struct firewire_softc *sc)
|
||||
}*/
|
||||
|
||||
/* bus_reset */
|
||||
FW_GLOCK(fc);
|
||||
fw_busreset(fc, FWBUSNOTREADY);
|
||||
FW_GUNLOCK(fc);
|
||||
fc->ibr(fc);
|
||||
|
||||
return 0;
|
||||
@@ -495,6 +522,8 @@ firewire_detach(struct firewire_softc *sc)
|
||||
mtx_unlock(&fc->wait_lock);
|
||||
DELAY(hz*60);
|
||||
|
||||
if (fc->arq !=0 && fc->arq->maxq > 0)
|
||||
fw_drain_txq(fc);
|
||||
/* if ((err = fwdev_destroydev(sc)) != 0)
|
||||
return err;
|
||||
|
||||
@@ -518,7 +547,7 @@ firewire_detach(struct firewire_softc *sc)
|
||||
delete_timer(fc->busprobe_callout);
|
||||
|
||||
|
||||
/* XXX xfree_free and untimeout on all xfers */
|
||||
/* XXX xfer_free and untimeout on all xfers */
|
||||
for (fwdev = STAILQ_FIRST(&fc->devices); fwdev != NULL;
|
||||
fwdev = fwdev_next) {
|
||||
fwdev_next = STAILQ_NEXT(fwdev, link);
|
||||
@@ -638,12 +667,6 @@ fw_init_crom(struct firewire_comm *fc)
|
||||
{
|
||||
struct crom_src *src;
|
||||
|
||||
fc->crom_src_buf = (struct crom_src_buf *)
|
||||
malloc(sizeof(struct crom_src_buf));
|
||||
if (fc->crom_src_buf == NULL)
|
||||
return;
|
||||
memset(fc->crom_src_buf, 0, sizeof(struct crom_src_buf));;
|
||||
|
||||
src = &fc->crom_src_buf->src;
|
||||
bzero(src, sizeof(struct crom_src));
|
||||
|
||||
@@ -660,7 +683,8 @@ fw_init_crom(struct firewire_comm *fc)
|
||||
src->businfo.cyc_clk_acc = 100;
|
||||
src->businfo.max_rec = fc->maxrec;
|
||||
src->businfo.max_rom = MAXROM_4;
|
||||
src->businfo.generation = 1;
|
||||
#define FW_GENERATION_CHANGEABLE 2
|
||||
src->businfo.generation = FW_GENERATION_CHANGEABLE;
|
||||
src->businfo.link_spd = fc->speed;
|
||||
|
||||
src->businfo.eui64.hi = fc->eui.hi;
|
||||
@@ -679,9 +703,6 @@ fw_reset_crom(struct firewire_comm *fc)
|
||||
struct crom_src *src;
|
||||
struct crom_chunk *root;
|
||||
|
||||
if (fc->crom_src_buf == NULL)
|
||||
fw_init_crom(fc);
|
||||
|
||||
buf = fc->crom_src_buf;
|
||||
src = fc->crom_src;
|
||||
root = fc->crom_root;
|
||||
@@ -716,20 +737,20 @@ fw_busreset(struct firewire_comm *fc, uint32_t new_status)
|
||||
struct firewire_dev_comm *fdc;
|
||||
struct crom_src *src;
|
||||
// device_t *devlistp;
|
||||
void *newrom;
|
||||
uint32_t *newrom;
|
||||
// int i, devcnt;
|
||||
struct firewire_child_info *element = fc->childList;
|
||||
|
||||
switch(fc->status){
|
||||
case FWBUSMGRELECT:
|
||||
FW_GLOCK_ASSERT(fc);
|
||||
if (fc->status == FWBUSMGRELECT)
|
||||
// callout_stop(&fc->bmr_callout);
|
||||
delete_timer(fc->bmr_callout);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
fc->status = new_status;
|
||||
fw_reset_csr(fc);
|
||||
|
||||
if (fc->status == FWBUSNOTREADY)
|
||||
fw_init_crom(fc);
|
||||
|
||||
fw_reset_crom(fc);
|
||||
|
||||
|
||||
@@ -751,17 +772,29 @@ fw_busreset(struct firewire_comm *fc, uint32_t new_status)
|
||||
element = element->link;
|
||||
}
|
||||
|
||||
src = &fc->crom_src_buf->src;
|
||||
/*
|
||||
* If the old config rom needs to be overwritten,
|
||||
* bump the businfo.generation indicator to
|
||||
* indicate that we need to be reprobed
|
||||
* See 1394a-2000 8.3.2.5.4 for more details.
|
||||
* generation starts at 2 and rolls over at 0xF
|
||||
* back to 2.
|
||||
*
|
||||
* A generation of 0 indicates a device
|
||||
* that is not 1394a-2000 compliant.
|
||||
* A generation of 1 indicates a device that
|
||||
* does not change it's Bus Info Block or
|
||||
* Configuration ROM.
|
||||
*/
|
||||
#define FW_MAX_GENERATION 0xF
|
||||
newrom = malloc(CROMSIZE);
|
||||
memset(newrom, 0, CROMSIZE);
|
||||
src = &fc->crom_src_buf->src;
|
||||
crom_load(src, (uint32_t *)newrom, CROMSIZE);
|
||||
crom_load(src, newrom, CROMSIZE);
|
||||
if (bcmp(newrom, fc->config_rom, CROMSIZE) != 0) {
|
||||
/* bump generation and reload */
|
||||
src->businfo.generation ++;
|
||||
/* generation must be between 0x2 and 0xF */
|
||||
if (src->businfo.generation < 2)
|
||||
src->businfo.generation ++;
|
||||
crom_load(src, (uint32_t *)newrom, CROMSIZE);
|
||||
if ( src->businfo.generation++ > FW_MAX_GENERATION )
|
||||
src->businfo.generation = FW_GENERATION_CHANGEABLE;
|
||||
bcopy(newrom, (void *)fc->config_rom, CROMSIZE);
|
||||
}
|
||||
free(newrom);
|
||||
@@ -828,13 +861,6 @@ void fw_init(struct firewire_comm *fc)
|
||||
fc->ir[i]->maxq = FWMAXQUEUE;
|
||||
fc->it[i]->maxq = FWMAXQUEUE;
|
||||
}
|
||||
/* Initialize csr registers */
|
||||
fc->topology_map = (struct fw_topology_map *)malloc(
|
||||
sizeof(struct fw_topology_map));
|
||||
memset(fc->topology_map, 0, sizeof(struct fw_topology_map));
|
||||
fc->speed_map = (struct fw_speed_map *)malloc(
|
||||
sizeof(struct fw_speed_map));
|
||||
memset(fc->speed_map, 0, sizeof(struct fw_speed_map));
|
||||
CSRARC(fc, TOPO_MAP) = 0x3f1 << 16;
|
||||
CSRARC(fc, TOPO_MAP + 4) = 1;
|
||||
CSRARC(fc, SPED_MAP) = 0x3f1 << 16;
|
||||
@@ -1300,12 +1326,11 @@ fw_phy_config(struct firewire_comm *fc, int root_node, int gap_count)
|
||||
fp->mode.common.tcode |= FWTCODE_PHY;
|
||||
|
||||
if (firewire_debug)
|
||||
printf("send phy_config root_node=%d gap_count=%d\n",
|
||||
root_node, gap_count);
|
||||
device_printf(fc->bdev, "%s: root_node=%d gap_count=%d\n",
|
||||
__func__, root_node, gap_count);
|
||||
fw_asyreq(fc, -1, xfer);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Dump self ID.
|
||||
*/
|
||||
@@ -1314,14 +1339,30 @@ fw_print_sid(uint32_t sid)
|
||||
{
|
||||
union fw_self_id *s;
|
||||
s = (union fw_self_id *) &sid;
|
||||
printf("node:%d link:%d gap:%d spd:%d del:%d con:%d pwr:%d"
|
||||
" p0:%d p1:%d p2:%d i:%d m:%d\n",
|
||||
s->p0.phy_id, s->p0.link_active, s->p0.gap_count,
|
||||
s->p0.phy_speed, s->p0.phy_delay, s->p0.contender,
|
||||
s->p0.power_class, s->p0.port0, s->p0.port1,
|
||||
s->p0.port2, s->p0.initiated_reset, s->p0.more_packets);
|
||||
if ( s->p0.sequel ) {
|
||||
if ( s->p1.sequence_num == FW_SELF_ID_PAGE0 ) {
|
||||
printf("node:%d p3:%d p4:%d p5:%d p6:%d p7:%d"
|
||||
"p8:%d p9:%d p10:%d\n",
|
||||
s->p1.phy_id, s->p1.port3, s->p1.port4,
|
||||
s->p1.port5, s->p1.port6, s->p1.port7,
|
||||
s->p1.port8, s->p1.port9, s->p1.port10);
|
||||
} else if (s->p2.sequence_num == FW_SELF_ID_PAGE1 ){
|
||||
printf("node:%d p11:%d p12:%d p13:%d p14:%d p15:%d\n",
|
||||
s->p2.phy_id, s->p2.port11, s->p2.port12,
|
||||
s->p2.port13, s->p2.port14, s->p2.port15);
|
||||
} else {
|
||||
printf("node:%d Unknown Self ID Page number %d\n",
|
||||
s->p1.phy_id, s->p1.sequence_num);
|
||||
}
|
||||
} else {
|
||||
printf("node:%d link:%d gap:%d spd:%d con:%d pwr:%d"
|
||||
" p0:%d p1:%d p2:%d i:%d m:%d\n",
|
||||
s->p0.phy_id, s->p0.link_active, s->p0.gap_count,
|
||||
s->p0.phy_speed, s->p0.contender,
|
||||
s->p0.power_class, s->p0.port0, s->p0.port1,
|
||||
s->p0.port2, s->p0.initiated_reset, s->p0.more_packets);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* To receive self ID.
|
||||
@@ -1345,7 +1386,8 @@ void fw_sidrcv(struct firewire_comm* fc, uint32_t *sid, u_int len)
|
||||
self_id = &fc->topology_map->self_id[0];
|
||||
for(i = 0; i < fc->sid_cnt; i ++){
|
||||
if (sid[1] != ~sid[0]) {
|
||||
printf("fw_sidrcv: invalid self-id packet\n");
|
||||
device_printf(fc->bdev, "%s:"
|
||||
"ERROR invalid self-id packet\n", __func__);
|
||||
sid += 2;
|
||||
continue;
|
||||
}
|
||||
@@ -1354,9 +1396,9 @@ void fw_sidrcv(struct firewire_comm* fc, uint32_t *sid, u_int len)
|
||||
if(self_id->p0.sequel == 0){
|
||||
fc->topology_map->node_count ++;
|
||||
c_port = 0;
|
||||
#if 0
|
||||
fw_print_sid(sid[0]);
|
||||
#endif
|
||||
if (firewire_debug)
|
||||
fw_print_sid(sid[0]);
|
||||
|
||||
node = self_id->p0.phy_id;
|
||||
if(fc->max_node < node){
|
||||
fc->max_node = self_id->p0.phy_id;
|
||||
@@ -1391,7 +1433,6 @@ void fw_sidrcv(struct firewire_comm* fc, uint32_t *sid, u_int len)
|
||||
self_id++;
|
||||
fc->topology_map->self_id_count ++;
|
||||
}
|
||||
device_printf(fc->bdev, "%d nodes", fc->max_node + 1);
|
||||
/* CRC */
|
||||
fc->topology_map->crc = fw_crc16(
|
||||
(uint32_t *)&fc->topology_map->generation,
|
||||
@@ -1410,16 +1451,11 @@ void fw_sidrcv(struct firewire_comm* fc, uint32_t *sid, u_int len)
|
||||
bcopy(p, &CSRARC(fc, SPED_MAP + 8), (fc->speed_map->crc_len - 1)*4);
|
||||
|
||||
fc->max_hop = fc->max_node - i_branch;
|
||||
printf(", maxhop <= %d", fc->max_hop);
|
||||
|
||||
if(fc->irm == -1 ){
|
||||
printf(", Not found IRM capable node");
|
||||
}else{
|
||||
printf(", cable IRM = %d", fc->irm);
|
||||
if (fc->irm == fc->nodeid)
|
||||
printf(" (me)");
|
||||
}
|
||||
printf("\n");
|
||||
device_printf(fc->bdev, "%d nodes, maxhop <= %d %s irm(%d) %s\n",
|
||||
fc->max_node + 1, fc->max_hop,
|
||||
(fc->irm == -1) ? "Not IRM capable" : "cable IRM",
|
||||
fc->irm,
|
||||
(fc->irm == fc->nodeid) ? " (me) " : "");
|
||||
|
||||
if (try_bmr && (fc->irm != -1) && (CSRARC(fc, BUS_MGR_ID) == 0x3f)) {
|
||||
if (fc->irm == fc->nodeid) {
|
||||
@@ -1456,10 +1492,24 @@ fw_bus_probe(void *arg)
|
||||
fc->status = FWBUSEXPLORE;
|
||||
|
||||
/* Invalidate all devices, just after bus reset. */
|
||||
if (firewire_debug)
|
||||
device_printf(fc->bdev, "%s:"
|
||||
"iterate and invalidate all nodes\n",
|
||||
__func__);
|
||||
STAILQ_FOREACH(fwdev, &fc->devices, link)
|
||||
if (fwdev->status != FWDEVINVAL) {
|
||||
fwdev->status = FWDEVINVAL;
|
||||
fwdev->rcnt = 0;
|
||||
if (firewire_debug)
|
||||
device_printf(fc->bdev, "%s:"
|
||||
"Invalidate Dev ID: %08x%08x\n",
|
||||
__func__, fwdev->eui.hi, fwdev->eui.lo);
|
||||
} else {
|
||||
if (firewire_debug)
|
||||
device_printf(fc->bdev, "%s:"
|
||||
"Dev ID: %08x%08x already invalid\n",
|
||||
__func__, fwdev->eui.hi, fwdev->eui.lo);
|
||||
|
||||
}
|
||||
splx(s);
|
||||
|
||||
@@ -1469,13 +1519,13 @@ fw_bus_probe(void *arg)
|
||||
|
||||
static int
|
||||
fw_explore_read_quads(struct fw_device *fwdev, int offset,
|
||||
uint32_t *quad, int n)
|
||||
uint32_t *quad, int length)
|
||||
{
|
||||
struct fw_xfer *xfer;
|
||||
uint32_t tmp;
|
||||
int i, error;
|
||||
|
||||
for (i = 0; i < n; i ++, offset += sizeof(uint32_t)) {
|
||||
for (i = 0; i < length; i ++, offset += sizeof(uint32_t)) {
|
||||
xfer = fwmem_read_quad(fwdev, NULL, -1,
|
||||
0xffff, 0xf0000000 | offset, (void *)&tmp,
|
||||
fw_xferwake);
|
||||
@@ -1552,7 +1602,8 @@ fw_explore_node(struct fw_device *dfwdev)
|
||||
uint32_t *csr;
|
||||
struct csrhdr *hdr;
|
||||
struct bus_info *binfo;
|
||||
int err, node, spd;
|
||||
int err, node;
|
||||
uint32_t speed_test = 0;
|
||||
|
||||
fc = dfwdev->fc;
|
||||
csr = dfwdev->csrrom;
|
||||
@@ -1560,28 +1611,49 @@ fw_explore_node(struct fw_device *dfwdev)
|
||||
|
||||
/* First quad */
|
||||
err = fw_explore_read_quads(dfwdev, CSRROMOFF, &csr[0], 1);
|
||||
if (err)
|
||||
if (err) {
|
||||
device_printf(fc->bdev, "%s: node%d: explore_read_quads failure\n",
|
||||
__func__, node);
|
||||
dfwdev->status = FWDEVINVAL;
|
||||
return (-1);
|
||||
}
|
||||
hdr = (struct csrhdr *)&csr[0];
|
||||
if (hdr->info_len != 4) {
|
||||
if (firewire_debug)
|
||||
printf("node%d: wrong bus info len(%d)\n",
|
||||
node, hdr->info_len);
|
||||
device_printf(fc->bdev, "%s:"
|
||||
" node%d: wrong bus info len(%d)\n",
|
||||
__func__, node, hdr->info_len);
|
||||
dfwdev->status = FWDEVINVAL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* bus info */
|
||||
err = fw_explore_read_quads(dfwdev, CSRROMOFF + 0x04, &csr[1], 4);
|
||||
if (err)
|
||||
return (-1);
|
||||
binfo = (struct bus_info *)&csr[1];
|
||||
if (binfo->bus_name != CSR_BUS_NAME_IEEE1394) {
|
||||
if (firewire_debug)
|
||||
printf("node%d: invalid bus name 0x%08x\n",
|
||||
node, binfo->bus_name);
|
||||
if (err) {
|
||||
device_printf(fc->bdev, "%s: node%d: error reading 0x04\n",
|
||||
__func__, node);
|
||||
dfwdev->status = FWDEVINVAL;
|
||||
return (-1);
|
||||
}
|
||||
spd = fc->speed_map->speed[fc->nodeid][node];
|
||||
binfo = (struct bus_info *)&csr[1];
|
||||
if (binfo->bus_name != CSR_BUS_NAME_IEEE1394) {
|
||||
device_printf(fc->bdev, "%s: node%d: invalid bus name 0x%08x\n",
|
||||
__func__, node, binfo->bus_name);
|
||||
dfwdev->status = FWDEVINVAL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (firewire_debug)
|
||||
device_printf(fc->bdev, "%s: node(%d) BUS INFO BLOCK:\n"
|
||||
"irmc(%d) cmc(%d) isc(%d) bmc(%d) pmc(%d) "
|
||||
"cyc_clk_acc(%d) max_rec(%d) max_rom(%d) "
|
||||
"generation(%d) link_spd(%d)\n",
|
||||
__func__, node,
|
||||
binfo->irmc, binfo->cmc, binfo->isc,
|
||||
binfo->bmc, binfo->pmc, binfo->cyc_clk_acc,
|
||||
binfo->max_rec, binfo->max_rom,
|
||||
binfo->generation, binfo->link_spd);
|
||||
|
||||
STAILQ_FOREACH(fwdev, &fc->devices, link)
|
||||
if (FW_EUI64_EQUAL(fwdev->eui, binfo->eui64))
|
||||
break;
|
||||
@@ -1589,13 +1661,49 @@ fw_explore_node(struct fw_device *dfwdev)
|
||||
/* new device */
|
||||
fwdev = malloc(sizeof(struct fw_device));
|
||||
if (fwdev == NULL) {
|
||||
if (firewire_debug)
|
||||
printf("node%d: no memory\n", node);
|
||||
device_printf(fc->bdev, "%s: node%d: no memory\n",
|
||||
__func__, node);
|
||||
return (-1);
|
||||
}
|
||||
memset(fwdev, 0, sizeof(struct fw_device));
|
||||
fwdev->fc = fc;
|
||||
fwdev->eui = binfo->eui64;
|
||||
fwdev->dst = dfwdev->dst;
|
||||
fwdev->maxrec = dfwdev->maxrec;
|
||||
fwdev->status = dfwdev->status;
|
||||
|
||||
/*
|
||||
* Pre-1394a-2000 didn't have link_spd in
|
||||
* the Bus Info block, so try and use the
|
||||
* speed map value.
|
||||
* 1394a-2000 compliant devices only use
|
||||
* the Bus Info Block link spd value, so
|
||||
* ignore the speed map alltogether. SWB
|
||||
*/
|
||||
if ( binfo->link_spd == FWSPD_S100 /* 0 */) {
|
||||
device_printf(fc->bdev, "%s: "
|
||||
"Pre 1394a-2000 detected\n",
|
||||
__func__);
|
||||
fwdev->speed = fc->speed_map->speed[fc->nodeid][node];
|
||||
} else
|
||||
fwdev->speed = binfo->link_spd;
|
||||
/*
|
||||
* Test this speed with a read to the CSRROM.
|
||||
* If it fails, slow down the speed and retry.
|
||||
*/
|
||||
while (fwdev->speed > FWSPD_S100 /* 0 */) {
|
||||
err = fw_explore_read_quads(fwdev, CSRROMOFF,
|
||||
&speed_test, 1);
|
||||
if (err) {
|
||||
device_printf(fc->bdev, "%s: fwdev->speed(%s)"
|
||||
" decremented due to negotiation\n",
|
||||
__func__,
|
||||
linkspeed[fwdev->speed]);
|
||||
fwdev->speed--;
|
||||
} else
|
||||
break;
|
||||
|
||||
}
|
||||
/* inesrt into sorted fwdev list */
|
||||
pfwdev = NULL;
|
||||
STAILQ_FOREACH(tfwdev, &fc->devices, link) {
|
||||
@@ -1611,18 +1719,17 @@ fw_explore_node(struct fw_device *dfwdev)
|
||||
STAILQ_INSERT_AFTER(&fc->devices, pfwdev, fwdev, link);
|
||||
|
||||
device_printf(fc->bdev, "New %s device ID:%08x%08x\n",
|
||||
linkspeed[spd],
|
||||
linkspeed[fwdev->speed],
|
||||
fwdev->eui.hi, fwdev->eui.lo);
|
||||
}
|
||||
fwdev->dst = node;
|
||||
fwdev->status = FWDEVINIT;
|
||||
fwdev->speed = spd;
|
||||
|
||||
/* unchanged ? */
|
||||
if (bcmp(&csr[0], &fwdev->csrrom[0], sizeof(uint32_t) * 5) == 0) {
|
||||
if (firewire_debug)
|
||||
printf("node%d: crom unchanged\n", node);
|
||||
return (0);
|
||||
} else {
|
||||
fwdev->dst = node;
|
||||
fwdev->status = FWDEVINIT;
|
||||
/* unchanged ? */
|
||||
if (bcmp(&csr[0], &fwdev->csrrom[0], sizeof(uint32_t) * 5) == 0) {
|
||||
if (firewire_debug)
|
||||
device_printf(fc->dev, "node%d: crom unchanged\n", node);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
bzero(&fwdev->csrrom[0], CROMSIZE);
|
||||
@@ -1634,6 +1741,10 @@ fw_explore_node(struct fw_device *dfwdev)
|
||||
err = fw_explore_csrblock(fwdev, 0x14, 1); /* root directory */
|
||||
|
||||
if (err) {
|
||||
if (firewire_debug)
|
||||
device_printf(fc->dev, "%s:"
|
||||
" explore csrblock failed err(%d)\n",
|
||||
__func__, err);
|
||||
fwdev->status = FWDEVINVAL;
|
||||
fwdev->csrrom[0] = 0;
|
||||
}
|
||||
@@ -1677,12 +1788,25 @@ fw_explore(struct firewire_comm *fc)
|
||||
|
||||
for (node = 0; node <= fc->max_node; node ++) {
|
||||
/* We don't probe myself and linkdown nodes */
|
||||
if (node == fc->nodeid)
|
||||
if (node == fc->nodeid) {
|
||||
if (firewire_debug)
|
||||
device_printf(fc->bdev, "%s:"
|
||||
" found myself node(%d) fc->nodeid(%d)"
|
||||
" fc->max_node(%d)\n",
|
||||
__func__, node, fc->nodeid, fc->max_node);
|
||||
|
||||
continue;
|
||||
} else if (firewire_debug) {
|
||||
device_printf(fc->bdev, "%s:"
|
||||
"node(%d) fc->max_node(%d) found\n",
|
||||
__func__, node, fc->max_node);
|
||||
}
|
||||
|
||||
fwsid = fw_find_self_id(fc, node);
|
||||
if (!fwsid || !fwsid->p0.link_active) {
|
||||
if (firewire_debug)
|
||||
printf("node%d: link down\n", node);
|
||||
device_printf(fc->bdev, "%s: node%d: link down\n",
|
||||
__func__, node);
|
||||
continue;
|
||||
}
|
||||
nodes[todo++] = node;
|
||||
@@ -1697,8 +1821,8 @@ fw_explore(struct firewire_comm *fc)
|
||||
if (err)
|
||||
nodes[todo2++] = nodes[i];
|
||||
if (firewire_debug)
|
||||
printf("%s: node %d, err = %d\n",
|
||||
__FUNCTION__, node, err);
|
||||
device_printf(fc->bdev, "%s: node %d, err = %d\n",
|
||||
__func__, node, err);
|
||||
}
|
||||
todo = todo2;
|
||||
}
|
||||
@@ -1730,7 +1854,7 @@ fw_bus_probe_thread(void *arg)
|
||||
|
||||
}
|
||||
mtx_unlock(&fc->wait_lock);
|
||||
// kthread_exit(0);
|
||||
// kproc_exit(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1753,11 +1877,18 @@ fw_attach_dev(struct firewire_comm *fc)
|
||||
fwdev->status = FWDEVATTACHED;
|
||||
} else if (fwdev->status == FWDEVINVAL) {
|
||||
fwdev->rcnt ++;
|
||||
if (firewire_debug)
|
||||
device_printf(fc->bdev, "%s:"
|
||||
"fwdev->rcnt(%d), hold_count(%d)\n",
|
||||
__func__, fwdev->rcnt, hold_count);
|
||||
if (fwdev->rcnt > hold_count) {
|
||||
/*
|
||||
* Remove devices which have not been seen
|
||||
* for a while.
|
||||
*/
|
||||
device_printf(fc->bdev, "%s:"
|
||||
"Removing missing device ID:%08x%08x\n",
|
||||
__func__, fwdev->eui.hi, fwdev->eui.lo);
|
||||
STAILQ_REMOVE(&fc->devices, fwdev, fw_device,
|
||||
link);
|
||||
free(fwdev);
|
||||
@@ -1766,16 +1897,16 @@ fw_attach_dev(struct firewire_comm *fc)
|
||||
}
|
||||
|
||||
/* err = device_get_children(fc->bdev, &devlistp, &devcnt);
|
||||
if( err != 0 )
|
||||
return;
|
||||
for( i = 0 ; i < devcnt ; i++){
|
||||
if (device_get_state(devlistp[i]) >= DS_ATTACHED) {
|
||||
fdc = device_get_softc(devlistp[i]);
|
||||
if (fdc->post_explore != NULL)
|
||||
fdc->post_explore(fdc);
|
||||
if( err == 0 ) {
|
||||
for( i = 0 ; i < devcnt ; i++){
|
||||
if (device_get_state(devlistp[i]) >= DS_ATTACHED) {
|
||||
fdc = device_get_softc(devlistp[i]);
|
||||
if (fdc->post_explore != NULL)
|
||||
fdc->post_explore(fdc);
|
||||
}
|
||||
}
|
||||
}
|
||||
free(devlistp, M_TEMP);*/
|
||||
free(devlistp, M_TEMP);
|
||||
}*/
|
||||
|
||||
while(element){
|
||||
// fdc = &element->cookie.fd;
|
||||
@@ -1864,8 +1995,9 @@ fw_rcv_copy(struct fw_rcv_buf *rb)
|
||||
for (i = 0; i < rb->nvec; i++, rb->vec++) {
|
||||
len = MIN(rb->vec->iov_len, plen);
|
||||
if (res < len) {
|
||||
printf("rcv buffer(%d) is %d bytes short.\n",
|
||||
rb->xfer->recv.pay_len, len - res);
|
||||
device_printf(rb->fc->bdev, "%s:"
|
||||
" rcv buffer(%d) is %d bytes short.\n",
|
||||
__func__, rb->xfer->recv.pay_len, len - res);
|
||||
len = res;
|
||||
}
|
||||
bcopy(rb->vec->iov_base, p, len);
|
||||
@@ -1912,13 +2044,15 @@ fw_rcv(struct fw_rcv_buf *rb)
|
||||
rb->xfer = fw_tl2xfer(rb->fc, fp->mode.hdr.src,
|
||||
fp->mode.hdr.tlrt >> 2, fp->mode.hdr.tcode);
|
||||
if(rb->xfer == NULL) {
|
||||
printf("fw_rcv: unknown response "
|
||||
"%s(%x) src=0x%x tl=0x%x rt=%d data=0x%x\n",
|
||||
tcode_str[tcode], tcode,
|
||||
fp->mode.hdr.src,
|
||||
fp->mode.hdr.tlrt >> 2,
|
||||
fp->mode.hdr.tlrt & 3,
|
||||
fp->mode.rresq.data);
|
||||
device_printf(rb->fc->bdev, "%s: "
|
||||
"unknown response "
|
||||
"%s(%x) src=0x%x tl=0x%x rt=%d data=0x%x\n",
|
||||
__func__,
|
||||
tcode_str[tcode], tcode,
|
||||
fp->mode.hdr.src,
|
||||
fp->mode.hdr.tlrt >> 2,
|
||||
fp->mode.hdr.tlrt & 3,
|
||||
fp->mode.rresq.data);
|
||||
#if 0
|
||||
printf("try ad-hoc work around!!\n");
|
||||
rb->xfer = fw_tl2xfer(rb->fc, fp->mode.hdr.src,
|
||||
@@ -1950,7 +2084,9 @@ fw_rcv(struct fw_rcv_buf *rb)
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
printf("unexpected flag 0x%02x\n", rb->xfer->flag);
|
||||
device_printf(rb->fc->bdev, "%s: "
|
||||
"unexpected flag 0x%02x\n", __func__, rb->xfer->flag);
|
||||
|
||||
}
|
||||
return;
|
||||
case FWTCODE_WREQQ:
|
||||
@@ -1961,13 +2097,20 @@ fw_rcv(struct fw_rcv_buf *rb)
|
||||
bind = fw_bindlookup(rb->fc, fp->mode.rreqq.dest_hi,
|
||||
fp->mode.rreqq.dest_lo);
|
||||
if(bind == NULL){
|
||||
printf("Unknown service addr 0x%04x:0x%08x %s(%x)"
|
||||
device_printf(rb->fc->bdev, "%s: "
|
||||
"Unknown service addr 0x%04x:0x%08x %s(%x)"
|
||||
" src=0x%x data=%lx\n",
|
||||
fp->mode.wreqq.dest_hi, fp->mode.wreqq.dest_lo,
|
||||
tcode_str[tcode], tcode,
|
||||
fp->mode.hdr.src, ntohl(fp->mode.wreqq.data));
|
||||
__func__,
|
||||
fp->mode.wreqq.dest_hi,
|
||||
fp->mode.wreqq.dest_lo,
|
||||
tcode_str[tcode], tcode,
|
||||
fp->mode.hdr.src,
|
||||
ntohl(fp->mode.wreqq.data));
|
||||
|
||||
if (rb->fc->status == FWBUSINIT) {
|
||||
printf("fw_rcv: cannot respond(bus reset)!\n");
|
||||
device_printf(rb->fc->bdev, "%s: "
|
||||
"cannot respond(bus reset)!\n",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
rb->xfer = fw_xfer_alloc();
|
||||
@@ -2013,9 +2156,9 @@ fw_rcv(struct fw_rcv_buf *rb)
|
||||
len += rb->vec[i].iov_len;
|
||||
rb->xfer = STAILQ_FIRST(&bind->xferlist);
|
||||
if (rb->xfer == NULL) {
|
||||
#if 1
|
||||
printf("Discard a packet for this bind.\n");
|
||||
#endif
|
||||
device_printf(rb->fc->bdev, "%s: "
|
||||
"Discard a packet for this bind.\n",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
STAILQ_REMOVE_HEAD(&bind->xferlist, link);
|
||||
@@ -2066,7 +2209,8 @@ fw_rcv(struct fw_rcv_buf *rb)
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
printf("fw_rcv: unknow tcode %d\n", tcode);
|
||||
device_printf(rb->fc->bdev,"%s: unknown tcode %d\n",
|
||||
__func__, tcode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2239,6 +2383,12 @@ fw_crc16(uint32_t *ptr, uint32_t len){
|
||||
return((uint16_t) crc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the root node, if it is not
|
||||
* Cycle Master Capable, then we should
|
||||
* override this and become the Cycle
|
||||
* Master
|
||||
*/
|
||||
static int
|
||||
fw_bmr(struct firewire_comm *fc)
|
||||
{
|
||||
@@ -2263,13 +2413,13 @@ fw_bmr(struct firewire_comm *fc)
|
||||
} else
|
||||
cmstr = -1;
|
||||
|
||||
device_printf(fc->bdev, "bus manager %d ", CSRARC(fc, BUS_MGR_ID));
|
||||
device_printf(fc->bdev, "bus manager %d %s\n",
|
||||
CSRARC(fc, BUS_MGR_ID),
|
||||
(CSRARC(fc, BUS_MGR_ID) != fc->nodeid) ? "(me)" : "");
|
||||
if(CSRARC(fc, BUS_MGR_ID) != fc->nodeid) {
|
||||
/* We are not the bus manager */
|
||||
printf("\n");
|
||||
return(0);
|
||||
}
|
||||
printf("(me)\n");
|
||||
|
||||
/* Optimize gapcount */
|
||||
if(fc->max_hop <= MAX_GAPHOP )
|
||||
|
||||
@@ -283,8 +283,8 @@ fwohci_set_bus_manager(struct firewire_comm *fc, u_int node)
|
||||
if((bm & 0x3f) == 0x3f)
|
||||
bm = node;
|
||||
if (firewire_debug)
|
||||
device_printf(sc->fc.dev,
|
||||
"fw_set_bus_manager: %d->%d (loop=%d)\n", bm, node, i);
|
||||
device_printf(sc->fc.dev, "%s: %d->%d (loop=%d)\n",
|
||||
__func__, bm, node, i);
|
||||
|
||||
return(bm);
|
||||
}
|
||||
@@ -309,7 +309,7 @@ again:
|
||||
}
|
||||
if(i >= MAX_RETRY) {
|
||||
if (firewire_debug)
|
||||
device_printf(sc->fc.dev, "phy read failed(1).\n");
|
||||
device_printf(sc->fc.dev, "%s: failed(1).\n", __func__);
|
||||
if (++retry < MAX_RETRY) {
|
||||
DELAY(100);
|
||||
goto again;
|
||||
@@ -320,15 +320,15 @@ again:
|
||||
if ((stat & OHCI_INT_REG_FAIL) != 0 ||
|
||||
((fun >> PHYDEV_REGADDR) & 0xf) != addr) {
|
||||
if (firewire_debug)
|
||||
device_printf(sc->fc.dev, "phy read failed(2).\n");
|
||||
device_printf(sc->fc.dev, "%s: failed(2).\n", __func__);
|
||||
if (++retry < MAX_RETRY) {
|
||||
DELAY(100);
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
if (firewire_debug || retry >= MAX_RETRY)
|
||||
device_printf(sc->fc.dev,
|
||||
"fwphy_rddata: 0x%x loop=%d, retry=%d\n", addr, i, retry);
|
||||
if (firewire_debug > 1 || retry >= MAX_RETRY)
|
||||
device_printf(sc->fc.dev, "%s: 0x%x loop=%d, retry=%d\n",
|
||||
__func__, addr, i, retry);
|
||||
#undef MAX_RETRY
|
||||
return((fun >> PHYDEV_RDDATA )& 0xff);
|
||||
}
|
||||
@@ -1007,7 +1007,7 @@ txloop:
|
||||
if (maxdesc < db_tr->dbcnt) {
|
||||
maxdesc = db_tr->dbcnt;
|
||||
if (firewire_debug)
|
||||
printf("maxdesc: %d\n", maxdesc);
|
||||
printf("%s: maxdesc %d\n", __func__, maxdesc);
|
||||
}
|
||||
/* last db */
|
||||
LAST_DB(db_tr, db);
|
||||
@@ -1478,10 +1478,12 @@ fwohci_rx_enable(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
|
||||
|
||||
ir = &dbch->xferq;
|
||||
if(ir->buf == NULL && (ir->flag & FWXFERQ_EXTBUF) == 0) {
|
||||
dbch->Area = alloc_mem(&buf_virt, &buf_phy,
|
||||
if (dbch->Area <= 0) {
|
||||
dbch->Area = alloc_mem(&buf_virt, &buf_phy,
|
||||
ir->psize * dbch->ndb, 0, "fw rx Area");
|
||||
if(dbch->Area < B_OK)
|
||||
return(ENOMEM);
|
||||
if(dbch->Area < B_OK)
|
||||
return(ENOMEM);
|
||||
}
|
||||
}
|
||||
|
||||
for (idb = 0; idb < dbch->ndb; idb ++) {
|
||||
@@ -1796,6 +1798,8 @@ fwohci_stop(struct fwohci_softc *sc)
|
||||
{
|
||||
u_int i;
|
||||
|
||||
fwohci_set_intr(&sc->fc, 0);
|
||||
|
||||
/* Now stopping all DMA channel */
|
||||
OWRITE(sc, OHCI_ARQCTLCLR, OHCI_CNTL_DMA_RUN);
|
||||
OWRITE(sc, OHCI_ARSCTLCLR, OHCI_CNTL_DMA_RUN);
|
||||
@@ -1807,9 +1811,6 @@ fwohci_stop(struct fwohci_softc *sc)
|
||||
OWRITE(sc, OHCI_ITCTLCLR(i), OHCI_CNTL_DMA_RUN);
|
||||
}
|
||||
|
||||
if (sc->fc.arq !=0 && sc->fc.arq->maxq > 0)
|
||||
fw_drain_txq(&sc->fc);
|
||||
|
||||
#if 0 /* Let dcons(4) be accessed */
|
||||
/* Stop interrupt */
|
||||
OWRITE(sc, FWOHCI_INTMASKCLR,
|
||||
@@ -1865,12 +1866,13 @@ fwohci_intr_core(struct fwohci_softc *sc, uint32_t stat, int count)
|
||||
struct firewire_comm *fc = (struct firewire_comm *)sc;
|
||||
uint32_t node_id, plen;
|
||||
|
||||
FW_GLOCK_ASSERT(fc);
|
||||
if ((stat & OHCI_INT_PHY_BUS_R) && (fc->status != FWBUSRESET)) {
|
||||
fc->status = FWBUSRESET;
|
||||
/* Disable bus reset interrupt until sid recv. */
|
||||
OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_PHY_BUS_R);
|
||||
|
||||
device_printf(fc->dev, "BUS reset\n");
|
||||
device_printf(fc->dev, "%s: BUS reset\n", __func__);
|
||||
OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_CYC_LOST);
|
||||
OWRITE(sc, OHCI_LNKCTLCLR, OHCI_CNTL_CYCSRC);
|
||||
|
||||
@@ -1908,10 +1910,11 @@ fwohci_intr_core(struct fwohci_softc *sc, uint32_t stat, int count)
|
||||
plen = OREAD(sc, OHCI_SID_CNT);
|
||||
|
||||
fc->nodeid = node_id & 0x3f;
|
||||
device_printf(fc->dev, "node_id=0x%08x, gen=%d, ",
|
||||
node_id, (plen >> 16) & 0xff);
|
||||
device_printf(fc->dev, "%s: node_id=0x%08x, SelfID Count=%d, ",
|
||||
__func__, fc->nodeid, (plen >> 16) & 0xff);
|
||||
if (!(node_id & OHCI_NODE_VALID)) {
|
||||
printf("Bus reset failure\n");
|
||||
device_printf(fc->dev, "%s: Bus reset failure\n",
|
||||
__func__);
|
||||
goto sidout;
|
||||
}
|
||||
|
||||
@@ -2023,9 +2026,11 @@ fwohci_task_busreset(void *arg)
|
||||
{
|
||||
struct fwohci_softc *sc = (struct fwohci_softc *)arg;
|
||||
|
||||
FW_GLOCK(&sc->fc);
|
||||
fw_busreset(&sc->fc, FWBUSRESET);
|
||||
OWRITE(sc, OHCI_CROMHDR, ntohl(sc->fc.config_rom[0]));
|
||||
OWRITE(sc, OHCI_BUS_OPT, ntohl(sc->fc.config_rom[2]));
|
||||
FW_GUNLOCK(&sc->fc);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2037,6 +2042,9 @@ fwohci_task_sid(void *arg)
|
||||
int i, plen;
|
||||
|
||||
|
||||
/* We really should have locking
|
||||
* here. Not sure why it's not
|
||||
*/
|
||||
plen = OREAD(sc, OHCI_SID_CNT);
|
||||
|
||||
if (plen & OHCI_SID_ERR) {
|
||||
@@ -2056,14 +2064,13 @@ fwohci_task_sid(void *arg)
|
||||
}
|
||||
for (i = 0; i < plen / 4; i ++)
|
||||
buf[i] = FWOHCI_DMA_READ(sc->sid_buf[i+1]);
|
||||
#if 1 /* XXX needed?? */
|
||||
|
||||
/* pending all pre-bus_reset packets */
|
||||
fwohci_txd(sc, &sc->atrq);
|
||||
fwohci_txd(sc, &sc->atrs);
|
||||
fwohci_arcv(sc, &sc->arrs, -1);
|
||||
fwohci_arcv(sc, &sc->arrq, -1);
|
||||
fw_drain_txq(fc);
|
||||
#endif
|
||||
fw_sidrcv(fc, buf, plen);
|
||||
free(buf);
|
||||
}
|
||||
@@ -2088,6 +2095,7 @@ fwohci_check_stat(struct fwohci_softc *sc)
|
||||
{
|
||||
uint32_t stat, irstat, itstat;
|
||||
|
||||
FW_GLOCK_ASSERT(&sc->fc);
|
||||
stat = OREAD(sc, FWOHCI_INTSTAT);
|
||||
if (stat == 0xffffffff) {
|
||||
device_printf(sc->fc.dev,
|
||||
@@ -2120,16 +2128,23 @@ fwohci_check_stat(struct fwohci_softc *sc)
|
||||
int32
|
||||
fwohci_intr(void *arg)
|
||||
{
|
||||
int32 ret;
|
||||
struct fwohci_softc *sc = (struct fwohci_softc *)arg;
|
||||
|
||||
return (fwohci_check_stat(sc));
|
||||
//FW_GLOCK(&sc->fc);
|
||||
ret = fwohci_check_stat(sc);
|
||||
//FW_GUNLOCK(&sc->fc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
fwohci_poll(struct firewire_comm *fc, int quick, int count)
|
||||
{
|
||||
struct fwohci_softc *sc = (struct fwohci_softc *)fc;
|
||||
|
||||
FW_GLOCK(fc);
|
||||
fwohci_check_stat(sc);
|
||||
FW_GUNLOCK(fc);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2479,6 +2494,7 @@ fwohci_ibr(struct firewire_comm *fc)
|
||||
device_printf(fc->dev, "Initiate bus reset\n");
|
||||
sc = (struct fwohci_softc *)fc;
|
||||
|
||||
FW_GLOCK(fc);
|
||||
/*
|
||||
* Make sure our cached values from the config rom are
|
||||
* initialised.
|
||||
@@ -2499,6 +2515,7 @@ fwohci_ibr(struct firewire_comm *fc)
|
||||
fun |= FW_PHY_ISBR | FW_PHY_RHB;
|
||||
fun = fwphy_wrdata(sc, FW_PHY_ISBR_REG, fun);
|
||||
#endif
|
||||
FW_GUNLOCK(fc);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2956,7 +2973,7 @@ err:
|
||||
db_tr = STAILQ_NEXT(db_tr, link);
|
||||
resCount = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res)
|
||||
& OHCI_COUNT_MASK;
|
||||
} while (resCount == 0)
|
||||
}
|
||||
printf(" done\n");
|
||||
dbch->top = db_tr;
|
||||
dbch->buf_offset = dbch->xferq.psize - resCount;
|
||||
|
||||
@@ -208,7 +208,8 @@ fwohci_pci_attach(int index)
|
||||
TRACE("mapped registers to %p\n", sc->regAddr);
|
||||
|
||||
// setup interrupt handler
|
||||
if (install_io_interrupt_handler(sc->irq, fwohci_intr, sc, 0) < B_OK) {
|
||||
if (install_io_interrupt_handler(sc->irq, fwohci_intr,
|
||||
sc, 0) < B_OK) {
|
||||
ERROR("can't install interrupt handler\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -415,32 +415,31 @@ struct fwohci_trailer{
|
||||
#define OHCI_CNTL_PHYPKT (0x1 << 10)
|
||||
#define OHCI_CNTL_SID (0x1 << 9)
|
||||
|
||||
/*
|
||||
* defined in OHCI 1.1
|
||||
* chapter 6.1
|
||||
*/
|
||||
#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_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_REG_FAIL (0x1 << 18)
|
||||
|
||||
#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
|
||||
|
||||
@@ -85,7 +85,6 @@ int fwohci_detach (struct fwohci_softc *);
|
||||
int fwohci_stop (struct fwohci_softc *);
|
||||
#else
|
||||
void fwohci_intr (void *arg);
|
||||
int fwohci_filt (void *arg);
|
||||
int fwohci_init (struct fwohci_softc *, device_t);
|
||||
void fwohci_poll (struct firewire_comm *, int, int);
|
||||
void fwohci_reset (struct fwohci_softc *, device_t);
|
||||
|
||||
+398
-153
@@ -46,14 +46,9 @@ __FBSDID("$FreeBSD: src/usr.sbin/fwcontrol/fwcontrol.c,v 1.23 2006/10/26 22:33:3
|
||||
#include "iec13213.h"
|
||||
#include "fwphyreg.h"
|
||||
#include "iec68113.h"
|
||||
#include <stdint.h>
|
||||
#include <netinet/in.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <err.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#define EX_SOFTWARE 1
|
||||
#define EX_IOERR 1
|
||||
#else
|
||||
#include <sys/param.h>
|
||||
#include <sys/malloc.h>
|
||||
@@ -67,16 +62,17 @@ __FBSDID("$FreeBSD: src/usr.sbin/fwcontrol/fwcontrol.c,v 1.23 2006/10/26 22:33:3
|
||||
#include <dev/firewire/iec13213.h>
|
||||
#include <dev/firewire/fwphyreg.h>
|
||||
#include <dev/firewire/iec68113.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <fcntl.h>
|
||||
#include <sysexits.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <fcntl.h>
|
||||
#include <err.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
#include <netinet/in.h>
|
||||
#include "fwmethods.h"
|
||||
|
||||
#ifndef __HAIKU__
|
||||
@@ -87,32 +83,31 @@ static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"fwcontrol [-u bus_num] [-rt] [-g gap_count] [-o node] "
|
||||
"[-b pri_req] [-c node] [-d node] [-l file] "
|
||||
#ifdef __HAIKU__
|
||||
"[-M mode] [-R file] [-S file] \n"
|
||||
#else
|
||||
"[-R file] [-S file] [-m target]\n"
|
||||
"fwcontrol [-u bus_num] [-prt] [-c node] [-d node] [-o node] [-s node]\n"
|
||||
"\t [-l file] [-g gap_count] [-f force_root ] [-b pri_req]\n"
|
||||
"\t [-M mode] [-R filename] [-S filename] "
|
||||
#ifndef __HAIKU__
|
||||
"[-m EUI64 | hostname]\n"
|
||||
#endif
|
||||
|
||||
"\t-u: specify bus number\n"
|
||||
"\t-g: broadcast gap_count by phy_config packet\n"
|
||||
"\t-o: send link-on packet to the node\n"
|
||||
"\t-s: write RESET_START register on the node\n"
|
||||
"\t-b: set PRIORITY_BUDGET register on all supported nodes\n"
|
||||
"\t-c: read configuration ROM\n"
|
||||
"\t-p: Display current PHY register settings\n"
|
||||
"\t-r: bus reset\n"
|
||||
"\t-t: read topology map\n"
|
||||
"\t-c: read configuration ROM\n"
|
||||
"\t-d: hex dump of configuration ROM\n"
|
||||
"\t-o: send link-on packet to the node\n"
|
||||
"\t-s: write RESET_START register on the node\n"
|
||||
"\t-l: load and parse hex dump file of configuration ROM\n"
|
||||
"\t-R: Receive DV or MPEG TS stream\n"
|
||||
#ifdef __HAIKU__
|
||||
"\t-g: broadcast gap_count by phy_config packet\n"
|
||||
"\t-f: broadcast force_root by phy_config packet\n"
|
||||
"\t-b: set PRIORITY_BUDGET register on all supported nodes\n"
|
||||
"\t-M: Specify either d for dv mode or m for mpeg mode\n"
|
||||
"\t-S: Send DV stream\n");
|
||||
#else
|
||||
"\t-R: Receive DV or MPEG TS stream\n"
|
||||
"\t-S: Send DV stream\n"
|
||||
"\t-m: set fwmem target\n");
|
||||
#ifndef __HAIKU__
|
||||
"\t-m: set fwmem target\n"
|
||||
#endif
|
||||
);
|
||||
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
@@ -124,18 +119,14 @@ fweui2eui64(const struct fw_eui64 *fweui, struct eui64 *eui)
|
||||
*(u_int32_t*)&(eui->octet[4]) = htonl(fweui->lo);
|
||||
}
|
||||
|
||||
static struct fw_devlstreq *
|
||||
get_dev(int fd)
|
||||
static void
|
||||
get_dev(int fd, struct fw_devlstreq *data)
|
||||
{
|
||||
struct fw_devlstreq *data;
|
||||
|
||||
data = (struct fw_devlstreq *)malloc(sizeof(struct fw_devlstreq));
|
||||
if (data == NULL)
|
||||
err(1, "malloc");
|
||||
err(1, "%s: data malloc", __func__);
|
||||
if( ioctl(fd, FW_GDEVLST, data) < 0) {
|
||||
err(1, "ioctl");
|
||||
err(1, "%s: ioctl", __func__);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -166,17 +157,25 @@ str2node(int fd, const char *nodestr)
|
||||
#endif
|
||||
return (-1);
|
||||
|
||||
data = get_dev(fd);
|
||||
data = (struct fw_devlstreq *)malloc(sizeof(struct fw_devlstreq));
|
||||
if (data == NULL)
|
||||
err(1, "%s: data malloc", __func__);
|
||||
get_dev(fd, data);
|
||||
|
||||
for (i = 0; i < data->info_len; i++) {
|
||||
fweui2eui64(&data->dev[i].eui, &tmpeui);
|
||||
if (memcmp(&eui, &tmpeui, sizeof(struct eui64)) == 0) {
|
||||
node = data->dev[i].dst;
|
||||
if (data != NULL)
|
||||
free(data);
|
||||
goto gotnode;
|
||||
}
|
||||
}
|
||||
if (i >= data->info_len)
|
||||
if (i >= data->info_len) {
|
||||
if (data != NULL)
|
||||
free(data);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
gotnode:
|
||||
if (node < 0 || node > 63)
|
||||
@@ -194,7 +193,10 @@ list_dev(int fd)
|
||||
char addr[EUI64_SIZ];
|
||||
int i;
|
||||
|
||||
data = get_dev(fd);
|
||||
data = (struct fw_devlstreq *)malloc(sizeof(struct fw_devlstreq));
|
||||
if (data == NULL)
|
||||
err(1, "%s: data malloc", __func__);
|
||||
get_dev(fd, data);
|
||||
printf("%d devices (info_len=%d)\n", data->n, data->info_len);
|
||||
printf("node EUI64 status\n");
|
||||
for (i = 0; i < data->info_len; i++) {
|
||||
@@ -217,6 +219,8 @@ read_write_quad(int fd, struct fw_eui64 eui, u_int32_t addr_lo, int readmode, u_
|
||||
u_int32_t *qld, res;
|
||||
|
||||
asyreq = (struct fw_asyreq *)malloc(sizeof(struct fw_asyreq_t) + 16);
|
||||
if (asyreq == NULL)
|
||||
err(1, "%s:asyreq malloc", __func__);
|
||||
asyreq->req.len = 16;
|
||||
#if 0
|
||||
asyreq->req.type = FWASREQNODE;
|
||||
@@ -236,7 +240,7 @@ read_write_quad(int fd, struct fw_eui64 eui, u_int32_t addr_lo, int readmode, u_
|
||||
|
||||
qld = (u_int32_t *)&asyreq->pkt;
|
||||
if (!readmode)
|
||||
asyreq->pkt.mode.wreqq.data = data;
|
||||
asyreq->pkt.mode.wreqq.data = htonl(data);
|
||||
|
||||
if (ioctl(fd, FW_ASYREQ, asyreq) < 0) {
|
||||
err(1, "ioctl");
|
||||
@@ -249,37 +253,56 @@ read_write_quad(int fd, struct fw_eui64 eui, u_int32_t addr_lo, int readmode, u_
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a PHY Config Packet
|
||||
* ieee 1394a-2005 4.3.4.3
|
||||
*
|
||||
* Message ID Root ID R T Gap Count
|
||||
* 00(2 bits) (6 bits) 1 1 (6 bits)
|
||||
*
|
||||
* if "R" is set, then Root ID will be the next
|
||||
* root node upon the next bus reset.
|
||||
* if "T" is set, then Gap Count will be the
|
||||
* value that all nodes use for their Gap Count
|
||||
* if "R" and "T" are not set, then this message
|
||||
* is either ignored or interpreted as an extended
|
||||
* PHY config Packet as per 1394a-2005 4.3.4.4
|
||||
*/
|
||||
static 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);
|
||||
if (asyreq == NULL)
|
||||
err(1, "%s:asyreq malloc", __func__);
|
||||
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] |= (root_node & 0x3f) << 24 | 1 << 23;
|
||||
asyreq->pkt.mode.ld[1] |= ((root_node << 24) | (1 << 23));
|
||||
if (gap_count >= 0)
|
||||
asyreq->pkt.mode.ld[1] |= 1 << 22 | (gap_count & 0x3f) << 16;
|
||||
asyreq->pkt.mode.ld[1] |= ((1 << 22) | (gap_count << 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");
|
||||
err(1, "%s: ioctl", __func__);
|
||||
free(asyreq);
|
||||
}
|
||||
|
||||
static void
|
||||
send_link_on(int fd, int node)
|
||||
link_on(int fd, int node)
|
||||
{
|
||||
struct fw_asyreq *asyreq;
|
||||
|
||||
asyreq = (struct fw_asyreq *)malloc(sizeof(struct fw_asyreq_t) + 12);
|
||||
if (asyreq == NULL)
|
||||
err(1, "%s:asyreq malloc", __func__);
|
||||
asyreq->req.len = 12;
|
||||
asyreq->req.type = FWASREQNODE;
|
||||
asyreq->pkt.mode.common.tcode = FWTCODE_PHY;
|
||||
@@ -287,7 +310,7 @@ send_link_on(int fd, int node)
|
||||
asyreq->pkt.mode.ld[2] = ~asyreq->pkt.mode.ld[1];
|
||||
|
||||
if (ioctl(fd, FW_ASYREQ, asyreq) < 0)
|
||||
err(1, "ioctl");
|
||||
err(1, "%s: ioctl", __func__);
|
||||
free(asyreq);
|
||||
}
|
||||
|
||||
@@ -297,6 +320,8 @@ reset_start(int fd, int node)
|
||||
struct fw_asyreq *asyreq;
|
||||
|
||||
asyreq = (struct fw_asyreq *)malloc(sizeof(struct fw_asyreq_t) + 16);
|
||||
if (asyreq == NULL)
|
||||
err(1, "%s:asyreq malloc", __func__);
|
||||
asyreq->req.len = 16;
|
||||
asyreq->req.type = FWASREQNODE;
|
||||
asyreq->pkt.mode.wreqq.dst = FWLOCALBUS | (node & 0x3f);
|
||||
@@ -309,7 +334,7 @@ reset_start(int fd, int node)
|
||||
asyreq->pkt.mode.wreqq.data = htonl(0x1);
|
||||
|
||||
if (ioctl(fd, FW_ASYREQ, asyreq) < 0)
|
||||
err(1, "ioctl");
|
||||
err(1, "%s: ioctl", __func__);
|
||||
free(asyreq);
|
||||
}
|
||||
|
||||
@@ -323,7 +348,10 @@ set_pri_req(int fd, u_int32_t pri_req)
|
||||
u_int32_t max, reg, old;
|
||||
int i;
|
||||
|
||||
data = get_dev(fd);
|
||||
data = (struct fw_devlstreq *)malloc(sizeof(struct fw_devlstreq));
|
||||
if (data == NULL)
|
||||
err(1, "%s: data malloc", __func__);
|
||||
get_dev(fd, data);
|
||||
#define BUGET_REG 0xf0000218
|
||||
for (i = 0; i < data->info_len; i++) {
|
||||
devinfo = &data->dev[i];
|
||||
@@ -377,7 +405,10 @@ get_crom(int fd, int node, void *crom_buf, int len)
|
||||
int i, error;
|
||||
struct fw_devlstreq *data;
|
||||
|
||||
data = get_dev(fd);
|
||||
data = (struct fw_devlstreq *)malloc(sizeof(struct fw_devlstreq));
|
||||
if (data == NULL)
|
||||
err(1, "%s: data malloc", __func__);
|
||||
get_dev(fd, data);
|
||||
|
||||
for (i = 0; i < data->info_len; i++) {
|
||||
if (data->dev[i].dst == node && data->dev[i].eui.lo != 0)
|
||||
@@ -393,7 +424,7 @@ get_crom(int fd, int node, void *crom_buf, int len)
|
||||
buf.ptr = crom_buf;
|
||||
bzero(crom_buf, len);
|
||||
if ((error = ioctl(fd, FW_GCROM, &buf)) < 0) {
|
||||
err(1, "ioctl");
|
||||
err(1, "%s: ioctl", __func__);
|
||||
}
|
||||
|
||||
return error;
|
||||
@@ -502,9 +533,9 @@ show_topology_map(int fd)
|
||||
static const char *speed[] = {"S100", "S200", "S400", "S800"};
|
||||
tmap = malloc(sizeof(struct fw_topology_map));
|
||||
if (tmap == NULL)
|
||||
return;
|
||||
err(1, "%s:tmap malloc", __func__);
|
||||
if (ioctl(fd, FW_GTPMAP, tmap) < 0) {
|
||||
err(1, "ioctl");
|
||||
err(1, "%s: ioctl", __func__);
|
||||
}
|
||||
printf("crc_len: %d generation:%d node_count:%d sid_count:%d\n",
|
||||
tmap->crc_len, tmap->generation,
|
||||
@@ -517,13 +548,12 @@ show_topology_map(int fd)
|
||||
printf("%02d sequel packet\n", sid.p0.phy_id);
|
||||
continue;
|
||||
}
|
||||
printf("%02d %2d %2d %4s %d %d %3s"
|
||||
printf("%02d %2d %2d %4s %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],
|
||||
@@ -545,7 +575,7 @@ read_phy_registers(int fd, u_int8_t *buf, int offset, int len)
|
||||
for (i = 0; i < len; i++) {
|
||||
reg.addr = offset + i;
|
||||
if (ioctl(fd, FWOHCI_RDPHYREG, ®) < 0)
|
||||
err(1, "ioctl");
|
||||
err(1, "%s: ioctl", __func__);
|
||||
buf[i] = (u_int8_t) reg.data;
|
||||
printf("0x%02x ", reg.data);
|
||||
}
|
||||
@@ -560,7 +590,7 @@ read_phy_page(int fd, u_int8_t *buf, int page, int port)
|
||||
reg.addr = 0x7;
|
||||
reg.data = ((page & 7) << 5) | (port & 0xf);
|
||||
if (ioctl(fd, FWOHCI_WRPHYREG, ®) < 0)
|
||||
err(1, "ioctl");
|
||||
err(1, "%s: ioctl", __func__);
|
||||
read_phy_registers(fd, buf, 8, 8);
|
||||
}
|
||||
|
||||
@@ -623,28 +653,15 @@ dump_phy_registers(int fd)
|
||||
);
|
||||
}
|
||||
|
||||
static void
|
||||
open_dev(int *fd, char *devbase)
|
||||
static int
|
||||
open_dev(int *fd, char *devname)
|
||||
{
|
||||
#ifndef __HAIKU__
|
||||
char name[256];
|
||||
int i;
|
||||
#endif
|
||||
|
||||
if (*fd < 0) {
|
||||
#ifdef __HAIKU__
|
||||
*fd = open(devbase, O_RDWR);
|
||||
#else
|
||||
for (i = 0; i < 4; i++) {
|
||||
snprintf(name, sizeof(name), "%s.%d", devbase, i);
|
||||
if ((*fd = open(name, O_RDWR)) >= 0)
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
*fd = open(devname, O_RDWR);
|
||||
if (*fd < 0)
|
||||
err(1, "open");
|
||||
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifndef __HAIKU__
|
||||
@@ -666,25 +683,40 @@ detect_recv_fn(int fd, char ich)
|
||||
u_int32_t *ptr;
|
||||
struct ciphdr *ciph;
|
||||
fwmethod *retfn;
|
||||
#define RECV_NUM_PACKET 16
|
||||
#define RECV_PACKET_SZ 1024
|
||||
|
||||
bufreq.rx.nchunk = 8;
|
||||
bufreq.rx.npacket = 16;
|
||||
bufreq.rx.psize = 1024;
|
||||
bufreq.rx.npacket = RECV_NUM_PACKET;
|
||||
bufreq.rx.psize = RECV_PACKET_SZ;
|
||||
bufreq.tx.nchunk = 0;
|
||||
bufreq.tx.npacket = 0;
|
||||
bufreq.tx.psize = 0;
|
||||
printf("detect dv format\n");
|
||||
|
||||
if (ioctl(fd, FW_SSTBUF, &bufreq) < 0)
|
||||
err(1, "ioctl FW_SSTBUF");
|
||||
err(1, "%s: ioctl FW_SSTBUF", __func__);
|
||||
|
||||
isoreq.ch = ich & 0x3f;
|
||||
isoreq.tag = (ich >> 6) & 3;
|
||||
|
||||
if (ioctl(fd, FW_SRSTREAM, &isoreq) < 0)
|
||||
err(1, "ioctl FW_SRSTREAM");
|
||||
err(1, "%s: ioctl FW_SRSTREAM", __func__);
|
||||
|
||||
buf = (char *)malloc(1024*16);
|
||||
len = read(fd, buf, 1024*16);
|
||||
buf = (char *)malloc(RECV_NUM_PACKET * RECV_PACKET_SZ);
|
||||
if (buf == NULL)
|
||||
err(1, "%s:buf malloc", __func__);
|
||||
/*
|
||||
* fwdev.c seems to return EIO on error and
|
||||
* the return value of the last uiomove
|
||||
* on success. For now, checking that the
|
||||
* return is not less than zero should be
|
||||
* sufficient. fwdev.c::fw_read() should
|
||||
* return the total length read, not the value
|
||||
* of the last uiomove().
|
||||
*/
|
||||
len = read(fd, buf, RECV_NUM_PACKET * RECV_PACKET_SZ);
|
||||
if (len < 0)
|
||||
err(1, "%s: error reading from device\n", __func__);
|
||||
ptr = (u_int32_t *) buf;
|
||||
ciph = (struct ciphdr *)(ptr + 1);
|
||||
|
||||
@@ -707,111 +739,180 @@ printf("detect dv format\n");
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
#define MAX_BOARDS 10
|
||||
u_int32_t crom_buf[1024/4];
|
||||
u_int32_t crom_buf_hex[1024/4];
|
||||
char devbase[64];
|
||||
#ifdef __HAIKU__
|
||||
char devbase[1024] = "/dev/bus/fw/0";
|
||||
const char *device_string = "/dev/bus/fw/";
|
||||
#else
|
||||
char devbase[1024] = "/dev/fw0";
|
||||
const char *device_string = "/dev/fw";
|
||||
#endif
|
||||
int fd, ch, len=1024;
|
||||
int fd = -1, ch, len=1024;
|
||||
int32_t current_board = 0;
|
||||
/*
|
||||
* If !command_set, then -u will display the nodes for the board.
|
||||
* This emulates the previous behavior when -u is passed by itself
|
||||
*/
|
||||
bool command_set = false;
|
||||
bool open_needed = false;
|
||||
long tmp;
|
||||
struct fw_eui64 eui;
|
||||
struct eui64 target;
|
||||
fwmethod *recvfn = NULL;
|
||||
/*
|
||||
* Holders for which functions
|
||||
* to iterate through
|
||||
*/
|
||||
bool display_board_only = false;
|
||||
bool display_crom = false;
|
||||
bool send_bus_reset = false;
|
||||
bool display_crom_hex = false;
|
||||
bool load_crom_from_file = false;
|
||||
#ifndef __HAIKU__
|
||||
bool set_fwmem_target = false;
|
||||
#endif
|
||||
bool dump_topology = false;
|
||||
bool dump_phy_reg = false;
|
||||
|
||||
fd = -1;
|
||||
int32_t priority_budget = -1;
|
||||
int32_t set_root_node = -1;
|
||||
int32_t set_gap_count = -1;
|
||||
int32_t send_link_on = -1;
|
||||
int32_t send_reset_start = -1;
|
||||
|
||||
char *crom_string = NULL;
|
||||
char *crom_string_hex = NULL;
|
||||
char *recv_data = NULL;
|
||||
char *send_data = NULL;
|
||||
|
||||
if (argc < 2) {
|
||||
open_dev(&fd, devbase);
|
||||
list_dev(fd);
|
||||
for (current_board = 0; current_board < MAX_BOARDS; current_board++) {
|
||||
snprintf(devbase, sizeof(devbase), "%s%d", device_string, current_board);
|
||||
if (open_dev(&fd, devbase) < 0) {
|
||||
if (current_board == 0) {
|
||||
usage();
|
||||
}
|
||||
return(EIO);
|
||||
}
|
||||
list_dev(fd);
|
||||
close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse all command line options, then execute requested operations.
|
||||
*/
|
||||
#ifdef __HAIKU__
|
||||
while ((ch = getopt(argc, argv, "M:g:o:s:b:prtc:d:l:u:R:S:")) != -1)
|
||||
while ((ch = getopt(argc, argv, "M:f:g:o:s:b:prtc:d:l:u:R:S:")) != -1) {
|
||||
#else
|
||||
while ((ch = getopt(argc, argv, "M:g:m:o:s:b:prtc:d:l:u:R:S:")) != -1)
|
||||
while ((ch = getopt(argc, argv, "M:f:g:m:o:s:b:prtc:d:l:u:R:S:")) != -1) {
|
||||
#endif
|
||||
switch(ch) {
|
||||
case 'b':
|
||||
tmp = strtol(optarg, NULL, 0);
|
||||
if (tmp < 0 || tmp > (long)0xffffffff)
|
||||
errx(EX_USAGE, "invalid number: %s", optarg);
|
||||
open_dev(&fd, devbase);
|
||||
set_pri_req(fd, tmp);
|
||||
priority_budget = strtol(optarg, NULL, 0);
|
||||
if (priority_budget < 0 || priority_budget > INT32_MAX)
|
||||
errx(EX_USAGE, "%s: invalid number: %s", __func__, optarg);
|
||||
command_set = true;
|
||||
open_needed = true;
|
||||
display_board_only = false;
|
||||
break;
|
||||
case 'c':
|
||||
open_dev(&fd, devbase);
|
||||
tmp = str2node(fd, optarg);
|
||||
get_crom(fd, tmp, crom_buf, len);
|
||||
show_crom(crom_buf);
|
||||
crom_string = malloc(strlen(optarg)+1);
|
||||
if (crom_string == NULL)
|
||||
err(EX_SOFTWARE, "%s:crom_string malloc", __func__);
|
||||
if ( (strtol(crom_string, NULL, 0) < 0) || strtol(crom_string, NULL, 0) > MAX_BOARDS)
|
||||
err(EX_USAGE, "%s:Invalid value for node", __func__);
|
||||
strcpy(crom_string, optarg);
|
||||
display_crom = 1;
|
||||
open_needed = true;
|
||||
command_set = true;
|
||||
display_board_only = false;
|
||||
break;
|
||||
case 'd':
|
||||
open_dev(&fd, devbase);
|
||||
tmp = str2node(fd, optarg);
|
||||
get_crom(fd, tmp, crom_buf, len);
|
||||
dump_crom(crom_buf);
|
||||
crom_string_hex = malloc(strlen(optarg)+1);
|
||||
if (crom_string_hex == NULL)
|
||||
err(EX_SOFTWARE, "%s:crom_string_hex malloc", __func__);
|
||||
strcpy(crom_string_hex, optarg);
|
||||
display_crom_hex = 1;
|
||||
open_needed = true;
|
||||
command_set = true;
|
||||
display_board_only = false;
|
||||
break;
|
||||
case 'f':
|
||||
#define MAX_PHY_CONFIG 0x3f
|
||||
set_root_node = strtol(optarg, NULL, 0);
|
||||
if ( (set_root_node < 0) || (set_root_node > MAX_PHY_CONFIG) )
|
||||
err(EX_USAGE, "%s:set_root_node out of range", __func__);
|
||||
open_needed = true;
|
||||
command_set = true;
|
||||
display_board_only = false;
|
||||
break;
|
||||
case 'g':
|
||||
tmp = strtol(optarg, NULL, 0);
|
||||
open_dev(&fd, devbase);
|
||||
send_phy_config(fd, -1, tmp);
|
||||
set_gap_count = strtol(optarg, NULL, 0);
|
||||
if ( (set_gap_count < 0) || (set_gap_count > MAX_PHY_CONFIG) )
|
||||
err(EX_USAGE, "%s:set_gap_count out of range", __func__);
|
||||
open_needed = true;
|
||||
command_set = true;
|
||||
display_board_only = false;
|
||||
break;
|
||||
case 'l':
|
||||
load_crom_from_file = 1;
|
||||
load_crom(optarg, crom_buf);
|
||||
show_crom(crom_buf);
|
||||
command_set = true;
|
||||
display_board_only = false;
|
||||
break;
|
||||
#ifndef __HAIKU__
|
||||
case 'm':
|
||||
if (eui64_hostton(optarg, &target) != 0 &&
|
||||
eui64_aton(optarg, &target) != 0)
|
||||
errx(EX_USAGE, "invalid target: %s", optarg);
|
||||
eui.hi = ntohl(*(u_int32_t*)&(target.octet[0]));
|
||||
eui.lo = ntohl(*(u_int32_t*)&(target.octet[4]));
|
||||
sysctl_set_int("hw.firewire.fwmem.eui64_hi", eui.hi);
|
||||
sysctl_set_int("hw.firewire.fwmem.eui64_lo", eui.lo);
|
||||
set_fwmem_target = 1;
|
||||
open_needed = 0;
|
||||
command_set = true;
|
||||
display_board_only = false;
|
||||
if (eui64_hostton(optarg, &target) != 0 &&
|
||||
eui64_aton(optarg, &target) != 0)
|
||||
err(EX_USAGE, "%s: invalid target: %s", __func__, optarg);
|
||||
break;
|
||||
#endif
|
||||
case 'o':
|
||||
open_dev(&fd, devbase);
|
||||
tmp = str2node(fd, optarg);
|
||||
send_link_on(fd, tmp);
|
||||
send_link_on = str2node(fd, optarg);
|
||||
if ( (send_link_on < 0) || (send_link_on > INT32_MAX) )
|
||||
err(EX_USAGE, "%s: node out of range: %s\n",__func__, optarg);
|
||||
open_needed = true;
|
||||
command_set = true;
|
||||
display_board_only = false;
|
||||
break;
|
||||
case 'p':
|
||||
open_dev(&fd, devbase);
|
||||
dump_phy_registers(fd);
|
||||
dump_phy_reg = 1;
|
||||
open_needed = true;
|
||||
command_set = true;
|
||||
display_board_only = false;
|
||||
break;
|
||||
case 'r':
|
||||
open_dev(&fd, devbase);
|
||||
if(ioctl(fd, FW_IBUSRST, &tmp) < 0)
|
||||
err(1, "ioctl");
|
||||
send_bus_reset = 1;
|
||||
open_needed = true;
|
||||
command_set = true;
|
||||
display_board_only = false;
|
||||
break;
|
||||
case 's':
|
||||
open_dev(&fd, devbase);
|
||||
tmp = str2node(fd, optarg);
|
||||
reset_start(fd, tmp);
|
||||
send_reset_start = str2node(fd, optarg);
|
||||
if ( (send_reset_start < 0) || (send_reset_start > INT32_MAX) )
|
||||
err(EX_USAGE, "%s: node out of range: %s\n", __func__, optarg);
|
||||
open_needed = true;
|
||||
command_set = true;
|
||||
display_board_only = false;
|
||||
break;
|
||||
case 't':
|
||||
open_dev(&fd, devbase);
|
||||
show_topology_map(fd);
|
||||
dump_topology = 1;
|
||||
open_needed = true;
|
||||
command_set = true;
|
||||
display_board_only = false;
|
||||
break;
|
||||
case 'u':
|
||||
tmp = strtol(optarg, NULL, 0);
|
||||
#ifdef __HAIKU__
|
||||
snprintf(devbase, sizeof(devbase), "/dev/bus/fw/%ld", tmp);
|
||||
#else
|
||||
snprintf(devbase, sizeof(devbase), "/dev/fw%ld", tmp);
|
||||
#endif
|
||||
if (fd > 0) {
|
||||
close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
if (argc == optind) {
|
||||
open_dev(&fd, devbase);
|
||||
list_dev(fd);
|
||||
}
|
||||
if(!command_set)
|
||||
display_board_only = true;
|
||||
current_board = strtol(optarg, NULL, 0);
|
||||
open_needed = true;
|
||||
break;
|
||||
#define TAG (1<<6)
|
||||
#define CHANNEL 63
|
||||
case 'M':
|
||||
switch (optarg[0]) {
|
||||
case 'm':
|
||||
@@ -824,22 +925,166 @@ main(int argc, char **argv)
|
||||
errx(EX_USAGE, "unrecognized method: %s",
|
||||
optarg);
|
||||
}
|
||||
command_set = true;
|
||||
display_board_only = false;
|
||||
break;
|
||||
case 'R':
|
||||
open_dev(&fd, devbase);
|
||||
if (recvfn == NULL) /* guess... */
|
||||
recvfn = detect_recv_fn(fd, TAG | CHANNEL);
|
||||
close(fd);
|
||||
fd = -1;
|
||||
open_dev(&fd, devbase);
|
||||
(*recvfn)(fd, optarg, TAG | CHANNEL, -1);
|
||||
recv_data = malloc(strlen(optarg)+1);
|
||||
if (recv_data == NULL)
|
||||
err(EX_SOFTWARE, "%s:recv_data malloc", __func__);
|
||||
strcpy(recv_data, optarg);
|
||||
open_needed = false;
|
||||
command_set = true;
|
||||
display_board_only = false;
|
||||
break;
|
||||
case 'S':
|
||||
open_dev(&fd, devbase);
|
||||
dvsend(fd, optarg, TAG | CHANNEL, -1);
|
||||
send_data = malloc(strlen(optarg)+1);
|
||||
if (send_data == NULL)
|
||||
err(EX_SOFTWARE, "%s:send_data malloc", __func__);
|
||||
strcpy(send_data, optarg);
|
||||
open_needed = true;
|
||||
command_set = true;
|
||||
display_board_only = false;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
return 0;
|
||||
}
|
||||
} /* end while */
|
||||
|
||||
/*
|
||||
* If -u <bus_number> is passed, execute
|
||||
* command for that card only.
|
||||
*
|
||||
* If -u <bus_number> is not passed, execute
|
||||
* command for card 0 only.
|
||||
*
|
||||
*/
|
||||
if(open_needed){
|
||||
snprintf(devbase, sizeof(devbase), "%s%d", device_string, current_board);
|
||||
if (open_dev(&fd, devbase) < 0) {
|
||||
errx(EX_IOERR, "%s: Error opening board #%d\n", __func__, current_board);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* display the nodes on this board "-u"
|
||||
* only
|
||||
*/
|
||||
if (display_board_only)
|
||||
list_dev(fd);
|
||||
|
||||
/*
|
||||
* dump_phy_reg "-p"
|
||||
*/
|
||||
if (dump_phy_reg)
|
||||
dump_phy_registers(fd);
|
||||
|
||||
/*
|
||||
* send a BUS_RESET Event "-r"
|
||||
*/
|
||||
if (send_bus_reset) {
|
||||
if(ioctl(fd, FW_IBUSRST, &tmp) < 0)
|
||||
err(EX_IOERR, "%s: ioctl", __func__);
|
||||
}
|
||||
/*
|
||||
* Print out the CROM for this node "-c"
|
||||
*/
|
||||
if (display_crom) {
|
||||
tmp = str2node(fd, crom_string);
|
||||
get_crom(fd, tmp, crom_buf, len);
|
||||
show_crom(crom_buf);
|
||||
free(crom_string);
|
||||
}
|
||||
/*
|
||||
* Hex Dump the CROM for this node "-d"
|
||||
*/
|
||||
if (display_crom_hex) {
|
||||
tmp = str2node(fd, crom_string_hex);
|
||||
get_crom(fd, tmp, crom_buf_hex, len);
|
||||
dump_crom(crom_buf_hex);
|
||||
free(crom_string_hex);
|
||||
}
|
||||
/*
|
||||
* Set Priority Budget to value for this node "-b"
|
||||
*/
|
||||
if (priority_budget >= 0)
|
||||
set_pri_req(fd, priority_budget);
|
||||
|
||||
/*
|
||||
* Explicitly set the root node of this bus to value "-f"
|
||||
*/
|
||||
if (set_root_node >= 0)
|
||||
send_phy_config(fd, set_root_node, -1);
|
||||
|
||||
/*
|
||||
* Set the gap count for this card/bus "-g"
|
||||
*/
|
||||
if (set_gap_count >= 0)
|
||||
send_phy_config(fd, -1, set_gap_count);
|
||||
|
||||
/*
|
||||
* Load a CROM from a file "-l"
|
||||
*/
|
||||
if (load_crom_from_file)
|
||||
show_crom(crom_buf);
|
||||
#ifndef __HAIKU__
|
||||
/*
|
||||
* Set the fwmem target for a node to argument "-m"
|
||||
*/
|
||||
if (set_fwmem_target) {
|
||||
eui.hi = ntohl(*(u_int32_t*)&(target.octet[0]));
|
||||
eui.lo = ntohl(*(u_int32_t*)&(target.octet[4]));
|
||||
sysctl_set_int("hw.firewire.fwmem.eui64_hi", eui.hi);
|
||||
sysctl_set_int("hw.firewire.fwmem.eui64_lo", eui.lo);
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Send a link on to this board/bus "-o"
|
||||
*/
|
||||
if (send_link_on >= 0)
|
||||
link_on(fd, send_link_on);
|
||||
|
||||
/*
|
||||
* Send a reset start to this board/bus "-s"
|
||||
*/
|
||||
if (send_reset_start >= 0)
|
||||
reset_start(fd, send_reset_start);
|
||||
|
||||
/*
|
||||
* Dump the node topology for this board/bus "-t"
|
||||
*/
|
||||
if (dump_topology)
|
||||
show_topology_map(fd);
|
||||
|
||||
/*
|
||||
* Recieve data file from node "-R"
|
||||
*/
|
||||
#define TAG (1<<6)
|
||||
#define CHANNEL 63
|
||||
if (recv_data != NULL){
|
||||
if (recvfn == NULL) { /* guess... */
|
||||
recvfn = detect_recv_fn(fd, TAG | CHANNEL);
|
||||
close(fd);
|
||||
}
|
||||
snprintf(devbase, sizeof(devbase), "%s%d", device_string, current_board);
|
||||
if (open_dev(&fd, devbase) < 0)
|
||||
errx(EX_IOERR, "%s: Error opening board #%d in recv_data\n", __func__, current_board);
|
||||
(*recvfn)(fd, recv_data, TAG | CHANNEL, -1);
|
||||
free(recv_data);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send data file to node "-S"
|
||||
*/
|
||||
if (send_data != NULL){
|
||||
dvsend(fd, send_data, TAG | CHANNEL, -1);
|
||||
free(send_data);
|
||||
}
|
||||
|
||||
if (fd > 0) {
|
||||
close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -211,14 +211,19 @@ again:
|
||||
(dv->payload[0] & DV_DSF_12) == 0)
|
||||
dv->payload[0] |= DV_DSF_12;
|
||||
nb = nblocks[system];
|
||||
fprintf(stderr, "%d", k%10);
|
||||
fprintf(stderr, "%d:%02d:%02d %d\r",
|
||||
k / (3600 * frame_rate[system]),
|
||||
(k / (60 * frame_rate[system])) % 60,
|
||||
(k / frame_rate[system]) % 60,
|
||||
k % frame_rate[system]);
|
||||
|
||||
#if FIX_FRAME
|
||||
if (m > 0 && m != nb) {
|
||||
/* padding bad frame */
|
||||
npad = ((nb - m) % nb);
|
||||
if (npad < 0)
|
||||
npad += nb;
|
||||
fprintf(stderr, "(%d blocks padded)",
|
||||
fprintf(stderr, "\n%d blocks padded\n",
|
||||
npad);
|
||||
npad *= DSIZE;
|
||||
wbuf[vec].iov_base = pad;
|
||||
@@ -230,10 +235,6 @@ again:
|
||||
}
|
||||
#endif
|
||||
k++;
|
||||
if (k % frame_rate[system] == 0) {
|
||||
/* every second */
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
fflush(stderr);
|
||||
m = 0;
|
||||
}
|
||||
@@ -254,9 +255,8 @@ next:
|
||||
if (vec > 0)
|
||||
writev(fd, wbuf, vec);
|
||||
}
|
||||
if(fd != STDOUT_FILENO) {
|
||||
if(fd != STDOUT_FILENO)
|
||||
close(fd);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -196,10 +196,9 @@ mpegtsrecv(int d, const char *filename, char ich, int count)
|
||||
if (len < 0) {
|
||||
if (errno == EAGAIN) {
|
||||
fprintf(stderr, "(EAGAIN) - push 'Play'?\n");
|
||||
if (len <= 0)
|
||||
continue;
|
||||
} else
|
||||
err(1, "read failed");
|
||||
continue;
|
||||
}
|
||||
err(1, "read failed");
|
||||
}
|
||||
ptr = (uint32_t *) buf;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user