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