Index: drivedb.h
===================================================================
--- drivedb.h	(revision 4002)
+++ drivedb.h	(working copy)
@@ -3276,6 +3276,12 @@
     "",
     "-d usbjmicron,0" // Port number is required
   },
+  { "USB: ; Prolific PL2773", // USB->SATA
+    "0x067b:0x2773",
+    "",
+    "",
+    "-d usbprolific"
+  },
   { "USB: ; Prolific PL3507", // USB+IEE1394->PATA
     "0x067b:0x3507",
     "", // 0x0001
Index: scsiata.cpp
===================================================================
--- scsiata.cpp	(revision 4002)
+++ scsiata.cpp	(working copy)
@@ -1120,6 +1120,147 @@
 
 /////////////////////////////////////////////////////////////////////////////
 
+/// Prolific USB Bridge support. (PL2773) (Probably works on PL2771 also...)
+
+class usbprolific_device
+: public tunnelled_device<
+    /*implements*/ ata_device,
+    /*by tunnelling through a*/ scsi_device
+  >
+{
+public:
+  usbprolific_device(smart_interface * intf, scsi_device * scsidev,
+                    const char * req_type);
+
+  virtual ~usbprolific_device() throw();
+
+  virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out);
+};
+
+
+usbprolific_device::usbprolific_device(smart_interface * intf, scsi_device * scsidev,
+                                     const char * req_type)
+: smart_device(intf, scsidev->get_dev_name(), "usbprolific", req_type),
+  tunnelled_device<ata_device, scsi_device>(scsidev)
+{
+  set_info().info_name = strprintf("%s [USB Prolific]", scsidev->get_info_name());
+}
+
+usbprolific_device::~usbprolific_device() throw()
+{
+}
+
+bool usbprolific_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out)
+{
+  if (!ata_cmd_is_supported(in,
+//    ata_device::supports_data_out |       // Does not work - better disable for now
+    ata_device::supports_smart_status,
+    "Prolific" )
+  )
+    return false;
+
+  scsi_cmnd_io io_hdr;
+  memset(&io_hdr, 0, sizeof(io_hdr));
+
+  switch (in.direction) {
+    case ata_cmd_in::no_data:
+      io_hdr.dxfer_dir = DXFER_NONE;
+      break;
+    case ata_cmd_in::data_in:
+      io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
+      io_hdr.dxfer_len = in.size;
+      io_hdr.dxferp = (unsigned char *)in.buffer;
+      memset(in.buffer, 0, in.size);
+      break;
+    case ata_cmd_in::data_out:
+      io_hdr.dxfer_dir = DXFER_TO_DEVICE;
+      io_hdr.dxfer_len = in.size;
+      io_hdr.dxferp = (unsigned char *)in.buffer;
+      break;
+    default:
+      return set_err(EINVAL);
+  }
+
+  // Based on reverse engineering of iSmart.exe with API Monitor. 
+  // http://www.prolific.com.tw/US/supportDownload.aspx?FileType=56&FileID=88&pcid=84&Page=0
+  // Seen commands:
+  // D0  0 0  0 06 7B 0 0 0 0 0 0                 // Read Firmware info?, reads 16 bytes
+  // F4  0 0  0 06 7B                             // ??
+  // D8 15 0 D8 06 7B 0 0 0 0 1 1 4F C2 A0 B0     // SMART Enable
+  // D8 15 0 D0 06 7B 0 0 2 0 1 1 4F C2 A0 B0     // SMART Read values
+  // D8 15 0 D1 06 7B 0 0 2 0 1 1 4F C2 A0 B0     // SMART Read thresholds
+  // D8 15 0 D4 06 7B 0 0 0 0 0 1 4F C2 A0 B0     // SMART Execute self test
+  // D7  0 0  0 06 7B 0 0 0 0 0 0 0 0 0 0         // Read status registers??, Reads 16 bytes of data, changes at self-test
+
+  // Build pass through command
+  unsigned char cdb[16];
+  cdb[ 0] = 0xD8;  // Prolific ATA pass through? (OPERATION CODE)
+  cdb[ 1] = 0x15;  // Magic?
+  cdb[ 2] = 0x0;   // Always 0?
+  cdb[ 3] = in.in_regs.features;        // SMART command 
+  cdb[ 4] = 0x06;  // VendorID magic? (Prolific VendorID: 0x067B)
+  cdb[ 5] = 0x7B;  // VendorID magic? (Prolific VendorID: 0x067B)
+  cdb[ 6] = 0;     // Always 0?
+  cdb[ 7] = 0;     // Always 0?
+  cdb[ 8] = (unsigned char)(io_hdr.dxfer_len >> 8);     // 2 when reading a sector
+  cdb[ 9] = (unsigned char)(io_hdr.dxfer_len     );     // Always 0? - Seems ok
+  cdb[10] = in.in_regs.sector_count;    // 0 when starting selftest
+  cdb[11] = in.in_regs.lba_low;         // LBA(7:0)   - Works for Log Address!
+  cdb[12] = in.in_regs.lba_mid;         // LBA(15:8)  - 0x4F
+  cdb[13] = in.in_regs.lba_high;        // LBA(23:16) - 0xC2
+  cdb[14] = in.in_regs.device | 0xA0;   // 0xA0;
+  cdb[15] = in.in_regs.command;         // ATA command
+
+//  printf("DEBUG:CDB %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n",
+//    cdb[0],cdb[1],cdb[2],cdb[3],cdb[4],cdb[5],cdb[6],cdb[7],
+//    cdb[8],cdb[9],cdb[10],cdb[11],cdb[12],cdb[13],cdb[14],cdb[15]);
+
+  io_hdr.cmnd = cdb;
+  io_hdr.cmnd_len = 16;
+
+  scsi_device * scsidev = get_tunnel_dev();
+  if (!scsi_pass_through_and_check(scsidev, &io_hdr,
+         "usbprolific_device::ata_pass_through: "))
+    return set_err(scsidev->get_err());
+
+  if (in.out_needed.is_set()) {
+    // Read ATA output registers
+    unsigned char regbuf[16] = {0, };
+    memset(&io_hdr, 0, sizeof(io_hdr));
+    io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
+    io_hdr.dxfer_len = sizeof(regbuf);
+    io_hdr.dxferp = regbuf;
+
+    memset(cdb, 0, sizeof(cdb));
+    cdb[ 0] = 0xD7;  // Prolific read registers?
+    cdb[ 4] = 0x06;  // VendorID magic? (Prolific VendorID: 0x067B)
+    cdb[ 5] = 0x7B;  // VendorID magic? (Prolific VendorID: 0x067B)
+    io_hdr.cmnd = cdb;
+    io_hdr.cmnd_len = sizeof(cdb);
+
+    if (!scsi_pass_through_and_check(scsidev, &io_hdr,
+           "usbprolific_device::scsi_pass_through (get registers): "))
+      return set_err(scsidev->get_err());
+
+//  printf("DEBUG:REG %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n",
+//    regbuf[0],regbuf[1],regbuf[2],regbuf[3],regbuf[4],regbuf[5],regbuf[6],regbuf[7],
+//    regbuf[8],regbuf[9],regbuf[10],regbuf[11],regbuf[12],regbuf[13],regbuf[14],regbuf[15]);
+//  // DEBUG:REG 50 0 0 0 0 0 4f 0 c2 0 a0 da 0 b0 0 50
+//    out.out_regs.error        = regbuf[X];
+//    out.out_regs.sector_count = regbuf[X];
+    out.out_regs.lba_low      = regbuf[4];  // Found by testing with other commands 
+    out.out_regs.lba_mid      = regbuf[6];
+    out.out_regs.lba_high     = regbuf[8];
+    out.out_regs.device       = regbuf[10];
+//    out.out_regs.status       = regbuf[X];
+  }
+
+  return true;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+
 /// SunplusIT USB Bridge support.
 
 class usbsunplus_device
@@ -1328,6 +1469,10 @@
     return new usbjmicron_device(this, scsidev, type, prolific, ata_48bit_support, port);
   }
 
+  else if (!strcmp(type, "usbprolific")) {
+    return new usbprolific_device(this, scsidev, type);
+  }
+
   else if (!strcmp(type, "usbsunplus")) {
     return new usbsunplus_device(this, scsidev, type);
   }
