29 #include <linux/module.h>
30 #include <scsi/scsi.h>
42 #ifdef CONFIG_USB_STORAGE_DEBUG
43 static void pdump (
void *,
int);
86 #define FCM_INT_STATUS 0x02
87 #define FCM_STATUS_BUSY 0x80
91 #define FCM_PACKET_ATAPI 0x21
92 #define FCM_PACKET_STATUS 0x20
96 #define FCM_PACKET_INPUT 0x81
99 #define FCM_PACKET_OUTPUT 0x01
103 #define FCM_PACKET_IDE_WRITE 0x40
104 #define FCM_PACKET_IDE_READ 0xC0
107 #define FCM_PACKET_LENGTH 64
108 #define FCM_STATUS_PACKET_LENGTH 4
110 static int init_freecom(
struct us_data *us);
116 #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
117 vendorName, productName, useProtocol, useTransport, \
118 initFunction, flags) \
119 { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
120 .driver_info = (flags) }
133 #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
134 vendor_name, product_name, use_protocol, use_transport, \
135 init_function, Flags) \
137 .vendorName = vendor_name, \
138 .productName = product_name, \
139 .useProtocol = use_protocol, \
140 .useTransport = use_transport, \
141 .initFunction = init_function, \
153 unsigned int ipipe,
unsigned int opipe,
int count)
164 US_DEBUGP(
"Read data Freecom! (c=%d)\n", count);
170 US_DEBUGP (
"Freecom readdata transport error\n");
186 int unsigned ipipe,
unsigned int opipe,
int count)
197 US_DEBUGP(
"Write data Freecom! (c=%d)\n", count);
203 US_DEBUGP (
"Freecom writedata transport error\n");
225 unsigned int ipipe, opipe;
227 unsigned int partial;
233 US_DEBUGP(
"Freecom TRANSPORT STARTED\n");
263 US_DEBUGP(
"foo Status result %d %u\n", result, partial);
267 US_DEBUG(pdump ((
void *) fst, partial));
278 US_DEBUGP(
"20 second USB/ATAPI bridge TIMEOUT occurred!\n");
304 US_DEBUGP(
"bar Status result %d %u\n", result, partial);
308 US_DEBUG(pdump ((
void *) fst, partial));
313 if ((fst->
Status & 1) != 0) {
321 US_DEBUGP(
"Device indicates that it has %d bytes available\n",
323 US_DEBUGP(
"SCSI requested %d\n", scsi_bufflen(srb));
326 switch (srb->
cmnd[0]) {
334 length = scsi_bufflen(srb);
338 if (length > scsi_bufflen(srb)) {
339 length = scsi_bufflen(srb);
340 US_DEBUGP(
"Truncating request to match buffer length: %d\n", length);
346 switch (us->
srb->sc_data_direction) {
354 US_DEBUGP(
"SCSI wants data, drive doesn't have any\n");
357 result = freecom_readdata (srb, us, ipipe, opipe, length);
364 US_DEBUG(pdump ((
void *) fst, partial));
372 if ((fst->
Reason & 3) != 3) {
386 result = freecom_writedata (srb, us, ipipe, opipe, length);
400 if ((fst->
Reason & 3) != 3) {
415 US_DEBUGP (
"freecom unimplemented direction: %d\n",
416 us->
srb->sc_data_direction);
425 static int init_freecom(
struct us_data *us)
435 0x4c, 0xc0, 0x4346, 0x0, buffer, 0x20, 3*
HZ);
437 US_DEBUGP(
"String returned from FC init is: %s\n", buffer);
447 0x4d, 0x40, 0x24d8, 0x0,
NULL, 0x0, 3*
HZ);
448 US_DEBUGP(
"result from activate reset is %d\n", result);
455 0x4d, 0x40, 0x24f8, 0x0,
NULL, 0x0, 3*
HZ);
456 US_DEBUGP(
"result from clear reset is %d\n", result);
464 static int usb_stor_freecom_reset(
struct us_data *us)
472 #ifdef CONFIG_USB_STORAGE_DEBUG
473 static void pdump (
void *ibuffer,
int length)
475 static char line[80];
477 unsigned char *
buffer = (
unsigned char *) ibuffer;
482 for (i = 0; i <
length; i++) {
485 offset +=
sprintf (line+offset,
" - ");
486 for (j = i - 16; j <
i; j++) {
487 if (buffer[j] >= 32 && buffer[j] <= 126)
488 line[offset++] = buffer[
j];
490 line[offset++] =
'.';
496 offset +=
sprintf (line+offset,
"%08x:", i);
497 }
else if ((i & 7) == 0) {
498 offset +=
sprintf (line+offset,
" -");
500 offset +=
sprintf (line+offset,
" %02x", buffer[i] & 0xff);
504 from = (length - 1) % 16;
505 base = ((length - 1) / 16) * 16;
507 for (i = from + 1; i < 16; i++)
508 offset +=
sprintf (line+offset,
" ");
510 offset +=
sprintf (line+offset,
" ");
511 offset +=
sprintf (line+offset,
" - ");
513 for (i = 0; i <=
from; i++) {
514 if (buffer[base+i] >= 32 && buffer[base+i] <= 126)
515 line[offset++] = buffer[base+
i];
517 line[offset++] =
'.';
532 (
id - freecom_usb_ids) + freecom_unusual_dev_list);
545 static struct usb_driver freecom_driver = {
546 .name =
"ums-freecom",
547 .probe = freecom_probe,
554 .id_table = freecom_usb_ids,