1 /* 2 * Driver for Freecom USB/IDE adaptor 3 * 4 * Freecom v0.1: 5 * 6 * First release 7 * 8 * Current development and maintenance by: 9 * (C) 2000 David Brown <usb-storage@davidb.org> 10 * 11 * This program is free software; you can redistribute it and/or modify it 12 * under the terms of the GNU General Public License as published by the 13 * Free Software Foundation; either version 2, or (at your option) any 14 * later version. 15 * 16 * This program is distributed in the hope that it will be useful, but 17 * WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 * General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License along 22 * with this program; if not, write to the Free Software Foundation, Inc., 23 * 675 Mass Ave, Cambridge, MA 02139, USA. 24 * 25 * This driver was developed with information provided in FREECOM's USB 26 * Programmers Reference Guide. For further information contact Freecom 27 * (http://www.freecom.de/) 28 */ 29 30 #include <linux/module.h> 31 #include <scsi/scsi.h> 32 #include <scsi/scsi_cmnd.h> 33 34 #include "usb.h" 35 #include "transport.h" 36 #include "protocol.h" 37 #include "debug.h" 38 #include "scsiglue.h" 39 40 #define DRV_NAME "ums-freecom" 41 42 MODULE_DESCRIPTION("Driver for Freecom USB/IDE adaptor"); 43 MODULE_AUTHOR("David Brown <usb-storage@davidb.org>"); 44 MODULE_LICENSE("GPL"); 45 46 #ifdef CONFIG_USB_STORAGE_DEBUG 47 static void pdump(struct us_data *us, void *ibuffer, int length); 48 #endif 49 50 /* Bits of HD_STATUS */ 51 #define ERR_STAT 0x01 52 #define DRQ_STAT 0x08 53 54 /* All of the outgoing packets are 64 bytes long. */ 55 struct freecom_cb_wrap { 56 u8 Type; /* Command type. */ 57 u8 Timeout; /* Timeout in seconds. */ 58 u8 Atapi[12]; /* An ATAPI packet. */ 59 u8 Filler[50]; /* Padding Data. */ 60 }; 61 62 struct freecom_xfer_wrap { 63 u8 Type; /* Command type. */ 64 u8 Timeout; /* Timeout in seconds. */ 65 __le32 Count; /* Number of bytes to transfer. */ 66 u8 Pad[58]; 67 } __attribute__ ((packed)); 68 69 struct freecom_ide_out { 70 u8 Type; /* Type + IDE register. */ 71 u8 Pad; 72 __le16 Value; /* Value to write. */ 73 u8 Pad2[60]; 74 }; 75 76 struct freecom_ide_in { 77 u8 Type; /* Type | IDE register. */ 78 u8 Pad[63]; 79 }; 80 81 struct freecom_status { 82 u8 Status; 83 u8 Reason; 84 __le16 Count; 85 u8 Pad[60]; 86 }; 87 88 /* 89 * Freecom stuffs the interrupt status in the INDEX_STAT bit of the ide 90 * register. 91 */ 92 #define FCM_INT_STATUS 0x02 /* INDEX_STAT */ 93 #define FCM_STATUS_BUSY 0x80 94 95 /* 96 * These are the packet types. The low bit indicates that this command 97 * should wait for an interrupt. 98 */ 99 #define FCM_PACKET_ATAPI 0x21 100 #define FCM_PACKET_STATUS 0x20 101 102 /* 103 * Receive data from the IDE interface. The ATAPI packet has already 104 * waited, so the data should be immediately available. 105 */ 106 #define FCM_PACKET_INPUT 0x81 107 108 /* Send data to the IDE interface. */ 109 #define FCM_PACKET_OUTPUT 0x01 110 111 /* 112 * Write a value to an ide register. Or the ide register to write after 113 * munging the address a bit. 114 */ 115 #define FCM_PACKET_IDE_WRITE 0x40 116 #define FCM_PACKET_IDE_READ 0xC0 117 118 /* All packets (except for status) are 64 bytes long. */ 119 #define FCM_PACKET_LENGTH 64 120 #define FCM_STATUS_PACKET_LENGTH 4 121 122 static int init_freecom(struct us_data *us); 123 124 125 /* 126 * The table of devices 127 */ 128 #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ 129 vendorName, productName, useProtocol, useTransport, \ 130 initFunction, flags) \ 131 { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ 132 .driver_info = (flags) } 133 134 static struct usb_device_id freecom_usb_ids[] = { 135 # include "unusual_freecom.h" 136 { } /* Terminating entry */ 137 }; 138 MODULE_DEVICE_TABLE(usb, freecom_usb_ids); 139 140 #undef UNUSUAL_DEV 141 142 /* 143 * The flags table 144 */ 145 #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ 146 vendor_name, product_name, use_protocol, use_transport, \ 147 init_function, Flags) \ 148 { \ 149 .vendorName = vendor_name, \ 150 .productName = product_name, \ 151 .useProtocol = use_protocol, \ 152 .useTransport = use_transport, \ 153 .initFunction = init_function, \ 154 } 155 156 static struct us_unusual_dev freecom_unusual_dev_list[] = { 157 # include "unusual_freecom.h" 158 { } /* Terminating entry */ 159 }; 160 161 #undef UNUSUAL_DEV 162 163 static int 164 freecom_readdata (struct scsi_cmnd *srb, struct us_data *us, 165 unsigned int ipipe, unsigned int opipe, int count) 166 { 167 struct freecom_xfer_wrap *fxfr = 168 (struct freecom_xfer_wrap *) us->iobuf; 169 int result; 170 171 fxfr->Type = FCM_PACKET_INPUT | 0x00; 172 fxfr->Timeout = 0; /* Short timeout for debugging. */ 173 fxfr->Count = cpu_to_le32 (count); 174 memset (fxfr->Pad, 0, sizeof (fxfr->Pad)); 175 176 usb_stor_dbg(us, "Read data Freecom! (c=%d)\n", count); 177 178 /* Issue the transfer command. */ 179 result = usb_stor_bulk_transfer_buf (us, opipe, fxfr, 180 FCM_PACKET_LENGTH, NULL); 181 if (result != USB_STOR_XFER_GOOD) { 182 usb_stor_dbg(us, "Freecom readdata transport error\n"); 183 return USB_STOR_TRANSPORT_ERROR; 184 } 185 186 /* Now transfer all of our blocks. */ 187 usb_stor_dbg(us, "Start of read\n"); 188 result = usb_stor_bulk_srb(us, ipipe, srb); 189 usb_stor_dbg(us, "freecom_readdata done!\n"); 190 191 if (result > USB_STOR_XFER_SHORT) 192 return USB_STOR_TRANSPORT_ERROR; 193 return USB_STOR_TRANSPORT_GOOD; 194 } 195 196 static int 197 freecom_writedata (struct scsi_cmnd *srb, struct us_data *us, 198 int unsigned ipipe, unsigned int opipe, int count) 199 { 200 struct freecom_xfer_wrap *fxfr = 201 (struct freecom_xfer_wrap *) us->iobuf; 202 int result; 203 204 fxfr->Type = FCM_PACKET_OUTPUT | 0x00; 205 fxfr->Timeout = 0; /* Short timeout for debugging. */ 206 fxfr->Count = cpu_to_le32 (count); 207 memset (fxfr->Pad, 0, sizeof (fxfr->Pad)); 208 209 usb_stor_dbg(us, "Write data Freecom! (c=%d)\n", count); 210 211 /* Issue the transfer command. */ 212 result = usb_stor_bulk_transfer_buf (us, opipe, fxfr, 213 FCM_PACKET_LENGTH, NULL); 214 if (result != USB_STOR_XFER_GOOD) { 215 usb_stor_dbg(us, "Freecom writedata transport error\n"); 216 return USB_STOR_TRANSPORT_ERROR; 217 } 218 219 /* Now transfer all of our blocks. */ 220 usb_stor_dbg(us, "Start of write\n"); 221 result = usb_stor_bulk_srb(us, opipe, srb); 222 223 usb_stor_dbg(us, "freecom_writedata done!\n"); 224 if (result > USB_STOR_XFER_SHORT) 225 return USB_STOR_TRANSPORT_ERROR; 226 return USB_STOR_TRANSPORT_GOOD; 227 } 228 229 /* 230 * Transport for the Freecom USB/IDE adaptor. 231 * 232 */ 233 static int freecom_transport(struct scsi_cmnd *srb, struct us_data *us) 234 { 235 struct freecom_cb_wrap *fcb; 236 struct freecom_status *fst; 237 unsigned int ipipe, opipe; /* We need both pipes. */ 238 int result; 239 unsigned int partial; 240 int length; 241 242 fcb = (struct freecom_cb_wrap *) us->iobuf; 243 fst = (struct freecom_status *) us->iobuf; 244 245 usb_stor_dbg(us, "Freecom TRANSPORT STARTED\n"); 246 247 /* Get handles for both transports. */ 248 opipe = us->send_bulk_pipe; 249 ipipe = us->recv_bulk_pipe; 250 251 /* The ATAPI Command always goes out first. */ 252 fcb->Type = FCM_PACKET_ATAPI | 0x00; 253 fcb->Timeout = 0; 254 memcpy (fcb->Atapi, srb->cmnd, 12); 255 memset (fcb->Filler, 0, sizeof (fcb->Filler)); 256 257 US_DEBUG(pdump(us, srb->cmnd, 12)); 258 259 /* Send it out. */ 260 result = usb_stor_bulk_transfer_buf (us, opipe, fcb, 261 FCM_PACKET_LENGTH, NULL); 262 263 /* 264 * The Freecom device will only fail if there is something wrong in 265 * USB land. It returns the status in its own registers, which 266 * come back in the bulk pipe. 267 */ 268 if (result != USB_STOR_XFER_GOOD) { 269 usb_stor_dbg(us, "freecom transport error\n"); 270 return USB_STOR_TRANSPORT_ERROR; 271 } 272 273 /* 274 * There are times we can optimize out this status read, but it 275 * doesn't hurt us to always do it now. 276 */ 277 result = usb_stor_bulk_transfer_buf (us, ipipe, fst, 278 FCM_STATUS_PACKET_LENGTH, &partial); 279 usb_stor_dbg(us, "foo Status result %d %u\n", result, partial); 280 if (result != USB_STOR_XFER_GOOD) 281 return USB_STOR_TRANSPORT_ERROR; 282 283 US_DEBUG(pdump(us, (void *)fst, partial)); 284 285 /* 286 * The firmware will time-out commands after 20 seconds. Some commands 287 * can legitimately take longer than this, so we use a different 288 * command that only waits for the interrupt and then sends status, 289 * without having to send a new ATAPI command to the device. 290 * 291 * NOTE: There is some indication that a data transfer after a timeout 292 * may not work, but that is a condition that should never happen. 293 */ 294 while (fst->Status & FCM_STATUS_BUSY) { 295 usb_stor_dbg(us, "20 second USB/ATAPI bridge TIMEOUT occurred!\n"); 296 usb_stor_dbg(us, "fst->Status is %x\n", fst->Status); 297 298 /* Get the status again */ 299 fcb->Type = FCM_PACKET_STATUS; 300 fcb->Timeout = 0; 301 memset (fcb->Atapi, 0, sizeof(fcb->Atapi)); 302 memset (fcb->Filler, 0, sizeof (fcb->Filler)); 303 304 /* Send it out. */ 305 result = usb_stor_bulk_transfer_buf (us, opipe, fcb, 306 FCM_PACKET_LENGTH, NULL); 307 308 /* 309 * The Freecom device will only fail if there is something 310 * wrong in USB land. It returns the status in its own 311 * registers, which come back in the bulk pipe. 312 */ 313 if (result != USB_STOR_XFER_GOOD) { 314 usb_stor_dbg(us, "freecom transport error\n"); 315 return USB_STOR_TRANSPORT_ERROR; 316 } 317 318 /* get the data */ 319 result = usb_stor_bulk_transfer_buf (us, ipipe, fst, 320 FCM_STATUS_PACKET_LENGTH, &partial); 321 322 usb_stor_dbg(us, "bar Status result %d %u\n", result, partial); 323 if (result != USB_STOR_XFER_GOOD) 324 return USB_STOR_TRANSPORT_ERROR; 325 326 US_DEBUG(pdump(us, (void *)fst, partial)); 327 } 328 329 if (partial != 4) 330 return USB_STOR_TRANSPORT_ERROR; 331 if ((fst->Status & 1) != 0) { 332 usb_stor_dbg(us, "operation failed\n"); 333 return USB_STOR_TRANSPORT_FAILED; 334 } 335 336 /* 337 * The device might not have as much data available as we 338 * requested. If you ask for more than the device has, this reads 339 * and such will hang. 340 */ 341 usb_stor_dbg(us, "Device indicates that it has %d bytes available\n", 342 le16_to_cpu(fst->Count)); 343 usb_stor_dbg(us, "SCSI requested %d\n", scsi_bufflen(srb)); 344 345 /* Find the length we desire to read. */ 346 switch (srb->cmnd[0]) { 347 case INQUIRY: 348 case REQUEST_SENSE: /* 16 or 18 bytes? spec says 18, lots of devices only have 16 */ 349 case MODE_SENSE: 350 case MODE_SENSE_10: 351 length = le16_to_cpu(fst->Count); 352 break; 353 default: 354 length = scsi_bufflen(srb); 355 } 356 357 /* verify that this amount is legal */ 358 if (length > scsi_bufflen(srb)) { 359 length = scsi_bufflen(srb); 360 usb_stor_dbg(us, "Truncating request to match buffer length: %d\n", 361 length); 362 } 363 364 /* 365 * What we do now depends on what direction the data is supposed to 366 * move in. 367 */ 368 369 switch (us->srb->sc_data_direction) { 370 case DMA_FROM_DEVICE: 371 /* catch bogus "read 0 length" case */ 372 if (!length) 373 break; 374 /* 375 * Make sure that the status indicates that the device 376 * wants data as well. 377 */ 378 if ((fst->Status & DRQ_STAT) == 0 || (fst->Reason & 3) != 2) { 379 usb_stor_dbg(us, "SCSI wants data, drive doesn't have any\n"); 380 return USB_STOR_TRANSPORT_FAILED; 381 } 382 result = freecom_readdata (srb, us, ipipe, opipe, length); 383 if (result != USB_STOR_TRANSPORT_GOOD) 384 return result; 385 386 usb_stor_dbg(us, "Waiting for status\n"); 387 result = usb_stor_bulk_transfer_buf (us, ipipe, fst, 388 FCM_PACKET_LENGTH, &partial); 389 US_DEBUG(pdump(us, (void *)fst, partial)); 390 391 if (partial != 4 || result > USB_STOR_XFER_SHORT) 392 return USB_STOR_TRANSPORT_ERROR; 393 if ((fst->Status & ERR_STAT) != 0) { 394 usb_stor_dbg(us, "operation failed\n"); 395 return USB_STOR_TRANSPORT_FAILED; 396 } 397 if ((fst->Reason & 3) != 3) { 398 usb_stor_dbg(us, "Drive seems still hungry\n"); 399 return USB_STOR_TRANSPORT_FAILED; 400 } 401 usb_stor_dbg(us, "Transfer happy\n"); 402 break; 403 404 case DMA_TO_DEVICE: 405 /* catch bogus "write 0 length" case */ 406 if (!length) 407 break; 408 /* 409 * Make sure the status indicates that the device wants to 410 * send us data. 411 */ 412 /* !!IMPLEMENT!! */ 413 result = freecom_writedata (srb, us, ipipe, opipe, length); 414 if (result != USB_STOR_TRANSPORT_GOOD) 415 return result; 416 417 usb_stor_dbg(us, "Waiting for status\n"); 418 result = usb_stor_bulk_transfer_buf (us, ipipe, fst, 419 FCM_PACKET_LENGTH, &partial); 420 421 if (partial != 4 || result > USB_STOR_XFER_SHORT) 422 return USB_STOR_TRANSPORT_ERROR; 423 if ((fst->Status & ERR_STAT) != 0) { 424 usb_stor_dbg(us, "operation failed\n"); 425 return USB_STOR_TRANSPORT_FAILED; 426 } 427 if ((fst->Reason & 3) != 3) { 428 usb_stor_dbg(us, "Drive seems still hungry\n"); 429 return USB_STOR_TRANSPORT_FAILED; 430 } 431 432 usb_stor_dbg(us, "Transfer happy\n"); 433 break; 434 435 436 case DMA_NONE: 437 /* Easy, do nothing. */ 438 break; 439 440 default: 441 /* should never hit here -- filtered in usb.c */ 442 usb_stor_dbg(us, "freecom unimplemented direction: %d\n", 443 us->srb->sc_data_direction); 444 /* Return fail, SCSI seems to handle this better. */ 445 return USB_STOR_TRANSPORT_FAILED; 446 break; 447 } 448 449 return USB_STOR_TRANSPORT_GOOD; 450 } 451 452 static int init_freecom(struct us_data *us) 453 { 454 int result; 455 char *buffer = us->iobuf; 456 457 /* 458 * The DMA-mapped I/O buffer is 64 bytes long, just right for 459 * all our packets. No need to allocate any extra buffer space. 460 */ 461 462 result = usb_stor_control_msg(us, us->recv_ctrl_pipe, 463 0x4c, 0xc0, 0x4346, 0x0, buffer, 0x20, 3*HZ); 464 buffer[32] = '\0'; 465 usb_stor_dbg(us, "String returned from FC init is: %s\n", buffer); 466 467 /* 468 * Special thanks to the people at Freecom for providing me with 469 * this "magic sequence", which they use in their Windows and MacOS 470 * drivers to make sure that all the attached perhiperals are 471 * properly reset. 472 */ 473 474 /* send reset */ 475 result = usb_stor_control_msg(us, us->send_ctrl_pipe, 476 0x4d, 0x40, 0x24d8, 0x0, NULL, 0x0, 3*HZ); 477 usb_stor_dbg(us, "result from activate reset is %d\n", result); 478 479 /* wait 250ms */ 480 mdelay(250); 481 482 /* clear reset */ 483 result = usb_stor_control_msg(us, us->send_ctrl_pipe, 484 0x4d, 0x40, 0x24f8, 0x0, NULL, 0x0, 3*HZ); 485 usb_stor_dbg(us, "result from clear reset is %d\n", result); 486 487 /* wait 3 seconds */ 488 mdelay(3 * 1000); 489 490 return USB_STOR_TRANSPORT_GOOD; 491 } 492 493 static int usb_stor_freecom_reset(struct us_data *us) 494 { 495 printk (KERN_CRIT "freecom reset called\n"); 496 497 /* We don't really have this feature. */ 498 return FAILED; 499 } 500 501 #ifdef CONFIG_USB_STORAGE_DEBUG 502 static void pdump(struct us_data *us, void *ibuffer, int length) 503 { 504 static char line[80]; 505 int offset = 0; 506 unsigned char *buffer = (unsigned char *) ibuffer; 507 int i, j; 508 int from, base; 509 510 offset = 0; 511 for (i = 0; i < length; i++) { 512 if ((i & 15) == 0) { 513 if (i > 0) { 514 offset += sprintf (line+offset, " - "); 515 for (j = i - 16; j < i; j++) { 516 if (buffer[j] >= 32 && buffer[j] <= 126) 517 line[offset++] = buffer[j]; 518 else 519 line[offset++] = '.'; 520 } 521 line[offset] = 0; 522 usb_stor_dbg(us, "%s\n", line); 523 offset = 0; 524 } 525 offset += sprintf (line+offset, "%08x:", i); 526 } else if ((i & 7) == 0) { 527 offset += sprintf (line+offset, " -"); 528 } 529 offset += sprintf (line+offset, " %02x", buffer[i] & 0xff); 530 } 531 532 /* Add the last "chunk" of data. */ 533 from = (length - 1) % 16; 534 base = ((length - 1) / 16) * 16; 535 536 for (i = from + 1; i < 16; i++) 537 offset += sprintf (line+offset, " "); 538 if (from < 8) 539 offset += sprintf (line+offset, " "); 540 offset += sprintf (line+offset, " - "); 541 542 for (i = 0; i <= from; i++) { 543 if (buffer[base+i] >= 32 && buffer[base+i] <= 126) 544 line[offset++] = buffer[base+i]; 545 else 546 line[offset++] = '.'; 547 } 548 line[offset] = 0; 549 usb_stor_dbg(us, "%s\n", line); 550 offset = 0; 551 } 552 #endif 553 554 static struct scsi_host_template freecom_host_template; 555 556 static int freecom_probe(struct usb_interface *intf, 557 const struct usb_device_id *id) 558 { 559 struct us_data *us; 560 int result; 561 562 result = usb_stor_probe1(&us, intf, id, 563 (id - freecom_usb_ids) + freecom_unusual_dev_list, 564 &freecom_host_template); 565 if (result) 566 return result; 567 568 us->transport_name = "Freecom"; 569 us->transport = freecom_transport; 570 us->transport_reset = usb_stor_freecom_reset; 571 us->max_lun = 0; 572 573 result = usb_stor_probe2(us); 574 return result; 575 } 576 577 static struct usb_driver freecom_driver = { 578 .name = DRV_NAME, 579 .probe = freecom_probe, 580 .disconnect = usb_stor_disconnect, 581 .suspend = usb_stor_suspend, 582 .resume = usb_stor_resume, 583 .reset_resume = usb_stor_reset_resume, 584 .pre_reset = usb_stor_pre_reset, 585 .post_reset = usb_stor_post_reset, 586 .id_table = freecom_usb_ids, 587 .soft_unbind = 1, 588 .no_dynamic_id = 1, 589 }; 590 591 module_usb_stor_driver(freecom_driver, freecom_host_template, DRV_NAME); 592