-// Areca RAID Controller
-bool win_areca_device::arcmsr_ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out)
-{
- // ATA input registers
- typedef struct _ATA_INPUT_REGISTERS
- {
- unsigned char features;
- unsigned char sector_count;
- unsigned char sector_number;
- unsigned char cylinder_low;
- unsigned char cylinder_high;
- unsigned char device_head;
- unsigned char command;
- unsigned char reserved[8];
- unsigned char data[512]; // [in/out] buffer for outgoing/incoming data
- } sATA_INPUT_REGISTERS;
-
- // ATA output registers
- // Note: The output registers is re-sorted for areca internal use only
- typedef struct _ATA_OUTPUT_REGISTERS
- {
- unsigned char error;
- unsigned char status;
- unsigned char sector_count;
- unsigned char sector_number;
- unsigned char cylinder_low;
- unsigned char cylinder_high;
- } sATA_OUTPUT_REGISTERS;
-
- // Areca packet format for outgoing:
- // B[0~2] : 3 bytes header, fixed value 0x5E, 0x01, 0x61
- // B[3~4] : 2 bytes command length + variant data length, little endian
- // B[5] : 1 bytes areca defined command code, ATA passthrough command code is 0x1c
- // B[6~last-1] : variant bytes payload data
- // B[last] : 1 byte checksum, simply sum(B[3] ~ B[last -1])
- //
- //
- // header 3 bytes length 2 bytes cmd 1 byte payload data x bytes cs 1 byte
- // +--------------------------------------------------------------------------------+
- // + 0x5E 0x01 0x61 | 0x00 0x00 | 0x1c | .................... | 0x00 |
- // +--------------------------------------------------------------------------------+
- //
-
- //Areca packet format for incoming:
- // B[0~2] : 3 bytes header, fixed value 0x5E, 0x01, 0x61
- // B[3~4] : 2 bytes payload length, little endian
- // B[5~last-1] : variant bytes returned payload data
- // B[last] : 1 byte checksum, simply sum(B[3] ~ B[last -1])
- //
- //
- // header 3 bytes length 2 bytes payload data x bytes cs 1 byte
- // +-------------------------------------------------------------------+
- // + 0x5E 0x01 0x61 | 0x00 0x00 | .................... | 0x00 |
- // +-------------------------------------------------------------------+
- unsigned char areca_packet[640];
- int areca_packet_len = sizeof(areca_packet);
- unsigned char cs = 0;
-
- sATA_INPUT_REGISTERS *ata_cmd;
-
- // For debugging
-#if 0
- memset(sInq, 0, sizeof(sInq));
- scsiStdInquiry(fd, (unsigned char *)sInq, (int)sizeof(sInq));
- dumpdata((unsigned char *)sInq, sizeof(sInq));
-#endif
- memset(areca_packet, 0, areca_packet_len);
+ // Interpret RAID drive map if present
+ if (vers_ex.wIdentifier == SMART_VENDOR_3WARE) {
+ // Skip if too many controllers or logical drive from this controller already seen
+ if (!(vers_ex.wControllerId < max_raid && !raid_seen[vers_ex.wControllerId]))
+ continue;
+ raid_seen[vers_ex.wControllerId] = true;
+ // Add physical drives
+ int len = strlen(name);
+ for (unsigned int pi = 0; pi < 32; pi++) {
+ if (vers_ex.dwDeviceMapEx & (1L << pi)) {
+ snprintf(name+len, sizeof(name)-1-len, ",%u", pi);
+ devlist.push_back( new win_ata_device(this, name, "ata") );
+ }
+ }
+ continue;
+ }