Ticket #482: PL2773_ver2.patch

File PL2773_ver2.patch, 7.6 KB (added by TomVe, 9 years ago)

Patch against SVN rev. 4002

  • drivedb.h

     
    32763276    "",
    32773277    "-d usbjmicron,0" // Port number is required
    32783278  },
     3279  { "USB: ; Prolific PL2773", // USB->SATA
     3280    "0x067b:0x2773",
     3281    "",
     3282    "",
     3283    "-d usbprolific"
     3284  },
    32793285  { "USB: ; Prolific PL3507", // USB+IEE1394->PATA
    32803286    "0x067b:0x3507",
    32813287    "", // 0x0001
  • scsiata.cpp

     
    11201120
    11211121/////////////////////////////////////////////////////////////////////////////
    11221122
     1123/// Prolific USB Bridge support. (PL2773) (Probably works on PL2771 also...)
     1124
     1125class usbprolific_device
     1126: public tunnelled_device<
     1127    /*implements*/ ata_device,
     1128    /*by tunnelling through a*/ scsi_device
     1129  >
     1130{
     1131public:
     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
     1141usbprolific_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
     1149usbprolific_device::~usbprolific_device() throw()
     1150{
     1151}
     1152
     1153bool 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
    11231262/// SunplusIT USB Bridge support.
    11241263
    11251264class usbsunplus_device
     
    13281467    return new usbjmicron_device(this, scsidev, type, prolific, ata_48bit_support, port);
    13291468  }
    13301469
     1470  else if (!strcmp(type, "usbprolific")) {
     1471    return new usbprolific_device(this, scsidev, type);
     1472  }
     1473
    13311474  else if (!strcmp(type, "usbsunplus")) {
    13321475    return new usbsunplus_device(this, scsidev, type);
    13331476  }
  • smartctl.8.in

     
    338338\'\-d usbjmicron,p\'.
    339339Note that this does not yet support the SMART status command.
    340340
     341.I usbprolific
     342\- this device type is for SATA disks that are behind a Prolific P2773 USB to
     343SATA bridge. This driver may work with other Prolific P277x devices - this is
     344however untested.
     345
    341346.I usbsunplus
    342347\- this device type is for SATA disks that are behind a SunplusIT USB to SATA
    343348bridge.
  • smartd.conf.5.in

     
    376376\'\-d usbjmicron,p\'.
    377377Note that this does not yet support the SMART status command.
    378378
     379.I usbprolific
     380\- this device type is for SATA disks that are behind a Prolific P2773 USB to
     381SATA bridge. This driver may work with other Prolific P277x devices - this is
     382however untested.
     383
    379384.I usbsunplus
    380385\- this device type is for SATA disks that are behind a SunplusIT USB to SATA
    381386bridge.