Back to cciss.sourceforge.net main page
So, what would it take to get cciss_vol_status to work with the MSA1000 (and similar) on FreeBSD?
You need to port this function:
726 int do_sg_io(int fd, unsigned char *cdb, unsigned char cdblen, unsigned char *buffer, 727 unsigned int buf_size, int direction) 728 { 729 int status; 730 sg_io_hdr_t sgio; 731 unsigned char sensebuffer[64]; 732 733 memset(buffer, 0, buf_size); 734 memset(&sgio, 0, sizeof(sgio)); 735 736 setup_sgio(&sgio, (unsigned char *) cdb, cdblen, buffer, 737 buf_size, sensebuffer, sizeof(sensebuffer), direction); 738 739 status = ioctl(fd, SG_IO, &sgio); 740 741 if (status == 0 && sgio.host_status == 0 && sgio.driver_status == 0) { /* cmd succeeded */ 742 if (sgio.status == 0 || (sgio.status == 2 && 743 (((sensebuffer[2] & 0x0f) == 0x00) || /* no error */ 744 ((sensebuffer[2] & 0x0f) == 0x01)))) { 745 return 0; 746 } 747 if (debug_sgio) 748 fprintf(stderr, "sgio cmd 0x%02x check condition, sense key = %d\n", 749 cdb[0], sensebuffer[2] & 0x0f); 750 return -1; 751 } 752 if (debug_sgio) 753 fprintf(stderr, "sgio ioctl: %d, cdb[0]=0x%02x, " 754 "status host/driver/scsi/sensekey = %d/%d/%d/0x%02x\n", 755 status, cdb[0], sgio.host_status, sgio.driver_status, 756 sgio.status, sensebuffer[2]); 757 return -1; 758 }
You can ignore the innards, and just implement a function with the same prototype which takes a file descriptor to the device you want to talk to, a SCSI CDB, CDB length, data buffer, and direction. The direction, as used in this program is always from the device, SG_DXFER_TO_FROM_DEV, but the possible values are these, from the linux kernel, include/scsi/sg.h:
/* Use negative values to flag difference from original sg_header structure */ #define SG_DXFER_NONE (-1) /* e.g. a SCSI Test Unit Ready command */ #define SG_DXFER_TO_DEV (-2) /* e.g. a SCSI WRITE command */ #define SG_DXFER_FROM_DEV (-3) /* e.g. a SCSI READ command */ #define SG_DXFER_TO_FROM_DEV (-4) /* treated like SG_DXFER_FROM_DEV with the additional property than during indirect IO the user buffer is copied into the kernel buffers before the transfer */ #define SG_DXFER_UNKNOWN (-5) /* Unknown data direction */
Once a FreeBSD version of this do_sg_io function exists, I think we'll be 98% of the way towards getting the MSA1000 to be working with cciss_vol_status on FreeBSD.
I looked into doing this myself, but it seems rather complicated and I don't know that much about FreeBSD. So I'm going to leave this task for others more knowledgeable. I can give some hints though. The sg3_utils package contains a file called sg_pt_freebsd.c, which implements a SCSI passthrough for FreeBSD. However, it's considerably more complicated than the code above, and I could not immediately see how to form a drop-in replacement for the above code for use on FreeBSD. Well, that's all the hints I have.
It may turn out to be the case that the way FreeBSD's SCSI system works (however that may be) is such that constructing a function which takes a file descriptor as do_sg_io does and expecting to be able to send arbitrary SCSI CDBs to the device just isn't how it works. If that's the case, then obviously what I've outlined here won't work as I've described it.
Feel free to send me a patch.