Skip to content

Instantly share code, notes, and snippets.

@fuzzy
Created June 5, 2011 18:17
Show Gist options
  • Save fuzzy/1009243 to your computer and use it in GitHub Desktop.
Save fuzzy/1009243 to your computer and use it in GitHub Desktop.
#include <Python.h>
#include <sys/ioctl.h>
#include <sys/stdint.h>
#include <sys/types.h>
#include <sys/endian.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
#include <err.h>
#include <libutil.h>
#include <cam/cam.h>
#include <cam/cam_debug.h>
#include <cam/cam_ccb.h>
#include <cam/scsi/scsi_all.h>
#include <cam/scsi/scsi_da.h>
#include <cam/scsi/scsi_pass.h>
#include <cam/scsi/scsi_message.h>
#include <cam/ata/ata_all.h>
#include <camlib.h>
typedef enum {
CAM_CMD_NONE = 0x00000000,
CAM_CMD_DEVLIST = 0x00000001,
CAM_CMD_TUR = 0x00000002,
CAM_CMD_INQUIRY = 0x00000003,
CAM_CMD_STARTSTOP = 0x00000004,
CAM_CMD_RESCAN = 0x00000005,
CAM_CMD_READ_DEFECTS = 0x00000006,
CAM_CMD_MODE_PAGE = 0x00000007,
CAM_CMD_SCSI_CMD = 0x00000008,
CAM_CMD_DEVTREE = 0x00000009,
CAM_CMD_USAGE = 0x0000000a,
CAM_CMD_DEBUG = 0x0000000b,
CAM_CMD_RESET = 0x0000000c,
CAM_CMD_FORMAT = 0x0000000d,
CAM_CMD_TAG = 0x0000000e,
CAM_CMD_RATE = 0x0000000f,
CAM_CMD_DETACH = 0x00000010,
CAM_CMD_REPORTLUNS = 0x00000011,
CAM_CMD_READCAP = 0x00000012,
CAM_CMD_IDENTIFY = 0x00000013,
CAM_CMD_IDLE = 0x00000014,
CAM_CMD_STANDBY = 0x00000015,
CAM_CMD_SLEEP = 0x00000016
} cam_cmdmask;
typedef enum {
CAM_ARG_NONE = 0x00000000,
CAM_ARG_VERBOSE = 0x00000001,
CAM_ARG_DEVICE = 0x00000002,
CAM_ARG_BUS = 0x00000004,
CAM_ARG_TARGET = 0x00000008,
CAM_ARG_LUN = 0x00000010,
CAM_ARG_EJECT = 0x00000020,
CAM_ARG_UNIT = 0x00000040,
CAM_ARG_FORMAT_BLOCK = 0x00000080,
CAM_ARG_FORMAT_BFI = 0x00000100,
CAM_ARG_FORMAT_PHYS = 0x00000200,
CAM_ARG_PLIST = 0x00000400,
CAM_ARG_GLIST = 0x00000800,
CAM_ARG_GET_SERIAL = 0x00001000,
CAM_ARG_GET_STDINQ = 0x00002000,
CAM_ARG_GET_XFERRATE = 0x00004000,
CAM_ARG_INQ_MASK = 0x00007000,
CAM_ARG_MODE_EDIT = 0x00008000,
CAM_ARG_PAGE_CNTL = 0x00010000,
CAM_ARG_TIMEOUT = 0x00020000,
CAM_ARG_CMD_IN = 0x00040000,
CAM_ARG_CMD_OUT = 0x00080000,
CAM_ARG_DBD = 0x00100000,
CAM_ARG_ERR_RECOVER = 0x00200000,
CAM_ARG_RETRIES = 0x00400000,
CAM_ARG_START_UNIT = 0x00800000,
CAM_ARG_DEBUG_INFO = 0x01000000,
CAM_ARG_DEBUG_TRACE = 0x02000000,
CAM_ARG_DEBUG_SUBTRACE = 0x04000000,
CAM_ARG_DEBUG_CDB = 0x08000000,
CAM_ARG_DEBUG_XPT = 0x10000000,
CAM_ARG_DEBUG_PERIPH = 0x20000000,
} cam_argmask;
cam_cmdmask cmdlist;
cam_argmask arglist;
static int
parse_btl(char *tstr, int *bus, int *target, int *lun, cam_argmask *arglst)
{
char *tmpstr;
int convs = 0;
while (isspace(*tstr) && (*tstr != '\0'))
tstr++;
tmpstr = (char *)strtok(tstr, ":");
if ((tmpstr != NULL) && (*tmpstr != '\0')) {
*bus = strtol(tmpstr, NULL, 0);
*arglst |= CAM_ARG_BUS;
convs++;
tmpstr = (char *)strtok(NULL, ":");
if ((tmpstr != NULL) && (*tmpstr != '\0')) {
*target = strtol(tmpstr, NULL, 0);
*arglst |= CAM_ARG_TARGET;
convs++;
tmpstr = (char *)strtok(NULL, ":");
if ((tmpstr != NULL) && (*tmpstr != '\0')) {
*lun = strtol(tmpstr, NULL, 0);
*arglst |= CAM_ARG_LUN;
convs++;
}
}
}
return convs;
}
static int getdevlist(void) {
int unit = 0;
struct cam_device *device = NULL;
char *dev_name = NULL;
union ccb *ccb;
char name[30];
char status[32];
int error = 0;
int bus, target, lun, rv;
/* arglist = CAM_ARG_NONE; */
arglist = CAM_ARG_DEVICE | CAM_ARG_UNIT;
/* rv = parse_btl("all", &bus, &target, &lun, &arglist); */
if (cam_get_device("xpt0", name, sizeof name, &unit) == -1)
errx(1, "%s", cam_errbuf);
dev_name = strdup("/dev/xpt");
arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
if ((device = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
cam_open_btl(bus, target, lun, O_RDWR, NULL) :
cam_open_spec_device(dev_name,unit,O_RDWR,NULL)))
== NULL) {
printf("There was a horrible error: %s\n", cam_errbuf);
return -1;
}
ccb = cam_getccb(device);
ccb->ccb_h.func_code = XPT_GDEVLIST;
ccb->ccb_h.flags = CAM_DIR_NONE;
ccb->ccb_h.retry_count = 1;
ccb->cgdl.index = 0;
ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
if (cam_send_ccb(device, ccb) < 0) {
perror("error getting device list");
cam_freeccb(ccb);
return(1);
}
status[0] = '\0';
switch (ccb->cgdl.status) {
case CAM_GDEVLIST_MORE_DEVS:
strcpy(status, "MORE");
break;
case CAM_GDEVLIST_LAST_DEVICE:
strcpy(status, "LAST");
break;
case CAM_GDEVLIST_LIST_CHANGED:
strcpy(status, "CHANGED");
break;
case CAM_GDEVLIST_ERROR:
strcpy(status, "ERROR");
error = 1;
break;
}
fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n",
ccb->cgdl.periph_name,
ccb->cgdl.unit_number,
ccb->cgdl.generation,
ccb->cgdl.index,
status);
/*
* If the list has changed, we need to start over from the
* beginning.
*/
if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED)
ccb->cgdl.index = 0;
}
cam_freeccb(ccb);
return(error);
}
static PyObject *
scsiDevList(PyObject *self, PyObject *args) {
getdevlist();
return Py_BuildValue("");
}
static PyMethodDef scsi_methods[] = {
{"scsiDevList", scsiDevList, METH_VARARGS, NULL},
{NULL, NULL} /* sentinel */
};
PyMODINIT_FUNC
initscsi(void) {
Py_InitModule3("scsi", scsi_methods, NULL);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment