25static void dumpdata(
unsigned char *block,
int len)
27 int ln = (len / 16) + 1;
31 printf(
" Address = %p, Length = (0x%x)%d\n", block, len, len);
32 printf(
" 0 1 2 3 4 5 6 7 8 9 A B C D E F ASCII \n");
33 printf(
"=====================================================================\n");
35 for (
int l = 0; l < ln && len; l++ )
40 for ( pos = 0; pos < 16 && len; pos++, len-- )
48 for (
int loop = pos; loop < 16; loop++ )
55 for (
int loop = 0; loop < pos; loop++ )
58 if ( c >= 0x20 && c <= 0x7F )
69 printf(
"=====================================================================\n");
114 ARCMSR_IOCTL_READ_RQBUFFER,
115 ARCMSR_IOCTL_WRITE_WQBUFFER,
116 ARCMSR_IOCTL_CLEAR_RQBUFFER,
117 ARCMSR_IOCTL_CLEAR_WQBUFFER,
118 ARCMSR_IOCTL_RETURN_CODE_3F
127 uint8_t sense[32]={};
129 unsigned char *areca_return_packet;
132 unsigned char return_buff[2048]={0};
133 unsigned char *ptr = &return_buff[0];
135 memset((
unsigned char *)&sBuf, 0,
sizeof(sBuf));
142 switch ( arcmsr_cmd )
146 if (
data && data_len )
171 cdb[5] = cmds[arcmsr_cmd] >> 24;
172 cdb[6] = cmds[arcmsr_cmd] >> 16;
173 cdb[7] = cmds[arcmsr_cmd] >> 8;
174 cdb[8] = cmds[arcmsr_cmd] & 0x0F;
178 iop.
dxferp = (
unsigned char *)&sBuf;
205 if ( expected < 0 && total >= 5 )
207 areca_return_packet = (
unsigned char *)&return_buff[0];
208 if ( areca_return_packet[0] == 0x5E &&
209 areca_return_packet[1] == 0x01 &&
210 areca_return_packet[2] == 0x61 )
215 expected = areca_return_packet[4] * 256 + areca_return_packet[3] + 6;
219 if ( total >= 7 && total >= expected )
238 pout(
"do_scsi_cmnd_io with write buffer failed code = %x\n", ioctlreturn);
244 pout(
"io_hdr.scsi_status with write buffer failed code = %x\n", iop.
scsi_status);
250 memcpy(
data, return_buff, total);
273 unsigned char return_buff[2048];
274 unsigned char cs = 0;
278 cs_pos = areca_packet_len - 1;
279 for(
int i = 3; i < cs_pos; i++)
281 areca_packet[cs_pos] += areca_packet[i];
299 if ( expected < 3 + 1 )
311 for (
int loop = 3; loop < expected - 1; loop++ )
313 cs += return_buff[loop];
316 if ( return_buff[expected - 1] != cs )
321 memcpy(result, return_buff, expected);
329 unsigned char return_buff[2048];
330 unsigned char areca_packet[] = {0x5E, 0x01, 0x61, 0x01, 0x00, 0x23, 0x00};
332 memset(return_buff, 0,
sizeof(return_buff));
339 return return_buff[0xc2];
345 unsigned char return_buff[2048];
349 unsigned char areca_packet[] = {0x5E, 0x01, 0x61, 0x03, 0x00, 0x22,
350 (
unsigned char)(disknum - 1), (
unsigned char)(encnum - 1), 0x00};
352 memset(return_buff, 0,
sizeof(return_buff));
366 if( ctlr_type == 0x02 ||
367 (ctlr_type == 0x03 && return_buff[0x52] & 0x01 ) )
380 typedef struct _ATA_INPUT_REGISTERS
382 unsigned char features;
383 unsigned char sector_count;
384 unsigned char sector_number;
385 unsigned char cylinder_low;
386 unsigned char cylinder_high;
387 unsigned char device_head;
388 unsigned char command;
389 unsigned char reserved[8];
390 unsigned char data[512];
391 } sATA_INPUT_REGISTERS;
395 typedef struct _ATA_OUTPUT_REGISTERS
398 unsigned char status;
399 unsigned char sector_count;
400 unsigned char sector_number;
401 unsigned char cylinder_low;
402 unsigned char cylinder_high;
403 } sATA_OUTPUT_REGISTERS;
430 unsigned char areca_packet[640];
431 int areca_packet_len =
sizeof(areca_packet);
432 unsigned char return_buff[2048];
435 sATA_INPUT_REGISTERS *ata_cmd;
439 memset(sInq, 0,
sizeof(sInq));
441 dumpdata((
unsigned char *)sInq,
sizeof(sInq));
443 memset(areca_packet, 0, areca_packet_len);
446 areca_packet[0] = 0x5E;
447 areca_packet[1] = 0x01;
448 areca_packet[2] = 0x61;
449 areca_packet[3] = (
unsigned char)((areca_packet_len - 6) & 0xff);
450 areca_packet[4] = (
unsigned char)(((areca_packet_len - 6) >> 8) & 0xff);
451 areca_packet[5] = 0x1c;
454 memcpy(&areca_packet[7],
"SmrT", 4);
455 ata_cmd = (sATA_INPUT_REGISTERS *)&areca_packet[12];
462 ata_cmd->sector_number = r.
lba_low;
463 ata_cmd->cylinder_low = r.
lba_mid;
464 ata_cmd->cylinder_high = r.
lba_high;
465 ata_cmd->device_head = r.
device;
468 bool readdata =
false;
472 areca_packet[6] = 0x13;
477 areca_packet[6] = 0x15;
483 areca_packet[6] = 0x14;
500 sATA_OUTPUT_REGISTERS *ata_out = (sATA_OUTPUT_REGISTERS *)&return_buff[5] ;
501 if ( ata_out->status )
519 r.
error = ata_out->error;
521 r.
lba_low = ata_out->sector_number;
522 r.
lba_mid = ata_out->cylinder_low;
523 r.
lba_high = ata_out->cylinder_high;
524 r.
status = ata_out->status;
556 unsigned char areca_packet[640];
557 int areca_packet_len =
sizeof(areca_packet);
558 unsigned char return_buff[2048];
562 set_err(EINVAL,
"cmnd_len too large");
566 memset(areca_packet, 0, areca_packet_len);
569 areca_packet[0] = 0x5E;
570 areca_packet[1] = 0x01;
571 areca_packet[2] = 0x61;
572 areca_packet[3] = (
unsigned char)((areca_packet_len - 6) & 0xff);
573 areca_packet[4] = (
unsigned char)(((areca_packet_len - 6) >> 8) & 0xff);
574 areca_packet[5] = 0x1c;
577 areca_packet[6] = 0x16;
578 memcpy(&areca_packet[7],
"SmrT", 4);
581 areca_packet[15] = (
unsigned char)iop->
dxfer_len;
582 areca_packet[16] = (
unsigned char)(iop->
dxfer_len >> 8);
583 areca_packet[17] = (
unsigned char)(iop->
dxfer_len >> 16);
584 areca_packet[18] = (
unsigned char)(iop->
dxfer_len >> 24);
587 areca_packet[13] |= 0x01;
608 return set_err(EIO,
"arcmsr_scsi_pass_through: I/O error");
610 return set_err(EIO,
"arcmsr_scsi_pass_through: missing data (%d bytes, expected %d)", expected, 15);
613 int in_data_len = return_buff[11] | return_buff[12] << 8 | return_buff[13] << 16 | return_buff[14] << 24;
618 memcpy(iop->
dxferp, &return_buff[15], in_data_len);
637 iop->
sensep[0] = return_buff[7];
638 iop->
sensep[1] = return_buff[8];
639 iop->
sensep[2] = return_buff[9];
640 iop->
sensep[3] = return_buff[10];
#define ATA_IDENTIFY_DEVICE
virtual bool ata_pass_through(const ata_cmd_in &in, ata_cmd_out &out) override
ATA pass through.
virtual bool scsi_pass_through(scsi_cmnd_io *iop) override
SCSI pass through.
bool ata_cmd_is_supported(const ata_cmd_in &in, unsigned flags, const char *type=0)
Check command input parameters.
virtual int arcmsr_get_dev_type()
virtual int arcmsr_do_scsi_io(struct scsi_cmnd_io *iop)=0
virtual int arcmsr_get_controller_type()
void set_disknum(int disknum)
virtual bool arcmsr_lock()=0
virtual bool arcmsr_unlock()=0
void set_encnum(int encnum)
virtual bool arcmsr_probe()
virtual bool arcmsr_ata_pass_through(const ata_cmd_in &in, ata_cmd_out &out)
virtual int arcmsr_ui_handler(unsigned char *areca_packet, int areca_packet_len, unsigned char *result)
virtual int arcmsr_command_handler(unsigned long arcmsr_cmd, unsigned char *data, int data_len)
virtual bool arcmsr_scsi_pass_through(scsi_cmnd_io *iop)
Base class for all devices.
bool set_err(int no, const char *msg,...) __attribute_format_printf(3
Set last error number and message.
virtual bool is_open() const =0
Return true if device is open.
device_info & set_info()
R/W access to device info struct.
virtual bool open()=0
Open device, return false on error.
The platform interface abstraction.
const char * dev_areca_cpp_cvsid
struct _ARCMSR_IO_HDR sARCMSR_IO_HDR
#define DEV_ARECA_H_CVSID
int scsiStdInquiry(scsi_device *device, uint8_t *pBuf, int bufLen)
#define DXFER_FROM_DEVICE
#define SCSI_TIMEOUT_DEFAULT
#define SCSI_STATUS_CHECK_CONDITION
void pout(const char *fmt,...)
unsigned int HeaderLength
unsigned char Signature[8]
unsigned char ioctldatabuffer[1032]
ATA pass through input parameters.
enum ata_cmd_in::@29 direction
I/O direction.
void * buffer
Pointer to data buffer.
ata_in_regs_48bit in_regs
Input registers.
unsigned size
Size of buffer.
ATA pass through output parameters.
ata_out_regs_48bit out_regs
Output registers.
ATA Input registers (for 28-bit commands)
ata_register sector_count
ATA Output registers (for 28-bit commands)
ata_register sector_count
std::string info_name
Informal name.
std::string strprintf(const char *fmt,...)
bool nonempty(const void *data, int size)