| 1123 | /// Prolific USB Bridge support. (PL2773) (Probably works on PL2771 also...) |
| 1124 | |
| 1125 | class usbprolific_device |
| 1126 | : public tunnelled_device< |
| 1127 | /*implements*/ ata_device, |
| 1128 | /*by tunnelling through a*/ scsi_device |
| 1129 | > |
| 1130 | { |
| 1131 | public: |
| 1132 | usbprolific_device(smart_interface * intf, scsi_device * scsidev, |
| 1133 | const char * req_type); |
| 1134 | |
| 1135 | virtual ~usbprolific_device() throw(); |
| 1136 | |
| 1137 | virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out); |
| 1138 | }; |
| 1139 | |
| 1140 | |
| 1141 | usbprolific_device::usbprolific_device(smart_interface * intf, scsi_device * scsidev, |
| 1142 | const char * req_type) |
| 1143 | : smart_device(intf, scsidev->get_dev_name(), "usbprolific", req_type), |
| 1144 | tunnelled_device<ata_device, scsi_device>(scsidev) |
| 1145 | { |
| 1146 | set_info().info_name = strprintf("%s [USB Prolific]", scsidev->get_info_name()); |
| 1147 | } |
| 1148 | |
| 1149 | usbprolific_device::~usbprolific_device() throw() |
| 1150 | { |
| 1151 | } |
| 1152 | |
| 1153 | bool usbprolific_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out) |
| 1154 | { |
| 1155 | if (!ata_cmd_is_supported(in, |
| 1156 | // ata_device::supports_data_out | // Does not work - better disable for now |
| 1157 | ata_device::supports_48bit_hi_null | |
| 1158 | ata_device::supports_smart_status, |
| 1159 | "Prolific" ) |
| 1160 | ) |
| 1161 | return false; |
| 1162 | |
| 1163 | scsi_cmnd_io io_hdr; |
| 1164 | memset(&io_hdr, 0, sizeof(io_hdr)); |
| 1165 | |
| 1166 | switch (in.direction) { |
| 1167 | case ata_cmd_in::no_data: |
| 1168 | io_hdr.dxfer_dir = DXFER_NONE; |
| 1169 | break; |
| 1170 | case ata_cmd_in::data_in: |
| 1171 | io_hdr.dxfer_dir = DXFER_FROM_DEVICE; |
| 1172 | io_hdr.dxfer_len = in.size; |
| 1173 | io_hdr.dxferp = (unsigned char *)in.buffer; |
| 1174 | memset(in.buffer, 0, in.size); |
| 1175 | break; |
| 1176 | case ata_cmd_in::data_out: |
| 1177 | io_hdr.dxfer_dir = DXFER_TO_DEVICE; |
| 1178 | io_hdr.dxfer_len = in.size; |
| 1179 | io_hdr.dxferp = (unsigned char *)in.buffer; |
| 1180 | break; |
| 1181 | default: |
| 1182 | return set_err(EINVAL); |
| 1183 | } |
| 1184 | |
| 1185 | // Based on reverse engineering of iSmart.exe with API Monitor. |
| 1186 | // http://www.prolific.com.tw/US/supportDownload.aspx?FileType=56&FileID=88&pcid=84&Page=0 |
| 1187 | // Seen commands: |
| 1188 | // D0 0 0 0 06 7B 0 0 0 0 0 0 // Read Firmware info?, reads 16 bytes |
| 1189 | // F4 0 0 0 06 7B // ?? |
| 1190 | // D8 15 0 D8 06 7B 0 0 0 0 1 1 4F C2 A0 B0 // SMART Enable |
| 1191 | // D8 15 0 D0 06 7B 0 0 2 0 1 1 4F C2 A0 B0 // SMART Read values |
| 1192 | // D8 15 0 D1 06 7B 0 0 2 0 1 1 4F C2 A0 B0 // SMART Read thresholds |
| 1193 | // D8 15 0 D4 06 7B 0 0 0 0 0 1 4F C2 A0 B0 // SMART Execute self test |
| 1194 | // D7 0 0 0 06 7B 0 0 0 0 0 0 0 0 0 0 // Read status registers, Reads 16 bytes of data |
| 1195 | |
| 1196 | // Build pass through command |
| 1197 | unsigned char cdb[16]; |
| 1198 | cdb[ 0] = 0xD8; // Prolific ATA pass through? (OPERATION CODE) |
| 1199 | cdb[ 1] = 0x15; // Magic? |
| 1200 | cdb[ 2] = 0x0; // Always 0? |
| 1201 | cdb[ 3] = in.in_regs.features; // SMART command |
| 1202 | cdb[ 4] = 0x06; // VendorID magic? (Prolific VendorID: 0x067B) |
| 1203 | cdb[ 5] = 0x7B; // VendorID magic? (Prolific VendorID: 0x067B) |
| 1204 | cdb[ 6] = 0; // Always 0? |
| 1205 | cdb[ 7] = 0; // Always 0? |
| 1206 | cdb[ 8] = (unsigned char)(io_hdr.dxfer_len >> 8); // 2 when reading a sector |
| 1207 | cdb[ 9] = (unsigned char)(io_hdr.dxfer_len ); // Always 0? - Seems ok |
| 1208 | cdb[10] = in.in_regs.sector_count; // 0 when starting selftest |
| 1209 | cdb[11] = in.in_regs.lba_low; // LBA(7:0) - Works for Log Address! |
| 1210 | cdb[12] = in.in_regs.lba_mid; // LBA(15:8) - 0x4F |
| 1211 | cdb[13] = in.in_regs.lba_high; // LBA(23:16) - 0xC2 |
| 1212 | cdb[14] = 0xA0; // Is A0 for both drives attached |
| 1213 | cdb[15] = in.in_regs.command; // ATA command |
| 1214 | // Use '-r scsiioctl,1' to print CDB for debug purposes |
| 1215 | |
| 1216 | io_hdr.cmnd = cdb; |
| 1217 | io_hdr.cmnd_len = 16; |
| 1218 | |
| 1219 | scsi_device * scsidev = get_tunnel_dev(); |
| 1220 | if (!scsi_pass_through_and_check(scsidev, &io_hdr, |
| 1221 | "usbprolific_device::ata_pass_through: ")) |
| 1222 | return set_err(scsidev->get_err()); |
| 1223 | |
| 1224 | if (in.out_needed.is_set()) { |
| 1225 | // Read ATA output registers |
| 1226 | unsigned char regbuf[16] = {0, }; |
| 1227 | memset(&io_hdr, 0, sizeof(io_hdr)); |
| 1228 | io_hdr.dxfer_dir = DXFER_FROM_DEVICE; |
| 1229 | io_hdr.dxfer_len = sizeof(regbuf); |
| 1230 | io_hdr.dxferp = regbuf; |
| 1231 | |
| 1232 | memset(cdb, 0, sizeof(cdb)); |
| 1233 | cdb[ 0] = 0xD7; // Prolific read registers? |
| 1234 | cdb[ 4] = 0x06; // VendorID magic? (Prolific VendorID: 0x067B) |
| 1235 | cdb[ 5] = 0x7B; // VendorID magic? (Prolific VendorID: 0x067B) |
| 1236 | io_hdr.cmnd = cdb; |
| 1237 | io_hdr.cmnd_len = sizeof(cdb); |
| 1238 | |
| 1239 | if (!scsi_pass_through_and_check(scsidev, &io_hdr, |
| 1240 | "usbprolific_device::scsi_pass_through (get registers): ")) |
| 1241 | return set_err(scsidev->get_err()); |
| 1242 | |
| 1243 | // Use '-r scsiioctl,2' to print input registers for debug purposes |
| 1244 | // Example: 50 00 00 00 00 01 4f 00 c2 00 a0 da 00 b0 00 50 |
| 1245 | // out.out_regs.status = regbuf[0]; // Guess: Was seen go 51 to indicate error |
| 1246 | // out.out_regs.error = regbuf[1]; // Guess: Was seen go 04 to indicate ABRT |
| 1247 | // out.out_regs.sector_count = regbuf[X]; // Not found... |
| 1248 | out.out_regs.lba_low = regbuf[4]; // Found by testing Log Address |
| 1249 | out.out_regs.lba_mid = regbuf[6]; // Needed for SMART STATUS |
| 1250 | out.out_regs.lba_high = regbuf[8]; // Needed for SMART STATUS |
| 1251 | out.out_regs.device = regbuf[10]; // Always A0? |
| 1252 | // = regbuf[11]; // ATA Feature |
| 1253 | // = regbuf[13]; // ATA Command |
| 1254 | } |
| 1255 | |
| 1256 | return true; |
| 1257 | } |
| 1258 | |
| 1259 | |
| 1260 | ///////////////////////////////////////////////////////////////////////////// |
| 1261 | |