^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Transport & Protocol Driver for In-System Design, Inc. ISD200 ASIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Current development and maintenance:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * (C) 2001-2002 Björn Stenberg (bjorn@haxx.se)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Developed with the assistance of:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * (C) 2002 Alan Stern <stern@rowland.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Initial work:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * (C) 2000 In-System Design, Inc. (support@in-system.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * The ISD200 ASIC does not natively support ATA devices. The chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * does implement an interface, the ATA Command Block (ATACB) which provides
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * a means of passing ATA commands and ATA register accesses to a device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * History:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * 2002-10-19: Removed the specialized transfer routines.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * (Alan Stern <stern@rowland.harvard.edu>)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * 2001-02-24: Removed lots of duplicate code and simplified the structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * (bjorn@haxx.se)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * 2002-01-16: Fixed endianness bug so it works on the ppc arch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * (Luc Saillard <luc@saillard.org>)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * 2002-01-17: All bitfields removed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * (bjorn@haxx.se)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /* Include files */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/ata.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/hdreg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/scatterlist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <scsi/scsi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <scsi/scsi_cmnd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <scsi/scsi_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include "usb.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include "transport.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include "protocol.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include "debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include "scsiglue.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define DRV_NAME "ums-isd200"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) MODULE_DESCRIPTION("Driver for In-System Design, Inc. ISD200 ASIC");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) MODULE_AUTHOR("Björn Stenberg <bjorn@haxx.se>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) MODULE_IMPORT_NS(USB_STORAGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static int isd200_Initialization(struct us_data *us);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * The table of devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) vendorName, productName, useProtocol, useTransport, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) initFunction, flags) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) .driver_info = (flags) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static struct usb_device_id isd200_usb_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) # include "unusual_isd200.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) { } /* Terminating entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) MODULE_DEVICE_TABLE(usb, isd200_usb_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #undef UNUSUAL_DEV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * The flags table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) vendor_name, product_name, use_protocol, use_transport, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) init_function, Flags) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) .vendorName = vendor_name, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) .productName = product_name, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) .useProtocol = use_protocol, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) .useTransport = use_transport, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) .initFunction = init_function, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static struct us_unusual_dev isd200_unusual_dev_list[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) # include "unusual_isd200.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) { } /* Terminating entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #undef UNUSUAL_DEV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) /* Timeout defines (in Seconds) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define ISD200_ENUM_BSY_TIMEOUT 35
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define ISD200_ENUM_DETECT_TIMEOUT 30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define ISD200_DEFAULT_TIMEOUT 30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /* device flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define DF_ATA_DEVICE 0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define DF_MEDIA_STATUS_ENABLED 0x0002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define DF_REMOVABLE_MEDIA 0x0004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /* capability bit definitions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define CAPABILITY_DMA 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define CAPABILITY_LBA 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /* command_setX bit definitions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define COMMANDSET_REMOVABLE 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define COMMANDSET_MEDIA_STATUS 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /* ATA Vendor Specific defines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define ATA_ADDRESS_DEVHEAD_STD 0xa0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define ATA_ADDRESS_DEVHEAD_LBA_MODE 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define ATA_ADDRESS_DEVHEAD_SLAVE 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /* Action Select bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define ACTION_SELECT_0 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define ACTION_SELECT_1 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define ACTION_SELECT_2 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define ACTION_SELECT_3 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define ACTION_SELECT_4 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define ACTION_SELECT_5 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define ACTION_SELECT_6 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define ACTION_SELECT_7 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /* Register Select bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define REG_ALTERNATE_STATUS 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define REG_DEVICE_CONTROL 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define REG_ERROR 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #define REG_FEATURES 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define REG_SECTOR_COUNT 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define REG_SECTOR_NUMBER 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define REG_CYLINDER_LOW 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define REG_CYLINDER_HIGH 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define REG_DEVICE_HEAD 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define REG_STATUS 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define REG_COMMAND 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* ATA registers offset definitions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define ATA_REG_ERROR_OFFSET 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define ATA_REG_LCYL_OFFSET 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define ATA_REG_HCYL_OFFSET 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define ATA_REG_STATUS_OFFSET 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) /* ATA error definitions not in <linux/hdreg.h> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #define ATA_ERROR_MEDIA_CHANGE 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /* ATA command definitions not in <linux/hdreg.h> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #define ATA_COMMAND_GET_MEDIA_STATUS 0xDA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #define ATA_COMMAND_MEDIA_EJECT 0xED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /* ATA drive control definitions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) #define ATA_DC_DISABLE_INTERRUPTS 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #define ATA_DC_RESET_CONTROLLER 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #define ATA_DC_REENABLE_CONTROLLER 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * General purpose return codes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #define ISD200_ERROR -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #define ISD200_GOOD 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * Transport return codes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) #define ISD200_TRANSPORT_GOOD 0 /* Transport good, command good */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) #define ISD200_TRANSPORT_FAILED 1 /* Transport good, command failed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) #define ISD200_TRANSPORT_ERROR 2 /* Transport bad (i.e. device dead) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /* driver action codes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) #define ACTION_READ_STATUS 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #define ACTION_RESET 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) #define ACTION_REENABLE 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) #define ACTION_SOFT_RESET 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) #define ACTION_ENUM 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) #define ACTION_IDENTIFY 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * ata_cdb struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) union ata_cdb {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) unsigned char SignatureByte0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) unsigned char SignatureByte1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) unsigned char ActionSelect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) unsigned char RegisterSelect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) unsigned char TransferBlockSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) unsigned char WriteData3F6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) unsigned char WriteData1F1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) unsigned char WriteData1F2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) unsigned char WriteData1F3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) unsigned char WriteData1F4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) unsigned char WriteData1F5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) unsigned char WriteData1F6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) unsigned char WriteData1F7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) unsigned char Reserved[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) } generic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) unsigned char SignatureByte0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) unsigned char SignatureByte1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) unsigned char ActionSelect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) unsigned char RegisterSelect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) unsigned char TransferBlockSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) unsigned char AlternateStatusByte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) unsigned char ErrorByte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) unsigned char SectorCountByte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) unsigned char SectorNumberByte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) unsigned char CylinderLowByte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) unsigned char CylinderHighByte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) unsigned char DeviceHeadByte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) unsigned char StatusByte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) unsigned char Reserved[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) } read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) unsigned char SignatureByte0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) unsigned char SignatureByte1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) unsigned char ActionSelect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) unsigned char RegisterSelect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) unsigned char TransferBlockSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) unsigned char DeviceControlByte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) unsigned char FeaturesByte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) unsigned char SectorCountByte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) unsigned char SectorNumberByte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) unsigned char CylinderLowByte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) unsigned char CylinderHighByte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) unsigned char DeviceHeadByte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) unsigned char CommandByte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) unsigned char Reserved[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) } write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * Inquiry data structure. This is the data returned from the target
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * after it receives an inquiry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * This structure may be extended by the number of bytes specified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * in the field AdditionalLength. The defined size constant only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * includes fields through ProductRevisionLevel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * DeviceType field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) #define DIRECT_ACCESS_DEVICE 0x00 /* disks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) #define DEVICE_REMOVABLE 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) struct inquiry_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) unsigned char DeviceType;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) unsigned char DeviceTypeModifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) unsigned char Versions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) unsigned char Format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) unsigned char AdditionalLength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) unsigned char Reserved[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) unsigned char Capability;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) unsigned char VendorId[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) unsigned char ProductId[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) unsigned char ProductRevisionLevel[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) unsigned char VendorSpecific[20];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) unsigned char Reserved3[40];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) } __attribute__ ((packed));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * INQUIRY data buffer size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) #define INQUIRYDATABUFFERSIZE 36
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) * ISD200 CONFIG data struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) #define ATACFG_TIMING 0x0f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) #define ATACFG_ATAPI_RESET 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) #define ATACFG_MASTER 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) #define ATACFG_BLOCKSIZE 0xa0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) #define ATACFGE_LAST_LUN 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) #define ATACFGE_DESC_OVERRIDE 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) #define ATACFGE_STATE_SUSPEND 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) #define ATACFGE_SKIP_BOOT 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) #define ATACFGE_CONF_DESC2 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) #define ATACFGE_INIT_STATUS 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) #define CFG_CAPABILITY_SRST 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct isd200_config {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) unsigned char EventNotification;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) unsigned char ExternalClock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) unsigned char ATAInitTimeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) unsigned char ATAConfig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) unsigned char ATAMajorCommand;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) unsigned char ATAMinorCommand;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) unsigned char ATAExtraConfig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) unsigned char Capability;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }__attribute__ ((packed));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * ISD200 driver information struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) struct isd200_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) struct inquiry_data InquiryData;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) u16 *id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) struct isd200_config ConfigData;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) unsigned char *RegsBuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) unsigned char ATARegs[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) unsigned char DeviceHead;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) unsigned char DeviceFlags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) /* maximum number of LUNs supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) unsigned char MaxLUNs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) unsigned char cmnd[BLK_MAX_CDB];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) struct scsi_cmnd srb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) struct scatterlist sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) * Read Capacity Data - returned in Big Endian format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) struct read_capacity_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) __be32 LogicalBlockAddress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) __be32 BytesPerBlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) * Read Block Limits Data - returned in Big Endian format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) * This structure returns the maximum and minimum block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) * size for a TAPE device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) struct read_block_limits {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) unsigned char Reserved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) unsigned char BlockMaximumSize[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) unsigned char BlockMinimumSize[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * Sense Data Format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) #define SENSE_ERRCODE 0x7f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) #define SENSE_ERRCODE_VALID 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) #define SENSE_FLAG_SENSE_KEY 0x0f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) #define SENSE_FLAG_BAD_LENGTH 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) #define SENSE_FLAG_END_OF_MEDIA 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) #define SENSE_FLAG_FILE_MARK 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) struct sense_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) unsigned char ErrorCode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) unsigned char SegmentNumber;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) unsigned char Flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) unsigned char Information[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) unsigned char AdditionalSenseLength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) unsigned char CommandSpecificInformation[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) unsigned char AdditionalSenseCode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) unsigned char AdditionalSenseCodeQualifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) unsigned char FieldReplaceableUnitCode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) unsigned char SenseKeySpecific[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) } __attribute__ ((packed));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) * Default request sense buffer size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) #define SENSE_BUFFER_SIZE 18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) * Helper routines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) ***********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) * isd200_build_sense
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) * Builds an artificial sense buffer to report the results of a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) * failed command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * RETURNS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) static void isd200_build_sense(struct us_data *us, struct scsi_cmnd *srb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) struct isd200_info *info = (struct isd200_info *)us->extra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) struct sense_data *buf = (struct sense_data *) &srb->sense_buffer[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) unsigned char error = info->ATARegs[ATA_REG_ERROR_OFFSET];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) if(error & ATA_ERROR_MEDIA_CHANGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) buf->ErrorCode = 0x70 | SENSE_ERRCODE_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) buf->AdditionalSenseLength = 0xb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) buf->Flags = UNIT_ATTENTION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) buf->AdditionalSenseCode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) buf->AdditionalSenseCodeQualifier = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) } else if (error & ATA_MCR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) buf->ErrorCode = 0x70 | SENSE_ERRCODE_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) buf->AdditionalSenseLength = 0xb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) buf->Flags = UNIT_ATTENTION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) buf->AdditionalSenseCode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) buf->AdditionalSenseCodeQualifier = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) } else if (error & ATA_TRK0NF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) buf->ErrorCode = 0x70 | SENSE_ERRCODE_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) buf->AdditionalSenseLength = 0xb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) buf->Flags = NOT_READY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) buf->AdditionalSenseCode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) buf->AdditionalSenseCodeQualifier = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) } else if (error & ATA_UNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) buf->ErrorCode = 0x70 | SENSE_ERRCODE_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) buf->AdditionalSenseLength = 0xb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) buf->Flags = DATA_PROTECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) buf->AdditionalSenseCode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) buf->AdditionalSenseCodeQualifier = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) buf->ErrorCode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) buf->AdditionalSenseLength = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) buf->Flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) buf->AdditionalSenseCode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) buf->AdditionalSenseCodeQualifier = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) * Transport routines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) ***********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) * isd200_set_srb(), isd200_srb_set_bufflen()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) * Two helpers to facilitate in initialization of scsi_cmnd structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) * Will need to change when struct scsi_cmnd changes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) static void isd200_set_srb(struct isd200_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) enum dma_data_direction dir, void* buff, unsigned bufflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) struct scsi_cmnd *srb = &info->srb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (buff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) sg_init_one(&info->sg, buff, bufflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) srb->sc_data_direction = dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) srb->sdb.table.sgl = buff ? &info->sg : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) srb->sdb.length = bufflen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) srb->sdb.table.nents = buff ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) static void isd200_srb_set_bufflen(struct scsi_cmnd *srb, unsigned bufflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) srb->sdb.length = bufflen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) * isd200_action
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) * Routine for sending commands to the isd200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) * RETURNS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) * ISD status code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) static int isd200_action( struct us_data *us, int action,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) void* pointer, int value )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) union ata_cdb ata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) /* static to prevent this large struct being placed on the valuable stack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) static struct scsi_device srb_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) struct isd200_info *info = (struct isd200_info *)us->extra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) struct scsi_cmnd *srb = &info->srb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) memset(&ata, 0, sizeof(ata));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) srb->cmnd = info->cmnd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) srb->device = &srb_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) ata.generic.SignatureByte0 = info->ConfigData.ATAMajorCommand;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) ata.generic.SignatureByte1 = info->ConfigData.ATAMinorCommand;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) ata.generic.TransferBlockSize = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) switch ( action ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) case ACTION_READ_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) usb_stor_dbg(us, " isd200_action(READ_STATUS)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) ata.generic.ActionSelect = ACTION_SELECT_0|ACTION_SELECT_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) ata.generic.RegisterSelect =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) REG_CYLINDER_LOW | REG_CYLINDER_HIGH |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) REG_STATUS | REG_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) isd200_set_srb(info, DMA_FROM_DEVICE, pointer, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) case ACTION_ENUM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) usb_stor_dbg(us, " isd200_action(ENUM,0x%02x)\n", value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) ata.generic.ActionSelect = ACTION_SELECT_1|ACTION_SELECT_2|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) ACTION_SELECT_3|ACTION_SELECT_4|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) ACTION_SELECT_5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) ata.generic.RegisterSelect = REG_DEVICE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) ata.write.DeviceHeadByte = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) isd200_set_srb(info, DMA_NONE, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) case ACTION_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) usb_stor_dbg(us, " isd200_action(RESET)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) ata.generic.ActionSelect = ACTION_SELECT_1|ACTION_SELECT_2|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) ACTION_SELECT_3|ACTION_SELECT_4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) ata.generic.RegisterSelect = REG_DEVICE_CONTROL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) ata.write.DeviceControlByte = ATA_DC_RESET_CONTROLLER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) isd200_set_srb(info, DMA_NONE, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) case ACTION_REENABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) usb_stor_dbg(us, " isd200_action(REENABLE)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) ata.generic.ActionSelect = ACTION_SELECT_1|ACTION_SELECT_2|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) ACTION_SELECT_3|ACTION_SELECT_4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) ata.generic.RegisterSelect = REG_DEVICE_CONTROL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) ata.write.DeviceControlByte = ATA_DC_REENABLE_CONTROLLER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) isd200_set_srb(info, DMA_NONE, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) case ACTION_SOFT_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) usb_stor_dbg(us, " isd200_action(SOFT_RESET)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) ata.generic.ActionSelect = ACTION_SELECT_1|ACTION_SELECT_5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) ata.generic.RegisterSelect = REG_DEVICE_HEAD | REG_COMMAND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) ata.write.DeviceHeadByte = info->DeviceHead;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) ata.write.CommandByte = ATA_CMD_DEV_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) isd200_set_srb(info, DMA_NONE, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) case ACTION_IDENTIFY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) usb_stor_dbg(us, " isd200_action(IDENTIFY)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) ata.generic.RegisterSelect = REG_COMMAND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) ata.write.CommandByte = ATA_CMD_ID_ATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) isd200_set_srb(info, DMA_FROM_DEVICE, info->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) ATA_ID_WORDS * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) usb_stor_dbg(us, "Error: Undefined action %d\n", action);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) return ISD200_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) memcpy(srb->cmnd, &ata, sizeof(ata.generic));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) srb->cmd_len = sizeof(ata.generic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) status = usb_stor_Bulk_transport(srb, us);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) if (status == USB_STOR_TRANSPORT_GOOD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) status = ISD200_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) usb_stor_dbg(us, " isd200_action(0x%02x) error: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) action, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) status = ISD200_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) /* need to reset device here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) * isd200_read_regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) * Read ATA Registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) * RETURNS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) * ISD status code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) static int isd200_read_regs( struct us_data *us )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) struct isd200_info *info = (struct isd200_info *)us->extra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) int retStatus = ISD200_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) int transferStatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) usb_stor_dbg(us, "Entering isd200_IssueATAReadRegs\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) transferStatus = isd200_action( us, ACTION_READ_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) info->RegsBuf, sizeof(info->ATARegs) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) if (transferStatus != ISD200_TRANSPORT_GOOD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) usb_stor_dbg(us, " Error reading ATA registers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) retStatus = ISD200_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) memcpy(info->ATARegs, info->RegsBuf, sizeof(info->ATARegs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) usb_stor_dbg(us, " Got ATA Register[ATA_REG_ERROR_OFFSET] = 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) info->ATARegs[ATA_REG_ERROR_OFFSET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) return retStatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) * Invoke the transport and basic error-handling/recovery methods
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) * This is used by the protocol layers to actually send the message to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) * the device and receive the response.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) static void isd200_invoke_transport( struct us_data *us,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) struct scsi_cmnd *srb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) union ata_cdb *ataCdb )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) int need_auto_sense = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) int transferStatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) /* send the command to the transport layer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) memcpy(srb->cmnd, ataCdb, sizeof(ataCdb->generic));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) srb->cmd_len = sizeof(ataCdb->generic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) transferStatus = usb_stor_Bulk_transport(srb, us);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) * if the command gets aborted by the higher layers, we need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) * short-circuit all other processing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) usb_stor_dbg(us, "-- command was aborted\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) goto Handle_Abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) switch (transferStatus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) case USB_STOR_TRANSPORT_GOOD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) /* Indicate a good result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) srb->result = SAM_STAT_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) case USB_STOR_TRANSPORT_NO_SENSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) usb_stor_dbg(us, "-- transport indicates protocol failure\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) srb->result = SAM_STAT_CHECK_CONDITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) case USB_STOR_TRANSPORT_FAILED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) usb_stor_dbg(us, "-- transport indicates command failure\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) need_auto_sense = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) case USB_STOR_TRANSPORT_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) usb_stor_dbg(us, "-- transport indicates transport error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) srb->result = DID_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) /* Need reset here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) usb_stor_dbg(us, "-- transport indicates unknown error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) srb->result = DID_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) /* Need reset here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) if ((scsi_get_resid(srb) > 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) !((srb->cmnd[0] == REQUEST_SENSE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) (srb->cmnd[0] == INQUIRY) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) (srb->cmnd[0] == MODE_SENSE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) (srb->cmnd[0] == LOG_SENSE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) (srb->cmnd[0] == MODE_SENSE_10))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) usb_stor_dbg(us, "-- unexpectedly short transfer\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) need_auto_sense = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) if (need_auto_sense) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) result = isd200_read_regs(us);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) usb_stor_dbg(us, "-- auto-sense aborted\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) goto Handle_Abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) if (result == ISD200_GOOD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) isd200_build_sense(us, srb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) srb->result = SAM_STAT_CHECK_CONDITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) /* If things are really okay, then let's show that */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if ((srb->sense_buffer[2] & 0xf) == 0x0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) srb->result = SAM_STAT_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) srb->result = DID_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) /* Need reset here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) * Regardless of auto-sense, if we _know_ we have an error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) * condition, show that in the result code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) if (transferStatus == USB_STOR_TRANSPORT_FAILED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) srb->result = SAM_STAT_CHECK_CONDITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) * abort processing: the bulk-only transport requires a reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) * following an abort
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) Handle_Abort:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) srb->result = DID_ABORT << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) /* permit the reset transfer to take place */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) clear_bit(US_FLIDX_ABORTING, &us->dflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) /* Need reset here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) #ifdef CONFIG_USB_STORAGE_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) static void isd200_log_config(struct us_data *us, struct isd200_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) usb_stor_dbg(us, " Event Notification: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) info->ConfigData.EventNotification);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) usb_stor_dbg(us, " External Clock: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) info->ConfigData.ExternalClock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) usb_stor_dbg(us, " ATA Init Timeout: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) info->ConfigData.ATAInitTimeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) usb_stor_dbg(us, " ATAPI Command Block Size: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) (info->ConfigData.ATAConfig & ATACFG_BLOCKSIZE) >> 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) usb_stor_dbg(us, " Master/Slave Selection: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) info->ConfigData.ATAConfig & ATACFG_MASTER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) usb_stor_dbg(us, " ATAPI Reset: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) info->ConfigData.ATAConfig & ATACFG_ATAPI_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) usb_stor_dbg(us, " ATA Timing: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) info->ConfigData.ATAConfig & ATACFG_TIMING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) usb_stor_dbg(us, " ATA Major Command: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) info->ConfigData.ATAMajorCommand);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) usb_stor_dbg(us, " ATA Minor Command: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) info->ConfigData.ATAMinorCommand);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) usb_stor_dbg(us, " Init Status: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) info->ConfigData.ATAExtraConfig & ATACFGE_INIT_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) usb_stor_dbg(us, " Config Descriptor 2: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) info->ConfigData.ATAExtraConfig & ATACFGE_CONF_DESC2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) usb_stor_dbg(us, " Skip Device Boot: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) info->ConfigData.ATAExtraConfig & ATACFGE_SKIP_BOOT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) usb_stor_dbg(us, " ATA 3 State Suspend: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) info->ConfigData.ATAExtraConfig & ATACFGE_STATE_SUSPEND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) usb_stor_dbg(us, " Descriptor Override: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) info->ConfigData.ATAExtraConfig & ATACFGE_DESC_OVERRIDE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) usb_stor_dbg(us, " Last LUN Identifier: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) info->ConfigData.ATAExtraConfig & ATACFGE_LAST_LUN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) usb_stor_dbg(us, " SRST Enable: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) info->ConfigData.ATAExtraConfig & CFG_CAPABILITY_SRST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) * isd200_write_config
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) * Write the ISD200 Configuration data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) * RETURNS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) * ISD status code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) static int isd200_write_config( struct us_data *us )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) struct isd200_info *info = (struct isd200_info *)us->extra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) int retStatus = ISD200_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) #ifdef CONFIG_USB_STORAGE_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) usb_stor_dbg(us, "Entering isd200_write_config\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) usb_stor_dbg(us, " Writing the following ISD200 Config Data:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) isd200_log_config(us, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) /* let's send the command via the control pipe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) result = usb_stor_ctrl_transfer(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) us,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) us->send_ctrl_pipe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 0x0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 0x0002,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) (void *) &info->ConfigData,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) sizeof(info->ConfigData));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) if (result >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) usb_stor_dbg(us, " ISD200 Config Data was written successfully\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) usb_stor_dbg(us, " Request to write ISD200 Config Data failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) retStatus = ISD200_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) usb_stor_dbg(us, "Leaving isd200_write_config %08X\n", retStatus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) return retStatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) * isd200_read_config
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) * Reads the ISD200 Configuration data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) * RETURNS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) * ISD status code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) static int isd200_read_config( struct us_data *us )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) struct isd200_info *info = (struct isd200_info *)us->extra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) int retStatus = ISD200_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) usb_stor_dbg(us, "Entering isd200_read_config\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) /* read the configuration information from ISD200. Use this to */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) /* determine what the special ATA CDB bytes are. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) result = usb_stor_ctrl_transfer(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) us,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) us->recv_ctrl_pipe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 0x02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 0x0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 0x0002,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) (void *) &info->ConfigData,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) sizeof(info->ConfigData));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) if (result >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) usb_stor_dbg(us, " Retrieved the following ISD200 Config Data:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) #ifdef CONFIG_USB_STORAGE_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) isd200_log_config(us, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) usb_stor_dbg(us, " Request to get ISD200 Config Data failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) retStatus = ISD200_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) usb_stor_dbg(us, "Leaving isd200_read_config %08X\n", retStatus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) return retStatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) * isd200_atapi_soft_reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) * Perform an Atapi Soft Reset on the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) * RETURNS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) * NT status code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) static int isd200_atapi_soft_reset( struct us_data *us )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) int retStatus = ISD200_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) int transferStatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) usb_stor_dbg(us, "Entering isd200_atapi_soft_reset\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) transferStatus = isd200_action( us, ACTION_SOFT_RESET, NULL, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) if (transferStatus != ISD200_TRANSPORT_GOOD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) usb_stor_dbg(us, " Error issuing Atapi Soft Reset\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) retStatus = ISD200_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) usb_stor_dbg(us, "Leaving isd200_atapi_soft_reset %08X\n", retStatus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) return retStatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) * isd200_srst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) * Perform an SRST on the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) * RETURNS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) * ISD status code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) static int isd200_srst( struct us_data *us )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) int retStatus = ISD200_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) int transferStatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) usb_stor_dbg(us, "Entering isd200_SRST\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) transferStatus = isd200_action( us, ACTION_RESET, NULL, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) /* check to see if this request failed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) if (transferStatus != ISD200_TRANSPORT_GOOD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) usb_stor_dbg(us, " Error issuing SRST\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) retStatus = ISD200_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) /* delay 10ms to give the drive a chance to see it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) msleep(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) transferStatus = isd200_action( us, ACTION_REENABLE, NULL, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) if (transferStatus != ISD200_TRANSPORT_GOOD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) usb_stor_dbg(us, " Error taking drive out of reset\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) retStatus = ISD200_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) /* delay 50ms to give the drive a chance to recover after SRST */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) msleep(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) usb_stor_dbg(us, "Leaving isd200_srst %08X\n", retStatus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) return retStatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) * isd200_try_enum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) * Helper function for isd200_manual_enum(). Does ENUM and READ_STATUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) * and tries to analyze the status registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) * RETURNS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) * ISD status code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) static int isd200_try_enum(struct us_data *us, unsigned char master_slave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) int detect )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) int status = ISD200_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) unsigned long endTime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) struct isd200_info *info = (struct isd200_info *)us->extra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) unsigned char *regs = info->RegsBuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) int recheckAsMaster = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) if ( detect )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) endTime = jiffies + ISD200_ENUM_DETECT_TIMEOUT * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) endTime = jiffies + ISD200_ENUM_BSY_TIMEOUT * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) /* loop until we detect !BSY or timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) while(1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) status = isd200_action( us, ACTION_ENUM, NULL, master_slave );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if ( status != ISD200_GOOD )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) status = isd200_action( us, ACTION_READ_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) regs, 8 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) if ( status != ISD200_GOOD )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) if (!detect) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (regs[ATA_REG_STATUS_OFFSET] & ATA_BUSY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) usb_stor_dbg(us, " %s status is still BSY, try again...\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) master_slave == ATA_ADDRESS_DEVHEAD_STD ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) "Master" : "Slave");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) usb_stor_dbg(us, " %s status !BSY, continue with next operation\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) master_slave == ATA_ADDRESS_DEVHEAD_STD ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) "Master" : "Slave");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) /* check for ATA_BUSY and */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) /* ATA_DF (workaround ATA Zip drive) and */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) /* ATA_ERR (workaround for Archos CD-ROM) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) else if (regs[ATA_REG_STATUS_OFFSET] &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) (ATA_BUSY | ATA_DF | ATA_ERR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) usb_stor_dbg(us, " Status indicates it is not ready, try again...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) /* check for DRDY, ATA devices set DRDY after SRST */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) else if (regs[ATA_REG_STATUS_OFFSET] & ATA_DRDY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) usb_stor_dbg(us, " Identified ATA device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) info->DeviceFlags |= DF_ATA_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) info->DeviceHead = master_slave;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) * check Cylinder High/Low to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) * determine if it is an ATAPI device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) else if (regs[ATA_REG_HCYL_OFFSET] == 0xEB &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) regs[ATA_REG_LCYL_OFFSET] == 0x14) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) * It seems that the RICOH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) * MP6200A CD/RW drive will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) * report itself okay as a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) * slave when it is really a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) * master. So this check again
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) * as a master device just to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) * make sure it doesn't report
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) * itself okay as a master also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) if ((master_slave & ATA_ADDRESS_DEVHEAD_SLAVE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) !recheckAsMaster) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) usb_stor_dbg(us, " Identified ATAPI device as slave. Rechecking again as master\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) recheckAsMaster = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) master_slave = ATA_ADDRESS_DEVHEAD_STD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) usb_stor_dbg(us, " Identified ATAPI device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) info->DeviceHead = master_slave;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) status = isd200_atapi_soft_reset(us);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) usb_stor_dbg(us, " Not ATA, not ATAPI - Weird\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) /* check for timeout on this request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) if (time_after_eq(jiffies, endTime)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) if (!detect)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) usb_stor_dbg(us, " BSY check timeout, just continue with next operation...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) usb_stor_dbg(us, " Device detect timeout!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) * isd200_manual_enum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) * Determines if the drive attached is an ATA or ATAPI and if it is a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) * master or slave.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) * RETURNS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) * ISD status code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) static int isd200_manual_enum(struct us_data *us)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) struct isd200_info *info = (struct isd200_info *)us->extra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) int retStatus = ISD200_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) usb_stor_dbg(us, "Entering isd200_manual_enum\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) retStatus = isd200_read_config(us);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) if (retStatus == ISD200_GOOD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) int isslave;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) /* master or slave? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) retStatus = isd200_try_enum( us, ATA_ADDRESS_DEVHEAD_STD, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) if (retStatus == ISD200_GOOD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) retStatus = isd200_try_enum( us, ATA_ADDRESS_DEVHEAD_SLAVE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) if (retStatus == ISD200_GOOD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) retStatus = isd200_srst(us);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) if (retStatus == ISD200_GOOD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) /* ata or atapi? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) retStatus = isd200_try_enum( us, ATA_ADDRESS_DEVHEAD_STD, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) isslave = (info->DeviceHead & ATA_ADDRESS_DEVHEAD_SLAVE) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) if (!(info->ConfigData.ATAConfig & ATACFG_MASTER)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) usb_stor_dbg(us, " Setting Master/Slave selection to %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) isslave);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) info->ConfigData.ATAConfig &= 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) info->ConfigData.ATAConfig |= (isslave<<6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) retStatus = isd200_write_config(us);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) usb_stor_dbg(us, "Leaving isd200_manual_enum %08X\n", retStatus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) return(retStatus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) static void isd200_fix_driveid(u16 *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) #ifndef __LITTLE_ENDIAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) # ifdef __BIG_ENDIAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) for (i = 0; i < ATA_ID_WORDS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) id[i] = __le16_to_cpu(id[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) # else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) # error "Please fix <asm/byteorder.h>"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) # endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) static void isd200_dump_driveid(struct us_data *us, u16 *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) usb_stor_dbg(us, " Identify Data Structure:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) usb_stor_dbg(us, " config = 0x%x\n", id[ATA_ID_CONFIG]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) usb_stor_dbg(us, " cyls = 0x%x\n", id[ATA_ID_CYLS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) usb_stor_dbg(us, " heads = 0x%x\n", id[ATA_ID_HEADS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) usb_stor_dbg(us, " track_bytes = 0x%x\n", id[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) usb_stor_dbg(us, " sector_bytes = 0x%x\n", id[5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) usb_stor_dbg(us, " sectors = 0x%x\n", id[ATA_ID_SECTORS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) usb_stor_dbg(us, " serial_no[0] = 0x%x\n", *(char *)&id[ATA_ID_SERNO]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) usb_stor_dbg(us, " buf_type = 0x%x\n", id[20]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) usb_stor_dbg(us, " buf_size = 0x%x\n", id[ATA_ID_BUF_SIZE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) usb_stor_dbg(us, " ecc_bytes = 0x%x\n", id[22]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) usb_stor_dbg(us, " fw_rev[0] = 0x%x\n", *(char *)&id[ATA_ID_FW_REV]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) usb_stor_dbg(us, " model[0] = 0x%x\n", *(char *)&id[ATA_ID_PROD]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) usb_stor_dbg(us, " max_multsect = 0x%x\n", id[ATA_ID_MAX_MULTSECT] & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) usb_stor_dbg(us, " dword_io = 0x%x\n", id[ATA_ID_DWORD_IO]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) usb_stor_dbg(us, " capability = 0x%x\n", id[ATA_ID_CAPABILITY] >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) usb_stor_dbg(us, " tPIO = 0x%x\n", id[ATA_ID_OLD_PIO_MODES] >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) usb_stor_dbg(us, " tDMA = 0x%x\n", id[ATA_ID_OLD_DMA_MODES] >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) usb_stor_dbg(us, " field_valid = 0x%x\n", id[ATA_ID_FIELD_VALID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) usb_stor_dbg(us, " cur_cyls = 0x%x\n", id[ATA_ID_CUR_CYLS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) usb_stor_dbg(us, " cur_heads = 0x%x\n", id[ATA_ID_CUR_HEADS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) usb_stor_dbg(us, " cur_sectors = 0x%x\n", id[ATA_ID_CUR_SECTORS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) usb_stor_dbg(us, " cur_capacity = 0x%x\n", ata_id_u32(id, 57));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) usb_stor_dbg(us, " multsect = 0x%x\n", id[ATA_ID_MULTSECT] & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) usb_stor_dbg(us, " lba_capacity = 0x%x\n", ata_id_u32(id, ATA_ID_LBA_CAPACITY));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) usb_stor_dbg(us, " command_set_1 = 0x%x\n", id[ATA_ID_COMMAND_SET_1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) usb_stor_dbg(us, " command_set_2 = 0x%x\n", id[ATA_ID_COMMAND_SET_2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) * isd200_get_inquiry_data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) * Get inquiry data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) * RETURNS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) * ISD status code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) static int isd200_get_inquiry_data( struct us_data *us )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) struct isd200_info *info = (struct isd200_info *)us->extra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) int retStatus = ISD200_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) u16 *id = info->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) usb_stor_dbg(us, "Entering isd200_get_inquiry_data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) /* set default to Master */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) info->DeviceHead = ATA_ADDRESS_DEVHEAD_STD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) /* attempt to manually enumerate this device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) retStatus = isd200_manual_enum(us);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) if (retStatus == ISD200_GOOD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) int transferStatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) /* check for an ATA device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) if (info->DeviceFlags & DF_ATA_DEVICE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) /* this must be an ATA device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) /* perform an ATA Command Identify */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) transferStatus = isd200_action( us, ACTION_IDENTIFY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) id, ATA_ID_WORDS * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) if (transferStatus != ISD200_TRANSPORT_GOOD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) /* Error issuing ATA Command Identify */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) usb_stor_dbg(us, " Error issuing ATA Command Identify\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) retStatus = ISD200_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) /* ATA Command Identify successful */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) __be16 *src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) __u16 *dest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) isd200_fix_driveid(id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) isd200_dump_driveid(us, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) memset(&info->InquiryData, 0, sizeof(info->InquiryData));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) /* Standard IDE interface only supports disks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) info->InquiryData.DeviceType = DIRECT_ACCESS_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) /* The length must be at least 36 (5 + 31) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) info->InquiryData.AdditionalLength = 0x1F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) if (id[ATA_ID_COMMAND_SET_1] & COMMANDSET_MEDIA_STATUS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) /* set the removable bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) info->InquiryData.DeviceTypeModifier = DEVICE_REMOVABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) info->DeviceFlags |= DF_REMOVABLE_MEDIA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) /* Fill in vendor identification fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) src = (__be16 *)&id[ATA_ID_PROD];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) dest = (__u16*)info->InquiryData.VendorId;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) for (i = 0; i < 4; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) dest[i] = be16_to_cpu(src[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) src = (__be16 *)&id[ATA_ID_PROD + 8/2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) dest = (__u16*)info->InquiryData.ProductId;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) for (i=0;i<8;i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) dest[i] = be16_to_cpu(src[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) src = (__be16 *)&id[ATA_ID_FW_REV];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) dest = (__u16*)info->InquiryData.ProductRevisionLevel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) for (i=0;i<2;i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) dest[i] = be16_to_cpu(src[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) /* determine if it supports Media Status Notification */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) if (id[ATA_ID_COMMAND_SET_2] & COMMANDSET_MEDIA_STATUS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) usb_stor_dbg(us, " Device supports Media Status Notification\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) * Indicate that it is enabled, even
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) * though it is not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) * This allows the lock/unlock of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) * media to work correctly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) info->DeviceFlags |= DF_MEDIA_STATUS_ENABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) info->DeviceFlags &= ~DF_MEDIA_STATUS_ENABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) * this must be an ATAPI device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) * use an ATAPI protocol (Transparent SCSI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) us->protocol_name = "Transparent SCSI";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) us->proto_handler = usb_stor_transparent_scsi_command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) usb_stor_dbg(us, "Protocol changed to: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) us->protocol_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) /* Free driver structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) us->extra_destructor(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) kfree(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) us->extra = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) us->extra_destructor = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) usb_stor_dbg(us, "Leaving isd200_get_inquiry_data %08X\n", retStatus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) return(retStatus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) * isd200_scsi_to_ata
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) * Translate SCSI commands to ATA commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) * RETURNS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) * 1 if the command needs to be sent to the transport layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) * 0 otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) union ata_cdb * ataCdb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) struct isd200_info *info = (struct isd200_info *)us->extra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) u16 *id = info->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) int sendToTransport = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) unsigned char sectnum, head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) unsigned short cylinder;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) unsigned long lba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) unsigned long blockCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) unsigned char senseData[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) memset(ataCdb, 0, sizeof(union ata_cdb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) /* SCSI Command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) switch (srb->cmnd[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) case INQUIRY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) usb_stor_dbg(us, " ATA OUT - INQUIRY\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) /* copy InquiryData */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) usb_stor_set_xfer_buf((unsigned char *) &info->InquiryData,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) sizeof(info->InquiryData), srb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) srb->result = SAM_STAT_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) sendToTransport = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) case MODE_SENSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) usb_stor_dbg(us, " ATA OUT - SCSIOP_MODE_SENSE\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) /* Initialize the return buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) usb_stor_set_xfer_buf(senseData, sizeof(senseData), srb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) if (info->DeviceFlags & DF_MEDIA_STATUS_ENABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) ataCdb->generic.SignatureByte0 = info->ConfigData.ATAMajorCommand;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) ataCdb->generic.SignatureByte1 = info->ConfigData.ATAMinorCommand;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) ataCdb->generic.TransferBlockSize = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) ataCdb->generic.RegisterSelect = REG_COMMAND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) ataCdb->write.CommandByte = ATA_COMMAND_GET_MEDIA_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) isd200_srb_set_bufflen(srb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) usb_stor_dbg(us, " Media Status not supported, just report okay\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) srb->result = SAM_STAT_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) sendToTransport = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) case TEST_UNIT_READY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) usb_stor_dbg(us, " ATA OUT - SCSIOP_TEST_UNIT_READY\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) if (info->DeviceFlags & DF_MEDIA_STATUS_ENABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) ataCdb->generic.SignatureByte0 = info->ConfigData.ATAMajorCommand;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) ataCdb->generic.SignatureByte1 = info->ConfigData.ATAMinorCommand;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) ataCdb->generic.TransferBlockSize = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) ataCdb->generic.RegisterSelect = REG_COMMAND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) ataCdb->write.CommandByte = ATA_COMMAND_GET_MEDIA_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) isd200_srb_set_bufflen(srb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) usb_stor_dbg(us, " Media Status not supported, just report okay\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) srb->result = SAM_STAT_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) sendToTransport = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) case READ_CAPACITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) unsigned long capacity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) struct read_capacity_data readCapacityData;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) usb_stor_dbg(us, " ATA OUT - SCSIOP_READ_CAPACITY\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) if (ata_id_has_lba(id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) capacity = ata_id_u32(id, ATA_ID_LBA_CAPACITY) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) capacity = (id[ATA_ID_HEADS] * id[ATA_ID_CYLS] *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) id[ATA_ID_SECTORS]) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) readCapacityData.LogicalBlockAddress = cpu_to_be32(capacity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) readCapacityData.BytesPerBlock = cpu_to_be32(0x200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) usb_stor_set_xfer_buf((unsigned char *) &readCapacityData,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) sizeof(readCapacityData), srb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) srb->result = SAM_STAT_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) sendToTransport = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) case READ_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) usb_stor_dbg(us, " ATA OUT - SCSIOP_READ\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) lba = be32_to_cpu(*(__be32 *)&srb->cmnd[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) blockCount = (unsigned long)srb->cmnd[7]<<8 | (unsigned long)srb->cmnd[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) if (ata_id_has_lba(id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) sectnum = (unsigned char)(lba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) cylinder = (unsigned short)(lba>>8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) head = ATA_ADDRESS_DEVHEAD_LBA_MODE | (unsigned char)(lba>>24 & 0x0F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) sectnum = (u8)((lba % id[ATA_ID_SECTORS]) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) cylinder = (u16)(lba / (id[ATA_ID_SECTORS] *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) id[ATA_ID_HEADS]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) head = (u8)((lba / id[ATA_ID_SECTORS]) %
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) id[ATA_ID_HEADS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) ataCdb->generic.SignatureByte0 = info->ConfigData.ATAMajorCommand;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) ataCdb->generic.SignatureByte1 = info->ConfigData.ATAMinorCommand;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) ataCdb->generic.TransferBlockSize = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) ataCdb->generic.RegisterSelect =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) REG_SECTOR_COUNT | REG_SECTOR_NUMBER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) REG_CYLINDER_LOW | REG_CYLINDER_HIGH |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) REG_DEVICE_HEAD | REG_COMMAND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) ataCdb->write.SectorCountByte = (unsigned char)blockCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) ataCdb->write.SectorNumberByte = sectnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) ataCdb->write.CylinderHighByte = (unsigned char)(cylinder>>8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) ataCdb->write.CylinderLowByte = (unsigned char)cylinder;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) ataCdb->write.DeviceHeadByte = (head | ATA_ADDRESS_DEVHEAD_STD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) ataCdb->write.CommandByte = ATA_CMD_PIO_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) case WRITE_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) usb_stor_dbg(us, " ATA OUT - SCSIOP_WRITE\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) lba = be32_to_cpu(*(__be32 *)&srb->cmnd[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) blockCount = (unsigned long)srb->cmnd[7]<<8 | (unsigned long)srb->cmnd[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) if (ata_id_has_lba(id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) sectnum = (unsigned char)(lba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) cylinder = (unsigned short)(lba>>8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) head = ATA_ADDRESS_DEVHEAD_LBA_MODE | (unsigned char)(lba>>24 & 0x0F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) sectnum = (u8)((lba % id[ATA_ID_SECTORS]) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) cylinder = (u16)(lba / (id[ATA_ID_SECTORS] *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) id[ATA_ID_HEADS]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) head = (u8)((lba / id[ATA_ID_SECTORS]) %
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) id[ATA_ID_HEADS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) ataCdb->generic.SignatureByte0 = info->ConfigData.ATAMajorCommand;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) ataCdb->generic.SignatureByte1 = info->ConfigData.ATAMinorCommand;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) ataCdb->generic.TransferBlockSize = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) ataCdb->generic.RegisterSelect =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) REG_SECTOR_COUNT | REG_SECTOR_NUMBER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) REG_CYLINDER_LOW | REG_CYLINDER_HIGH |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) REG_DEVICE_HEAD | REG_COMMAND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) ataCdb->write.SectorCountByte = (unsigned char)blockCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) ataCdb->write.SectorNumberByte = sectnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) ataCdb->write.CylinderHighByte = (unsigned char)(cylinder>>8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) ataCdb->write.CylinderLowByte = (unsigned char)cylinder;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) ataCdb->write.DeviceHeadByte = (head | ATA_ADDRESS_DEVHEAD_STD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) ataCdb->write.CommandByte = ATA_CMD_PIO_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) case ALLOW_MEDIUM_REMOVAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) usb_stor_dbg(us, " ATA OUT - SCSIOP_MEDIUM_REMOVAL\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) if (info->DeviceFlags & DF_REMOVABLE_MEDIA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) usb_stor_dbg(us, " srb->cmnd[4] = 0x%X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) srb->cmnd[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) ataCdb->generic.SignatureByte0 = info->ConfigData.ATAMajorCommand;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) ataCdb->generic.SignatureByte1 = info->ConfigData.ATAMinorCommand;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) ataCdb->generic.TransferBlockSize = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) ataCdb->generic.RegisterSelect = REG_COMMAND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) ataCdb->write.CommandByte = (srb->cmnd[4] & 0x1) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) ATA_CMD_MEDIA_LOCK : ATA_CMD_MEDIA_UNLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) isd200_srb_set_bufflen(srb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) usb_stor_dbg(us, " Not removable media, just report okay\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) srb->result = SAM_STAT_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) sendToTransport = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) case START_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) usb_stor_dbg(us, " ATA OUT - SCSIOP_START_STOP_UNIT\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) usb_stor_dbg(us, " srb->cmnd[4] = 0x%X\n", srb->cmnd[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) if ((srb->cmnd[4] & 0x3) == 0x2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) usb_stor_dbg(us, " Media Eject\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) ataCdb->generic.SignatureByte0 = info->ConfigData.ATAMajorCommand;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) ataCdb->generic.SignatureByte1 = info->ConfigData.ATAMinorCommand;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) ataCdb->generic.TransferBlockSize = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) ataCdb->generic.RegisterSelect = REG_COMMAND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) ataCdb->write.CommandByte = ATA_COMMAND_MEDIA_EJECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) } else if ((srb->cmnd[4] & 0x3) == 0x1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) usb_stor_dbg(us, " Get Media Status\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) ataCdb->generic.SignatureByte0 = info->ConfigData.ATAMajorCommand;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) ataCdb->generic.SignatureByte1 = info->ConfigData.ATAMinorCommand;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) ataCdb->generic.TransferBlockSize = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) ataCdb->generic.RegisterSelect = REG_COMMAND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) ataCdb->write.CommandByte = ATA_COMMAND_GET_MEDIA_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) isd200_srb_set_bufflen(srb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) usb_stor_dbg(us, " Nothing to do, just report okay\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) srb->result = SAM_STAT_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) sendToTransport = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) usb_stor_dbg(us, "Unsupported SCSI command - 0x%X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) srb->cmnd[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) srb->result = DID_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) sendToTransport = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) return(sendToTransport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) * isd200_free_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) * Frees the driver structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) static void isd200_free_info_ptrs(void *info_)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) struct isd200_info *info = (struct isd200_info *) info_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) if (info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) kfree(info->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) kfree(info->RegsBuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) kfree(info->srb.sense_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) * isd200_init_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) * Allocates (if necessary) and initializes the driver structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) * RETURNS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) * ISD status code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) static int isd200_init_info(struct us_data *us)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) struct isd200_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) info = kzalloc(sizeof(struct isd200_info), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) return ISD200_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) info->id = kzalloc(ATA_ID_WORDS * 2, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) info->RegsBuf = kmalloc(sizeof(info->ATARegs), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) info->srb.sense_buffer = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) if (!info->id || !info->RegsBuf || !info->srb.sense_buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) isd200_free_info_ptrs(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) kfree(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) return ISD200_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) us->extra = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) us->extra_destructor = isd200_free_info_ptrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) return ISD200_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) * Initialization for the ISD200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) static int isd200_Initialization(struct us_data *us)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) usb_stor_dbg(us, "ISD200 Initialization...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) /* Initialize ISD200 info struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) if (isd200_init_info(us) == ISD200_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) usb_stor_dbg(us, "ERROR Initializing ISD200 Info struct\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) /* Get device specific data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) if (isd200_get_inquiry_data(us) != ISD200_GOOD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) usb_stor_dbg(us, "ISD200 Initialization Failure\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) usb_stor_dbg(us, "ISD200 Initialization complete\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) * Protocol and Transport for the ISD200 ASIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) * This protocol and transport are for ATA devices connected to an ISD200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) * ASIC. An ATAPI device that is connected as a slave device will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) * detected in the driver initialization function and the protocol will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) * be changed to an ATAPI protocol (Transparent SCSI).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) static void isd200_ata_command(struct scsi_cmnd *srb, struct us_data *us)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) int sendToTransport, orig_bufflen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) union ata_cdb ataCdb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) /* Make sure driver was initialized */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) if (us->extra == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) usb_stor_dbg(us, "ERROR Driver not initialized\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) srb->result = DID_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) scsi_set_resid(srb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) /* scsi_bufflen might change in protocol translation to ata */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) orig_bufflen = scsi_bufflen(srb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) sendToTransport = isd200_scsi_to_ata(srb, us, &ataCdb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) /* send the command to the transport layer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) if (sendToTransport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) isd200_invoke_transport(us, srb, &ataCdb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) isd200_srb_set_bufflen(srb, orig_bufflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) static struct scsi_host_template isd200_host_template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) static int isd200_probe(struct usb_interface *intf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) const struct usb_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) struct us_data *us;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) result = usb_stor_probe1(&us, intf, id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) (id - isd200_usb_ids) + isd200_unusual_dev_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) &isd200_host_template);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) us->protocol_name = "ISD200 ATA/ATAPI";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) us->proto_handler = isd200_ata_command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) result = usb_stor_probe2(us);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) static struct usb_driver isd200_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) .name = DRV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) .probe = isd200_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) .disconnect = usb_stor_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) .suspend = usb_stor_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) .resume = usb_stor_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) .reset_resume = usb_stor_reset_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) .pre_reset = usb_stor_pre_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) .post_reset = usb_stor_post_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) .id_table = isd200_usb_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) .soft_unbind = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) .no_dynamic_id = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) module_usb_stor_driver(isd200_driver, isd200_host_template, DRV_NAME);