18#if defined(linux) || defined(__linux__)
19# include <sys/ioctl.h>
20# ifdef HAVE_LINUX_COMPILER_H
21# include <linux/compiler.h>
23# if defined(HAVE_LINUX_CCISS_IOCTL_H)
24# include <linux/cciss_ioctl.h>
27# include <asm/byteorder.h>
29# define be32toh __be32_to_cpu
31#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
32# include <sys/endian.h>
33# include CISS_LOCATION
42const char * cciss_cpp_cvsid =
"$Id: cciss.cpp 4977 2019-11-22 19:57:04Z chrfranke $"
45typedef struct _ReportLUNdata_struct
47 uint32_t LUNListLength;
50} ReportLunData_struct;
54#define CISS_MAX_LUN 16
56#define CISS_MAX_PHYS_LUN 1024
57#define CISS_REPORT_PHYS 0xc3
59#define LSCSI_DRIVER_SENSE 0x8
60#define SEND_IOCTL_RESP_SENSE_LEN 16
62static int cciss_getlun(
int device,
int target,
unsigned char *physlun,
int report);
63static int cciss_sendpassthru(
unsigned int cmdtype,
unsigned char *
CDB,
64 unsigned int CDBlen,
char *buff,
65 unsigned int size,
unsigned int LunID,
66 unsigned char *scsi3addr,
int fd);
79 unsigned char phylun[8] = {0};
81 int status = cciss_getlun(device, target, phylun, report);
83 pout(
" cciss_getlun(%d, %d) = 0x%x; scsi3addr: %02x %02x %02x %02x %02x %02x %02x %02x\n",
84 device, target, status,
85 phylun[0], phylun[1], phylun[2], phylun[3], phylun[4], phylun[5], phylun[6], phylun[7]);
91 unsigned char * pBuf = (iop->
dxferp ? iop->
dxferp : sensebuf);
94 status = cciss_sendpassthru( 2, iop->
cmnd, iop->
cmnd_len, (
char*) pBuf, iBufLen, 1, phylun, device);
104 int trunc = (iop->
dxfer_len > 256) ? 1 : 0;
106 (trunc ?
" [only first 256 bytes shown]" :
""));
122 memcpy(iop->
sensep, pBuf, len);
126 pout(
" >>> Sense buffer, len=%d:\n", (
int)len);
127 dStrHex((
const uint8_t *)pBuf, len , 1);
133 pout(
" status=%x: sense_key=%x asc=%x ascq=%x\n", status & 0xff,
134 pBuf[2] & 0xf, pBuf[12], pBuf[13]);
137 pout(
" status=0x%x\n", status);
144 pout(
" ioctl status=0x%x but scsi status=0, fail with ENXIO\n", status);
149static int cciss_sendpassthru(
unsigned int cmdtype,
unsigned char *
CDB,
150 unsigned int CDBlen,
char *buff,
151 unsigned int size,
unsigned int LunID,
152 unsigned char *scsi3addr,
int fd)
155 IOCTL_Command_struct iocommand;
157 memset(&iocommand, 0,
sizeof(iocommand));
163 else if (cmdtype == 1)
165 iocommand.LUN_info.LogDev.VolId = LunID;
166 iocommand.LUN_info.LogDev.Mode = 1;
168 else if (cmdtype == 2)
170 memcpy(&iocommand.LUN_info.LunAddrBytes,scsi3addr,8);
171 iocommand.LUN_info.LogDev.Mode = 0;
175 pout(
"cciss_sendpassthru: bad cmdtype\n");
179 memcpy(&iocommand.Request.CDB[0],
CDB, CDBlen);
180 iocommand.Request.CDBLen = CDBlen;
181 iocommand.Request.Type.Type =
TYPE_CMD;
183 iocommand.Request.Type.Direction =
XFER_READ;
184 iocommand.Request.Timeout = 0;
186 iocommand.buf_size =
size;
187 iocommand.buf = (
unsigned char *)buff;
191 pout(
"CCISS ioctl error %d (fd %d CDBLen %u buf_size %u)\n",
192 fd, err, CDBlen,
size);
197static int cciss_getlun(
int device,
int target,
unsigned char *physlun,
int report)
199 unsigned char CDB[16]= {0};
200 ReportLunData_struct *luns;
201 int reportlunsize =
sizeof(*luns) + CISS_MAX_PHYS_LUN * 8;
204 luns = (ReportLunData_struct *)malloc(reportlunsize);
206 memset(luns, 0, reportlunsize);
209 CDB[0] = CISS_REPORT_PHYS;
210 CDB[6] = (reportlunsize >> 24) & 0xFF;
211 CDB[7] = (reportlunsize >> 16) & 0xFF;
212 CDB[8] = (reportlunsize >> 8) & 0xFF;
213 CDB[9] = reportlunsize & 0xFF;
215 if ((ret = cciss_sendpassthru(0,
CDB, 12, (
char *)luns, reportlunsize, 0, NULL, device)))
224 unsigned char *stuff = (
unsigned char *)luns;
226 pout(
"\n===== [%s] DATA START (BASE-16) =====\n",
"LUN DATA");
227 for (i=0; i<(
sizeof(_ReportLUNdata_struct)+15)/16; i++){
228 pout(
"%03d-%03d: ", 16*i, 16*(i+1)-1);
230 pout(
"%02x ",*stuff++);
231 pout(
"%02x\n",*stuff++);
233 pout(
"===== [%s] DATA END (%u Bytes) =====\n\n",
"LUN DATA", (
unsigned)
sizeof(_ReportLUNdata_struct));
236 if (target >= 0 && target < (
int) be32toh(luns->LUNListLength) / 8)
238 memcpy(physlun, luns->LUN[target], 8);
int cciss_io_interface(int device, int target, struct scsi_cmnd_io *iop, int report)
#define SEND_IOCTL_RESP_SENSE_LEN
#define LSCSI_DRIVER_SENSE
void dStrHex(const uint8_t *up, int len, int no_ascii)
#define DXFER_FROM_DEVICE
#define SCSI_STATUS_CHECK_CONDITION
void pout(const char *fmt,...)