From f32ddaddf95d8a30be5a41cf681bc8792bc42ec7 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Thu, 24 Apr 2008 23:17:47 +0200 Subject: firewire: fw-sbp2: log scsi_target ID at release Makes the good-by message more informative. Signed-off-by: Stefan Richter Signed-off-by: Jarod Wilson --- drivers/firewire/fw-sbp2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/firewire') diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 2a999373863..62e3c919098 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -784,7 +784,7 @@ static void sbp2_release_target(struct kref *kref) kfree(lu); } scsi_remove_host(shost); - fw_notify("released %s\n", tgt->bus_id); + fw_notify("released %s, target %d:0:0\n", tgt->bus_id, shost->host_no); fw_unit_put(tgt->unit); scsi_host_put(shost); -- cgit v1.2.3 From 64a87b244b9297667ca80264aab849a36f494884 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Wed, 30 Apr 2008 11:19:47 +0300 Subject: [SCSI] Let scsi_cmnd->cmnd use request->cmd buffer - struct scsi_cmnd had a 16 bytes command buffer of its own. This is an unnecessary duplication and copy of request's cmd. It is probably left overs from the time that scsi_cmnd could function without a request attached. So clean that up. - Once above is done, few places, apart from scsi-ml, needed adjustments due to changing the data type of scsi_cmnd->cmnd. - Lots of drivers still use MAX_COMMAND_SIZE. So I have left that #define but equate it to BLK_MAX_CDB. The way I see it and is reflected in the patch below is. MAX_COMMAND_SIZE - means: The longest fixed-length (*) SCSI CDB as per the SCSI standard and is not related to the implementation. BLK_MAX_CDB. - The allocated space at the request level - I have audit all ISA drivers and made sure none use ->cmnd in a DMA Operation. Same audit was done by Andi Kleen. (*)fixed-length here means commands that their size can be determined by their opcode and the CDB does not carry a length specifier, (unlike the VARIABLE_LENGTH_CMD(0x7f) command). This is actually not exactly true and the SCSI standard also defines extended commands and vendor specific commands that can be bigger than 16 bytes. The kernel will support these using the same infrastructure used for VARLEN CDB's. So in effect MAX_COMMAND_SIZE means the maximum size command scsi-ml supports without specifying a cmd_len by ULD's Signed-off-by: Boaz Harrosh Signed-off-by: James Bottomley --- drivers/firewire/fw-sbp2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/firewire') diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 2a999373863..dda82f37cab 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -1487,7 +1487,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) if (scsi_sg_count(cmd) && sbp2_map_scatterlist(orb, device, lu) < 0) goto out; - memcpy(orb->request.command_block, cmd->cmnd, COMMAND_SIZE(*cmd->cmnd)); + memcpy(orb->request.command_block, cmd->cmnd, cmd->cmd_len); orb->base.callback = complete_command_orb; orb->base.request_bus = -- cgit v1.2.3 From 551f4cb9de716ffcdaf968c99a450c22ff12e8c3 Mon Sep 17 00:00:00 2001 From: Jay Fenlason Date: Fri, 16 May 2008 11:15:23 -0400 Subject: firewire: prevent userspace from accessing shut down devices If userspace ignores the POLLERR bit from poll(), and only attempts to read() the device when POLLIN is set, it can still make ioctl() calls on a device that has been removed from the system. The node_id and generation returned by GET_INFO will be outdated, but INITIATE_BUS_RESET would still cause a bus reset, and GET_CYCLE_TIMER will return data. And if you guess the correct generation to use, you can send requests to a different device on the bus, and get responses back. This patch prevents open, ioctl, compat_ioctl, and mmap against shutdown devices. Signed-off-by: Jay Fenlason Signed-off-by: Stefan Richter --- drivers/firewire/fw-cdev.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers/firewire') diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c index 4a541921a14..dda14015e87 100644 --- a/drivers/firewire/fw-cdev.c +++ b/drivers/firewire/fw-cdev.c @@ -113,6 +113,11 @@ static int fw_device_op_open(struct inode *inode, struct file *file) if (device == NULL) return -ENODEV; + if (fw_device_is_shutdown(device)) { + fw_device_put(device); + return -ENODEV; + } + client = kzalloc(sizeof(*client), GFP_KERNEL); if (client == NULL) { fw_device_put(device); @@ -901,6 +906,9 @@ fw_device_op_ioctl(struct file *file, { struct client *client = file->private_data; + if (fw_device_is_shutdown(client->device)) + return -ENODEV; + return dispatch_ioctl(client, cmd, (void __user *) arg); } @@ -911,6 +919,9 @@ fw_device_op_compat_ioctl(struct file *file, { struct client *client = file->private_data; + if (fw_device_is_shutdown(client->device)) + return -ENODEV; + return dispatch_ioctl(client, cmd, compat_ptr(arg)); } #endif @@ -922,6 +933,9 @@ static int fw_device_op_mmap(struct file *file, struct vm_area_struct *vma) unsigned long size; int page_count, retval; + if (fw_device_is_shutdown(client->device)) + return -ENODEV; + /* FIXME: We could support multiple buffers, but we don't. */ if (client->buffer.pages != NULL) return -EBUSY; -- cgit v1.2.3 From 0bf607c5b4edd13362e4add6ca1e81f8a9fbd47c Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 31 May 2008 19:01:26 +0200 Subject: firewire: don't panic on invalid AR request buffer BUG() at this place is wrong. (Unless if the low level driver would already do higher-level input validation of incoming request headers.) Invalid incoming requests or bugs in the controller which corrupt the AR-req buffer needlessly crashed the box because this is run in tasklet context. Signed-off-by: Stefan Richter --- drivers/firewire/fw-transaction.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/firewire') diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c index ccf0e4cf108..7f92c45349e 100644 --- a/drivers/firewire/fw-transaction.c +++ b/drivers/firewire/fw-transaction.c @@ -572,7 +572,8 @@ allocate_request(struct fw_packet *p) break; default: - BUG(); + fw_error("ERROR - corrupt request received - %08x %08x %08x\n", + p->header[0], p->header[1], p->header[2]); return NULL; } -- cgit v1.2.3 From ccff962943df539c5860aa120eecc189d70a308b Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 31 May 2008 19:36:06 +0200 Subject: firewire: fw-ohci: use of uninitialized data in AR handler header_length and payload_length are filled with random data if an unknown tcode was read from the AR buffer (i.e. if the AR buffer contained invalid data). We still need a better strategy to recover from this, but at least handle_ar_packet now doesn't return out of bound buffer addresses anymore. Signed-off-by: Stefan Richter --- drivers/firewire/fw-ohci.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/firewire') diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c index 4f02c55f13e..b062e736b78 100644 --- a/drivers/firewire/fw-ohci.c +++ b/drivers/firewire/fw-ohci.c @@ -548,6 +548,11 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer) p.header_length = 12; p.payload_length = 0; break; + + default: + /* FIXME: Stop context, discard everything, and restart? */ + p.header_length = 0; + p.payload_length = 0; } p.payload = (void *) buffer + p.header_length; -- cgit v1.2.3 From e896ec4302f45fdaf2fc78aec0093eca5478fe28 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Thu, 5 Jun 2008 20:49:38 +0200 Subject: firewire: fw-ohci: disable PHY packet reception into AR context We want the rcvPhyPkt bit in LinkControl off before we start using the chip. However, the spec says that the reset value of it is undefined. Hence switch it explicitly off. https://bugzilla.redhat.com/show_bug.cgi?id=244576#c48 shows that for example the nForce2 integrated FireWire controller seems to have it on by default. Signed-off-by: Stefan Richter Signed-off-by: Jarod Wilson --- drivers/firewire/fw-ohci.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/firewire') diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c index b062e736b78..481d3f3e2ef 100644 --- a/drivers/firewire/fw-ohci.c +++ b/drivers/firewire/fw-ohci.c @@ -1473,6 +1473,8 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length) reg_write(ohci, OHCI1394_HCControlClear, OHCI1394_HCControl_noByteSwapData); + reg_write(ohci, OHCI1394_LinkControlClear, + OHCI1394_LinkControl_rcvPhyPkt); reg_write(ohci, OHCI1394_LinkControlSet, OHCI1394_LinkControl_rcvSelfID | OHCI1394_LinkControl_cycleTimerEnable | -- cgit v1.2.3 From affc9c24ade666f9903163c12686da567dbfe06f Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Thu, 5 Jun 2008 20:50:53 +0200 Subject: firewire: fw-ohci: write selfIDBufferPtr before LinkControl.rcvSelfID MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit OHCI 1.1 clause 5.10 requires that selfIDBufferPtr is valid when a 1 is written into LinkControl.rcvSelfID. This driver bug has so far not been known to cause harm because most chips obviously accept a later selfIDBufferPtr write, at least before HCControl.linkEnable is written. Signed-off-by: Stefan Richter Signed-off-by: Jarod Wilson Signed-off-by: Kristian Høgsberg --- drivers/firewire/fw-ohci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/firewire') diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c index 481d3f3e2ef..96e3cce3693 100644 --- a/drivers/firewire/fw-ohci.c +++ b/drivers/firewire/fw-ohci.c @@ -1473,6 +1473,7 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length) reg_write(ohci, OHCI1394_HCControlClear, OHCI1394_HCControl_noByteSwapData); + reg_write(ohci, OHCI1394_SelfIDBuffer, ohci->self_id_bus); reg_write(ohci, OHCI1394_LinkControlClear, OHCI1394_LinkControl_rcvPhyPkt); reg_write(ohci, OHCI1394_LinkControlSet, @@ -1488,7 +1489,6 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length) ar_context_run(&ohci->ar_request_ctx); ar_context_run(&ohci->ar_response_ctx); - reg_write(ohci, OHCI1394_SelfIDBuffer, ohci->self_id_bus); reg_write(ohci, OHCI1394_PhyUpperBound, 0x00010000); reg_write(ohci, OHCI1394_IntEventClear, ~0); reg_write(ohci, OHCI1394_IntMaskClear, ~0); -- cgit v1.2.3 From 5cb84067d646fa3889463129dad8b218806b4698 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Fri, 6 Jun 2008 22:11:30 +0200 Subject: firewire: fill_bus_reset_event needs lock protection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Callers of fill_bus_reset_event() have to take card->lock. Otherwise access to node data may oops if node removal is in progress. A lockless alternative would be - event->local_node_id = card->local_node->node_id; + tmp = fw_node_get(card->local_node); + event->local_node_id = tmp->node_id; + fw_node_put(tmp); and ditto with the other node pointers which fill_bus_reset_event() accesses. But I went the locked route because one of the two callers already holds the lock. As a bonus, we don't need the memory barrier anymore because device->generation and device->node_id are written in a card->lock protected section. Signed-off-by: Stefan Richter Signed-off-by: Kristian Høgsberg --- drivers/firewire/fw-cdev.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/firewire') diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c index dda14015e87..c639915fc3c 100644 --- a/drivers/firewire/fw-cdev.c +++ b/drivers/firewire/fw-cdev.c @@ -205,6 +205,7 @@ fw_device_op_read(struct file *file, return dequeue_event(client, buffer, count); } +/* caller must hold card->lock so that node pointers can be dereferenced here */ static void fill_bus_reset_event(struct fw_cdev_event_bus_reset *event, struct client *client) @@ -214,7 +215,6 @@ fill_bus_reset_event(struct fw_cdev_event_bus_reset *event, event->closure = client->bus_reset_closure; event->type = FW_CDEV_EVENT_BUS_RESET; event->generation = client->device->generation; - smp_rmb(); /* node_id must not be older than generation */ event->node_id = client->device->node_id; event->local_node_id = card->local_node->node_id; event->bm_node_id = 0; /* FIXME: We don't track the BM. */ @@ -274,6 +274,7 @@ static int ioctl_get_info(struct client *client, void *buffer) { struct fw_cdev_get_info *get_info = buffer; struct fw_cdev_event_bus_reset bus_reset; + struct fw_card *card = client->device->card; unsigned long ret = 0; client->version = get_info->version; @@ -299,13 +300,17 @@ static int ioctl_get_info(struct client *client, void *buffer) client->bus_reset_closure = get_info->bus_reset_closure; if (get_info->bus_reset != 0) { void __user *uptr = u64_to_uptr(get_info->bus_reset); + unsigned long flags; + spin_lock_irqsave(&card->lock, flags); fill_bus_reset_event(&bus_reset, client); + spin_unlock_irqrestore(&card->lock, flags); + if (copy_to_user(uptr, &bus_reset, sizeof(bus_reset))) return -EFAULT; } - get_info->card = client->device->card->index; + get_info->card = card->index; return 0; } -- cgit v1.2.3 From 161b96e782ec995c55843101976d9c35b57aa109 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 14 Jun 2008 14:23:43 +0200 Subject: firewire: fw-ohci: unify printk prefixes The messages which can be enabled by fw-ohci's debug module parameter are changed from KERN_DEBUG to KERN_NOTICE level and uniformly prefixed with "firewire_ohci: ". This further simplifies communication with users when we ask them to capture debug messages. Signed-off-by: Stefan Richter --- drivers/firewire/fw-ohci.c | 101 +++++++++++++++++++++------------------------ 1 file changed, 48 insertions(+), 53 deletions(-) (limited to 'drivers/firewire') diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c index 96e3cce3693..0b66306af47 100644 --- a/drivers/firewire/fw-ohci.c +++ b/drivers/firewire/fw-ohci.c @@ -265,27 +265,25 @@ static void log_irqs(u32 evt) !(evt & OHCI1394_busReset)) return; - printk(KERN_DEBUG KBUILD_MODNAME ": IRQ " - "%08x%s%s%s%s%s%s%s%s%s%s%s%s%s\n", - evt, - evt & OHCI1394_selfIDComplete ? " selfID" : "", - evt & OHCI1394_RQPkt ? " AR_req" : "", - evt & OHCI1394_RSPkt ? " AR_resp" : "", - evt & OHCI1394_reqTxComplete ? " AT_req" : "", - evt & OHCI1394_respTxComplete ? " AT_resp" : "", - evt & OHCI1394_isochRx ? " IR" : "", - evt & OHCI1394_isochTx ? " IT" : "", - evt & OHCI1394_postedWriteErr ? " postedWriteErr" : "", - evt & OHCI1394_cycleTooLong ? " cycleTooLong" : "", - evt & OHCI1394_cycle64Seconds ? " cycle64Seconds" : "", - evt & OHCI1394_regAccessFail ? " regAccessFail" : "", - evt & OHCI1394_busReset ? " busReset" : "", - evt & ~(OHCI1394_selfIDComplete | OHCI1394_RQPkt | - OHCI1394_RSPkt | OHCI1394_reqTxComplete | - OHCI1394_respTxComplete | OHCI1394_isochRx | - OHCI1394_isochTx | OHCI1394_postedWriteErr | - OHCI1394_cycleTooLong | OHCI1394_cycle64Seconds | - OHCI1394_regAccessFail | OHCI1394_busReset) + fw_notify("IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt, + evt & OHCI1394_selfIDComplete ? " selfID" : "", + evt & OHCI1394_RQPkt ? " AR_req" : "", + evt & OHCI1394_RSPkt ? " AR_resp" : "", + evt & OHCI1394_reqTxComplete ? " AT_req" : "", + evt & OHCI1394_respTxComplete ? " AT_resp" : "", + evt & OHCI1394_isochRx ? " IR" : "", + evt & OHCI1394_isochTx ? " IT" : "", + evt & OHCI1394_postedWriteErr ? " postedWriteErr" : "", + evt & OHCI1394_cycleTooLong ? " cycleTooLong" : "", + evt & OHCI1394_cycle64Seconds ? " cycle64Seconds" : "", + evt & OHCI1394_regAccessFail ? " regAccessFail" : "", + evt & OHCI1394_busReset ? " busReset" : "", + evt & ~(OHCI1394_selfIDComplete | OHCI1394_RQPkt | + OHCI1394_RSPkt | OHCI1394_reqTxComplete | + OHCI1394_respTxComplete | OHCI1394_isochRx | + OHCI1394_isochTx | OHCI1394_postedWriteErr | + OHCI1394_cycleTooLong | OHCI1394_cycle64Seconds | + OHCI1394_regAccessFail | OHCI1394_busReset) ? " ?" : ""); } @@ -308,23 +306,22 @@ static void log_selfids(int node_id, int generation, int self_id_count, u32 *s) if (likely(!(param_debug & OHCI_PARAM_DEBUG_SELFIDS))) return; - printk(KERN_DEBUG KBUILD_MODNAME ": %d selfIDs, generation %d, " - "local node ID %04x\n", self_id_count, generation, node_id); + fw_notify("%d selfIDs, generation %d, local node ID %04x\n", + self_id_count, generation, node_id); for (; self_id_count--; ++s) if ((*s & 1 << 23) == 0) - printk(KERN_DEBUG "selfID 0: %08x, phy %d [%c%c%c] " - "%s gc=%d %s %s%s%s\n", - *s, *s >> 24 & 63, _p(s, 6), _p(s, 4), _p(s, 2), - speed[*s >> 14 & 3], *s >> 16 & 63, - power[*s >> 8 & 7], *s >> 22 & 1 ? "L" : "", - *s >> 11 & 1 ? "c" : "", *s & 2 ? "i" : ""); + fw_notify("selfID 0: %08x, phy %d [%c%c%c] " + "%s gc=%d %s %s%s%s\n", + *s, *s >> 24 & 63, _p(s, 6), _p(s, 4), _p(s, 2), + speed[*s >> 14 & 3], *s >> 16 & 63, + power[*s >> 8 & 7], *s >> 22 & 1 ? "L" : "", + *s >> 11 & 1 ? "c" : "", *s & 2 ? "i" : ""); else - printk(KERN_DEBUG "selfID n: %08x, phy %d " - "[%c%c%c%c%c%c%c%c]\n", - *s, *s >> 24 & 63, - _p(s, 16), _p(s, 14), _p(s, 12), _p(s, 10), - _p(s, 8), _p(s, 6), _p(s, 4), _p(s, 2)); + fw_notify("selfID n: %08x, phy %d [%c%c%c%c%c%c%c%c]\n", + *s, *s >> 24 & 63, + _p(s, 16), _p(s, 14), _p(s, 12), _p(s, 10), + _p(s, 8), _p(s, 6), _p(s, 4), _p(s, 2)); } static const char *evts[] = { @@ -373,15 +370,14 @@ static void log_ar_at_event(char dir, int speed, u32 *header, int evt) evt = 0x1f; if (evt == OHCI1394_evt_bus_reset) { - printk(KERN_DEBUG "A%c evt_bus_reset, generation %d\n", - dir, (header[2] >> 16) & 0xff); + fw_notify("A%c evt_bus_reset, generation %d\n", + dir, (header[2] >> 16) & 0xff); return; } if (header[0] == ~header[1]) { - printk(KERN_DEBUG "A%c %s, %s, %08x\n", - dir, evts[evt], phys[header[0] >> 30 & 0x3], - header[0]); + fw_notify("A%c %s, %s, %08x\n", + dir, evts[evt], phys[header[0] >> 30 & 0x3], header[0]); return; } @@ -400,24 +396,23 @@ static void log_ar_at_event(char dir, int speed, u32 *header, int evt) switch (tcode) { case 0xe: case 0xa: - printk(KERN_DEBUG "A%c %s, %s\n", - dir, evts[evt], tcodes[tcode]); + fw_notify("A%c %s, %s\n", dir, evts[evt], tcodes[tcode]); break; case 0x0: case 0x1: case 0x4: case 0x5: case 0x9: - printk(KERN_DEBUG "A%c spd %x tl %02x, " - "%04x -> %04x, %s, " - "%s, %04x%08x%s\n", - dir, speed, header[0] >> 10 & 0x3f, - header[1] >> 16, header[0] >> 16, evts[evt], - tcodes[tcode], header[1] & 0xffff, header[2], specific); + fw_notify("A%c spd %x tl %02x, " + "%04x -> %04x, %s, " + "%s, %04x%08x%s\n", + dir, speed, header[0] >> 10 & 0x3f, + header[1] >> 16, header[0] >> 16, evts[evt], + tcodes[tcode], header[1] & 0xffff, header[2], specific); break; default: - printk(KERN_DEBUG "A%c spd %x tl %02x, " - "%04x -> %04x, %s, " - "%s%s\n", - dir, speed, header[0] >> 10 & 0x3f, - header[1] >> 16, header[0] >> 16, evts[evt], - tcodes[tcode], specific); + fw_notify("A%c spd %x tl %02x, " + "%04x -> %04x, %s, " + "%s%s\n", + dir, speed, header[0] >> 10 & 0x3f, + header[1] >> 16, header[0] >> 16, evts[evt], + tcodes[tcode], specific); } } -- cgit v1.2.3 From ae1e53557911d7e60a637b2400173add958aae94 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Wed, 18 Jun 2008 18:20:45 +0200 Subject: firewire: deadline for PHY config transmission If the low-level driver failed to initialize a card properly without noticing it, fw-core was blocked indefinitely when trying to send a PHY config packet. This hung up the events kernel thread, e.g. locked up keyboard input. https://bugzilla.redhat.com/show_bug.cgi?id=444694 https://bugzilla.redhat.com/show_bug.cgi?id=446763 This problem was introduced between 2.6.25 and 2.6.26-rc1 by commit 2a0a2590498be7b92e3e76409c9b8ee722e23c8f "firewire: wait until PHY configuration packet was transmitted (fix bus reset loop)". The solution is to wait with timeout. I tested it with 7 different working controllers and 1 non-working controller. On the working ones, the packet callback complete()s usually --- but not always --- before a timeout of 10ms. Hence I chose a safer timeout of 100ms. On the few tests with the non-working controller ALi M5271, PHY config packet transmission always timed out so far. (Fw-ohci needs to be fixed for this controller independently of this deadline fix. Often the core doesn't even attempt to send a phy config because not even self ID reception works.) Signed-off-by: Stefan Richter --- drivers/firewire/fw-transaction.c | 49 +++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 15 deletions(-) (limited to 'drivers/firewire') diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c index 7f92c45349e..03ae8a77c47 100644 --- a/drivers/firewire/fw-transaction.c +++ b/drivers/firewire/fw-transaction.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -297,37 +298,55 @@ EXPORT_SYMBOL(fw_send_request); struct fw_phy_packet { struct fw_packet packet; struct completion done; + struct kref kref; }; -static void -transmit_phy_packet_callback(struct fw_packet *packet, - struct fw_card *card, int status) +static void phy_packet_release(struct kref *kref) +{ + struct fw_phy_packet *p = + container_of(kref, struct fw_phy_packet, kref); + kfree(p); +} + +static void transmit_phy_packet_callback(struct fw_packet *packet, + struct fw_card *card, int status) { struct fw_phy_packet *p = container_of(packet, struct fw_phy_packet, packet); complete(&p->done); + kref_put(&p->kref, phy_packet_release); } void fw_send_phy_config(struct fw_card *card, int node_id, int generation, int gap_count) { - struct fw_phy_packet p; + struct fw_phy_packet *p; + long timeout = DIV_ROUND_UP(HZ, 10); u32 data = PHY_IDENTIFIER(PHY_PACKET_CONFIG) | PHY_CONFIG_ROOT_ID(node_id) | PHY_CONFIG_GAP_COUNT(gap_count); - p.packet.header[0] = data; - p.packet.header[1] = ~data; - p.packet.header_length = 8; - p.packet.payload_length = 0; - p.packet.speed = SCODE_100; - p.packet.generation = generation; - p.packet.callback = transmit_phy_packet_callback; - init_completion(&p.done); - - card->driver->send_request(card, &p.packet); - wait_for_completion(&p.done); + p = kmalloc(sizeof(*p), GFP_KERNEL); + if (p == NULL) + return; + + p->packet.header[0] = data; + p->packet.header[1] = ~data; + p->packet.header_length = 8; + p->packet.payload_length = 0; + p->packet.speed = SCODE_100; + p->packet.generation = generation; + p->packet.callback = transmit_phy_packet_callback; + init_completion(&p->done); + kref_set(&p->kref, 2); + + card->driver->send_request(card, &p->packet); + timeout = wait_for_completion_timeout(&p->done, timeout); + kref_put(&p->kref, phy_packet_release); + + /* will leak p if the callback is never executed */ + WARN_ON(timeout == 0); } void fw_flush_transactions(struct fw_card *card) -- cgit v1.2.3 From a7b64b8704b03c9972b114932fdf517e06153f11 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 14 Jun 2008 14:24:53 +0200 Subject: firewire: Kconfig menu touch-up Emphasize the recommendation to build only one stack. Trim the prompts to better fit into short attention spans. Signed-off-by: Stefan Richter --- drivers/firewire/Kconfig | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) (limited to 'drivers/firewire') diff --git a/drivers/firewire/Kconfig b/drivers/firewire/Kconfig index fb4d391810b..76f26710fc1 100644 --- a/drivers/firewire/Kconfig +++ b/drivers/firewire/Kconfig @@ -1,28 +1,26 @@ -comment "An alternative FireWire stack is available with EXPERIMENTAL=y" +comment "A new alternative FireWire stack is available with EXPERIMENTAL=y" depends on EXPERIMENTAL=n +comment "Enable only one of the two stacks, unless you know what you are doing" + depends on EXPERIMENTAL + config FIREWIRE - tristate "IEEE 1394 (FireWire) support - alternative stack, EXPERIMENTAL" + tristate "New FireWire stack, EXPERIMENTAL" depends on EXPERIMENTAL select CRC_ITU_T help This is the "Juju" FireWire stack, a new alternative implementation designed for robustness and simplicity. You can build either this - stack, or the classic stack (the ieee1394 driver, ohci1394 etc.) - or both. Please read http://wiki.linux1394.org/JujuMigration before - you enable the new stack. + stack, or the old stack (the ieee1394 driver, ohci1394 etc.) or both. + Please read http://wiki.linux1394.org/JujuMigration before you + enable the new stack. To compile this driver as a module, say M here: the module will be called firewire-core. It functionally replaces ieee1394, raw1394, and video1394. - NOTE: - - You should only build ONE of the stacks, unless you REALLY know what - you are doing. - config FIREWIRE_OHCI - tristate "Support for OHCI FireWire host controllers" + tristate "OHCI-1394 controllers" depends on PCI && FIREWIRE help Enable this driver if you have a FireWire controller based @@ -33,12 +31,12 @@ config FIREWIRE_OHCI called firewire-ohci. It replaces ohci1394 of the classic IEEE 1394 stack. - NOTE: + NOTE: - You should only build ohci1394 or firewire-ohci, but not both. - If you nevertheless want to install both, you should configure them - only as modules and blacklist the driver(s) which you don't want to - have auto-loaded. Add either + You should only build either firewire-ohci or the old ohci1394 driver, + but not both. If you nevertheless want to install both, you should + configure them only as modules and blacklist the driver(s) which you + don't want to have auto-loaded. Add either blacklist firewire-ohci or @@ -60,7 +58,7 @@ config FIREWIRE_OHCI_DEBUG default y config FIREWIRE_SBP2 - tristate "Support for storage devices (SBP-2 protocol driver)" + tristate "Storage devices (SBP-2 protocol)" depends on FIREWIRE && SCSI help This option enables you to use SBP-2 devices connected to a -- cgit v1.2.3 From 0e3e2eabf4fbc0162e1f1eb4fd90cb3e9513a554 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Tue, 24 Jun 2008 19:11:13 -0700 Subject: firewire: fw-sbp2: fix parsing of logical unit directories MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is a small off-by-one bug in firewire-sbp2. This causes problems when a device exports multiple LUN Directories. I found it when trying to talk to a SONY DVD Jukebox. Signed-off-by: Richard Sharpe Acked-by: Kristian Høgsberg Signed-off-by: Stefan Richter (op. order, changelog) --- drivers/firewire/fw-sbp2.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/firewire') diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index b2458bb8e9c..227d2e036cd 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -1051,7 +1051,8 @@ static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 *directory, break; case SBP2_CSR_LOGICAL_UNIT_DIRECTORY: - if (sbp2_scan_logical_unit_dir(tgt, ci.p + value) < 0) + /* Adjust for the increment in the iterator */ + if (sbp2_scan_logical_unit_dir(tgt, ci.p - 1 + value) < 0) return -ENOMEM; break; } -- cgit v1.2.3