Lines Matching +full:compact +full:- +full:flash

1 // SPDX-License-Identifier: GPL-2.0+
3 * Driver for Datafab USB Compact Flash reader
15 * Some bugfixes and scatter-gather code by Gregory P. Smith
16 * (greg-usb@electricrain.com)
26 * based on Datafab USB-to-ATA chips. It was specifically developed for the
27 * Datafab MDCFE-B USB CompactFlash reader but has since been found to work
28 * with a variety of Datafab-based devices from a number of manufacturers.
29 * I've received a report of this driver working with a Datafab-based
34 * however, you can force the driver into a write-protected state by setting
52 #define DRV_NAME "ums-datafab"
54 MODULE_DESCRIPTION("Driver for Datafab USB Compact Flash reader");
62 signed char lun; /* used for dual-slot readers */
119 return usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, in datafab_bulk_read()
130 return usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, in datafab_bulk_write()
140 unsigned char *command = us->iobuf; in datafab_read_data()
149 // we can support up to 28-bit addressing. I don't know if Datafab in datafab_read_data()
150 // supports beyond 24-bit addressing. It's kind of hard to test in datafab_read_data()
156 if (info->lun == -1) { in datafab_read_data()
162 totallen = sectors * info->ssize; in datafab_read_data()
175 // (min(128k, 255*info->ssize) is the real limit) in datafab_read_data()
178 thistime = (len / info->ssize) & 0xff; in datafab_read_data()
186 command[5] = 0xE0 + (info->lun << 4); in datafab_read_data()
202 usb_stor_access_xfer_buf(buffer, len, us->srb, in datafab_read_data()
206 totallen -= len; in datafab_read_data()
223 unsigned char *command = us->iobuf; in datafab_write_data()
224 unsigned char *reply = us->iobuf; in datafab_write_data()
233 // we can support up to 28-bit addressing. I don't know if Datafab in datafab_write_data()
234 // supports beyond 24-bit addressing. It's kind of hard to test in datafab_write_data()
240 if (info->lun == -1) { in datafab_write_data()
246 totallen = sectors * info->ssize; in datafab_write_data()
259 // (min(128k, 255*info->ssize) is the real limit) in datafab_write_data()
262 thistime = (len / info->ssize) & 0xff; in datafab_write_data()
265 usb_stor_access_xfer_buf(buffer, len, us->srb, in datafab_write_data()
274 command[5] = 0xE0 + (info->lun << 4); in datafab_write_data()
301 totallen -= len; in datafab_write_data()
316 // Dual-slot readers can be thought of as dual-LUN devices. in datafab_determine_lun()
323 unsigned char *command = us->iobuf; in datafab_determine_lun()
350 info->lun = 0; in datafab_determine_lun()
365 info->lun = 1; in datafab_determine_lun()
388 unsigned char *command = us->iobuf; in datafab_id_device()
395 if (info->lun == -1) { in datafab_id_device()
406 command[5] += (info->lun << 4); in datafab_id_device()
418 // capacity is at word offset 57-58 in datafab_id_device()
420 info->sectors = ((u32)(reply[117]) << 24) | in datafab_id_device()
454 struct datafab_info *info = (struct datafab_info *) (us->extra); in datafab_handle_mode_sense()
455 unsigned char *ptr = us->iobuf; in datafab_handle_mode_sense()
462 pc = srb->cmnd[2] >> 6; in datafab_handle_mode_sense()
463 page_code = srb->cmnd[2] & 0x3F; in datafab_handle_mode_sense()
491 // vendor-specific mode in datafab_handle_mode_sense()
492 info->sense_key = 0x05; in datafab_handle_mode_sense()
493 info->sense_asc = 0x24; in datafab_handle_mode_sense()
494 info->sense_ascq = 0x00; in datafab_handle_mode_sense()
530 ptr[0] = i - 1; in datafab_handle_mode_sense()
532 ((__be16 *) ptr)[0] = cpu_to_be16(i - 2); in datafab_handle_mode_sense()
545 // Transport for the Datafab MDCFE-B
552 unsigned char *ptr = us->iobuf; in datafab_transport()
557 if (!us->extra) { in datafab_transport()
558 us->extra = kzalloc_obj(struct datafab_info, GFP_NOIO); in datafab_transport()
559 if (!us->extra) in datafab_transport()
562 us->extra_destructor = datafab_info_destructor; in datafab_transport()
563 ((struct datafab_info *)us->extra)->lun = -1; in datafab_transport()
566 info = (struct datafab_info *) (us->extra); in datafab_transport()
568 if (srb->cmnd[0] == INQUIRY) { in datafab_transport()
569 usb_stor_dbg(us, "INQUIRY - Returning bogus response\n"); in datafab_transport()
575 if (srb->cmnd[0] == READ_CAPACITY) { in datafab_transport()
576 info->ssize = 0x200; // hard coded 512 byte sectors as per ATA spec in datafab_transport()
582 info->sectors, info->ssize); in datafab_transport()
586 ((__be32 *) ptr)[0] = cpu_to_be32(info->sectors - 1); in datafab_transport()
587 ((__be32 *) ptr)[1] = cpu_to_be32(info->ssize); in datafab_transport()
593 if (srb->cmnd[0] == MODE_SELECT_10) { in datafab_transport()
600 if (srb->cmnd[0] == READ_10) { in datafab_transport()
601 block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) | in datafab_transport()
602 ((u32)(srb->cmnd[4]) << 8) | ((u32)(srb->cmnd[5])); in datafab_transport()
604 blocks = ((u32)(srb->cmnd[7]) << 8) | ((u32)(srb->cmnd[8])); in datafab_transport()
611 if (srb->cmnd[0] == READ_12) { in datafab_transport()
614 block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) | in datafab_transport()
615 ((u32)(srb->cmnd[4]) << 8) | ((u32)(srb->cmnd[5])); in datafab_transport()
617 blocks = ((u32)(srb->cmnd[6]) << 24) | ((u32)(srb->cmnd[7]) << 16) | in datafab_transport()
618 ((u32)(srb->cmnd[8]) << 8) | ((u32)(srb->cmnd[9])); in datafab_transport()
625 if (srb->cmnd[0] == WRITE_10) { in datafab_transport()
626 block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) | in datafab_transport()
627 ((u32)(srb->cmnd[4]) << 8) | ((u32)(srb->cmnd[5])); in datafab_transport()
629 blocks = ((u32)(srb->cmnd[7]) << 8) | ((u32)(srb->cmnd[8])); in datafab_transport()
636 if (srb->cmnd[0] == WRITE_12) { in datafab_transport()
639 block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) | in datafab_transport()
640 ((u32)(srb->cmnd[4]) << 8) | ((u32)(srb->cmnd[5])); in datafab_transport()
642 blocks = ((u32)(srb->cmnd[6]) << 24) | ((u32)(srb->cmnd[7]) << 16) | in datafab_transport()
643 ((u32)(srb->cmnd[8]) << 8) | ((u32)(srb->cmnd[9])); in datafab_transport()
650 if (srb->cmnd[0] == TEST_UNIT_READY) { in datafab_transport()
655 if (srb->cmnd[0] == REQUEST_SENSE) { in datafab_transport()
656 usb_stor_dbg(us, "REQUEST_SENSE - Returning faked response\n"); in datafab_transport()
664 ptr[2] = info->sense_key; in datafab_transport()
666 ptr[12] = info->sense_asc; in datafab_transport()
667 ptr[13] = info->sense_ascq; in datafab_transport()
673 if (srb->cmnd[0] == MODE_SENSE) { in datafab_transport()
678 if (srb->cmnd[0] == MODE_SENSE_10) { in datafab_transport()
683 if (srb->cmnd[0] == ALLOW_MEDIUM_REMOVAL) { in datafab_transport()
691 if (srb->cmnd[0] == START_STOP) { in datafab_transport()
703 info->sense_key = NO_SENSE; in datafab_transport()
704 srb->result = SUCCESS; in datafab_transport()
706 info->sense_key = UNIT_ATTENTION; in datafab_transport()
707 srb->result = SAM_STAT_CHECK_CONDITION; in datafab_transport()
713 srb->cmnd[0], srb->cmnd[0]); in datafab_transport()
714 info->sense_key = 0x05; in datafab_transport()
715 info->sense_asc = 0x20; in datafab_transport()
716 info->sense_ascq = 0x00; in datafab_transport()
729 (id - datafab_usb_ids) + datafab_unusual_dev_list, in datafab_probe()
734 us->transport_name = "Datafab Bulk-Only"; in datafab_probe()
735 us->transport = datafab_transport; in datafab_probe()
736 us->transport_reset = usb_stor_Bulk_reset; in datafab_probe()
737 us->max_lun = 1; in datafab_probe()