> Is the size of the card reported correctly, or is it 1 too large?
On an 8 MB CF card:
datafab: SCSI device sdd: 15873 512-byte hdwr sectors (8 MB)
sddr09: SCSI device sdb: 15872 512-byte hdwr sectors (8 MB)
Hmm. Now that I look - it is just that the driver is broken.
Nothing wrong with the device.
The ATA convention is to return the capacity.
The SCSI convention is to return the highest block number,
one less than the capacity.
So, the driver misses a -1.
Another problem causing hangs was that the SCSI code does
TEST_UNIT_READY, and datafab.c first wants to determine
which lun it is using, and tries to find out, but the attempt
fails and causes scsi error-recovery, but that does TEST_UNIT_READY
and we have a recursion.
Below a patch fixing both problems. Now my two-lun device works
for CF and it works for SM but not both - depending on the order
of the entries in unusual_devices.
In the good old days I showed versions that just worked, but the
vanilla kernel does not yet handle multi-lun devices.
Andries
------------------------------------------------------------------
--- /linux/2.6/linux-2.6.0-test11/linux/drivers/usb/storage/datafab.c Wed Nov 26
21:45:53 2003
+++ ./datafab.c Thu Dec 4 23:35:58 2003
@@ -294,11 +294,12 @@
// There might be a better way of doing this?
static unsigned char scommand[8] = { 0, 1, 0, 0, 0, 0xa0, 0xec, 1 };
+ static int beenhere = 0; /* protect against recursive calls */
unsigned char *command = us->iobuf;
unsigned char *buf;
int count = 0, rc;
- if (!us || !info)
+ if (!us || !info || beenhere)
return USB_STOR_TRANSPORT_ERROR;
memcpy(command, scommand, 8);
@@ -306,6 +307,8 @@
if (!buf)
return USB_STOR_TRANSPORT_ERROR;
+ beenhere = 1;
+
US_DEBUGP("datafab_determine_lun: locating...\n");
// we'll try 3 times before giving up...
@@ -387,7 +390,7 @@
// we'll go ahead and extract the media capacity while we're here...
//
- rc = datafab_bulk_read(us, reply, sizeof(reply));
+ rc = datafab_bulk_read(us, reply, 512);
if (rc == USB_STOR_XFER_GOOD) {
// capacity is at word offset 57-58
//
@@ -574,20 +577,26 @@
}
if (srb->cmnd[0] == READ_CAPACITY) {
- info->ssize = 0x200; // hard coded 512 byte sectors as per ATA spec
- rc = datafab_id_device(us, info);
+ unsigned long size_minus1;
+
+ info->ssize = 0x200; // 512 byte sectors as per ATA spec
+
+ rc = datafab_id_device(us, info); // reads capacity
if (rc != USB_STOR_TRANSPORT_GOOD)
return rc;
- US_DEBUGP("datafab_transport: READ_CAPACITY: %ld sectors, %ld bytes
per sector\n",
+ US_DEBUGP("datafab_transport: READ_CAPACITY: "
+ "%ld sectors, %ld bytes per sector\n",
info->sectors, info->ssize);
// build the reply
- //
- ptr[0] = (info->sectors >> 24) & 0xFF;
- ptr[1] = (info->sectors >> 16) & 0xFF;
- ptr[2] = (info->sectors >> 8) & 0xFF;
- ptr[3] = (info->sectors) & 0xFF;
+ // convert ATA to SCSI convention
+ size_minus1 = info->sectors - 1;
+
+ ptr[0] = (size_minus1 >> 24) & 0xFF;
+ ptr[1] = (size_minus1 >> 16) & 0xFF;
+ ptr[2] = (size_minus1 >> 8) & 0xFF;
+ ptr[3] = (size_minus1) & 0xFF;
ptr[4] = (info->ssize >> 24) & 0xFF;
ptr[5] = (info->ssize >> 16) & 0xFF;
-------------------------------------------------------
This SF.net email is sponsored by: IBM Linux Tutorials.
Become an expert in LINUX or just sharpen your skills. Sign up for IBM's
Free Linux Tutorials. Learn everything from the bash shell to sys admin.
Click now! http://ads.osdn.com/?ad_id=1278&alloc_id=3371&op=click
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel