180ee5cbfSDavid du Colombier /* 280ee5cbfSDavid du Colombier * Storage Device. 380ee5cbfSDavid du Colombier */ 4fef25afaSDavid du Colombier #include <diskcmd.h> 5fef25afaSDavid du Colombier 680ee5cbfSDavid du Colombier typedef struct SDev SDev; 780ee5cbfSDavid du Colombier typedef struct SDifc SDifc; 80cc6832dSDavid du Colombier typedef struct SDio SDio; 980ee5cbfSDavid du Colombier typedef struct SDpart SDpart; 1080ee5cbfSDavid du Colombier typedef struct SDperm SDperm; 1180ee5cbfSDavid du Colombier typedef struct SDreq SDreq; 1280ee5cbfSDavid du Colombier typedef struct SDunit SDunit; 139a747e4fSDavid du Colombier 149a747e4fSDavid du Colombier struct SDperm { 159a747e4fSDavid du Colombier char* name; 169a747e4fSDavid du Colombier char* user; 1780ee5cbfSDavid du Colombier ulong perm; 189a747e4fSDavid du Colombier }; 1980ee5cbfSDavid du Colombier 209a747e4fSDavid du Colombier struct SDpart { 2117629263SDavid du Colombier uvlong start; 2217629263SDavid du Colombier uvlong end; 2380ee5cbfSDavid du Colombier SDperm; 2480ee5cbfSDavid du Colombier int valid; 2580ee5cbfSDavid du Colombier ulong vers; 269a747e4fSDavid du Colombier }; 2780ee5cbfSDavid du Colombier 289a747e4fSDavid du Colombier struct SDunit { 2980ee5cbfSDavid du Colombier SDev* dev; 3080ee5cbfSDavid du Colombier int subno; 31eb2d877eSDavid du Colombier uchar inquiry[255]; /* format follows SCSI spec */ 324de34a7eSDavid du Colombier uchar sense[18]; /* format follows SCSI spec */ 3380ee5cbfSDavid du Colombier SDperm; 3480ee5cbfSDavid du Colombier 3580ee5cbfSDavid du Colombier QLock ctl; 3617629263SDavid du Colombier uvlong sectors; 3780ee5cbfSDavid du Colombier ulong secsize; 3880ee5cbfSDavid du Colombier SDpart* part; /* nil or array of size npart */ 3980ee5cbfSDavid du Colombier int npart; 4080ee5cbfSDavid du Colombier ulong vers; 4180ee5cbfSDavid du Colombier SDperm ctlperm; 4280ee5cbfSDavid du Colombier 4380ee5cbfSDavid du Colombier QLock raw; /* raw read or write in progress */ 449a747e4fSDavid du Colombier ulong rawinuse; /* really just a test-and-set */ 4580ee5cbfSDavid du Colombier int state; 4680ee5cbfSDavid du Colombier SDreq* req; 4780ee5cbfSDavid du Colombier SDperm rawperm; 489a747e4fSDavid du Colombier }; 4980ee5cbfSDavid du Colombier 509a747e4fSDavid du Colombier /* 519a747e4fSDavid du Colombier * Each controller is represented by a SDev. 529a747e4fSDavid du Colombier */ 539a747e4fSDavid du Colombier struct SDev { 549a747e4fSDavid du Colombier Ref r; /* Number of callers using device */ 5580ee5cbfSDavid du Colombier SDifc* ifc; /* pnp/legacy */ 5680ee5cbfSDavid du Colombier void* ctlr; 5780ee5cbfSDavid du Colombier int idno; 584de34a7eSDavid du Colombier char name[8]; 5980ee5cbfSDavid du Colombier SDev* next; 6080ee5cbfSDavid du Colombier 6180ee5cbfSDavid du Colombier QLock; /* enable/disable */ 6280ee5cbfSDavid du Colombier int enabled; 639a747e4fSDavid du Colombier int nunit; /* Number of units */ 649a747e4fSDavid du Colombier QLock unitlock; /* `Loading' of units */ 659a747e4fSDavid du Colombier int* unitflg; /* Unit flags */ 669a747e4fSDavid du Colombier SDunit**unit; 679a747e4fSDavid du Colombier }; 6880ee5cbfSDavid du Colombier 699a747e4fSDavid du Colombier struct SDifc { 7080ee5cbfSDavid du Colombier char* name; 7180ee5cbfSDavid du Colombier 7280ee5cbfSDavid du Colombier SDev* (*pnp)(void); 7380ee5cbfSDavid du Colombier SDev* (*legacy)(int, int); 7480ee5cbfSDavid du Colombier int (*enable)(SDev*); 7580ee5cbfSDavid du Colombier int (*disable)(SDev*); 7680ee5cbfSDavid du Colombier 7780ee5cbfSDavid du Colombier int (*verify)(SDunit*); 7880ee5cbfSDavid du Colombier int (*online)(SDunit*); 7980ee5cbfSDavid du Colombier int (*rio)(SDreq*); 8080ee5cbfSDavid du Colombier int (*rctl)(SDunit*, char*, int); 8180ee5cbfSDavid du Colombier int (*wctl)(SDunit*, Cmdbuf*); 8280ee5cbfSDavid du Colombier 8317629263SDavid du Colombier long (*bio)(SDunit*, int, int, void*, long, uvlong); 849a747e4fSDavid du Colombier SDev* (*probe)(DevConf*); 859a747e4fSDavid du Colombier void (*clear)(SDev*); 864de34a7eSDavid du Colombier char* (*rtopctl)(SDev*, char*, char*); 874de34a7eSDavid du Colombier int (*wtopctl)(SDev*, Cmdbuf*); 889a747e4fSDavid du Colombier }; 8980ee5cbfSDavid du Colombier 909a747e4fSDavid du Colombier struct SDreq { 9180ee5cbfSDavid du Colombier SDunit* unit; 9280ee5cbfSDavid du Colombier int lun; 9380ee5cbfSDavid du Colombier int write; 9480ee5cbfSDavid du Colombier uchar cmd[16]; 9580ee5cbfSDavid du Colombier int clen; 9680ee5cbfSDavid du Colombier void* data; 9780ee5cbfSDavid du Colombier int dlen; 9880ee5cbfSDavid du Colombier 9980ee5cbfSDavid du Colombier int flags; 10080ee5cbfSDavid du Colombier 10180ee5cbfSDavid du Colombier int status; 10280ee5cbfSDavid du Colombier long rlen; 10380ee5cbfSDavid du Colombier uchar sense[256]; 1049a747e4fSDavid du Colombier }; 10580ee5cbfSDavid du Colombier 10680ee5cbfSDavid du Colombier enum { 10780ee5cbfSDavid du Colombier SDnosense = 0x00000001, 10880ee5cbfSDavid du Colombier SDvalidsense = 0x00010000, 10927522402SDavid du Colombier 11027522402SDavid du Colombier SDinq0periphqual= 0xe0, 11127522402SDavid du Colombier SDinq0periphtype= 0x1f, 11227522402SDavid du Colombier SDinq1removable = 0x80, 11327522402SDavid du Colombier 11427522402SDavid du Colombier /* periphtype values */ 11527522402SDavid du Colombier SDperdisk = 0, /* Direct access (disk) */ 11627522402SDavid du Colombier SDpertape = 1, /* Sequential eg, tape */ 11727522402SDavid du Colombier SDperpr = 2, /* Printer */ 11827522402SDavid du Colombier SDperworm = 4, /* Worm */ 11927522402SDavid du Colombier SDpercd = 5, /* CD-ROM */ 12027522402SDavid du Colombier SDpermo = 7, /* rewriteable MO */ 12127522402SDavid du Colombier SDperjuke = 8, /* medium-changer */ 12280ee5cbfSDavid du Colombier }; 12380ee5cbfSDavid du Colombier 12480ee5cbfSDavid du Colombier enum { 12580ee5cbfSDavid du Colombier SDretry = -5, /* internal to controllers */ 12680ee5cbfSDavid du Colombier SDmalloc = -4, 12780ee5cbfSDavid du Colombier SDeio = -3, 12880ee5cbfSDavid du Colombier SDtimeout = -2, 12980ee5cbfSDavid du Colombier SDnostatus = -1, 13080ee5cbfSDavid du Colombier 13180ee5cbfSDavid du Colombier SDok = 0, 13280ee5cbfSDavid du Colombier 13380ee5cbfSDavid du Colombier SDcheck = 0x02, /* check condition */ 13480ee5cbfSDavid du Colombier SDbusy = 0x08, /* busy */ 13580ee5cbfSDavid du Colombier 13680ee5cbfSDavid du Colombier SDmaxio = 2048*1024, 13780ee5cbfSDavid du Colombier SDnpart = 16, 13880ee5cbfSDavid du Colombier }; 13980ee5cbfSDavid du Colombier 1407ee275a1SDavid du Colombier /* 1417ee275a1SDavid du Colombier * Allow the default #defines for sdmalloc & sdfree to be overridden by 1427ee275a1SDavid du Colombier * system-specific versions. This can be used to avoid extra copying 1437ee275a1SDavid du Colombier * by making sure sd buffers are cache-aligned (some ARM systems) or 1447ee275a1SDavid du Colombier * page-aligned (xen) for DMA. 1457ee275a1SDavid du Colombier */ 1467ee275a1SDavid du Colombier #ifndef sdmalloc 14780ee5cbfSDavid du Colombier #define sdmalloc(n) malloc(n) 14880ee5cbfSDavid du Colombier #define sdfree(p) free(p) 1497ee275a1SDavid du Colombier #endif 15080ee5cbfSDavid du Colombier 1510cc6832dSDavid du Colombier /* 1520cc6832dSDavid du Colombier * mmc/sd/sdio host controller interface 1530cc6832dSDavid du Colombier */ 1540cc6832dSDavid du Colombier 1550cc6832dSDavid du Colombier struct SDio { 1560cc6832dSDavid du Colombier char *name; 1570cc6832dSDavid du Colombier int (*init)(void); 1580cc6832dSDavid du Colombier void (*enable)(void); 1590cc6832dSDavid du Colombier int (*inquiry)(char*, int); 1600cc6832dSDavid du Colombier int (*cmd)(u32int, u32int, u32int*); 1610cc6832dSDavid du Colombier void (*iosetup)(int, void*, int, int); 1620cc6832dSDavid du Colombier void (*io)(int, uchar*, int); 1630cc6832dSDavid du Colombier }; 1640cc6832dSDavid du Colombier 1650cc6832dSDavid du Colombier extern SDio sdio; 1660cc6832dSDavid du Colombier 1674de34a7eSDavid du Colombier /* devsd.c */ 1684de34a7eSDavid du Colombier extern void sdadddevs(SDev*); 1692210c76eSDavid du Colombier extern void sdaddconf(SDunit*); 1702210c76eSDavid du Colombier extern void sdaddallconfs(void (*f)(SDunit*)); 1712210c76eSDavid du Colombier extern void sdaddpart(SDunit*, char*, uvlong, uvlong); 1724de34a7eSDavid du Colombier extern int sdsetsense(SDreq*, int, int, int, int); 1734de34a7eSDavid du Colombier extern int sdmodesense(SDreq*, uchar*, void*, int); 1744de34a7eSDavid du Colombier extern int sdfakescsi(SDreq*, void*, int); 175*5a0d9eb8SDavid du Colombier extern int sdfakescsirw(SDreq*, uvlong*, int*, int*); 1764de34a7eSDavid du Colombier 17780ee5cbfSDavid du Colombier /* sdscsi.c */ 17880ee5cbfSDavid du Colombier extern int scsiverify(SDunit*); 17980ee5cbfSDavid du Colombier extern int scsionline(SDunit*); 18017629263SDavid du Colombier extern long scsibio(SDunit*, int, int, void*, long, uvlong); 18180ee5cbfSDavid du Colombier extern SDev* scsiid(SDev*, SDifc*); 1822a044a09SDavid du Colombier extern void scsilbacount(uchar *, int, uvlong*, ulong*); 183