* Re: [linux-usb-devel] 2.6.24: NULL scatter-gather pointer in usb_storage:usb_stor_access_xfer_buf?
[not found] ` <20080131070846.4464eb3c-uevSgErl2ChVvDCLMmKh5Q@public.gmane.org>
@ 2008-01-31 15:17 ` Boaz Harrosh
2008-01-31 16:45 ` Alan Stern
[not found] ` <47A1E6A0.8050500-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org>
0 siblings, 2 replies; 36+ messages in thread
From: Boaz Harrosh @ 2008-01-31 15:17 UTC (permalink / raw)
To: Mark Glines; +Cc: Alan Stern, USB list, linux-scsi
On Thu, Jan 31 2008 at 17:08 +0200, Mark Glines <mark-6pk7R1svBr8dnm+yROfE0A@public.gmane.org> wrote:
> On Thu, 31 Jan 2008 11:27:39 +0200
> Boaz Harrosh <bharrosh-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org> wrote:
>
>> Please check the below patch.
>>
>> one thing that I can see is that the isd200 does an INQUARY transfer
>> of sizeof(struct inquiry_data) which is 96 bytes, when scsi_scan.c
>> sends an INQUARY with 36 bytes buffer. So we have an underflow in
>> usb_stor_access_xfer_buf().
>>
>> The below patch will only check my theory. I will send a proper fix
>> later, please confirm that this fixes it.
>>
>> What kills me is that this condition has existed before my patch, I'll
>> try to see why it is triggered now
>
> I applied this patch to 2.6.24, and it now works for me. It was
> crashing consistently whenever I'd plug this device in, now it goes
> through successfully:
>
Yes Thanks this is grate :)
I will send a proper patch to scsi maintainer. Alan is it OK to send this
patch threw James's scsi-misc?
>
> [24775.788039] usb 3-2: new full speed USB device using uhci_hcd and address 3
> [24775.939275] usb 3-2: configuration #1 chosen from 1 choice
> [24776.084409] usbcore: registered new interface driver libusual
> [24776.103604] Initializing USB Mass Storage driver...
> [24776.213916] scsi3 : SCSI emulation for USB Mass Storage devices
> [24776.214366] usbcore: registered new interface driver usb-storage
> [24776.214377] USB Mass Storage support registered.
> [24776.215604] usb-storage: device found at 3
> [24776.215724] usb-storage: waiting for device to settle before scanning
> [24778.333378] scsi 3:0:0:0: Direct-Access SAMSUNG HM120JC YL10 PQ: 0 ANSI: 0
> [24778.333715] sd 3:0:0:0: [sdb] 234441648 512-byte hardware sectors (120034 MB)
> [24778.333841] sd 3:0:0:0: [sdb] Write Protect is off
> [24778.333848] sd 3:0:0:0: [sdb] Mode Sense: 00 00 00 00
> [24778.333853] sd 3:0:0:0: [sdb] Assuming drive cache: write through
> [24778.334196] sd 3:0:0:0: [sdb] 234441648 512-byte hardware sectors (120034 MB)
> [24778.334396] sd 3:0:0:0: [sdb] Write Protect is off
> [24778.334403] sd 3:0:0:0: [sdb] Mode Sense: 00 00 00 00
> [24778.334408] sd 3:0:0:0: [sdb] Assuming drive cache: write through
> [24778.334414] sdb: sdb1
> [24778.824103] sd 3:0:0:0: [sdb] Attached SCSI disk
> [24778.824210] sd 3:0:0:0: Attached scsi generic sg1 type 0
> [24778.825119] usb-storage: device scan complete
>
>
> I'm happy to test further patches. Let me know if you need more
> testing.
>
> Do you still want me to try out the scsi-misc branch?
>
No, That was my mistake, scsi-misc is now identical to mainline.
This here is a new fix that will need to go in. I will send a patch
soonish. If you can test it and send a Tested-by: it could be grate
> Mark
>
>
>> ---
>> drivers/usb/storage/protocol.c | 6 ++++++
>> 1 files changed, 6 insertions(+), 0 deletions(-)
>>
>> diff --git a/drivers/usb/storage/protocol.c
>> b/drivers/usb/storage/protocol.c index a41ce21..d0ff1f6 100644
>> --- a/drivers/usb/storage/protocol.c
>> +++ b/drivers/usb/storage/protocol.c
>> @@ -229,6 +229,12 @@ void usb_stor_set_xfer_buf(unsigned char *buffer,
>> unsigned int offset = 0;
>> struct scatterlist *sg = NULL;
>>
>> + BUG_ON(!scsi_sglist(srb));
>> +
>> + if(buflen > scsi_bufflen(srb))
>> + buflen = scsi_bufflen(srb);
>> + /*FIXME: should we set an underflow condition here*/
>> +
>> usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
>> TO_XFER_BUF);
>> if (buflen < scsi_bufflen(srb))
>>
Thanks Mark
(CCing linux-scsi ml)
Boaz
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [linux-usb-devel] 2.6.24: NULL scatter-gather pointer in usb_storage:usb_stor_access_xfer_buf?
2008-01-31 15:17 ` [linux-usb-devel] 2.6.24: NULL scatter-gather pointer in usb_storage:usb_stor_access_xfer_buf? Boaz Harrosh
@ 2008-01-31 16:45 ` Alan Stern
[not found] ` <Pine.LNX.4.44L0.0801311143180.3970-100000-IYeN2dnnYyZXsRXLowluHWD2FQJk+8+b@public.gmane.org>
[not found] ` <47A1E6A0.8050500-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org>
1 sibling, 1 reply; 36+ messages in thread
From: Alan Stern @ 2008-01-31 16:45 UTC (permalink / raw)
To: Boaz Harrosh; +Cc: Mark Glines, USB list, linux-scsi
On Thu, 31 Jan 2008, Boaz Harrosh wrote:
> >> Please check the below patch.
> >>
> >> one thing that I can see is that the isd200 does an INQUARY transfer
> >> of sizeof(struct inquiry_data) which is 96 bytes, when scsi_scan.c
> >> sends an INQUARY with 36 bytes buffer. So we have an underflow in
> >> usb_stor_access_xfer_buf().
Maybe the isd200 routine should be changed also, so that it doesn't try
to store too much data in the buffer.
> I will send a proper patch to scsi maintainer. Alan is it OK to send this
> patch threw James's scsi-misc?
You should send patches to Matt Dharm, since he is the usb-storage
maintainer.
Alan Stern
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH] bugfix for an underflow condition in usb storage & isd200.c
[not found] ` <47A1E6A0.8050500-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org>
@ 2008-01-31 17:19 ` Boaz Harrosh
[not found] ` <47A2033D.2050502-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org>
0 siblings, 1 reply; 36+ messages in thread
From: Boaz Harrosh @ 2008-01-31 17:19 UTC (permalink / raw)
To: Mark Glines, Matthew Dharm, James Bottomley
Cc: Alan Stern, USB list, linux-scsi
scsi_scan is issuing a 36-byte INQUIRY request to llds. isd200 would
volunteer 96 bytes of INQUIRY. This caused an underflow condition in
protocol.c usb_stor_access_xfer_buf(). So first fix is to
usb_stor_access_xfer_buf() to properly handle underflow conditions.
Then usb_stor_set_xfer_buf() should report this condition as a negative
resid. Should we also set cmnd->status in the underflow condition?
Then also isd200.c is fixed to only return the type of INQUIRY && SENSE
the upper layer asked for.
Signed-off-by: Boaz Harrosh <bharrosh-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org>
---
drivers/usb/storage/isd200.c | 7 +++++--
drivers/usb/storage/protocol.c | 13 +++++++++----
2 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c
index 0db4886..4394930 100644
--- a/drivers/usb/storage/isd200.c
+++ b/drivers/usb/storage/isd200.c
@@ -1261,6 +1261,7 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
unsigned long lba;
unsigned long blockCount;
unsigned char senseData[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+ unsigned xfer_len;
memset(ataCdb, 0, sizeof(union ata_cdb));
@@ -1270,8 +1271,9 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
US_DEBUGP(" ATA OUT - INQUIRY\n");
/* copy InquiryData */
+ xfer_len = min(sizeof(info->InquiryData), scsi_bufflen(srb));
usb_stor_set_xfer_buf((unsigned char *) &info->InquiryData,
- sizeof(info->InquiryData), srb);
+ xfer_len, srb);
srb->result = SAM_STAT_GOOD;
sendToTransport = 0;
break;
@@ -1280,7 +1282,8 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
US_DEBUGP(" ATA OUT - SCSIOP_MODE_SENSE\n");
/* Initialize the return buffer */
- usb_stor_set_xfer_buf(senseData, sizeof(senseData), srb);
+ xfer_len = min(sizeof(senseData), scsi_bufflen(srb));
+ usb_stor_set_xfer_buf(senseData, xfer_len, srb);
if (info->DeviceFlags & DF_MEDIA_STATUS_ENABLED)
{
diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c
index a41ce21..6200f62 100644
--- a/drivers/usb/storage/protocol.c
+++ b/drivers/usb/storage/protocol.c
@@ -175,7 +175,7 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
* and the starting offset within the page, and update
* the *offset and **sgptr values for the next loop. */
cnt = 0;
- while (cnt < buflen) {
+ while (cnt < buflen && sg) {
struct page *page = sg_page(sg) +
((sg->offset + *offset) >> PAGE_SHIFT);
unsigned int poff =
@@ -228,9 +228,14 @@ void usb_stor_set_xfer_buf(unsigned char *buffer,
{
unsigned int offset = 0;
struct scatterlist *sg = NULL;
+ unsigned int count;
- usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
+ count = usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
TO_XFER_BUF);
- if (buflen < scsi_bufflen(srb))
- scsi_set_resid(srb, scsi_bufflen(srb) - buflen);
+
+ /* Check for underflow */
+ if (buflen > scsi_bufflen(srb))
+ count = buflen;
+
+ scsi_set_resid(srb, scsi_bufflen(srb) - count);
}
--
1.5.3.3
^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [linux-usb-devel] 2.6.24: NULL scatter-gather pointer in usb_storage:usb_stor_access_xfer_buf?
[not found] ` <Pine.LNX.4.44L0.0801311143180.3970-100000-IYeN2dnnYyZXsRXLowluHWD2FQJk+8+b@public.gmane.org>
@ 2008-01-31 17:20 ` Boaz Harrosh
0 siblings, 0 replies; 36+ messages in thread
From: Boaz Harrosh @ 2008-01-31 17:20 UTC (permalink / raw)
To: Alan Stern; +Cc: Mark Glines, USB list, linux-scsi, Matthew Dharm
On Thu, Jan 31 2008 at 18:45 +0200, Alan Stern <stern-nwvwT67g6+6dFdvTe/nMLpVzexx5G7lz@public.gmane.org> wrote:
> On Thu, 31 Jan 2008, Boaz Harrosh wrote:
>
>>>> Please check the below patch.
>>>>
>>>> one thing that I can see is that the isd200 does an INQUARY transfer
>>>> of sizeof(struct inquiry_data) which is 96 bytes, when scsi_scan.c
>>>> sends an INQUARY with 36 bytes buffer. So we have an underflow in
>>>> usb_stor_access_xfer_buf().
>
> Maybe the isd200 routine should be changed also, so that it doesn't try
> to store too much data in the buffer.
>
>> I will send a proper patch to scsi maintainer. Alan is it OK to send this
>> patch threw James's scsi-misc?
>
> You should send patches to Matt Dharm, since he is the usb-storage
> maintainer.
>
> Alan Stern
>
> -
Right, Please see patch posted as reply to the original email.
I have also fixed isd200 to return what was asked. The fix
to protocol.c is also different and more general now.
Will send to Matthew Dharm.
Matthew - is it OK to send this threw James, please ACK.
Mark - this fix is different we do need testing.
Thanks to all
Boaz
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] bugfix for an underflow condition in usb storage & isd200.c
[not found] ` <47A2033D.2050502-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org>
@ 2008-01-31 17:49 ` Alan Stern
[not found] ` <Pine.LNX.4.44L0.0801311244430.4373-100000-IYeN2dnnYyZXsRXLowluHWD2FQJk+8+b@public.gmane.org>
2008-01-31 18:00 ` Greg KH
1 sibling, 1 reply; 36+ messages in thread
From: Alan Stern @ 2008-01-31 17:49 UTC (permalink / raw)
To: Boaz Harrosh
Cc: Mark Glines, Matthew Dharm, James Bottomley, USB list, linux-scsi
On Thu, 31 Jan 2008, Boaz Harrosh wrote:
> @@ -228,9 +228,14 @@ void usb_stor_set_xfer_buf(unsigned char *buffer,
> {
> unsigned int offset = 0;
> struct scatterlist *sg = NULL;
> + unsigned int count;
>
> - usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
> + count = usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
> TO_XFER_BUF);
> - if (buflen < scsi_bufflen(srb))
> - scsi_set_resid(srb, scsi_bufflen(srb) - buflen);
> +
> + /* Check for underflow */
> + if (buflen > scsi_bufflen(srb))
> + count = buflen;
> +
> + scsi_set_resid(srb, scsi_bufflen(srb) - count);
> }
This last "if" statement doesn't look right. And since you know that
count will never be larger than scsi_bufflen(srb), you don't have to
check for underflow at all. Just leave out the "if" and call
scsi_set_resid() directly.
Alan Stern
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] bugfix for an underflow condition in usb storage & isd200.c
[not found] ` <47A2033D.2050502-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org>
2008-01-31 17:49 ` Alan Stern
@ 2008-01-31 18:00 ` Greg KH
2008-01-31 18:32 ` Boaz Harrosh
2008-01-31 19:37 ` [PATCH 2.6.24] bugfix for an overflow " Boaz Harrosh
1 sibling, 2 replies; 36+ messages in thread
From: Greg KH @ 2008-01-31 18:00 UTC (permalink / raw)
To: Boaz Harrosh
Cc: Mark Glines, Matthew Dharm, James Bottomley, Alan Stern, USB list,
linux-scsi
On Thu, Jan 31, 2008 at 07:19:57PM +0200, Boaz Harrosh wrote:
>
> scsi_scan is issuing a 36-byte INQUIRY request to llds. isd200 would
> volunteer 96 bytes of INQUIRY. This caused an underflow condition in
> protocol.c usb_stor_access_xfer_buf(). So first fix is to
> usb_stor_access_xfer_buf() to properly handle underflow conditions.
> Then usb_stor_set_xfer_buf() should report this condition as a negative
> resid. Should we also set cmnd->status in the underflow condition?
>
> Then also isd200.c is fixed to only return the type of INQUIRY && SENSE
> the upper layer asked for.
>
> Signed-off-by: Boaz Harrosh <bharrosh-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org>
As this is a regression and hits 2.6.24, can you send the final version
of this patch to the stable-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org address so we can get it into the
2.6.24.y tree?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] bugfix for an underflow condition in usb storage & isd200.c
2008-01-31 18:00 ` Greg KH
@ 2008-01-31 18:32 ` Boaz Harrosh
2008-01-31 19:37 ` [PATCH 2.6.24] bugfix for an overflow " Boaz Harrosh
1 sibling, 0 replies; 36+ messages in thread
From: Boaz Harrosh @ 2008-01-31 18:32 UTC (permalink / raw)
To: Greg KH, Mark Glines
Cc: Matthew Dharm, James Bottomley, Alan Stern, USB list, linux-scsi
On Thu, Jan 31 2008 at 20:00 +0200, Greg KH <greg@kroah.com> wrote:
> On Thu, Jan 31, 2008 at 07:19:57PM +0200, Boaz Harrosh wrote:
>> scsi_scan is issuing a 36-byte INQUIRY request to llds. isd200 would
>> volunteer 96 bytes of INQUIRY. This caused an underflow condition in
>> protocol.c usb_stor_access_xfer_buf(). So first fix is to
>> usb_stor_access_xfer_buf() to properly handle underflow conditions.
>> Then usb_stor_set_xfer_buf() should report this condition as a negative
>> resid. Should we also set cmnd->status in the underflow condition?
>>
>> Then also isd200.c is fixed to only return the type of INQUIRY && SENSE
>> the upper layer asked for.
>>
>> Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
>
> As this is a regression and hits 2.6.24, can you send the final version
> of this patch to the stable@kernel.org address so we can get it into the
> 2.6.24.y tree?
>
> thanks,
>
> greg k-h
> -
On Thu, Jan 31 2008 at 20:00 +0200, Mark Glines <mark@glines.org> wrote:
>> On Thu, 31 Jan 2008 19:20:26 +0200
>> Hi,
>>
>> This patch fails to apply to 2.6.24. What should I apply it to, for
>> testing? USB Git, or SCSI git or something?
>>
>> patching file drivers/usb/storage/isd200.c
>> Hunk #1 succeeded at 1238 (offset -23 lines).
>> Hunk #2 succeeded at 1248 (offset -23 lines).
>> Hunk #3 succeeded at 1259 (offset -23 lines).
>> patching file drivers/usb/storage/protocol.c
>> Hunk #1 FAILED at 175.
>> Hunk #2 FAILED at 228.
>> 2 out of 2 hunks FAILED -- saving rejects to file drivers/usb/storage/protocol.c.rej
>>
>> Thanks,
>>
>> Mark
>
OK, I was confused with what versions this belongs to. This also answers
my original question of why it happens with my patch, as it did not
it happened before my patch. My patches only went into the 2.6.25 merge window.
So I will need to send 2 Patches. One for stable@kernel.org on top of 2.6.24.
The second is for mainline, which is the one I sent. Should go threw scsi-misc
which it is based on.
patch for 2.6.24 stable@kernel.org on the way
Boaz
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] bugfix for an underflow condition in usb storage & isd200.c
[not found] ` <Pine.LNX.4.44L0.0801311244430.4373-100000-IYeN2dnnYyZXsRXLowluHWD2FQJk+8+b@public.gmane.org>
@ 2008-01-31 19:00 ` Boaz Harrosh
2008-01-31 19:34 ` Alan Stern
0 siblings, 1 reply; 36+ messages in thread
From: Boaz Harrosh @ 2008-01-31 19:00 UTC (permalink / raw)
To: Alan Stern
Cc: Mark Glines, Matthew Dharm, James Bottomley, USB list, linux-scsi
On Thu, Jan 31 2008 at 19:49 +0200, Alan Stern <stern-nwvwT67g6+6dFdvTe/nMLpVzexx5G7lz@public.gmane.org> wrote:
> On Thu, 31 Jan 2008, Boaz Harrosh wrote:
>
>> @@ -228,9 +228,14 @@ void usb_stor_set_xfer_buf(unsigned char *buffer,
>> {
>> unsigned int offset = 0;
>> struct scatterlist *sg = NULL;
>> + unsigned int count;
>>
>> - usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
>> + count = usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
>> TO_XFER_BUF);
>> - if (buflen < scsi_bufflen(srb))
>> - scsi_set_resid(srb, scsi_bufflen(srb) - buflen);
>> +
>> + /* Check for underflow */
>> + if (buflen > scsi_bufflen(srb))
>> + count = buflen;
>> +
>> + scsi_set_resid(srb, scsi_bufflen(srb) - count);
>> }
>
> This last "if" statement doesn't look right. And since you know that
> count will never be larger than scsi_bufflen(srb), you don't have to
> check for underflow at all. Just leave out the "if" and call
> scsi_set_resid() directly.
>
> Alan Stern
>
I was thinking about that hard. And I disagree. It could be that we have
sg-list length (The total of all sg->length) that does not match
scsi_bufflen() - More or less. The code in usb_stor_access_xfer_buf() will
now correctly attempt to transfer according to buflen and what ever is available
at the passed sg's. Now this can be less or it can be more. SCSI standard defines
this as underflow/overflow. When overflow should be reported as negative values.
and an error status. (BUT not CHECK_CONDITION)
so the code is actualy
if (buflen > scsi_bufflen(srb))
scsi_set_resid(srb, scsi_bufflen(srb) - buflen); /* Negative overflow */
else
scsi_set_resid(srb, scsi_bufflen(srb) - count);
So this is actually code equivalent to above. Minus the extra call site.
The SCSI standard does allow these conditions and the system should cope
and go on. So a BUG_ON() is not accepted, I think.
But, ok, I mixed up with the comment I'll resend. underflow => overflow.
Boaz
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] bugfix for an underflow condition in usb storage & isd200.c
2008-01-31 19:00 ` Boaz Harrosh
@ 2008-01-31 19:34 ` Alan Stern
2008-01-31 19:53 ` Boaz Harrosh
0 siblings, 1 reply; 36+ messages in thread
From: Alan Stern @ 2008-01-31 19:34 UTC (permalink / raw)
To: Boaz Harrosh
Cc: Mark Glines, Matthew Dharm, James Bottomley, USB list, linux-scsi
On Thu, 31 Jan 2008, Boaz Harrosh wrote:
> On Thu, Jan 31 2008 at 19:49 +0200, Alan Stern <stern@rowland.harvard.edu> wrote:
> > On Thu, 31 Jan 2008, Boaz Harrosh wrote:
> >
> >> @@ -228,9 +228,14 @@ void usb_stor_set_xfer_buf(unsigned char *buffer,
> >> {
> >> unsigned int offset = 0;
> >> struct scatterlist *sg = NULL;
> >> + unsigned int count;
> >>
> >> - usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
> >> + count = usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
> >> TO_XFER_BUF);
> >> - if (buflen < scsi_bufflen(srb))
> >> - scsi_set_resid(srb, scsi_bufflen(srb) - buflen);
> >> +
> >> + /* Check for underflow */
> >> + if (buflen > scsi_bufflen(srb))
> >> + count = buflen;
> >> +
> >> + scsi_set_resid(srb, scsi_bufflen(srb) - count);
> >> }
> >
> > This last "if" statement doesn't look right. And since you know that
> > count will never be larger than scsi_bufflen(srb), you don't have to
> > check for underflow at all. Just leave out the "if" and call
> > scsi_set_resid() directly.
> >
> > Alan Stern
> >
> I was thinking about that hard. And I disagree. It could be that we have
> sg-list length (The total of all sg->length) that does not match
> scsi_bufflen() - More or less.
If that ever happens we'll be in big trouble. Not just here but in
other places as well.
> The code in usb_stor_access_xfer_buf() will
> now correctly attempt to transfer according to buflen and what ever is available
> at the passed sg's. Now this can be less or it can be more. SCSI standard defines
> this as underflow/overflow. When overflow should be reported as negative values.
> and an error status. (BUT not CHECK_CONDITION)
I don't understand. How could you ever transfer more data than the
requested amount? The host won't expect to receive it and won't be
able to handle it when it arrives.
(Furthmore, the USB mass-storage specification does not permit more
data to be transferred than requested. This fact isn't relevant to our
discussion because we're talking about situations where the data was
transferred via a non-standard protocol. But even so...)
> so the code is actualy
> if (buflen > scsi_bufflen(srb))
> scsi_set_resid(srb, scsi_bufflen(srb) - buflen); /* Negative overflow */
Okay, let's assume that both buflen and the sum of the sg-list lengths
are somehow greater than scsi_bufflen(srb). You still don't know that
they are equal to each other. All you know is that the amount actually
transferred is stored in count. Hence the negative overflow value
should be
scsi_bufflen(srb) - count
and not
scsi_bufflen(srb) - bufflen.
Alan Stern
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 2.6.24] bugfix for an overflow condition in usb storage & isd200.c
2008-01-31 18:00 ` Greg KH
2008-01-31 18:32 ` Boaz Harrosh
@ 2008-01-31 19:37 ` Boaz Harrosh
[not found] ` <47A22369.80906-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org>
1 sibling, 1 reply; 36+ messages in thread
From: Boaz Harrosh @ 2008-01-31 19:37 UTC (permalink / raw)
To: Greg KH, Mark Glines
Cc: Matthew Dharm, James Bottomley, Alan Stern, USB list, linux-scsi
Greg KH <greg@kroah.com> rote:
> As this is a regression and hits 2.6.24, can you send the final version
> of this patch to the stable@kernel.org address so we can get it into the
> 2.6.24.y tree?
>
> thanks,
>
> greg k-h
Mark - This is for you on top of vanila v2.6.24 kernel from Linus.
---
scsi_scan is issuing a 36-byte INQUIRY request to llds. isd200 would
volunteer 96 bytes of INQUIRY. This caused an overflow condition in
protocol.c usb_stor_access_xfer_buf(). So first fix is to
usb_stor_access_xfer_buf() to properly handle overflow/underflow conditions.
Then usb_stor_set_xfer_buf() should report this condition as a negative
resid. Should we also set cmnd->status in the overflow condition?
Then also isd200.c is fixed to only return the type of INQUIRY && SENSE
the upper layer asked for.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
---
drivers/usb/storage/isd200.c | 7 +++++--
drivers/usb/storage/protocol.c | 13 +++++++++----
2 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c
index 49ba6c0..8186e93 100644
--- a/drivers/usb/storage/isd200.c
+++ b/drivers/usb/storage/isd200.c
@@ -1238,6 +1238,7 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
unsigned long lba;
unsigned long blockCount;
unsigned char senseData[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+ unsigned xfer_len;
memset(ataCdb, 0, sizeof(union ata_cdb));
@@ -1247,8 +1248,9 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
US_DEBUGP(" ATA OUT - INQUIRY\n");
/* copy InquiryData */
+ xfer_len = min(sizeof(info->InquiryData), scsi_bufflen(srb));
usb_stor_set_xfer_buf((unsigned char *) &info->InquiryData,
- sizeof(info->InquiryData), srb);
+ xfer_len, srb);
srb->result = SAM_STAT_GOOD;
sendToTransport = 0;
break;
@@ -1257,7 +1259,8 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
US_DEBUGP(" ATA OUT - SCSIOP_MODE_SENSE\n");
/* Initialize the return buffer */
- usb_stor_set_xfer_buf(senseData, sizeof(senseData), srb);
+ xfer_len = min(sizeof(senseData), scsi_bufflen(srb));
+ usb_stor_set_xfer_buf(senseData, xfer_len, srb);
if (info->DeviceFlags & DF_MEDIA_STATUS_ENABLED)
{
diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c
index 889622b..038a284 100644
--- a/drivers/usb/storage/protocol.c
+++ b/drivers/usb/storage/protocol.c
@@ -194,7 +194,7 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
* and the starting offset within the page, and update
* the *offset and *index values for the next loop. */
cnt = 0;
- while (cnt < buflen) {
+ while (cnt < buflen && sg) {
struct page *page = sg_page(sg) +
((sg->offset + *offset) >> PAGE_SHIFT);
unsigned int poff =
@@ -248,9 +248,14 @@ void usb_stor_set_xfer_buf(unsigned char *buffer,
{
unsigned int offset = 0;
struct scatterlist *sg = NULL;
+ unsigned count;
- usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
+ count = usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
TO_XFER_BUF);
- if (buflen < srb->request_bufflen)
- srb->resid = srb->request_bufflen - buflen;
+
+ /* Check for overflow */
+ if (buflen > scsi_bufflen(srb))
+ count = buflen;
+
+ scsi_set_resid(srb, scsi_bufflen(srb) - count);
}
--
1.5.3.3
^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [PATCH 2.6.24] bugfix for an overflow condition in usb storage & isd200.c
[not found] ` <47A22369.80906-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org>
@ 2008-01-31 19:49 ` Matthew Dharm
2008-01-31 20:05 ` Boaz Harrosh
[not found] ` <47A229FF.4040404@panasas.com>
2008-02-02 0:55 ` Mark Glines
1 sibling, 2 replies; 36+ messages in thread
From: Matthew Dharm @ 2008-01-31 19:49 UTC (permalink / raw)
To: Boaz Harrosh
Cc: Greg KH, Mark Glines, James Bottomley, Alan Stern, USB list,
linux-scsi
[-- Attachment #1: Type: text/plain, Size: 4944 bytes --]
No. No no no.
The ISD200 code was written by the ISD200 developers. I really don't want
to go mucking about changing what commands actually get send to the ISD200
parts. We have no idea if the will reliably accept a 36-byte INQUIRY.
Just because it happens to work for a couple of people doesn't mean it
works in the general case. Without guidance from In-System, this is a bad
idea.
The way to deal with this is to do this via bounce buffering. The two
commands affected (INQUIRY and MODE_SENSE) are low-performance items.
Discarding data from the end of them is also perfectly legal per spec.
Also, the entire idea of a negative resid makes my head hurt. That sort of
change is in the category of "likely to break something else" which only
expects positive resid values.
Matt
On Thu, Jan 31, 2008 at 09:37:13PM +0200, Boaz Harrosh wrote:
> Greg KH <greg-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org> rote:
> > As this is a regression and hits 2.6.24, can you send the final version
> > of this patch to the stable-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org address so we can get it into the
> > 2.6.24.y tree?
> >
> > thanks,
> >
> > greg k-h
>
> Mark - This is for you on top of vanila v2.6.24 kernel from Linus.
>
> ---
>
> scsi_scan is issuing a 36-byte INQUIRY request to llds. isd200 would
> volunteer 96 bytes of INQUIRY. This caused an overflow condition in
> protocol.c usb_stor_access_xfer_buf(). So first fix is to
> usb_stor_access_xfer_buf() to properly handle overflow/underflow conditions.
> Then usb_stor_set_xfer_buf() should report this condition as a negative
> resid. Should we also set cmnd->status in the overflow condition?
>
> Then also isd200.c is fixed to only return the type of INQUIRY && SENSE
> the upper layer asked for.
>
> Signed-off-by: Boaz Harrosh <bharrosh-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org>
> ---
> drivers/usb/storage/isd200.c | 7 +++++--
> drivers/usb/storage/protocol.c | 13 +++++++++----
> 2 files changed, 14 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c
> index 49ba6c0..8186e93 100644
> --- a/drivers/usb/storage/isd200.c
> +++ b/drivers/usb/storage/isd200.c
> @@ -1238,6 +1238,7 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
> unsigned long lba;
> unsigned long blockCount;
> unsigned char senseData[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
> + unsigned xfer_len;
>
> memset(ataCdb, 0, sizeof(union ata_cdb));
>
> @@ -1247,8 +1248,9 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
> US_DEBUGP(" ATA OUT - INQUIRY\n");
>
> /* copy InquiryData */
> + xfer_len = min(sizeof(info->InquiryData), scsi_bufflen(srb));
> usb_stor_set_xfer_buf((unsigned char *) &info->InquiryData,
> - sizeof(info->InquiryData), srb);
> + xfer_len, srb);
> srb->result = SAM_STAT_GOOD;
> sendToTransport = 0;
> break;
> @@ -1257,7 +1259,8 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
> US_DEBUGP(" ATA OUT - SCSIOP_MODE_SENSE\n");
>
> /* Initialize the return buffer */
> - usb_stor_set_xfer_buf(senseData, sizeof(senseData), srb);
> + xfer_len = min(sizeof(senseData), scsi_bufflen(srb));
> + usb_stor_set_xfer_buf(senseData, xfer_len, srb);
>
> if (info->DeviceFlags & DF_MEDIA_STATUS_ENABLED)
> {
> diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c
> index 889622b..038a284 100644
> --- a/drivers/usb/storage/protocol.c
> +++ b/drivers/usb/storage/protocol.c
> @@ -194,7 +194,7 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
> * and the starting offset within the page, and update
> * the *offset and *index values for the next loop. */
> cnt = 0;
> - while (cnt < buflen) {
> + while (cnt < buflen && sg) {
> struct page *page = sg_page(sg) +
> ((sg->offset + *offset) >> PAGE_SHIFT);
> unsigned int poff =
> @@ -248,9 +248,14 @@ void usb_stor_set_xfer_buf(unsigned char *buffer,
> {
> unsigned int offset = 0;
> struct scatterlist *sg = NULL;
> + unsigned count;
>
> - usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
> + count = usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
> TO_XFER_BUF);
> - if (buflen < srb->request_bufflen)
> - srb->resid = srb->request_bufflen - buflen;
> +
> + /* Check for overflow */
> + if (buflen > scsi_bufflen(srb))
> + count = buflen;
> +
> + scsi_set_resid(srb, scsi_bufflen(srb) - count);
> }
> --
> 1.5.3.3
>
--
Matthew Dharm Home: mdharm-usb@one-eyed-alien.net
Maintainer, Linux USB Mass Storage Driver
M: No, Windows doesn't have any nag screens.
C: Then what are those blue and white screens I get every day?
-- Mike and Cobb
User Friendly, 1/4/1999
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] bugfix for an underflow condition in usb storage & isd200.c
2008-01-31 19:34 ` Alan Stern
@ 2008-01-31 19:53 ` Boaz Harrosh
2008-01-31 20:56 ` Alan Stern
0 siblings, 1 reply; 36+ messages in thread
From: Boaz Harrosh @ 2008-01-31 19:53 UTC (permalink / raw)
To: Alan Stern
Cc: Mark Glines, Matthew Dharm, James Bottomley, USB list, linux-scsi
On Thu, Jan 31 2008 at 21:34 +0200, Alan Stern <stern@rowland.harvard.edu> wrote:
> On Thu, 31 Jan 2008, Boaz Harrosh wrote:
>
>> On Thu, Jan 31 2008 at 19:49 +0200, Alan Stern <stern@rowland.harvard.edu> wrote:
>>> On Thu, 31 Jan 2008, Boaz Harrosh wrote:
>>>
>>>> @@ -228,9 +228,14 @@ void usb_stor_set_xfer_buf(unsigned char *buffer,
>>>> {
>>>> unsigned int offset = 0;
>>>> struct scatterlist *sg = NULL;
>>>> + unsigned int count;
>>>>
>>>> - usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
>>>> + count = usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
>>>> TO_XFER_BUF);
>>>> - if (buflen < scsi_bufflen(srb))
>>>> - scsi_set_resid(srb, scsi_bufflen(srb) - buflen);
>>>> +
>>>> + /* Check for underflow */
>>>> + if (buflen > scsi_bufflen(srb))
>>>> + count = buflen;
>>>> +
>>>> + scsi_set_resid(srb, scsi_bufflen(srb) - count);
>>>> }
>>> This last "if" statement doesn't look right. And since you know that
>>> count will never be larger than scsi_bufflen(srb), you don't have to
>>> check for underflow at all. Just leave out the "if" and call
>>> scsi_set_resid() directly.
>>>
>>> Alan Stern
>>>
>> I was thinking about that hard. And I disagree. It could be that we have
>> sg-list length (The total of all sg->length) that does not match
>> scsi_bufflen() - More or less.
>
> If that ever happens we'll be in big trouble. Not just here but in
> other places as well.
Other places is other places, but you cannot put a BUG_ON here for other
places. This place here should be correct.
>
>> The code in usb_stor_access_xfer_buf() will
>> now correctly attempt to transfer according to buflen and what ever is available
>> at the passed sg's. Now this can be less or it can be more. SCSI standard defines
>> this as underflow/overflow. When overflow should be reported as negative values.
>> and an error status. (BUT not CHECK_CONDITION)
>
> I don't understand. How could you ever transfer more data than the
> requested amount? The host won't expect to receive it and won't be
> able to handle it when it arrives.
>
> (Furthmore, the USB mass-storage specification does not permit more
> data to be transferred than requested. This fact isn't relevant to our
> discussion because we're talking about situations where the data was
> transferred via a non-standard protocol. But even so...)
That's fine then the transfer will abort with an error condition and will
be handled correctly.
>
>> so the code is actualy
>> if (buflen > scsi_bufflen(srb))
>> scsi_set_resid(srb, scsi_bufflen(srb) - buflen); /* Negative overflow */
>
> Okay, let's assume that both buflen and the sum of the sg-list lengths
> are somehow greater than scsi_bufflen(srb). You still don't know that
> they are equal to each other. All you know is that the amount actually
> transferred is stored in count. Hence the negative overflow value
> should be
>
> scsi_bufflen(srb) - count
>
> and not
>
> scsi_bufflen(srb) - bufflen.
>
> Alan Stern
>
No, it is possible that sg-length was good and count == bufflen,
But the CDB contains scsi_bufflen(srb) and this is an overflow
condition. with your code resid will be Zero.
Also the standard say that we should return the expected overflow and
not the actual on-the-wire overflow.
We could check and truncate beforehand, and mark a flag for overflow
and set negative resid. But since usb_stor_access_xfer_buf() properly
handles that and returns, then this form saves cycles for the common
case and waists cycles for the very rare BUG case of overflow, but is
still correct and safe.
Boaz
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 2.6.24] bugfix for an overflow condition in usb storage & isd200.c
2008-01-31 19:49 ` Matthew Dharm
@ 2008-01-31 20:05 ` Boaz Harrosh
[not found] ` <47A229FF.4040404@panasas.com>
1 sibling, 0 replies; 36+ messages in thread
From: Boaz Harrosh @ 2008-01-31 20:05 UTC (permalink / raw)
To: Boaz Harrosh, Greg KH, Mark Glines, James Bottomley, Alan Stern
On Thu, Jan 31 2008 at 21:49 +0200, Matthew Dharm <mdharm-scsi@one-eyed-alien.net> wrote:
> No. No no no.
>
> The ISD200 code was written by the ISD200 developers. I really don't want
> to go mucking about changing what commands actually get send to the ISD200
> parts. We have no idea if the will reliably accept a 36-byte INQUIRY.
>
> Just because it happens to work for a couple of people doesn't mean it
> works in the general case. Without guidance from In-System, this is a bad
> idea.
>
> The way to deal with this is to do this via bounce buffering. The two
> commands affected (INQUIRY and MODE_SENSE) are low-performance items.
> Discarding data from the end of them is also perfectly legal per spec.
>
> Also, the entire idea of a negative resid makes my head hurt. That sort of
> change is in the category of "likely to break something else" which only
> expects positive resid values.
>
> Matt
>
Please re-inspect the code again.
There is no device involved here. The code completely emulates this commands
with a driver made up information. the send_to_device is Zero.
(Nothing to bounce)
There is one more command like that but the standard does not permit choice
in that respect.
The negative resid is returned by iscsi for ages so I would say the scsi-ml
is fine with it. But if you want I can reset the resid and mark an overflow
condition in cmnd->status.
Boaz
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 2.6.24] bugfix for an overflow condition in usb storage & isd200.c
[not found] ` <47A229FF.4040404@panasas.com>
@ 2008-01-31 20:16 ` Matthew Dharm
0 siblings, 0 replies; 36+ messages in thread
From: Matthew Dharm @ 2008-01-31 20:16 UTC (permalink / raw)
To: Boaz Harrosh
Cc: Greg KH, Mark Glines, James Bottomley, Alan Stern, USB list,
linux-scsi
[-- Attachment #1: Type: text/plain, Size: 1010 bytes --]
On Thu, Jan 31, 2008 at 10:05:19PM +0200, Boaz Harrosh wrote:
> On Thu, Jan 31 2008 at 21:49 +0200, Matthew Dharm <mdharm-scsi@one-eyed-alien.net> wrote:
> > No. No no no.
>
> Please re-inspect the code again.
> There is no device involved here. The code completely emulates this commands
> with a driver made up information. the send_to_device is Zero.
> (Nothing to bounce)
Okay, I see what you're doing there, and I can live with that.
> The negative resid is returned by iscsi for ages so I would say the scsi-ml
> is fine with it. But if you want I can reset the resid and mark an overflow
> condition in cmnd->status.
I'd be fine if one of the SCSI guru's would comment on this as being
acceptable.
Matt
--
Matthew Dharm Home: mdharm-usb@one-eyed-alien.net
Maintainer, Linux USB Mass Storage Driver
Hey Chief. We've figured out how to save the technical department. We
need to be committed.
-- The Techs
User Friendly, 1/22/1998
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] bugfix for an underflow condition in usb storage & isd200.c
2008-01-31 19:53 ` Boaz Harrosh
@ 2008-01-31 20:56 ` Alan Stern
[not found] ` <Pine.LNX.4.44L0.0801311546450.22845-100000-IYeN2dnnYyZXsRXLowluHWD2FQJk+8+b@public.gmane.org>
0 siblings, 1 reply; 36+ messages in thread
From: Alan Stern @ 2008-01-31 20:56 UTC (permalink / raw)
To: Boaz Harrosh
Cc: Mark Glines, Matthew Dharm, James Bottomley, USB list, linux-scsi
On Thu, 31 Jan 2008, Boaz Harrosh wrote:
> >> The code in usb_stor_access_xfer_buf() will
> >> now correctly attempt to transfer according to buflen and what ever is available
> >> at the passed sg's. Now this can be less or it can be more. SCSI standard defines
> >> this as underflow/overflow. When overflow should be reported as negative values.
> >> and an error status. (BUT not CHECK_CONDITION)
> >
> > I don't understand. How could you ever transfer more data than the
> > requested amount? The host won't expect to receive it and won't be
> > able to handle it when it arrives.
> >
> > (Furthmore, the USB mass-storage specification does not permit more
> > data to be transferred than requested. This fact isn't relevant to our
> > discussion because we're talking about situations where the data was
> > transferred via a non-standard protocol. But even so...)
> That's fine then the transfer will abort with an error condition and will
> be handled correctly.
I still don't understand. Can you explain exactly what an overflow
condition (negative residue) really means?
Does it mean that the device had more data available than the host
asked for? If it does, then you don't need to change the isd200 code
at all. The changes to protocol.c will be enough.
However you should realize that usb-storage, as it stands, won't work
properly with negative residues. Look at usb_stor_Bulk_transport() in
transport.c. The residue variable is declared to be unsigned int.
There's also code later on in the routine which assumes the residue is
never negative.
Alan Stern
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 2.6.24] bugfix for an overflow condition in usb storage & isd200.c
[not found] ` <47A22369.80906-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org>
2008-01-31 19:49 ` Matthew Dharm
@ 2008-02-02 0:55 ` Mark Glines
1 sibling, 0 replies; 36+ messages in thread
From: Mark Glines @ 2008-02-02 0:55 UTC (permalink / raw)
To: Boaz Harrosh
Cc: Greg KH, Matthew Dharm, James Bottomley, Alan Stern, USB list,
linux-scsi
On Thu, 31 Jan 2008 21:37:13 +0200
Boaz Harrosh <bharrosh-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org> wrote:
>
> Mark - This is for you on top of vanila v2.6.24 kernel from Linus.
Sorry I didn't get back to you sooner. This fixes the issue I was
having.
> ---
>
> scsi_scan is issuing a 36-byte INQUIRY request to llds. isd200 would
> volunteer 96 bytes of INQUIRY. This caused an overflow condition in
> protocol.c usb_stor_access_xfer_buf(). So first fix is to
> usb_stor_access_xfer_buf() to properly handle overflow/underflow
> conditions. Then usb_stor_set_xfer_buf() should report this condition
> as a negative resid. Should we also set cmnd->status in the overflow
> condition?
>
> Then also isd200.c is fixed to only return the type of INQUIRY &&
> SENSE the upper layer asked for.
>
> Signed-off-by: Boaz Harrosh <bharrosh-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org>
Tested-by: Mark Glines <mark-6pk7R1svBr8dnm+yROfE0A@public.gmane.org>
> ---
> drivers/usb/storage/isd200.c | 7 +++++--
> drivers/usb/storage/protocol.c | 13 +++++++++----
> 2 files changed, 14 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/usb/storage/isd200.c
> b/drivers/usb/storage/isd200.c index 49ba6c0..8186e93 100644
> --- a/drivers/usb/storage/isd200.c
> +++ b/drivers/usb/storage/isd200.c
> @@ -1238,6 +1238,7 @@ static int isd200_scsi_to_ata(struct scsi_cmnd
> *srb, struct us_data *us, unsigned long lba;
> unsigned long blockCount;
> unsigned char senseData[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
> + unsigned xfer_len;
>
> memset(ataCdb, 0, sizeof(union ata_cdb));
>
> @@ -1247,8 +1248,9 @@ static int isd200_scsi_to_ata(struct scsi_cmnd
> *srb, struct us_data *us, US_DEBUGP(" ATA OUT - INQUIRY\n");
>
> /* copy InquiryData */
> + xfer_len = min(sizeof(info->InquiryData),
> scsi_bufflen(srb)); usb_stor_set_xfer_buf((unsigned char *)
> &info->InquiryData,
> - sizeof(info->InquiryData), srb);
> + xfer_len, srb);
> srb->result = SAM_STAT_GOOD;
> sendToTransport = 0;
> break;
> @@ -1257,7 +1259,8 @@ static int isd200_scsi_to_ata(struct scsi_cmnd
> *srb, struct us_data *us, US_DEBUGP(" ATA OUT -
> SCSIOP_MODE_SENSE\n");
> /* Initialize the return buffer */
> - usb_stor_set_xfer_buf(senseData, sizeof(senseData),
> srb);
> + xfer_len = min(sizeof(senseData), scsi_bufflen(srb));
> + usb_stor_set_xfer_buf(senseData, xfer_len, srb);
>
> if (info->DeviceFlags & DF_MEDIA_STATUS_ENABLED)
> {
> diff --git a/drivers/usb/storage/protocol.c
> b/drivers/usb/storage/protocol.c index 889622b..038a284 100644
> --- a/drivers/usb/storage/protocol.c
> +++ b/drivers/usb/storage/protocol.c
> @@ -194,7 +194,7 @@ unsigned int usb_stor_access_xfer_buf(unsigned
> char *buffer,
> * and the starting offset within the page, and
> update
> * the *offset and *index values for the next loop.
> */ cnt = 0;
> - while (cnt < buflen) {
> + while (cnt < buflen && sg) {
> struct page *page = sg_page(sg) +
> ((sg->offset + *offset) >>
> PAGE_SHIFT); unsigned int poff =
> @@ -248,9 +248,14 @@ void usb_stor_set_xfer_buf(unsigned char *buffer,
> {
> unsigned int offset = 0;
> struct scatterlist *sg = NULL;
> + unsigned count;
>
> - usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
> + count = usb_stor_access_xfer_buf(buffer, buflen, srb, &sg,
> &offset, TO_XFER_BUF);
> - if (buflen < srb->request_bufflen)
> - srb->resid = srb->request_bufflen - buflen;
> +
> + /* Check for overflow */
> + if (buflen > scsi_bufflen(srb))
> + count = buflen;
> +
> + scsi_set_resid(srb, scsi_bufflen(srb) - count);
> }
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] bugfix for an underflow condition in usb storage & isd200.c
[not found] ` <Pine.LNX.4.44L0.0801311546450.22845-100000-IYeN2dnnYyZXsRXLowluHWD2FQJk+8+b@public.gmane.org>
@ 2008-02-03 8:59 ` Boaz Harrosh
[not found] ` <47A5825D.2030901-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org>
0 siblings, 1 reply; 36+ messages in thread
From: Boaz Harrosh @ 2008-02-03 8:59 UTC (permalink / raw)
To: Alan Stern
Cc: Mark Glines, Matthew Dharm, James Bottomley, USB list, linux-scsi
On Thu, Jan 31 2008 at 22:56 +0200, Alan Stern <stern-nwvwT67g6+6dFdvTe/nMLpVzexx5G7lz@public.gmane.org> wrote:
> On Thu, 31 Jan 2008, Boaz Harrosh wrote:
>
>>>> The code in usb_stor_access_xfer_buf() will
>>>> now correctly attempt to transfer according to buflen and what ever is available
>>>> at the passed sg's. Now this can be less or it can be more. SCSI standard defines
>>>> this as underflow/overflow. When overflow should be reported as negative values.
>>>> and an error status. (BUT not CHECK_CONDITION)
>>> I don't understand. How could you ever transfer more data than the
>>> requested amount? The host won't expect to receive it and won't be
>>> able to handle it when it arrives.
>>>
>>> (Furthmore, the USB mass-storage specification does not permit more
>>> data to be transferred than requested. This fact isn't relevant to our
>>> discussion because we're talking about situations where the data was
>>> transferred via a non-standard protocol. But even so...)
>> That's fine then the transfer will abort with an error condition and will
>> be handled correctly.
>
> I still don't understand. Can you explain exactly what an overflow
> condition (negative residue) really means?
As far as the protocol it is an error condition. But it is an error
condition that should be handled and io should continue. What it usually means
is that either target or Initiator had, like you said, more data then
expected. Usually an encoding error of the different stages of transfer
like sum of R2Ts or DATA is bigger then CDB length and so on.
The important thing is that the system should continue, and that this
is not a check_condition error.
>
> Does it mean that the device had more data available than the host
> asked for? If it does, then you don't need to change the isd200 code
> at all. The changes to protocol.c will be enough.
I do in the sense that the target should return correct information requested.
overflow is still an error. A recoverable but none-standard error. The INQUIRY
has 3 flavors based on requested size. The target should comply.
>
> However you should realize that usb-storage, as it stands, won't work
> properly with negative residues. Look at usb_stor_Bulk_transport() in
> transport.c. The residue variable is declared to be unsigned int.
> There's also code later on in the routine which assumes the residue is
> never negative.
>
> Alan Stern
>
> -
I will change that, but if you don't mind with a FIXME: comment next
to it. I will set resid to 1 and set the cmnd->status. Setting of command
status is ineffective as it is, most probably, been set afterwards.
Should I also put a WARN_ON()? I would say yes.
I'll send a patch.
Boaz
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] bugfix for an underflow condition in usb storage & isd200.c
[not found] ` <47A5825D.2030901-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org>
@ 2008-02-03 16:01 ` Alan Stern
2008-02-03 16:28 ` Boaz Harrosh
0 siblings, 1 reply; 36+ messages in thread
From: Alan Stern @ 2008-02-03 16:01 UTC (permalink / raw)
To: Boaz Harrosh
Cc: Mark Glines, Matthew Dharm, James Bottomley, USB list, linux-scsi
Sorry, I understood only about half of what you wrote -- maybe less!
On Sun, 3 Feb 2008, Boaz Harrosh wrote:
> On Thu, Jan 31 2008 at 22:56 +0200, Alan Stern <stern-nwvwT67g6+6dFdvTe/nMLpVzexx5G7lz@public.gmane.org> wrote:
> > I still don't understand. Can you explain exactly what an overflow
> > condition (negative residue) really means?
> As far as the protocol it is an error condition. But it is an error
> condition that should be handled and io should continue. What it usually means
> is that either target or Initiator had, like you said, more data then
> expected. Usually an encoding error of the different stages of transfer
> like sum of R2Ts or DATA is bigger then CDB length and so on.
> The important thing is that the system should continue, and that this
> is not a check_condition error.
What is an R2T?
How does a negative residue differ from a Phase error?
What exactly do you mean by "more data then expected"? The USB
mass-storage protocol specifies the length of a transfer in at least
three different places, and those places won't always agree:
(1) For some commands, the device may have a specific amount
of data it can supply or expect to receive. For example,
the device might have 90 bytes of INQUIRY data available.
(2) Many CDBs include a field specifying how much data should
be transferred (INQUIRY does). The amount of data actually
transferred is supposed to be the smaller of this value
and the size in (1).
(3) The USB Bulk-only transport includes fields in the CDB
wrapper specifying the number of bytes the host expects to
transfer and the direction.
If (3) is different from (2) or if the direction disagrees with what
the device expects, the device is supposed to return a Phase error.
If (1) < (2) = (3) then it isn't an error; in this case the residue is
given by (2) - (1). If (1) > (2) = (3) then according to the USB
protocol nothing special happens -- no error and residue = 0.
(Note however that the INQUIRY response data includes a field in which
the device can tell the host that more data is available.)
In no cases does this allow for a negative residue.
> > Does it mean that the device had more data available than the host
> > asked for? If it does, then you don't need to change the isd200 code
> > at all. The changes to protocol.c will be enough.
> I do in the sense that the target should return correct information requested.
Doesn't the existing code in isd200 together with your changes to
protocol.c do exactly that?
> overflow is still an error.
Once again: What exactly do you mean by "overflow"? In what sense is
it an error?
> A recoverable but none-standard error. The INQUIRY
> has 3 flavors based on requested size. The target should comply.
What 3 flavors are you talking about? As far as I know there's only
one type of INQUIRY command.
> > However you should realize that usb-storage, as it stands, won't work
> > properly with negative residues. Look at usb_stor_Bulk_transport() in
> > transport.c. The residue variable is declared to be unsigned int.
> > There's also code later on in the routine which assumes the residue is
> > never negative.
> >
> > Alan Stern
> >
> > -
> I will change that, but if you don't mind with a FIXME: comment next
> to it. I will set resid to 1 and set the cmnd->status.
Where will you change this? Why set resid to 1? That means the device
sent 1 byte less than the host expected.
> Setting of command
> status is ineffective as it is, most probably, been set afterwards.
After what?
> Should I also put a WARN_ON()? I would say yes.
> I'll send a patch.
Maybe this will be more clear once you do. As it is, I'm totally in
the dark.
Alan Stern
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] bugfix for an underflow condition in usb storage & isd200.c
2008-02-03 16:01 ` Alan Stern
@ 2008-02-03 16:28 ` Boaz Harrosh
2008-02-03 19:23 ` Matthew Dharm
[not found] ` <47A5EBC0.3060401-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org>
0 siblings, 2 replies; 36+ messages in thread
From: Boaz Harrosh @ 2008-02-03 16:28 UTC (permalink / raw)
To: Alan Stern
Cc: Mark Glines, Matthew Dharm, James Bottomley, USB list, linux-scsi
On Sun, Feb 03 2008 at 18:01 +0200, Alan Stern <stern@rowland.harvard.edu> wrote:
> Sorry, I understood only about half of what you wrote -- maybe less!
>
> On Sun, 3 Feb 2008, Boaz Harrosh wrote:
>
>> On Thu, Jan 31 2008 at 22:56 +0200, Alan Stern <stern@rowland.harvard.edu> wrote:
>
>>> I still don't understand. Can you explain exactly what an overflow
>>> condition (negative residue) really means?
>> As far as the protocol it is an error condition. But it is an error
>> condition that should be handled and io should continue. What it usually means
>> is that either target or Initiator had, like you said, more data then
>> expected. Usually an encoding error of the different stages of transfer
>> like sum of R2Ts or DATA is bigger then CDB length and so on.
>> The important thing is that the system should continue, and that this
>> is not a check_condition error.
>
> What is an R2T?
>
> How does a negative residue differ from a Phase error?
>
> What exactly do you mean by "more data then expected"? The USB
> mass-storage protocol specifies the length of a transfer in at least
> three different places, and those places won't always agree:
>
> (1) For some commands, the device may have a specific amount
> of data it can supply or expect to receive. For example,
> the device might have 90 bytes of INQUIRY data available.
>
> (2) Many CDBs include a field specifying how much data should
> be transferred (INQUIRY does). The amount of data actually
> transferred is supposed to be the smaller of this value
> and the size in (1).
>
> (3) The USB Bulk-only transport includes fields in the CDB
> wrapper specifying the number of bytes the host expects to
> transfer and the direction.
>
> If (3) is different from (2) or if the direction disagrees with what
> the device expects, the device is supposed to return a Phase error.
> If (1) < (2) = (3) then it isn't an error; in this case the residue is
> given by (2) - (1). If (1) > (2) = (3) then according to the USB
> protocol nothing special happens -- no error and residue = 0.
> (Note however that the INQUIRY response data includes a field in which
> the device can tell the host that more data is available.)
>
> In no cases does this allow for a negative residue.
>
>>> Does it mean that the device had more data available than the host
>>> asked for? If it does, then you don't need to change the isd200 code
>>> at all. The changes to protocol.c will be enough.
>> I do in the sense that the target should return correct information requested.
>
> Doesn't the existing code in isd200 together with your changes to
> protocol.c do exactly that?
>
>> overflow is still an error.
>
> Once again: What exactly do you mean by "overflow"? In what sense is
> it an error?
>
>> A recoverable but none-standard error. The INQUIRY
>> has 3 flavors based on requested size. The target should comply.
>
> What 3 flavors are you talking about? As far as I know there's only
> one type of INQUIRY command.
>
>>> However you should realize that usb-storage, as it stands, won't work
>>> properly with negative residues. Look at usb_stor_Bulk_transport() in
>>> transport.c. The residue variable is declared to be unsigned int.
>>> There's also code later on in the routine which assumes the residue is
>>> never negative.
>>>
>>> Alan Stern
>>>
>>> -
>> I will change that, but if you don't mind with a FIXME: comment next
>> to it. I will set resid to 1 and set the cmnd->status.
>
> Where will you change this? Why set resid to 1? That means the device
> sent 1 byte less than the host expected.
>
>> Setting of command
>> status is ineffective as it is, most probably, been set afterwards.
>
> After what?
>
>> Should I also put a WARN_ON()? I would say yes.
>> I'll send a patch.
>
> Maybe this will be more clear once you do. As it is, I'm totally in
> the dark.
>
> Alan Stern
>
> -
below is what I have so far. It is for v2.6.24 if it's acceptable then
I'll also send a patch for head-of-line. Please comment.
Boaz
----
>From 3610cfa93c990bbbafb296134ac01ef6d426eb8d Mon Sep 17 00:00:00 2001
From: Boaz Harrosh <bharrosh@panasas.com>
Date: Thu, 31 Jan 2008 21:31:31 +0200
Subject: [PATCH] bugfix for an overflow condition in usb storage & isd200.c
scsi_scan is issuing a 36-byte INQUIRY request to llds. isd200 would
volunteer 96 bytes of INQUIRY. This caused an overflow condition in
protocol.c usb_stor_access_xfer_buf(). So first fix is to
usb_stor_access_xfer_buf() to properly handle overflow/underflow conditions.
Then usb_stor_set_xfer_buf() should report this condition as cmnd->result ==
(DID_BAD_TARGET << 16).
Then also isd200.c is fixed to only return the type of INQUIRY && SENSE
the upper layer asked for.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
---
drivers/usb/storage/isd200.c | 7 +++++--
drivers/usb/storage/protocol.c | 20 ++++++++++++++++----
2 files changed, 21 insertions(+), 6 deletions(-)
diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c
index 49ba6c0..8186e93 100644
--- a/drivers/usb/storage/isd200.c
+++ b/drivers/usb/storage/isd200.c
@@ -1238,6 +1238,7 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
unsigned long lba;
unsigned long blockCount;
unsigned char senseData[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+ unsigned xfer_len;
memset(ataCdb, 0, sizeof(union ata_cdb));
@@ -1247,8 +1248,9 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
US_DEBUGP(" ATA OUT - INQUIRY\n");
/* copy InquiryData */
+ xfer_len = min(sizeof(info->InquiryData), scsi_bufflen(srb));
usb_stor_set_xfer_buf((unsigned char *) &info->InquiryData,
- sizeof(info->InquiryData), srb);
+ xfer_len, srb);
srb->result = SAM_STAT_GOOD;
sendToTransport = 0;
break;
@@ -1257,7 +1259,8 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
US_DEBUGP(" ATA OUT - SCSIOP_MODE_SENSE\n");
/* Initialize the return buffer */
- usb_stor_set_xfer_buf(senseData, sizeof(senseData), srb);
+ xfer_len = min(sizeof(senseData), scsi_bufflen(srb));
+ usb_stor_set_xfer_buf(senseData, xfer_len, srb);
if (info->DeviceFlags & DF_MEDIA_STATUS_ENABLED)
{
diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c
index 889622b..f141819 100644
--- a/drivers/usb/storage/protocol.c
+++ b/drivers/usb/storage/protocol.c
@@ -194,7 +194,7 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
* and the starting offset within the page, and update
* the *offset and *index values for the next loop. */
cnt = 0;
- while (cnt < buflen) {
+ while (cnt < buflen && sg) {
struct page *page = sg_page(sg) +
((sg->offset + *offset) >> PAGE_SHIFT);
unsigned int poff =
@@ -248,9 +248,21 @@ void usb_stor_set_xfer_buf(unsigned char *buffer,
{
unsigned int offset = 0;
struct scatterlist *sg = NULL;
+ unsigned count;
- usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
+ count = usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
TO_XFER_BUF);
- if (buflen < srb->request_bufflen)
- srb->resid = srb->request_bufflen - buflen;
+
+ /* Check for overflow */
+ if (buflen > scsi_bufflen(srb)) {
+ /* FIXME: we set resid to 0, and set status. but also put a
+ * a WARN_ON. The status will most probably not reach upper
+ * layer and the WARN_ON is the only indication of this glitch.
+ */
+ WARN_ON(1);
+ srb->result = (DID_BAD_TARGET << 16);
+ count = scsi_bufflen(srb);
+ }
+
+ scsi_set_resid(srb, scsi_bufflen(srb) - count);
}
--
1.5.3.3
^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [PATCH] bugfix for an underflow condition in usb storage & isd200.c
2008-02-03 16:28 ` Boaz Harrosh
@ 2008-02-03 19:23 ` Matthew Dharm
2008-02-04 9:05 ` Boaz Harrosh
2008-02-04 20:05 ` Alan Stern
[not found] ` <47A5EBC0.3060401-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org>
1 sibling, 2 replies; 36+ messages in thread
From: Matthew Dharm @ 2008-02-03 19:23 UTC (permalink / raw)
To: Boaz Harrosh
Cc: Alan Stern, Mark Glines, James Bottomley, USB list, linux-scsi
[-- Attachment #1: Type: text/plain, Size: 2881 bytes --]
On Sun, Feb 03, 2008 at 06:28:48PM +0200, Boaz Harrosh wrote:
> >From 3610cfa93c990bbbafb296134ac01ef6d426eb8d Mon Sep 17 00:00:00 2001
> From: Boaz Harrosh <bharrosh@panasas.com>
> Date: Thu, 31 Jan 2008 21:31:31 +0200
> Subject: [PATCH] bugfix for an overflow condition in usb storage & isd200.c
>
> scsi_scan is issuing a 36-byte INQUIRY request to llds. isd200 would
> volunteer 96 bytes of INQUIRY. This caused an overflow condition in
> protocol.c usb_stor_access_xfer_buf(). So first fix is to
> usb_stor_access_xfer_buf() to properly handle overflow/underflow conditions.
> Then usb_stor_set_xfer_buf() should report this condition as cmnd->result ==
> (DID_BAD_TARGET << 16).
>
> Then also isd200.c is fixed to only return the type of INQUIRY && SENSE
> the upper layer asked for.
>
> Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
> ---
> drivers/usb/storage/isd200.c | 7 +++++--
> drivers/usb/storage/protocol.c | 20 ++++++++++++++++----
> 2 files changed, 21 insertions(+), 6 deletions(-)
Looking at this again, I think I see Alan's point. The modifications to
ISD200 code aren't really needed.
Or, put another way, if you're going to modify the ISD200 code, you should
fix up all the other users of usb_stor_access_xfer_buf() -- there are over
a dozen or so, and it looks like none of them have sanity checks for length
(but the happen to work right now).
But, the modifications to usb_stor_access_xfer_buf() look good -- no
request from a sub-driver should be allowed to scribble into memory. The
current code does make the implicit assumption that there is enough
storage, and will walk right off the end of the sg list if there isn't.
I'm not sure I like the mods to usb_stor_set_xfer_buf(). Any place we set
a status that we know is going to be thrown away is an invitation for a
problem later if someone changes the code to preserve that status. It's a
jack-in-the-box, waiting to spring open in our face later. The limit check
(which mirrors the usb_stor_access_xfer_buf modification) and WARN_ON() are
probably good.
In a strictly technical sense, the change to protocol.c are sufficient.
That is, they will prevent a serious error. There is a justification tho
to fix all of the users of usb_stor_access_buf() to not attempt to use more
SCSI buffer than exists.
My opinion is this: Let's make the protocol.c mods (modulo my comments
about setting useless status bits) now. Then, let's decide if we're going
to patch all the other users of the usb_stor_*_xfer_buf() functions as a
separate discussion.
Matt
--
Matthew Dharm Home: mdharm-usb@one-eyed-alien.net
Maintainer, Linux USB Mass Storage Driver
C: They kicked your ass, didn't they?
S: They were cheating!
-- The Chief and Stef
User Friendly, 11/19/1997
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] bugfix for an underflow condition in usb storage & isd200.c
[not found] ` <47A5EBC0.3060401-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org>
@ 2008-02-03 21:09 ` Matthew Dharm
0 siblings, 0 replies; 36+ messages in thread
From: Matthew Dharm @ 2008-02-03 21:09 UTC (permalink / raw)
To: Boaz Harrosh
Cc: Alan Stern, Mark Glines, James Bottomley, USB list, linux-scsi
[-- Attachment #1: Type: text/plain, Size: 536 bytes --]
One more comment on the patch...
On Sun, Feb 03, 2008 at 06:28:48PM +0200, Boaz Harrosh wrote:
> + /* Check for overflow */
> + if (buflen > scsi_bufflen(srb)) {
This really should have an unlikely() around it. This is an often-executed
code path, and we want to optimize it as much as possible.
Matt
--
Matthew Dharm Home: mdharm-usb@one-eyed-alien.net
Maintainer, Linux USB Mass Storage Driver
Type "format c:" That should fix everything.
-- Greg
User Friendly, 12/18/1997
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] bugfix for an underflow condition in usb storage & isd200.c
2008-02-03 19:23 ` Matthew Dharm
@ 2008-02-04 9:05 ` Boaz Harrosh
2008-02-04 20:05 ` Alan Stern
1 sibling, 0 replies; 36+ messages in thread
From: Boaz Harrosh @ 2008-02-04 9:05 UTC (permalink / raw)
To: Boaz Harrosh, Alan Stern, Mark Glines, James Bottomley, USB list
On Sun, Feb 03 2008 at 21:23 +0200, Matthew Dharm <mdharm-scsi@one-eyed-alien.net> wrote:
> On Sun, Feb 03, 2008 at 06:28:48PM +0200, Boaz Harrosh wrote:
>> >From 3610cfa93c990bbbafb296134ac01ef6d426eb8d Mon Sep 17 00:00:00 2001
>> From: Boaz Harrosh <bharrosh@panasas.com>
>> Date: Thu, 31 Jan 2008 21:31:31 +0200
>> Subject: [PATCH] bugfix for an overflow condition in usb storage & isd200.c
>>
>> scsi_scan is issuing a 36-byte INQUIRY request to llds. isd200 would
>> volunteer 96 bytes of INQUIRY. This caused an overflow condition in
>> protocol.c usb_stor_access_xfer_buf(). So first fix is to
>> usb_stor_access_xfer_buf() to properly handle overflow/underflow conditions.
>> Then usb_stor_set_xfer_buf() should report this condition as cmnd->result ==
>> (DID_BAD_TARGET << 16).
>>
>> Then also isd200.c is fixed to only return the type of INQUIRY && SENSE
>> the upper layer asked for.
>>
>> Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
>> ---
>> drivers/usb/storage/isd200.c | 7 +++++--
>> drivers/usb/storage/protocol.c | 20 ++++++++++++++++----
>> 2 files changed, 21 insertions(+), 6 deletions(-)
>
> Looking at this again, I think I see Alan's point. The modifications to
> ISD200 code aren't really needed.
>
> Or, put another way, if you're going to modify the ISD200 code, you should
> fix up all the other users of usb_stor_access_xfer_buf() -- there are over
> a dozen or so, and it looks like none of them have sanity checks for length
> (but the happen to work right now).
>
> But, the modifications to usb_stor_access_xfer_buf() look good -- no
> request from a sub-driver should be allowed to scribble into memory. The
> current code does make the implicit assumption that there is enough
> storage, and will walk right off the end of the sg list if there isn't.
>
> I'm not sure I like the mods to usb_stor_set_xfer_buf(). Any place we set
> a status that we know is going to be thrown away is an invitation for a
> problem later if someone changes the code to preserve that status. It's a
> jack-in-the-box, waiting to spring open in our face later. The limit check
> (which mirrors the usb_stor_access_xfer_buf modification) and WARN_ON() are
> probably good.
>
If you want the WARN_ON() then isd200 code modification must stay, other
wise the WARN_ON will trigger regularly.
You will find that most other places are naturally bound by other factors
and will not overflow. I think that those places that can, like INQUIRY,
should be fixed, and the WARN_ON should stay. If you don't fix them the
WARN_ON must go.
> In a strictly technical sense, the change to protocol.c are sufficient.
> That is, they will prevent a serious error. There is a justification tho
> to fix all of the users of usb_stor_access_buf() to not attempt to use more
> SCSI buffer than exists.
>
> My opinion is this: Let's make the protocol.c mods (modulo my comments
> about setting useless status bits) now. Then, let's decide if we're going
> to patch all the other users of the usb_stor_*_xfer_buf() functions as a
> separate discussion.
>
> Matt
>
I'm removing the set of result. I don't see any danger in it but it's your
code. But if the WARN_ON stays then so is the isd200 fixes.
Boaz
---
>From cd66d4d4a4a239e580714e926e9635f3426dd7fd Mon Sep 17 00:00:00 2001
From: Boaz Harrosh <bharrosh@panasas.com>
Date: Thu, 31 Jan 2008 21:31:31 +0200
Subject: [PATCH] bugfix for an overflow condition in usb storage & isd200.c
scsi_scan is issuing a 36-byte INQUIRY request to llds. isd200 would
volunteer 96 bytes of INQUIRY. This caused an overflow condition in
protocol.c usb_stor_access_xfer_buf(). So first fix is to
usb_stor_access_xfer_buf() to properly handle overflow/underflow conditions.
Then put a WARN_ON in usb_stor_set_xfer_buf().
isd200.c is fixed to only return the type of INQUIRY && SENSE
the upper layer asked for.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
---
drivers/usb/storage/isd200.c | 7 +++++--
drivers/usb/storage/protocol.c | 12 ++++++++----
2 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c
index 49ba6c0..8186e93 100644
--- a/drivers/usb/storage/isd200.c
+++ b/drivers/usb/storage/isd200.c
@@ -1238,6 +1238,7 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
unsigned long lba;
unsigned long blockCount;
unsigned char senseData[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+ unsigned xfer_len;
memset(ataCdb, 0, sizeof(union ata_cdb));
@@ -1247,8 +1248,9 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
US_DEBUGP(" ATA OUT - INQUIRY\n");
/* copy InquiryData */
+ xfer_len = min(sizeof(info->InquiryData), scsi_bufflen(srb));
usb_stor_set_xfer_buf((unsigned char *) &info->InquiryData,
- sizeof(info->InquiryData), srb);
+ xfer_len, srb);
srb->result = SAM_STAT_GOOD;
sendToTransport = 0;
break;
@@ -1257,7 +1259,8 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
US_DEBUGP(" ATA OUT - SCSIOP_MODE_SENSE\n");
/* Initialize the return buffer */
- usb_stor_set_xfer_buf(senseData, sizeof(senseData), srb);
+ xfer_len = min(sizeof(senseData), scsi_bufflen(srb));
+ usb_stor_set_xfer_buf(senseData, xfer_len, srb);
if (info->DeviceFlags & DF_MEDIA_STATUS_ENABLED)
{
diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c
index 889622b..a3d1d8e 100644
--- a/drivers/usb/storage/protocol.c
+++ b/drivers/usb/storage/protocol.c
@@ -194,7 +194,7 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
* and the starting offset within the page, and update
* the *offset and *index values for the next loop. */
cnt = 0;
- while (cnt < buflen) {
+ while (cnt < buflen && sg) {
struct page *page = sg_page(sg) +
((sg->offset + *offset) >> PAGE_SHIFT);
unsigned int poff =
@@ -248,9 +248,13 @@ void usb_stor_set_xfer_buf(unsigned char *buffer,
{
unsigned int offset = 0;
struct scatterlist *sg = NULL;
+ unsigned count;
- usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
+ count = usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
TO_XFER_BUF);
- if (buflen < srb->request_bufflen)
- srb->resid = srb->request_bufflen - buflen;
+
+ /* Check for overflow */
+ WARN_ON(buflen > scsi_bufflen(srb));
+
+ scsi_set_resid(srb, scsi_bufflen(srb) - count);
}
--
1.5.3.3
^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [PATCH] bugfix for an underflow condition in usb storage & isd200.c
2008-02-03 19:23 ` Matthew Dharm
2008-02-04 9:05 ` Boaz Harrosh
@ 2008-02-04 20:05 ` Alan Stern
[not found] ` <Pine.LNX.4.44L0.0802041500420.5186-100000-IYeN2dnnYyZXsRXLowluHWD2FQJk+8+b@public.gmane.org>
2008-02-05 17:54 ` Matthew Dharm
1 sibling, 2 replies; 36+ messages in thread
From: Alan Stern @ 2008-02-04 20:05 UTC (permalink / raw)
To: Matthew Dharm
Cc: Boaz Harrosh, Mark Glines, James Bottomley, USB list, linux-scsi
On Sun, 3 Feb 2008, Matthew Dharm wrote:
> But, the modifications to usb_stor_access_xfer_buf() look good -- no
> request from a sub-driver should be allowed to scribble into memory. The
> current code does make the implicit assumption that there is enough
> storage, and will walk right off the end of the sg list if there isn't.
>
> I'm not sure I like the mods to usb_stor_set_xfer_buf(). Any place we set
> a status that we know is going to be thrown away is an invitation for a
> problem later if someone changes the code to preserve that status. It's a
> jack-in-the-box, waiting to spring open in our face later. The limit check
> (which mirrors the usb_stor_access_xfer_buf modification) and WARN_ON() are
> probably good.
>
> In a strictly technical sense, the change to protocol.c are sufficient.
> That is, they will prevent a serious error. There is a justification tho
> to fix all of the users of usb_stor_access_buf() to not attempt to use more
> SCSI buffer than exists.
>
> My opinion is this: Let's make the protocol.c mods (modulo my comments
> about setting useless status bits) now. Then, let's decide if we're going
> to patch all the other users of the usb_stor_*_xfer_buf() functions as a
> separate discussion.
I think the correct approach is to modify those routines so that they
will never overrun the s-g buffer (like Boaz has done), and _document_
this behavior. Then the callers can feel free to try and transfer as
much as they want, knowing that an overrun can't occur. There won't
be any need for a WARN_ON or anything else.
However the interface to usb_stor_access_xfer_buf() will have to change
slightly. Right now if it sees that *sgptr is NULL, it assumes this
means it should start at the beginning of the s-g buffer. But with
Boaz's change, *sgptr == NULL means the transfer has reached the end of
the buffer. So I'll have to go through and audit all the callers.
Alan Stern
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] bugfix for an underflow condition in usb storage & isd200.c
[not found] ` <Pine.LNX.4.44L0.0802041500420.5186-100000-IYeN2dnnYyZXsRXLowluHWD2FQJk+8+b@public.gmane.org>
@ 2008-02-05 8:41 ` Boaz Harrosh
[not found] ` <47A8213B.9050705-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org>
0 siblings, 1 reply; 36+ messages in thread
From: Boaz Harrosh @ 2008-02-05 8:41 UTC (permalink / raw)
To: Alan Stern
Cc: Matthew Dharm, Mark Glines, James Bottomley, USB list, linux-scsi
On Mon, Feb 04 2008 at 22:05 +0200, Alan Stern <stern-nwvwT67g6+6dFdvTe/nMLpVzexx5G7lz@public.gmane.org> wrote:
> On Sun, 3 Feb 2008, Matthew Dharm wrote:
>
>> But, the modifications to usb_stor_access_xfer_buf() look good -- no
>> request from a sub-driver should be allowed to scribble into memory. The
>> current code does make the implicit assumption that there is enough
>> storage, and will walk right off the end of the sg list if there isn't.
>>
>> I'm not sure I like the mods to usb_stor_set_xfer_buf(). Any place we set
>> a status that we know is going to be thrown away is an invitation for a
>> problem later if someone changes the code to preserve that status. It's a
>> jack-in-the-box, waiting to spring open in our face later. The limit check
>> (which mirrors the usb_stor_access_xfer_buf modification) and WARN_ON() are
>> probably good.
>>
>> In a strictly technical sense, the change to protocol.c are sufficient.
>> That is, they will prevent a serious error. There is a justification tho
>> to fix all of the users of usb_stor_access_buf() to not attempt to use more
>> SCSI buffer than exists.
>>
>> My opinion is this: Let's make the protocol.c mods (modulo my comments
>> about setting useless status bits) now. Then, let's decide if we're going
>> to patch all the other users of the usb_stor_*_xfer_buf() functions as a
>> separate discussion.
>
> I think the correct approach is to modify those routines so that they
> will never overrun the s-g buffer (like Boaz has done), and _document_
> this behavior. Then the callers can feel free to try and transfer as
> much as they want, knowing that an overrun can't occur. There won't
> be any need for a WARN_ON or anything else.
>
> However the interface to usb_stor_access_xfer_buf() will have to change
> slightly. Right now if it sees that *sgptr is NULL, it assumes this
> means it should start at the beginning of the s-g buffer. But with
> Boaz's change, *sgptr == NULL means the transfer has reached the end of
> the buffer. So I'll have to go through and audit all the callers.
>
> Alan Stern
>
> -
No it does not, this as not changed. Please look again.
Note that this patch was tested and working. It is a bug
in v2.2.24 and it should be accepted already. One way or
the other.
Callers of usb_stor_access_xfer_buf() need not change.
Matthew Dharm should decide if he wants the WARN_ON in
usb_stor_set_xfer_buf() or not and be done with it.
I have found and fixed the bug, but it is not a SCSI
related bug, and it is not do to any scsi changes. It
is a bug from the SG changes of early 2.6.24. Please
take it through the USB tree. Feel free to change it
the way you like it, and submit it.
Boaz
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] bugfix for an underflow condition in usb storage & isd200.c
[not found] ` <47A8213B.9050705-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org>
@ 2008-02-05 15:42 ` Alan Stern
2008-02-05 16:54 ` Boaz Harrosh
0 siblings, 1 reply; 36+ messages in thread
From: Alan Stern @ 2008-02-05 15:42 UTC (permalink / raw)
To: Boaz Harrosh
Cc: Matthew Dharm, Mark Glines, James Bottomley, USB list, linux-scsi
On Tue, 5 Feb 2008, Boaz Harrosh wrote:
> > However the interface to usb_stor_access_xfer_buf() will have to change
> > slightly. Right now if it sees that *sgptr is NULL, it assumes this
> > means it should start at the beginning of the s-g buffer. But with
> > Boaz's change, *sgptr == NULL means the transfer has reached the end of
> > the buffer. So I'll have to go through and audit all the callers.
> >
> > Alan Stern
> >
> > -
> No it does not, this as not changed. Please look again.
You look again. Your patched code goes like this:
struct scatterlist *sg = *sgptr;
if (!sg)
sg = (struct scatterlist *) srb->request_buffer;
Hence if *sgptr is NULL upon entry, it is taken to mean that the
transfer should start at the beginning of the s-g buffer.
/* This loop handles a single s-g list entry, which may
* include multiple pages. Find the initial page structure
* and the starting offset within the page, and update
* the *offset and *index values for the next loop. */
cnt = 0;
while (cnt < buflen && sg) {
Hence if sg is NULL, it indicates the end of the buffer has been
reached. And then down near the end of the routine:
*sgptr = sg;
Hence if the end is reached and the caller makes another call to try
transferring more data, the additional data will get stored back at the
beginning of the buffer.
> Note that this patch was tested and working. It is a bug
> in v2.2.24 and it should be accepted already. One way or
> the other.
>
> Callers of usb_stor_access_xfer_buf() need not change.
> Matthew Dharm should decide if he wants the WARN_ON in
> usb_stor_set_xfer_buf() or not and be done with it.
>
> I have found and fixed the bug, but it is not a SCSI
> related bug, and it is not do to any scsi changes. It
> is a bug from the SG changes of early 2.6.24. Please
> take it through the USB tree. Feel free to change it
> the way you like it, and submit it.
I will post a new version of this which handles all these issues.
Expect it in a day or so.
Alan Stern
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] bugfix for an underflow condition in usb storage & isd200.c
2008-02-05 15:42 ` Alan Stern
@ 2008-02-05 16:54 ` Boaz Harrosh
0 siblings, 0 replies; 36+ messages in thread
From: Boaz Harrosh @ 2008-02-05 16:54 UTC (permalink / raw)
To: Alan Stern
Cc: Matthew Dharm, Mark Glines, James Bottomley, USB list, linux-scsi
On Tue, Feb 05 2008 at 17:42 +0200, Alan Stern <stern@rowland.harvard.edu> wrote:
> On Tue, 5 Feb 2008, Boaz Harrosh wrote:
>
>>> However the interface to usb_stor_access_xfer_buf() will have to change
>>> slightly. Right now if it sees that *sgptr is NULL, it assumes this
>>> means it should start at the beginning of the s-g buffer. But with
>>> Boaz's change, *sgptr == NULL means the transfer has reached the end of
>>> the buffer. So I'll have to go through and audit all the callers.
>>>
>>> Alan Stern
>>>
>>> -
>> No it does not, this as not changed. Please look again.
>
> You look again. Your patched code goes like this:
>
> struct scatterlist *sg = *sgptr;
>
> if (!sg)
> sg = (struct scatterlist *) srb->request_buffer;
>
> Hence if *sgptr is NULL upon entry, it is taken to mean that the
> transfer should start at the beginning of the s-g buffer.
>
> /* This loop handles a single s-g list entry, which may
> * include multiple pages. Find the initial page structure
> * and the starting offset within the page, and update
> * the *offset and *index values for the next loop. */
> cnt = 0;
> while (cnt < buflen && sg) {
>
> Hence if sg is NULL, it indicates the end of the buffer has been
> reached. And then down near the end of the routine:
>
> *sgptr = sg;
>
> Hence if the end is reached and the caller makes another call to try
> transferring more data, the additional data will get stored back at the
> beginning of the buffer.
>
That behavior did not change. In the likely event of sg-length matching
bufflen the last call to sg_next will return NULL, and will be returned
in *sgptr. The end condition of an outside caller is either sum of
returned counts reaching some target count, or *sgptr return to NULL.
The code before the sg change would have *indexptr >= some_sg_count, but
now we do not have an index we have a pointer and the termination condition
is *sgptr == NULL.
So I guess you are afraid that calling code that was converted from index
to pointer, was done wrong, and where something did *indexptr >= some_sg_count
before, does not do *sgptr == NULL now.
So I guess, yes you are welcome to check. I did not do the conversion so
I can not comment.
>> Note that this patch was tested and working. It is a bug
>> in v2.2.24 and it should be accepted already. One way or
>> the other.
>>
>> Callers of usb_stor_access_xfer_buf() need not change.
>> Matthew Dharm should decide if he wants the WARN_ON in
>> usb_stor_set_xfer_buf() or not and be done with it.
>>
>> I have found and fixed the bug, but it is not a SCSI
>> related bug, and it is not do to any scsi changes. It
>> is a bug from the SG changes of early 2.6.24. Please
>> take it through the USB tree. Feel free to change it
>> the way you like it, and submit it.
>
> I will post a new version of this which handles all these issues.
> Expect it in a day or so.
>
Please do. Thanks, that would be better.
Don't forget to also submit a patch for current head-of-line. It's exactly
the same fix but has diff conflicts with surrounding code.
> Alan Stern
>
Boaz
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] bugfix for an underflow condition in usb storage & isd200.c
2008-02-04 20:05 ` Alan Stern
[not found] ` <Pine.LNX.4.44L0.0802041500420.5186-100000-IYeN2dnnYyZXsRXLowluHWD2FQJk+8+b@public.gmane.org>
@ 2008-02-05 17:54 ` Matthew Dharm
[not found] ` <20080205175403.GA31714-JGfshJpz5UybPZpvUQj5UqxOck334EZe@public.gmane.org>
1 sibling, 1 reply; 36+ messages in thread
From: Matthew Dharm @ 2008-02-05 17:54 UTC (permalink / raw)
To: Alan Stern
Cc: Boaz Harrosh, Mark Glines, James Bottomley, USB list, linux-scsi
[-- Attachment #1: Type: text/plain, Size: 1194 bytes --]
On Mon, Feb 04, 2008 at 03:05:58PM -0500, Alan Stern wrote:
> On Sun, 3 Feb 2008, Matthew Dharm wrote:
>
> I think the correct approach is to modify those routines so that they
> will never overrun the s-g buffer (like Boaz has done), and _document_
> this behavior. Then the callers can feel free to try and transfer as
> much as they want, knowing that an overrun can't occur. There won't
> be any need for a WARN_ON or anything else.
Six of one and a half-dozen of the other. All we're arguing over is the
definition of "correct behavior" here. You want to change the API so that
overrun is acceptable and handled; I prefer calling it a Bad Thing(tm).
We both agree that the code shouldn't run off the end of the s-g list.
Since you've already committed to updating the patch, then we can do it
your way. Just make sure it's very very clear in the comments.
Matt
--
Matthew Dharm Home: mdharm-usb@one-eyed-alien.net
Maintainer, Linux USB Mass Storage Driver
E: You run this ship with Windows?! YOU IDIOT!
L: Give me a break, it came bundled with the computer!
-- ESR and Lan Solaris
User Friendly, 12/8/1998
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] bugfix for an underflow condition in usb storage & isd200.c
[not found] ` <20080205175403.GA31714-JGfshJpz5UybPZpvUQj5UqxOck334EZe@public.gmane.org>
@ 2008-02-06 20:23 ` Alan Stern
2008-02-06 21:05 ` Matthew Dharm
2008-02-08 16:46 ` Alan Stern
1 sibling, 1 reply; 36+ messages in thread
From: Alan Stern @ 2008-02-06 20:23 UTC (permalink / raw)
To: Matthew Dharm
Cc: Boaz Harrosh, Mark Glines, James Bottomley, USB list, linux-scsi
On Tue, 5 Feb 2008, Matthew Dharm wrote:
> Six of one and a half-dozen of the other. All we're arguing over is the
> definition of "correct behavior" here. You want to change the API so that
> overrun is acceptable and handled; I prefer calling it a Bad Thing(tm).
>
> We both agree that the code shouldn't run off the end of the s-g list.
>
> Since you've already committed to updating the patch, then we can do it
> your way. Just make sure it's very very clear in the comments.
Okay, here's my version. It makes some significant changes to the
interface for usb_stor_access_xfer_buf() -- in particular, the context
information is now stored in an opaque structure rather than in ad-hoc
local variables. All the callers are updated to use the new interface.
Functionally it's almost the same as before. It's more careful about
not letting callers overrun the transfer buffer, and it can now set the
SCSI residue when a copy is finished.
This patch applies to 2.6.24. If it's acceptable I'll send a patch for
2.6.25-rc1 (once it has been released), complete with Changelog and
a Signed-off-by: line.
Note that this has been compile-tested only! Verification that it
works okay would be appreciated.
Alan Stern
Index: 2.6.24/drivers/usb/storage/protocol.h
===================================================================
--- 2.6.24.orig/drivers/usb/storage/protocol.h
+++ 2.6.24/drivers/usb/storage/protocol.h
@@ -48,13 +48,23 @@ extern void usb_stor_ufi_command(struct
extern void usb_stor_transparent_scsi_command(struct scsi_cmnd*,
struct us_data*);
-/* struct scsi_cmnd transfer buffer access utilities */
+/* Utility routines for accessing data in scsi_cmnd transfer buffers */
enum xfer_buf_dir {TO_XFER_BUF, FROM_XFER_BUF};
+struct xfer_buf_params {
+ struct scsi_cmnd *srb;
+ struct scatterlist *sg;
+ enum xfer_buf_dir dir;
+ unsigned int offset;
+ unsigned int count;
+};
+
+extern void usb_stor_init_xfer_buf(struct xfer_buf_params *xbp,
+ struct us_data *us, enum xfer_buf_dir dir);
extern unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
- unsigned int buflen, struct scsi_cmnd *srb, struct scatterlist **,
- unsigned int *offset, enum xfer_buf_dir dir);
+ unsigned int buflen, struct xfer_buf_params *xbp);
+extern void usb_stor_finish_xfer_buf(struct xfer_buf_params *xbp);
extern void usb_stor_set_xfer_buf(unsigned char *buffer,
- unsigned int buflen, struct scsi_cmnd *srb);
+ unsigned int buflen, struct us_data *us);
#endif
Index: 2.6.24/drivers/usb/storage/protocol.c
===================================================================
--- 2.6.24.orig/drivers/usb/storage/protocol.c
+++ 2.6.24/drivers/usb/storage/protocol.c
@@ -148,33 +148,66 @@ void usb_stor_transparent_scsi_command(s
* Scatter-gather transfer buffer access routines
***********************************************************************/
-/* Copy a buffer of length buflen to/from the srb's transfer buffer.
- * (Note: for scatter-gather transfers (srb->use_sg > 0), srb->request_buffer
- * points to a list of s-g entries and we ignore srb->request_bufflen.
- * For non-scatter-gather transfers, srb->request_buffer points to the
- * transfer buffer itself and srb->request_bufflen is the buffer's length.)
- * Update the *index and *offset variables so that the next copy will
- * pick up from where this one left off. */
+/* usb_stor_init_xfer_buf - initialize an xfer_buf_params structure
+ *
+ * Store in @xbp the values needed for accessing a transfer buffer
+ * through several calls to usb_stor_access_xfer_buf(). The sg
+ * and offset members are initialized to point to the start of the
+ * transfer buffer for @us->srb.
+ */
+void usb_stor_init_xfer_buf(struct xfer_buf_params *xbp,
+ struct us_data *us, enum xfer_buf_dir dir)
+{
+ xbp->srb = us->srb;
+ xbp->sg = (struct scatterlist *) xbp->srb->request_buffer;
+ xbp->dir = dir;
+ xbp->offset = 0;
+ xbp->count = 0;
+}
+/* usb_stor_access_xfer_buf - copy data to/from a scsi_cmnd's transfer buffer
+ *
+ * Copy data between @buffer and @xbp->srb's transfer buffer. Data
+ * can be copied incrementally through successive calls to this routine;
+ * each copy will pick up from the location in the transfer buffer where
+ * the previous call left off.
+ *
+ * The direction of the copy is as specified in usb_stor_init_xfer_buf(),
+ * which must have been called earlier.
+ *
+ * The amount of data to copy is given by @buflen, but it is limited
+ * by @xbp->srb->request_bufflen as well as by the total length of
+ * the scatter-gather buffers (if @xbp->srb uses scatter-gather).
+ * It's not an error for the caller to try copying too much data;
+ * when that happens only the data that fits will be copied.
+ *
+ * The sg and offset members of @xbp are updated to point to the next
+ * location in the transfer buffer. The count member is updated to
+ * keep track of the total number of bytes copied across multiple
+ * calls.
+ *
+ * Returns the number of bytes transferred in this call.
+ */
unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
- unsigned int buflen, struct scsi_cmnd *srb, struct scatterlist **sgptr,
- unsigned int *offset, enum xfer_buf_dir dir)
+ unsigned int buflen, struct xfer_buf_params *xbp)
{
unsigned int cnt;
- /* If not using scatter-gather, just transfer the data directly.
- * Make certain it will fit in the available buffer space. */
- if (srb->use_sg == 0) {
- if (*offset >= srb->request_bufflen)
- return 0;
- cnt = min(buflen, srb->request_bufflen - *offset);
- if (dir == TO_XFER_BUF)
- memcpy((unsigned char *) srb->request_buffer + *offset,
+ /* Make sure we don't try to copy too much data */
+ buflen = min(buflen, xbp->srb->request_bufflen - xbp->count);
+
+ /* If not using scatter-gather, just transfer the data directly */
+ if (xbp->srb->use_sg == 0) {
+ cnt = buflen;
+ if (xbp->dir == TO_XFER_BUF)
+ memcpy(xbp->offset + (unsigned char *)
+ xbp->srb->request_buffer,
buffer, cnt);
else
- memcpy(buffer, (unsigned char *) srb->request_buffer +
- *offset, cnt);
- *offset += cnt;
+ memcpy(buffer, xbp->offset + (unsigned char *)
+ xbp->srb->request_buffer, cnt);
+ xbp->offset += cnt;
+ }
/* Using scatter-gather. We have to go through the list one entry
* at a time. Each s-g entry contains some number of pages, and
@@ -183,34 +216,32 @@ unsigned int usb_stor_access_xfer_buf(un
* If the page is not directly accessible -- such as a user buffer
* located in high memory -- then kmap() will map it to a temporary
* position in the kernel's virtual address space. */
- } else {
- struct scatterlist *sg = *sgptr;
-
- if (!sg)
- sg = (struct scatterlist *) srb->request_buffer;
+ else {
/* This loop handles a single s-g list entry, which may
* include multiple pages. Find the initial page structure
* and the starting offset within the page, and update
* the *offset and *index values for the next loop. */
cnt = 0;
- while (cnt < buflen) {
- struct page *page = sg_page(sg) +
- ((sg->offset + *offset) >> PAGE_SHIFT);
+ while (cnt < buflen && xbp->sg) {
+ struct page *page = sg_page(xbp->sg) +
+ ((xbp->sg->offset + xbp->offset) >>
+ PAGE_SHIFT);
unsigned int poff =
- (sg->offset + *offset) & (PAGE_SIZE-1);
- unsigned int sglen = sg->length - *offset;
+ (xbp->sg->offset + xbp->offset) &
+ (PAGE_SIZE-1);
+ unsigned int sglen = xbp->sg->length - xbp->offset;
if (sglen > buflen - cnt) {
/* Transfer ends within this s-g entry */
sglen = buflen - cnt;
- *offset += sglen;
+ xbp->offset += sglen;
} else {
/* Transfer continues to next s-g entry */
- *offset = 0;
- sg = sg_next(sg);
+ xbp->offset = 0;
+ xbp->sg = sg_next(xbp->sg);
}
/* Transfer the data for all the pages in this
@@ -221,7 +252,7 @@ unsigned int usb_stor_access_xfer_buf(un
PAGE_SIZE - poff);
unsigned char *ptr = kmap(page);
- if (dir == TO_XFER_BUF)
+ if (xbp->dir == TO_XFER_BUF)
memcpy(ptr + poff, buffer + cnt, plen);
else
memcpy(buffer + cnt, ptr + poff, plen);
@@ -234,23 +265,31 @@ unsigned int usb_stor_access_xfer_buf(un
sglen -= plen;
}
}
- *sgptr = sg;
}
/* Return the amount actually transferred */
+ xbp->count += cnt;
return cnt;
}
+/* usb_stor_finish_xfer_buf - end a transfer buffer data copy
+ *
+ * Sets @xbp->srb->resid based on the total amount of data copied.
+ */
+void usb_stor_finish_xfer_buf(struct xfer_buf_params *xbp)
+{
+ if (xbp->count < xbp->srb->request_bufflen)
+ xbp->srb->resid = xbp->srb->request_bufflen - xbp->count;
+}
+
/* Store the contents of buffer into srb's transfer buffer and set the
* SCSI residue. */
void usb_stor_set_xfer_buf(unsigned char *buffer,
- unsigned int buflen, struct scsi_cmnd *srb)
+ unsigned int buflen, struct us_data *us)
{
- unsigned int offset = 0;
- struct scatterlist *sg = NULL;
+ struct xfer_buf_params xbp;
- usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
- TO_XFER_BUF);
- if (buflen < srb->request_bufflen)
- srb->resid = srb->request_bufflen - buflen;
+ usb_stor_init_xfer_buf(&xbp, us, TO_XFER_BUF);
+ usb_stor_access_xfer_buf(buffer, buflen, &xbp);
+ usb_stor_finish_xfer_buf(&xbp);
}
Index: 2.6.24/drivers/usb/storage/alauda.c
===================================================================
--- 2.6.24.orig/drivers/usb/storage/alauda.c
+++ 2.6.24/drivers/usb/storage/alauda.c
@@ -798,14 +798,14 @@ static int alauda_read_data(struct us_da
{
unsigned char *buffer;
u16 lba, max_lba;
- unsigned int page, len, offset;
+ unsigned int page, len;
unsigned int blockshift = MEDIA_INFO(us).blockshift;
unsigned int pageshift = MEDIA_INFO(us).pageshift;
unsigned int blocksize = MEDIA_INFO(us).blocksize;
unsigned int pagesize = MEDIA_INFO(us).pagesize;
unsigned int uzonesize = MEDIA_INFO(us).uzonesize;
- struct scatterlist *sg;
int result;
+ struct xfer_buf_params xbp;
/*
* Since we only read in one block at a time, we have to create
@@ -828,8 +828,7 @@ static int alauda_read_data(struct us_da
max_lba = MEDIA_INFO(us).capacity >> (blockshift + pageshift);
result = USB_STOR_TRANSPORT_GOOD;
- offset = 0;
- sg = NULL;
+ usb_stor_init_xfer_buf(&xbp, us, TO_XFER_BUF);
while (sectors > 0) {
unsigned int zone = lba / uzonesize; /* integer division */
@@ -874,13 +873,13 @@ static int alauda_read_data(struct us_da
}
/* Store the data in the transfer buffer */
- usb_stor_access_xfer_buf(buffer, len, us->srb,
- &sg, &offset, TO_XFER_BUF);
+ usb_stor_access_xfer_buf(buffer, len, &xbp);
page = 0;
lba++;
sectors -= pages;
}
+ usb_stor_finish_xfer_buf(&xbp);
kfree(buffer);
return result;
@@ -893,14 +892,14 @@ static int alauda_write_data(struct us_d
unsigned int sectors)
{
unsigned char *buffer, *blockbuffer;
- unsigned int page, len, offset;
+ unsigned int page, len;
unsigned int blockshift = MEDIA_INFO(us).blockshift;
unsigned int pageshift = MEDIA_INFO(us).pageshift;
unsigned int blocksize = MEDIA_INFO(us).blocksize;
unsigned int pagesize = MEDIA_INFO(us).pagesize;
- struct scatterlist *sg;
u16 lba, max_lba;
int result;
+ struct xfer_buf_params xbp;
/*
* Since we don't write the user data directly to the device,
@@ -932,8 +931,7 @@ static int alauda_write_data(struct us_d
max_lba = MEDIA_INFO(us).capacity >> (pageshift + blockshift);
result = USB_STOR_TRANSPORT_GOOD;
- offset = 0;
- sg = NULL;
+ usb_stor_init_xfer_buf(&xbp, us, FROM_XFER_BUF);
while (sectors > 0) {
/* Write as many sectors as possible in this block */
@@ -949,8 +947,7 @@ static int alauda_write_data(struct us_d
}
/* Get the data from the transfer buffer */
- usb_stor_access_xfer_buf(buffer, len, us->srb,
- &sg, &offset, FROM_XFER_BUF);
+ usb_stor_access_xfer_buf(buffer, len, &xbp);
result = alauda_write_lba(us, lba, page, pages, buffer,
blockbuffer);
@@ -961,6 +958,7 @@ static int alauda_write_data(struct us_d
lba++;
sectors -= pages;
}
+ usb_stor_finish_xfer_buf(&xbp);
kfree(buffer);
kfree(blockbuffer);
@@ -1053,7 +1051,7 @@ int alauda_transport(struct scsi_cmnd *s
((__be32 *) ptr)[0] = cpu_to_be32(capacity - 1);
((__be32 *) ptr)[1] = cpu_to_be32(512);
- usb_stor_set_xfer_buf(ptr, 8, srb);
+ usb_stor_set_xfer_buf(ptr, 8, us);
return USB_STOR_TRANSPORT_GOOD;
}
@@ -1102,7 +1100,7 @@ int alauda_transport(struct scsi_cmnd *s
ptr[7] = 11;
ptr[12] = info->sense_asc;
ptr[13] = info->sense_ascq;
- usb_stor_set_xfer_buf(ptr, 18, srb);
+ usb_stor_set_xfer_buf(ptr, 18, us);
return USB_STOR_TRANSPORT_GOOD;
}
Index: 2.6.24/drivers/usb/storage/datafab.c
===================================================================
--- 2.6.24.orig/drivers/usb/storage/datafab.c
+++ 2.6.24/drivers/usb/storage/datafab.c
@@ -98,8 +98,7 @@ static int datafab_read_data(struct us_d
unsigned char thistime;
unsigned int totallen, alloclen;
int len, result;
- unsigned int sg_offset = 0;
- struct scatterlist *sg = NULL;
+ struct xfer_buf_params xbp;
// we're working in LBA mode. according to the ATA spec,
// we can support up to 28-bit addressing. I don't know if Datafab
@@ -126,6 +125,7 @@ static int datafab_read_data(struct us_d
if (buffer == NULL)
return USB_STOR_TRANSPORT_ERROR;
+ usb_stor_init_xfer_buf(&xbp, us, TO_XFER_BUF);
do {
// loop, never allocate or transfer more than 64k at once
// (min(128k, 255*info->ssize) is the real limit)
@@ -155,13 +155,13 @@ static int datafab_read_data(struct us_d
goto leave;
// Store the data in the transfer buffer
- usb_stor_access_xfer_buf(buffer, len, us->srb,
- &sg, &sg_offset, TO_XFER_BUF);
+ usb_stor_access_xfer_buf(buffer, len, &xbp);
sector += thistime;
totallen -= len;
} while (totallen > 0);
+ usb_stor_finish_xfer_buf(&xbp);
kfree(buffer);
return USB_STOR_TRANSPORT_GOOD;
@@ -182,8 +182,7 @@ static int datafab_write_data(struct us_
unsigned char thistime;
unsigned int totallen, alloclen;
int len, result;
- unsigned int sg_offset = 0;
- struct scatterlist *sg = NULL;
+ struct xfer_buf_params xbp;
// we're working in LBA mode. according to the ATA spec,
// we can support up to 28-bit addressing. I don't know if Datafab
@@ -210,6 +209,7 @@ static int datafab_write_data(struct us_
if (buffer == NULL)
return USB_STOR_TRANSPORT_ERROR;
+ usb_stor_init_xfer_buf(&xbp, us, FROM_XFER_BUF);
do {
// loop, never allocate or transfer more than 64k at once
// (min(128k, 255*info->ssize) is the real limit)
@@ -218,8 +218,7 @@ static int datafab_write_data(struct us_
thistime = (len / info->ssize) & 0xff;
// Get the data from the transfer buffer
- usb_stor_access_xfer_buf(buffer, len, us->srb,
- &sg, &sg_offset, FROM_XFER_BUF);
+ usb_stor_access_xfer_buf(buffer, len, &xbp);
command[0] = 0;
command[1] = thistime;
@@ -259,6 +258,7 @@ static int datafab_write_data(struct us_
totallen -= len;
} while (totallen > 0);
+ usb_stor_finish_xfer_buf(&xbp);
kfree(buffer);
return USB_STOR_TRANSPORT_GOOD;
@@ -488,7 +488,7 @@ static int datafab_handle_mode_sense(str
ptr[0] = i - 1;
else
((__be16 *) ptr)[0] = cpu_to_be16(i - 2);
- usb_stor_set_xfer_buf(ptr, i, srb);
+ usb_stor_set_xfer_buf(ptr, i, us);
return USB_STOR_TRANSPORT_GOOD;
}
@@ -545,7 +545,7 @@ int datafab_transport(struct scsi_cmnd *
// we need the last sector, not the number of sectors
((__be32 *) ptr)[0] = cpu_to_be32(info->sectors - 1);
((__be32 *) ptr)[1] = cpu_to_be32(info->ssize);
- usb_stor_set_xfer_buf(ptr, 8, srb);
+ usb_stor_set_xfer_buf(ptr, 8, us);
return USB_STOR_TRANSPORT_GOOD;
}
@@ -621,7 +621,7 @@ int datafab_transport(struct scsi_cmnd *
ptr[7] = 11;
ptr[12] = info->sense_asc;
ptr[13] = info->sense_ascq;
- usb_stor_set_xfer_buf(ptr, 18, srb);
+ usb_stor_set_xfer_buf(ptr, 18, us);
return USB_STOR_TRANSPORT_GOOD;
}
Index: 2.6.24/drivers/usb/storage/isd200.c
===================================================================
--- 2.6.24.orig/drivers/usb/storage/isd200.c
+++ 2.6.24/drivers/usb/storage/isd200.c
@@ -1248,7 +1248,7 @@ static int isd200_scsi_to_ata(struct scs
/* copy InquiryData */
usb_stor_set_xfer_buf((unsigned char *) &info->InquiryData,
- sizeof(info->InquiryData), srb);
+ sizeof(info->InquiryData), us);
srb->result = SAM_STAT_GOOD;
sendToTransport = 0;
break;
@@ -1257,7 +1257,7 @@ static int isd200_scsi_to_ata(struct scs
US_DEBUGP(" ATA OUT - SCSIOP_MODE_SENSE\n");
/* Initialize the return buffer */
- usb_stor_set_xfer_buf(senseData, sizeof(senseData), srb);
+ usb_stor_set_xfer_buf(senseData, sizeof(senseData), us);
if (info->DeviceFlags & DF_MEDIA_STATUS_ENABLED)
{
@@ -1310,7 +1310,7 @@ static int isd200_scsi_to_ata(struct scs
readCapacityData.BytesPerBlock = cpu_to_be32(0x200);
usb_stor_set_xfer_buf((unsigned char *) &readCapacityData,
- sizeof(readCapacityData), srb);
+ sizeof(readCapacityData), us);
srb->result = SAM_STAT_GOOD;
sendToTransport = 0;
}
Index: 2.6.24/drivers/usb/storage/jumpshot.c
===================================================================
--- 2.6.24.orig/drivers/usb/storage/jumpshot.c
+++ 2.6.24/drivers/usb/storage/jumpshot.c
@@ -119,8 +119,7 @@ static int jumpshot_read_data(struct us_
unsigned char thistime;
unsigned int totallen, alloclen;
int len, result;
- unsigned int sg_offset = 0;
- struct scatterlist *sg = NULL;
+ struct xfer_buf_params xbp;
// we're working in LBA mode. according to the ATA spec,
// we can support up to 28-bit addressing. I don't know if Jumpshot
@@ -141,6 +140,7 @@ static int jumpshot_read_data(struct us_
if (buffer == NULL)
return USB_STOR_TRANSPORT_ERROR;
+ usb_stor_init_xfer_buf(&xbp, us, TO_XFER_BUF);
do {
// loop, never allocate or transfer more than 64k at once
// (min(128k, 255*info->ssize) is the real limit)
@@ -170,13 +170,13 @@ static int jumpshot_read_data(struct us_
US_DEBUGP("jumpshot_read_data: %d bytes\n", len);
// Store the data in the transfer buffer
- usb_stor_access_xfer_buf(buffer, len, us->srb,
- &sg, &sg_offset, TO_XFER_BUF);
+ usb_stor_access_xfer_buf(buffer, len, &xbp);
sector += thistime;
totallen -= len;
} while (totallen > 0);
+ usb_stor_finish_xfer_buf(&xbp);
kfree(buffer);
return USB_STOR_TRANSPORT_GOOD;
@@ -196,8 +196,7 @@ static int jumpshot_write_data(struct us
unsigned char thistime;
unsigned int totallen, alloclen;
int len, result, waitcount;
- unsigned int sg_offset = 0;
- struct scatterlist *sg = NULL;
+ struct xfer_buf_params xbp;
// we're working in LBA mode. according to the ATA spec,
// we can support up to 28-bit addressing. I don't know if Jumpshot
@@ -218,6 +217,7 @@ static int jumpshot_write_data(struct us
if (buffer == NULL)
return USB_STOR_TRANSPORT_ERROR;
+ usb_stor_init_xfer_buf(&xbp, us, FROM_XFER_BUF);
do {
// loop, never allocate or transfer more than 64k at once
// (min(128k, 255*info->ssize) is the real limit)
@@ -226,8 +226,7 @@ static int jumpshot_write_data(struct us
thistime = (len / info->ssize) & 0xff;
// Get the data from the transfer buffer
- usb_stor_access_xfer_buf(buffer, len, us->srb,
- &sg, &sg_offset, FROM_XFER_BUF);
+ usb_stor_access_xfer_buf(buffer, len, &xbp);
command[0] = 0;
command[1] = thistime;
@@ -269,6 +268,7 @@ static int jumpshot_write_data(struct us
totallen -= len;
} while (totallen > 0);
+ usb_stor_finish_xfer_buf(&xbp);
kfree(buffer);
return result;
@@ -415,7 +415,7 @@ static int jumpshot_handle_mode_sense(st
ptr[0] = i - 1;
else
((__be16 *) ptr)[0] = cpu_to_be16(i - 2);
- usb_stor_set_xfer_buf(ptr, i, srb);
+ usb_stor_set_xfer_buf(ptr, i, us);
return USB_STOR_TRANSPORT_GOOD;
}
@@ -477,7 +477,7 @@ int jumpshot_transport(struct scsi_cmnd
//
((__be32 *) ptr)[0] = cpu_to_be32(info->sectors - 1);
((__be32 *) ptr)[1] = cpu_to_be32(info->ssize);
- usb_stor_set_xfer_buf(ptr, 8, srb);
+ usb_stor_set_xfer_buf(ptr, 8, us);
return USB_STOR_TRANSPORT_GOOD;
}
@@ -548,7 +548,7 @@ int jumpshot_transport(struct scsi_cmnd
ptr[7] = 11;
ptr[12] = info->sense_asc;
ptr[13] = info->sense_ascq;
- usb_stor_set_xfer_buf(ptr, 18, srb);
+ usb_stor_set_xfer_buf(ptr, 18, us);
return USB_STOR_TRANSPORT_GOOD;
}
Index: 2.6.24/drivers/usb/storage/sddr09.c
===================================================================
--- 2.6.24.orig/drivers/usb/storage/sddr09.c
+++ 2.6.24/drivers/usb/storage/sddr09.c
@@ -705,9 +705,9 @@ sddr09_read_data(struct us_data *us,
unsigned char *buffer;
unsigned int lba, maxlba, pba;
unsigned int page, pages;
- unsigned int len, offset;
- struct scatterlist *sg;
+ unsigned int len;
int result;
+ struct xfer_buf_params xbp;
// Figure out the initial LBA and page
lba = address >> info->blockshift;
@@ -731,8 +731,7 @@ sddr09_read_data(struct us_data *us,
// contiguous LBA's. Another exercise left to the student.
result = 0;
- offset = 0;
- sg = NULL;
+ usb_stor_init_xfer_buf(&xbp, us, TO_XFER_BUF);
while (sectors > 0) {
@@ -778,14 +777,14 @@ sddr09_read_data(struct us_data *us,
}
// Store the data in the transfer buffer
- usb_stor_access_xfer_buf(buffer, len, us->srb,
- &sg, &offset, TO_XFER_BUF);
+ usb_stor_access_xfer_buf(buffer, len, &xbp);
page = 0;
lba++;
sectors -= pages;
}
+ usb_stor_finish_xfer_buf(&xbp);
kfree(buffer);
return result;
}
@@ -933,9 +932,9 @@ sddr09_write_data(struct us_data *us,
unsigned int pagelen, blocklen;
unsigned char *blockbuffer;
unsigned char *buffer;
- unsigned int len, offset;
- struct scatterlist *sg;
+ unsigned int len;
int result;
+ struct xfer_buf_params xbp;
// Figure out the initial LBA and page
lba = address >> info->blockshift;
@@ -971,8 +970,7 @@ sddr09_write_data(struct us_data *us,
}
result = 0;
- offset = 0;
- sg = NULL;
+ usb_stor_init_xfer_buf(&xbp, us, FROM_XFER_BUF);
while (sectors > 0) {
@@ -990,8 +988,7 @@ sddr09_write_data(struct us_data *us,
}
// Get the data from the transfer buffer
- usb_stor_access_xfer_buf(buffer, len, us->srb,
- &sg, &offset, FROM_XFER_BUF);
+ usb_stor_access_xfer_buf(buffer, len, &xbp);
result = sddr09_write_lba(us, lba, page, pages,
buffer, blockbuffer);
@@ -1003,6 +1000,7 @@ sddr09_write_data(struct us_data *us,
sectors -= pages;
}
+ usb_stor_finish_xfer_buf(&xbp);
kfree(buffer);
kfree(blockbuffer);
@@ -1480,7 +1478,7 @@ int sddr09_transport(struct scsi_cmnd *s
ptr[2] = sensekey;
ptr[7] = 11;
ptr[12] = sensecode;
- usb_stor_set_xfer_buf(ptr, 18, srb);
+ usb_stor_set_xfer_buf(ptr, 18, us);
sensekey = sensecode = havefakesense = 0;
return USB_STOR_TRANSPORT_GOOD;
}
@@ -1532,7 +1530,7 @@ int sddr09_transport(struct scsi_cmnd *s
// Report page size
((__be32 *) ptr)[1] = cpu_to_be32(info->pagesize);
- usb_stor_set_xfer_buf(ptr, 8, srb);
+ usb_stor_set_xfer_buf(ptr, 8, us);
return USB_STOR_TRANSPORT_GOOD;
}
@@ -1550,7 +1548,7 @@ int sddr09_transport(struct scsi_cmnd *s
memcpy(ptr, mode_page_01, sizeof(mode_page_01));
((__be16*)ptr)[0] = cpu_to_be16(sizeof(mode_page_01) - 2);
ptr[3] = (info->flags & SDDR09_WP) ? 0x80 : 0;
- usb_stor_set_xfer_buf(ptr, sizeof(mode_page_01), srb);
+ usb_stor_set_xfer_buf(ptr, sizeof(mode_page_01), us);
return USB_STOR_TRANSPORT_GOOD;
}
Index: 2.6.24/drivers/usb/storage/sddr55.c
===================================================================
--- 2.6.24.orig/drivers/usb/storage/sddr55.c
+++ 2.6.24/drivers/usb/storage/sddr55.c
@@ -167,8 +167,8 @@ static int sddr55_read_data(struct us_da
unsigned long address;
unsigned short pages;
- unsigned int len, offset;
- struct scatterlist *sg;
+ unsigned int len;
+ struct xfer_buf_params xbp;
// Since we only read in one block at a time, we have to create
// a bounce buffer and move the data a piece at a time between the
@@ -179,8 +179,7 @@ static int sddr55_read_data(struct us_da
buffer = kmalloc(len, GFP_NOIO);
if (buffer == NULL)
return USB_STOR_TRANSPORT_ERROR; /* out of memory */
- offset = 0;
- sg = NULL;
+ usb_stor_init_xfer_buf(&xbp, us, TO_XFER_BUF);
while (sectors>0) {
@@ -256,14 +255,14 @@ static int sddr55_read_data(struct us_da
}
// Store the data in the transfer buffer
- usb_stor_access_xfer_buf(buffer, len, us->srb,
- &sg, &offset, TO_XFER_BUF);
+ usb_stor_access_xfer_buf(buffer, len, &xbp);
page = 0;
lba++;
sectors -= pages >> info->smallpageshift;
}
+ usb_stor_finish_xfer_buf(&xbp);
result = USB_STOR_TRANSPORT_GOOD;
leave:
@@ -289,8 +288,8 @@ static int sddr55_write_data(struct us_d
unsigned short pages;
int i;
- unsigned int len, offset;
- struct scatterlist *sg;
+ unsigned int len;
+ struct xfer_buf_params xbp;
/* check if we are allowed to write */
if (info->read_only || info->force_read_only) {
@@ -307,8 +306,7 @@ static int sddr55_write_data(struct us_d
buffer = kmalloc(len, GFP_NOIO);
if (buffer == NULL)
return USB_STOR_TRANSPORT_ERROR;
- offset = 0;
- sg = NULL;
+ usb_stor_init_xfer_buf(&xbp, us, FROM_XFER_BUF);
while (sectors > 0) {
@@ -325,8 +323,7 @@ static int sddr55_write_data(struct us_d
len = pages << info->pageshift;
// Get the data from the transfer buffer
- usb_stor_access_xfer_buf(buffer, len, us->srb,
- &sg, &offset, FROM_XFER_BUF);
+ usb_stor_access_xfer_buf(buffer, len, &xbp);
US_DEBUGP("Write %02X pages, to PBA %04X"
" (LBA %04X) page %02X\n",
@@ -472,6 +469,7 @@ static int sddr55_write_data(struct us_d
sectors -= pages >> info->smallpageshift;
}
result = USB_STOR_TRANSPORT_GOOD;
+ usb_stor_finish_xfer_buf(&xbp);
leave:
kfree(buffer);
@@ -770,7 +768,7 @@ int sddr55_transport(struct scsi_cmnd *s
memcpy (ptr, info->sense_data, sizeof info->sense_data);
ptr[0] = 0x70;
ptr[7] = 11;
- usb_stor_set_xfer_buf (ptr, sizeof info->sense_data, srb);
+ usb_stor_set_xfer_buf(ptr, sizeof info->sense_data, us);
memset (info->sense_data, 0, sizeof info->sense_data);
return USB_STOR_TRANSPORT_GOOD;
@@ -835,7 +833,7 @@ int sddr55_transport(struct scsi_cmnd *s
((__be32 *) ptr)[0] = cpu_to_be32(capacity);
((__be32 *) ptr)[1] = cpu_to_be32(PAGESIZE);
- usb_stor_set_xfer_buf(ptr, 8, srb);
+ usb_stor_set_xfer_buf(ptr, 8, us);
sddr55_read_map(us);
@@ -846,7 +844,7 @@ int sddr55_transport(struct scsi_cmnd *s
memcpy(ptr, mode_page_01, sizeof mode_page_01);
ptr[3] = (info->read_only || info->force_read_only) ? 0x80 : 0;
- usb_stor_set_xfer_buf(ptr, sizeof(mode_page_01), srb);
+ usb_stor_set_xfer_buf(ptr, sizeof(mode_page_01), us);
if ( (srb->cmnd[2] & 0x3F) == 0x01 ) {
US_DEBUGP(
Index: 2.6.24/drivers/usb/storage/shuttle_usbat.c
===================================================================
--- 2.6.24.orig/drivers/usb/storage/shuttle_usbat.c
+++ 2.6.24/drivers/usb/storage/shuttle_usbat.c
@@ -993,8 +993,7 @@ static int usbat_flash_read_data(struct
unsigned char thistime;
unsigned int totallen, alloclen;
int len, result;
- unsigned int sg_offset = 0;
- struct scatterlist *sg = NULL;
+ struct xfer_buf_params xbp;
result = usbat_flash_check_media(us, info);
if (result != USB_STOR_TRANSPORT_GOOD)
@@ -1023,6 +1022,7 @@ static int usbat_flash_read_data(struct
if (buffer == NULL)
return USB_STOR_TRANSPORT_ERROR;
+ usb_stor_init_xfer_buf(&xbp, us, TO_XFER_BUF);
do {
/*
* loop, never allocate or transfer more than 64k at once
@@ -1047,13 +1047,13 @@ static int usbat_flash_read_data(struct
US_DEBUGP("usbat_flash_read_data: %d bytes\n", len);
/* Store the data in the transfer buffer */
- usb_stor_access_xfer_buf(buffer, len, us->srb,
- &sg, &sg_offset, TO_XFER_BUF);
+ usb_stor_access_xfer_buf(buffer, len, &xbp);
sector += thistime;
totallen -= len;
} while (totallen > 0);
+ usb_stor_finish_xfer_buf(&xbp);
kfree(buffer);
return USB_STOR_TRANSPORT_GOOD;
@@ -1084,8 +1084,7 @@ static int usbat_flash_write_data(struct
unsigned char thistime;
unsigned int totallen, alloclen;
int len, result;
- unsigned int sg_offset = 0;
- struct scatterlist *sg = NULL;
+ struct xfer_buf_params xbp;
result = usbat_flash_check_media(us, info);
if (result != USB_STOR_TRANSPORT_GOOD)
@@ -1114,6 +1113,7 @@ static int usbat_flash_write_data(struct
if (buffer == NULL)
return USB_STOR_TRANSPORT_ERROR;
+ usb_stor_init_xfer_buf(&xbp, us, FROM_XFER_BUF);
do {
/*
* loop, never allocate or transfer more than 64k at once
@@ -1123,8 +1123,7 @@ static int usbat_flash_write_data(struct
thistime = (len / info->ssize) & 0xff;
/* Get the data from the transfer buffer */
- usb_stor_access_xfer_buf(buffer, len, us->srb,
- &sg, &sg_offset, FROM_XFER_BUF);
+ usb_stor_access_xfer_buf(buffer, len, &xbp);
/* ATA command 0x30 (WRITE SECTORS) */
usbat_pack_ata_sector_cmd(command, thistime, sector, 0x30);
@@ -1143,6 +1142,7 @@ static int usbat_flash_write_data(struct
totallen -= len;
} while (totallen > 0);
+ usb_stor_finish_xfer_buf(&xbp);
kfree(buffer);
return result;
@@ -1164,8 +1164,7 @@ static int usbat_hp8200e_handle_read10(s
unsigned char *buffer;
unsigned int len;
unsigned int sector;
- unsigned int sg_offset = 0;
- struct scatterlist *sg = NULL;
+ struct xfer_buf_params xbp;
US_DEBUGP("handle_read10: transfersize %d\n",
srb->transfersize);
@@ -1222,6 +1221,7 @@ static int usbat_hp8200e_handle_read10(s
sector |= short_pack(data[7+5], data[7+4]);
transferred = 0;
+ usb_stor_init_xfer_buf(&xbp, us, TO_XFER_BUF);
while (transferred != srb->request_bufflen) {
if (len > srb->request_bufflen - transferred)
@@ -1253,8 +1253,7 @@ static int usbat_hp8200e_handle_read10(s
break;
/* Store the data in the transfer buffer */
- usb_stor_access_xfer_buf(buffer, len, srb,
- &sg, &sg_offset, TO_XFER_BUF);
+ usb_stor_access_xfer_buf(buffer, len, &xbp);
/* Update the amount transferred and the sector number */
@@ -1263,6 +1262,7 @@ static int usbat_hp8200e_handle_read10(s
} /* while transferred != srb->request_bufflen */
+ usb_stor_finish_xfer_buf(&xbp);
kfree(buffer);
return result;
}
@@ -1603,7 +1603,7 @@ static int usbat_flash_transport(struct
*/
((__be32 *) ptr)[0] = cpu_to_be32(info->sectors - 1);
((__be32 *) ptr)[1] = cpu_to_be32(info->ssize);
- usb_stor_set_xfer_buf(ptr, 8, srb);
+ usb_stor_set_xfer_buf(ptr, 8, us);
return USB_STOR_TRANSPORT_GOOD;
}
@@ -1681,7 +1681,7 @@ static int usbat_flash_transport(struct
ptr[7] = 11;
ptr[12] = info->sense_asc;
ptr[13] = info->sense_ascq;
- usb_stor_set_xfer_buf(ptr, 18, srb);
+ usb_stor_set_xfer_buf(ptr, 18, us);
return USB_STOR_TRANSPORT_GOOD;
}
Index: 2.6.24/drivers/usb/storage/usb.c
===================================================================
--- 2.6.24.orig/drivers/usb/storage/usb.c
+++ 2.6.24/drivers/usb/storage/usb.c
@@ -299,7 +299,7 @@ void fill_inquiry_response(struct us_dat
data[35] = 0x30 + ((bcdDevice) & 0x0F);
}
- usb_stor_set_xfer_buf(data, data_len, us->srb);
+ usb_stor_set_xfer_buf(data, data_len, us);
}
static int usb_stor_control_thread(void * __us)
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] bugfix for an underflow condition in usb storage & isd200.c
2008-02-06 20:23 ` Alan Stern
@ 2008-02-06 21:05 ` Matthew Dharm
2008-02-06 22:18 ` Alan Stern
0 siblings, 1 reply; 36+ messages in thread
From: Matthew Dharm @ 2008-02-06 21:05 UTC (permalink / raw)
To: Alan Stern
Cc: Boaz Harrosh, Mark Glines, James Bottomley, USB list, linux-scsi
[-- Attachment #1: Type: text/plain, Size: 1329 bytes --]
On Wed, Feb 06, 2008 at 03:23:39PM -0500, Alan Stern wrote:
> On Tue, 5 Feb 2008, Matthew Dharm wrote:
>
> > Six of one and a half-dozen of the other. All we're arguing over is the
> > definition of "correct behavior" here. You want to change the API so that
> > overrun is acceptable and handled; I prefer calling it a Bad Thing(tm).
> >
> > We both agree that the code shouldn't run off the end of the s-g list.
> >
> > Since you've already committed to updating the patch, then we can do it
> > your way. Just make sure it's very very clear in the comments.
>
> Okay, here's my version. It makes some significant changes to the
> interface for usb_stor_access_xfer_buf() -- in particular, the context
> information is now stored in an opaque structure rather than in ad-hoc
> local variables. All the callers are updated to use the new interface.
Maybe this is a crazy question, but...
Why is this not in the SCSI core? It's hardly USB-specific, and I'm
willing to bet that there are other HCDs (at least spb2) which need to do
this sort of thing...
Matt
--
Matthew Dharm Home: mdharm-usb@one-eyed-alien.net
Maintainer, Linux USB Mass Storage Driver
YOU SEE!!?? It's like being born with only one nipple!
-- Erwin
User Friendly, 10/19/1998
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] bugfix for an underflow condition in usb storage & isd200.c
2008-02-06 21:05 ` Matthew Dharm
@ 2008-02-06 22:18 ` Alan Stern
2008-02-06 23:01 ` James Bottomley
0 siblings, 1 reply; 36+ messages in thread
From: Alan Stern @ 2008-02-06 22:18 UTC (permalink / raw)
To: James Bottomley, Matthew Dharm
Cc: Boaz Harrosh, Mark Glines, USB list, linux-scsi
On Wed, 6 Feb 2008, Matthew Dharm wrote:
> Maybe this is a crazy question, but...
>
> Why is this not in the SCSI core?
Or even in the block core?
> It's hardly USB-specific, and I'm
> willing to bet that there are other HCDs (at least spb2) which need to do
> this sort of thing...
James, do you have any idea?
What we're talking about is a routine that provides drivers a simple
way to access the data in a scatter-gather buffer (which may lie in
highmem or otherwise not be easily reachable). The idea is that some
commands are emulated by the driver rather than carried out by the
device, and the driver needs some way to stick the results in the
transfer buffer.
Alan Stern
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] bugfix for an underflow condition in usb storage & isd200.c
2008-02-06 22:18 ` Alan Stern
@ 2008-02-06 23:01 ` James Bottomley
[not found] ` <1202338869.3112.138.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
0 siblings, 1 reply; 36+ messages in thread
From: James Bottomley @ 2008-02-06 23:01 UTC (permalink / raw)
To: Alan Stern; +Cc: Matthew Dharm, Boaz Harrosh, Mark Glines, USB list, linux-scsi
On Wed, 2008-02-06 at 17:18 -0500, Alan Stern wrote:
> On Wed, 6 Feb 2008, Matthew Dharm wrote:
>
> > Maybe this is a crazy question, but...
> >
> > Why is this not in the SCSI core?
>
> Or even in the block core?
>
> > It's hardly USB-specific, and I'm
> > willing to bet that there are other HCDs (at least spb2) which need to do
> > this sort of thing...
>
> James, do you have any idea?
>
> What we're talking about is a routine that provides drivers a simple
> way to access the data in a scatter-gather buffer (which may lie in
> highmem or otherwise not be easily reachable). The idea is that some
> commands are emulated by the driver rather than carried out by the
> device, and the driver needs some way to stick the results in the
> transfer buffer.
Isn't that what scsi_kmap_sg() is designed for ... or do you need
something slightly different?
James
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] bugfix for an underflow condition in usb storage & isd200.c
[not found] ` <1202338869.3112.138.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
@ 2008-02-06 23:25 ` Alan Stern
2008-02-06 23:55 ` James Bottomley
0 siblings, 1 reply; 36+ messages in thread
From: Alan Stern @ 2008-02-06 23:25 UTC (permalink / raw)
To: James Bottomley
Cc: Matthew Dharm, Boaz Harrosh, Mark Glines, USB list, linux-scsi
On Wed, 6 Feb 2008, James Bottomley wrote:
> > What we're talking about is a routine that provides drivers a simple
> > way to access the data in a scatter-gather buffer (which may lie in
> > highmem or otherwise not be easily reachable). The idea is that some
> > commands are emulated by the driver rather than carried out by the
> > device, and the driver needs some way to stick the results in the
> > transfer buffer.
>
> Isn't that what scsi_kmap_sg() is designed for ... or do you need
> something slightly different?
I don't know -- I've never heard of scsi_kmap_sg(). And it doesn't
appear to exist anywhere in my kernel source.
Did you mean scsi_kmap_atomic_sg()? That appears to do only part of
what usb_stor_access_xfer_buf() does. In fact, all it does is map a
single page.
Alan Stern
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] bugfix for an underflow condition in usb storage & isd200.c
2008-02-06 23:25 ` Alan Stern
@ 2008-02-06 23:55 ` James Bottomley
[not found] ` <1202342108.3112.146.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
0 siblings, 1 reply; 36+ messages in thread
From: James Bottomley @ 2008-02-06 23:55 UTC (permalink / raw)
To: Alan Stern; +Cc: Matthew Dharm, Boaz Harrosh, Mark Glines, USB list, linux-scsi
On Wed, 2008-02-06 at 18:25 -0500, Alan Stern wrote:
> On Wed, 6 Feb 2008, James Bottomley wrote:
>
> > > What we're talking about is a routine that provides drivers a simple
> > > way to access the data in a scatter-gather buffer (which may lie in
> > > highmem or otherwise not be easily reachable). The idea is that some
> > > commands are emulated by the driver rather than carried out by the
> > > device, and the driver needs some way to stick the results in the
> > > transfer buffer.
> >
> > Isn't that what scsi_kmap_sg() is designed for ... or do you need
> > something slightly different?
>
> I don't know -- I've never heard of scsi_kmap_sg(). And it doesn't
> appear to exist anywhere in my kernel source.
>
> Did you mean scsi_kmap_atomic_sg()?
Yes .. I replied from memory rather than looking in the source.
> That appears to do only part of
> what usb_stor_access_xfer_buf() does. In fact, all it does is map a
> single page.
Um, it does everything you asked about above. It's designed as a helper
for SCSI devices that need to modify data for automatically generated
returns (RAID devices and INQUIRY strings for instance). It's also used
by some of the less well automated devices that might need to do an
effective PIO feed on DMA engine halts. It allows you to address a sg
list by offset and length (although it will adjust the length if there's
a mapping problem). Since the only way to guarantee access to highmem
is by kmap_atomic (which has limited slots), any API that does this sort
of thing is necessarily page based and does single page mappings at a
time. Why don't you tell me what you think is missing rather than me
having to dig around in the usb sources to try to work it out.
James
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] bugfix for an underflow condition in usb storage & isd200.c
[not found] ` <1202342108.3112.146.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
@ 2008-02-07 16:35 ` Alan Stern
0 siblings, 0 replies; 36+ messages in thread
From: Alan Stern @ 2008-02-07 16:35 UTC (permalink / raw)
To: James Bottomley
Cc: Matthew Dharm, Boaz Harrosh, Mark Glines, USB list, linux-scsi
On Wed, 6 Feb 2008, James Bottomley wrote:
> > Did you mean scsi_kmap_atomic_sg()?
>
> Yes .. I replied from memory rather than looking in the source.
>
> > That appears to do only part of
> > what usb_stor_access_xfer_buf() does. In fact, all it does is map a
> > single page.
>
> Um, it does everything you asked about above. It's designed as a helper
> for SCSI devices that need to modify data for automatically generated
> returns (RAID devices and INQUIRY strings for instance). It's also used
> by some of the less well automated devices that might need to do an
> effective PIO feed on DMA engine halts. It allows you to address a sg
> list by offset and length (although it will adjust the length if there's
> a mapping problem). Since the only way to guarantee access to highmem
> is by kmap_atomic (which has limited slots), any API that does this sort
> of thing is necessarily page based and does single page mappings at a
> time. Why don't you tell me what you think is missing rather than me
> having to dig around in the usb sources to try to work it out.
Sure. The USB routine takes as arguments a pointer to a memory buffer,
a length, a scsi_cmnd, an offset value, and a direction flag. It
copies data between the memory buffer and the scsi_cmnd's transfer
buffer, starting at the specified offset in the transfer buffer. It
works regardless of whether use_sg is 0 in the scsi_cmnd, by mapping
the pages in the scatter-gather list one at a time (if use_sg > 0) and
looping over these pages as needed. It also updates the offset value
so that a subsequent call will pick up from where the current call left
off, allowing a large transfer buffer to be read/written in multiple
smaller increments.
The added value here is that the USB routine automatically keeps track
of all the details and automatically does the copying. The caller
doesn't have to worry about anything other than supplying the memory
buffer and the length.
Comparing the USB routine with the SCSI routine shows one potential
weakness: The USB routine uses kmap() and not kmap_atomic(). Perhaps
it should call scsi_kmap_atomic_sg() to do that part of its work. (And
perhaps the whole thing should be moved into the SCSI core.)
Alan Stern
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] bugfix for an underflow condition in usb storage & isd200.c
[not found] ` <20080205175403.GA31714-JGfshJpz5UybPZpvUQj5UqxOck334EZe@public.gmane.org>
2008-02-06 20:23 ` Alan Stern
@ 2008-02-08 16:46 ` Alan Stern
[not found] ` <Pine.LNX.4.44L0.0802081143010.4593-100000-IYeN2dnnYyZXsRXLowluHWD2FQJk+8+b@public.gmane.org>
1 sibling, 1 reply; 36+ messages in thread
From: Alan Stern @ 2008-02-08 16:46 UTC (permalink / raw)
To: Matthew Dharm
Cc: Boaz Harrosh, Mark Glines, James Bottomley, USB list, linux-scsi
On Tue, 5 Feb 2008, Matthew Dharm wrote:
> We both agree that the code shouldn't run off the end of the s-g list.
Incidentally, if people want a simple bugfix patch for 2.6.24.stable,
this should do it. Mark, can you confirm that this patch alone fixes
the problem?
Alan Stern
Index: 2.6.24/drivers/usb/storage/protocol.c
===================================================================
--- 2.6.24.orig/drivers/usb/storage/protocol.c
+++ 2.6.24/drivers/usb/storage/protocol.c
@@ -194,7 +194,7 @@ unsigned int usb_stor_access_xfer_buf(un
* and the starting offset within the page, and update
* the *offset and *index values for the next loop. */
cnt = 0;
- while (cnt < buflen) {
+ while (cnt < buflen && sg) {
struct page *page = sg_page(sg) +
((sg->offset + *offset) >> PAGE_SHIFT);
unsigned int poff =
@@ -249,6 +249,7 @@ void usb_stor_set_xfer_buf(unsigned char
unsigned int offset = 0;
struct scatterlist *sg = NULL;
+ buflen = min(buflen, srb->request_bufflen);
usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
TO_XFER_BUF);
if (buflen < srb->request_bufflen)
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] bugfix for an underflow condition in usb storage & isd200.c
[not found] ` <Pine.LNX.4.44L0.0802081143010.4593-100000-IYeN2dnnYyZXsRXLowluHWD2FQJk+8+b@public.gmane.org>
@ 2008-02-08 16:59 ` Mark Glines
0 siblings, 0 replies; 36+ messages in thread
From: Mark Glines @ 2008-02-08 16:59 UTC (permalink / raw)
To: Alan Stern
Cc: Matthew Dharm, Boaz Harrosh, James Bottomley, USB list,
linux-scsi
On Fri, 8 Feb 2008 11:46:13 -0500 (EST)
Alan Stern <stern-nwvwT67g6+6dFdvTe/nMLpVzexx5G7lz@public.gmane.org> wrote:
> On Tue, 5 Feb 2008, Matthew Dharm wrote:
>
> > We both agree that the code shouldn't run off the end of the s-g
> > list.
>
> Incidentally, if people want a simple bugfix patch for 2.6.24.stable,
> this should do it. Mark, can you confirm that this patch alone fixes
> the problem?
Confirmed: works just fine.
Tested-by: Mark Glines <mark-6pk7R1svBr8dnm+yROfE0A@public.gmane.org>
>
> Alan Stern
>
>
>
> Index: 2.6.24/drivers/usb/storage/protocol.c
> ===================================================================
> --- 2.6.24.orig/drivers/usb/storage/protocol.c
> +++ 2.6.24/drivers/usb/storage/protocol.c
> @@ -194,7 +194,7 @@ unsigned int usb_stor_access_xfer_buf(un
> * and the starting offset within the page, and
> update
> * the *offset and *index values for the next loop.
> */ cnt = 0;
> - while (cnt < buflen) {
> + while (cnt < buflen && sg) {
> struct page *page = sg_page(sg) +
> ((sg->offset + *offset) >>
> PAGE_SHIFT); unsigned int poff =
> @@ -249,6 +249,7 @@ void usb_stor_set_xfer_buf(unsigned char
> unsigned int offset = 0;
> struct scatterlist *sg = NULL;
>
> + buflen = min(buflen, srb->request_bufflen);
> usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
> TO_XFER_BUF);
> if (buflen < srb->request_bufflen)
>
^ permalink raw reply [flat|nested] 36+ messages in thread
end of thread, other threads:[~2008-02-08 16:59 UTC | newest]
Thread overview: 36+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <Pine.LNX.4.44L0.0801301807420.17156-100000@iolanthe.rowland.org>
[not found] ` <47A1948B.2010402@panasas.com>
[not found] ` <20080131070846.4464eb3c@chirp.tahoe>
[not found] ` <20080131070846.4464eb3c-uevSgErl2ChVvDCLMmKh5Q@public.gmane.org>
2008-01-31 15:17 ` [linux-usb-devel] 2.6.24: NULL scatter-gather pointer in usb_storage:usb_stor_access_xfer_buf? Boaz Harrosh
2008-01-31 16:45 ` Alan Stern
[not found] ` <Pine.LNX.4.44L0.0801311143180.3970-100000-IYeN2dnnYyZXsRXLowluHWD2FQJk+8+b@public.gmane.org>
2008-01-31 17:20 ` Boaz Harrosh
[not found] ` <47A1E6A0.8050500-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org>
2008-01-31 17:19 ` [PATCH] bugfix for an underflow condition in usb storage & isd200.c Boaz Harrosh
[not found] ` <47A2033D.2050502-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org>
2008-01-31 17:49 ` Alan Stern
[not found] ` <Pine.LNX.4.44L0.0801311244430.4373-100000-IYeN2dnnYyZXsRXLowluHWD2FQJk+8+b@public.gmane.org>
2008-01-31 19:00 ` Boaz Harrosh
2008-01-31 19:34 ` Alan Stern
2008-01-31 19:53 ` Boaz Harrosh
2008-01-31 20:56 ` Alan Stern
[not found] ` <Pine.LNX.4.44L0.0801311546450.22845-100000-IYeN2dnnYyZXsRXLowluHWD2FQJk+8+b@public.gmane.org>
2008-02-03 8:59 ` Boaz Harrosh
[not found] ` <47A5825D.2030901-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org>
2008-02-03 16:01 ` Alan Stern
2008-02-03 16:28 ` Boaz Harrosh
2008-02-03 19:23 ` Matthew Dharm
2008-02-04 9:05 ` Boaz Harrosh
2008-02-04 20:05 ` Alan Stern
[not found] ` <Pine.LNX.4.44L0.0802041500420.5186-100000-IYeN2dnnYyZXsRXLowluHWD2FQJk+8+b@public.gmane.org>
2008-02-05 8:41 ` Boaz Harrosh
[not found] ` <47A8213B.9050705-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org>
2008-02-05 15:42 ` Alan Stern
2008-02-05 16:54 ` Boaz Harrosh
2008-02-05 17:54 ` Matthew Dharm
[not found] ` <20080205175403.GA31714-JGfshJpz5UybPZpvUQj5UqxOck334EZe@public.gmane.org>
2008-02-06 20:23 ` Alan Stern
2008-02-06 21:05 ` Matthew Dharm
2008-02-06 22:18 ` Alan Stern
2008-02-06 23:01 ` James Bottomley
[not found] ` <1202338869.3112.138.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2008-02-06 23:25 ` Alan Stern
2008-02-06 23:55 ` James Bottomley
[not found] ` <1202342108.3112.146.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2008-02-07 16:35 ` Alan Stern
2008-02-08 16:46 ` Alan Stern
[not found] ` <Pine.LNX.4.44L0.0802081143010.4593-100000-IYeN2dnnYyZXsRXLowluHWD2FQJk+8+b@public.gmane.org>
2008-02-08 16:59 ` Mark Glines
[not found] ` <47A5EBC0.3060401-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org>
2008-02-03 21:09 ` Matthew Dharm
2008-01-31 18:00 ` Greg KH
2008-01-31 18:32 ` Boaz Harrosh
2008-01-31 19:37 ` [PATCH 2.6.24] bugfix for an overflow " Boaz Harrosh
[not found] ` <47A22369.80906-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org>
2008-01-31 19:49 ` Matthew Dharm
2008-01-31 20:05 ` Boaz Harrosh
[not found] ` <47A229FF.4040404@panasas.com>
2008-01-31 20:16 ` Matthew Dharm
2008-02-02 0:55 ` Mark Glines
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.