From b0ea5f19d3d848008d87e455c8d9b6d9cae7101a Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 25 Nov 2012 18:45:25 +0100 Subject: firewire: sbp2: allow WRITE SAME and REPORT SUPPORTED OPERATION CODES The commits 3c6bdaeab4fd "[SCSI] Add a report opcode helper" 5db44863b6eb "[SCSI] sd: Implement support for WRITE SAME" introduced in-kernel uses of the mentioned commands but cautiously blacklisted them for any IEEE 1394 (SBP-2/3) targets and some other transports. I looked through a range of SBP devices and found that the blacklist flags can be removed: The kernel never attempts these commands if the device's INQUIRY data claim a SCSI revision of less than 0x05. This is the case with all SBP devices that I checked, except for three more recent devices which claimed a revision of 0x05 i.e. conformance with SPC-3 (two devices based on the OXUF936QSE chip but having different firmwares, one based on OXUF934DSB.) I tried "sg_opcodes" from sg3_utils on several older and newer devices and did not encounter any apparent firmware bugs with it. All devices returned Illegal Request/ Invalid command operation code and carried on. I furthermore tried "sg_write_same -U" on the OXUF934DSB device with the same result. Alas I did not have a TRIM enabled SSD available for these tests. All of the bridges were correctly identified by the kernel as "fully provisioned", CD-ROM devices aside. The kernel won't issue WRITE SAME to fully provisioned devices, nor would it attempt REPORT SUPPORTED OPERATION CODES or WRITE SAME with UNMAP bit on devices which do not claim conformance to SPC-3 or later. Hence let's remove the no_report_opcodes and no_write_same blacklist flags so that these commands can be used on newer targets with respective capabilities. I guess the Linux sbp-target could be such a target. Signed-off-by: Stefan Richter --- drivers/firewire/sbp2.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/firewire') diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index bb1b392f5cd..1162d6b3bf8 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c @@ -1546,8 +1546,6 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev) struct sbp2_logical_unit *lu = sdev->hostdata; sdev->use_10_for_rw = 1; - sdev->no_report_opcodes = 1; - sdev->no_write_same = 1; if (sbp2_param_exclusive_login) sdev->manage_start_stop = 1; -- cgit v1.2.3-70-g09d2 From 9d2373420900a39f5212a3b289331aa3535b1000 Mon Sep 17 00:00:00 2001 From: Stephan Gatzka Date: Wed, 28 Nov 2012 20:04:32 +0100 Subject: firewire: net: Fix handling of fragmented multicast/broadcast packets. This patch fixes both the transmit and receive portion of sending fragmented mutlicast and broadcast packets. The transmit section was broken because the offset for INTFRAG and LASTFRAG packets were just miscalculated by IEEE1394_GASP_HDR_SIZE (which was reserved with skb_push() in fwnet_send_packet). The receive section was broken because in fwnet_incoming_packet is a call to fwnet_peer_find_by_node_id(). Called with generation == -1 it will not find a peer and the partial datagrams are associated to a peer. [Stefan R: The fix to use context->card->generation is not perfect. It relies on the IR tasklet which processes packets from the prior bus generation to run before the self-ID-complete worklet which sets the current card generation. Alas, there is no simple way of a race-free implementation. Let's do it this way for now.] Signed-off-by: Stephan Gatzka Cc: stable Signed-off-by: Stefan Richter --- drivers/firewire/net.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers/firewire') diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 08c674957af..638e1f71284 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -861,8 +861,8 @@ static void fwnet_receive_broadcast(struct fw_iso_context *context, if (specifier_id == IANA_SPECIFIER_ID && ver == RFC2734_SW_VERSION) { buf_ptr += 2; length -= IEEE1394_GASP_HDR_SIZE; - fwnet_incoming_packet(dev, buf_ptr, length, - source_node_id, -1, true); + fwnet_incoming_packet(dev, buf_ptr, length, source_node_id, + context->card->generation, true); } packet.payload_length = dev->rcv_buffer_size; @@ -958,7 +958,12 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) break; } - skb_pull(skb, ptask->max_payload); + if (ptask->dest_node == IEEE1394_ALL_NODES) { + skb_pull(skb, + ptask->max_payload + IEEE1394_GASP_HDR_SIZE); + } else { + skb_pull(skb, ptask->max_payload); + } if (ptask->outstanding_pkts > 1) { fwnet_make_sf_hdr(&ptask->hdr, RFC2374_HDR_INTFRAG, dg_size, fg_off, datagram_label); @@ -1062,7 +1067,7 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask) smp_rmb(); node_id = dev->card->node_id; - p = skb_push(ptask->skb, 8); + p = skb_push(ptask->skb, IEEE1394_GASP_HDR_SIZE); put_unaligned_be32(node_id << 16 | IANA_SPECIFIER_ID >> 8, p); put_unaligned_be32((IANA_SPECIFIER_ID & 0xff) << 24 | RFC2734_SW_VERSION, &p[4]); -- cgit v1.2.3-70-g09d2 From db2cad2f55078e90f84960b84b721291efa83d36 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 3 Dec 2012 08:11:17 -0500 Subject: firewire: net: remove unused variable in fwnet_receive_broadcast() The variable card is initialized but never used otherwise, so remove the unused variable. Signed-off-by: Wei Yongjun Signed-off-by: Stefan Richter --- drivers/firewire/net.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/firewire') diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 638e1f71284..e7a711f53a6 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -828,7 +828,6 @@ static void fwnet_receive_broadcast(struct fw_iso_context *context, { struct fwnet_device *dev; struct fw_iso_packet packet; - struct fw_card *card; __be16 *hdr_ptr; __be32 *buf_ptr; int retval; @@ -840,7 +839,6 @@ static void fwnet_receive_broadcast(struct fw_iso_context *context, unsigned long flags; dev = data; - card = dev->card; hdr_ptr = header; length = be16_to_cpup(hdr_ptr); -- cgit v1.2.3-70-g09d2