19ef1f84bSDavid du Colombier /* 29ef1f84bSDavid du Colombier * Storage Device. 39ef1f84bSDavid du Colombier */ 4a72b0d60SDavid du Colombier #include <diskcmd.h> 5a72b0d60SDavid du Colombier 69ef1f84bSDavid du Colombier typedef struct SDev SDev; 79ef1f84bSDavid du Colombier typedef struct SDifc SDifc; 89ef1f84bSDavid du Colombier typedef struct SDio SDio; 99ef1f84bSDavid du Colombier typedef struct SDpart SDpart; 109ef1f84bSDavid du Colombier typedef struct SDperm SDperm; 119ef1f84bSDavid du Colombier typedef struct SDreq SDreq; 129ef1f84bSDavid du Colombier typedef struct SDunit SDunit; 139ef1f84bSDavid du Colombier 149ef1f84bSDavid du Colombier struct SDperm { 159ef1f84bSDavid du Colombier char* name; 169ef1f84bSDavid du Colombier char* user; 179ef1f84bSDavid du Colombier ulong perm; 189ef1f84bSDavid du Colombier }; 199ef1f84bSDavid du Colombier 209ef1f84bSDavid du Colombier struct SDpart { 219ef1f84bSDavid du Colombier uvlong start; 229ef1f84bSDavid du Colombier uvlong end; 239ef1f84bSDavid du Colombier SDperm; 249ef1f84bSDavid du Colombier int valid; 259ef1f84bSDavid du Colombier ulong vers; 269ef1f84bSDavid du Colombier }; 279ef1f84bSDavid du Colombier 289ef1f84bSDavid du Colombier struct SDunit { 299ef1f84bSDavid du Colombier SDev* dev; 309ef1f84bSDavid du Colombier int subno; 319ef1f84bSDavid du Colombier uchar inquiry[255]; /* format follows SCSI spec */ 329ef1f84bSDavid du Colombier uchar sense[18]; /* format follows SCSI spec */ 339ef1f84bSDavid du Colombier SDperm; 349ef1f84bSDavid du Colombier 359ef1f84bSDavid du Colombier QLock ctl; 369ef1f84bSDavid du Colombier uvlong sectors; 379ef1f84bSDavid du Colombier ulong secsize; 389ef1f84bSDavid du Colombier SDpart* part; /* nil or array of size npart */ 399ef1f84bSDavid du Colombier int npart; 409ef1f84bSDavid du Colombier ulong vers; 419ef1f84bSDavid du Colombier SDperm ctlperm; 429ef1f84bSDavid du Colombier 439ef1f84bSDavid du Colombier QLock raw; /* raw read or write in progress */ 449ef1f84bSDavid du Colombier ulong rawinuse; /* really just a test-and-set */ 459ef1f84bSDavid du Colombier int state; 469ef1f84bSDavid du Colombier SDreq* req; 479ef1f84bSDavid du Colombier SDperm rawperm; 489ef1f84bSDavid du Colombier }; 499ef1f84bSDavid du Colombier 509ef1f84bSDavid du Colombier /* 519ef1f84bSDavid du Colombier * Each controller is represented by a SDev. 529ef1f84bSDavid du Colombier */ 539ef1f84bSDavid du Colombier struct SDev { 549ef1f84bSDavid du Colombier Ref r; /* Number of callers using device */ 559ef1f84bSDavid du Colombier SDifc* ifc; /* pnp/legacy */ 569ef1f84bSDavid du Colombier void* ctlr; 579ef1f84bSDavid du Colombier int idno; 589ef1f84bSDavid du Colombier char name[8]; 599ef1f84bSDavid du Colombier SDev* next; 609ef1f84bSDavid du Colombier 619ef1f84bSDavid du Colombier QLock; /* enable/disable */ 629ef1f84bSDavid du Colombier int enabled; 639ef1f84bSDavid du Colombier int nunit; /* Number of units */ 649ef1f84bSDavid du Colombier QLock unitlock; /* `Loading' of units */ 659ef1f84bSDavid du Colombier int* unitflg; /* Unit flags */ 669ef1f84bSDavid du Colombier SDunit**unit; 679ef1f84bSDavid du Colombier }; 689ef1f84bSDavid du Colombier 699ef1f84bSDavid du Colombier struct SDifc { 709ef1f84bSDavid du Colombier char* name; 719ef1f84bSDavid du Colombier 729ef1f84bSDavid du Colombier SDev* (*pnp)(void); 739ef1f84bSDavid du Colombier SDev* (*legacy)(int, int); 749ef1f84bSDavid du Colombier int (*enable)(SDev*); 759ef1f84bSDavid du Colombier int (*disable)(SDev*); 769ef1f84bSDavid du Colombier 779ef1f84bSDavid du Colombier int (*verify)(SDunit*); 789ef1f84bSDavid du Colombier int (*online)(SDunit*); 799ef1f84bSDavid du Colombier int (*rio)(SDreq*); 809ef1f84bSDavid du Colombier int (*rctl)(SDunit*, char*, int); 819ef1f84bSDavid du Colombier int (*wctl)(SDunit*, Cmdbuf*); 829ef1f84bSDavid du Colombier 839ef1f84bSDavid du Colombier long (*bio)(SDunit*, int, int, void*, long, uvlong); 849ef1f84bSDavid du Colombier SDev* (*probe)(DevConf*); 859ef1f84bSDavid du Colombier void (*clear)(SDev*); 869ef1f84bSDavid du Colombier char* (*rtopctl)(SDev*, char*, char*); 879ef1f84bSDavid du Colombier int (*wtopctl)(SDev*, Cmdbuf*); 889ef1f84bSDavid du Colombier }; 899ef1f84bSDavid du Colombier 909ef1f84bSDavid du Colombier struct SDreq { 919ef1f84bSDavid du Colombier SDunit* unit; 929ef1f84bSDavid du Colombier int lun; 939ef1f84bSDavid du Colombier int write; 949ef1f84bSDavid du Colombier uchar cmd[16]; 959ef1f84bSDavid du Colombier int clen; 969ef1f84bSDavid du Colombier void* data; 979ef1f84bSDavid du Colombier int dlen; 989ef1f84bSDavid du Colombier 999ef1f84bSDavid du Colombier int flags; 1009ef1f84bSDavid du Colombier 1019ef1f84bSDavid du Colombier int status; 1029ef1f84bSDavid du Colombier long rlen; 1039ef1f84bSDavid du Colombier uchar sense[256]; 1049ef1f84bSDavid du Colombier }; 1059ef1f84bSDavid du Colombier 1069ef1f84bSDavid du Colombier enum { 1079ef1f84bSDavid du Colombier SDnosense = 0x00000001, 1089ef1f84bSDavid du Colombier SDvalidsense = 0x00010000, 1099ef1f84bSDavid du Colombier 1109ef1f84bSDavid du Colombier SDinq0periphqual= 0xe0, 1119ef1f84bSDavid du Colombier SDinq0periphtype= 0x1f, 1129ef1f84bSDavid du Colombier SDinq1removable = 0x80, 1139ef1f84bSDavid du Colombier 1149ef1f84bSDavid du Colombier /* periphtype values */ 1159ef1f84bSDavid du Colombier SDperdisk = 0, /* Direct access (disk) */ 1169ef1f84bSDavid du Colombier SDpertape = 1, /* Sequential eg, tape */ 1179ef1f84bSDavid du Colombier SDperpr = 2, /* Printer */ 1189ef1f84bSDavid du Colombier SDperworm = 4, /* Worm */ 1199ef1f84bSDavid du Colombier SDpercd = 5, /* CD-ROM */ 1209ef1f84bSDavid du Colombier SDpermo = 7, /* rewriteable MO */ 1219ef1f84bSDavid du Colombier SDperjuke = 8, /* medium-changer */ 1229ef1f84bSDavid du Colombier }; 1239ef1f84bSDavid du Colombier 1249ef1f84bSDavid du Colombier enum { 1259ef1f84bSDavid du Colombier SDretry = -5, /* internal to controllers */ 1269ef1f84bSDavid du Colombier SDmalloc = -4, 1279ef1f84bSDavid du Colombier SDeio = -3, 1289ef1f84bSDavid du Colombier SDtimeout = -2, 1299ef1f84bSDavid du Colombier SDnostatus = -1, 1309ef1f84bSDavid du Colombier 1319ef1f84bSDavid du Colombier SDok = 0, 1329ef1f84bSDavid du Colombier 1339ef1f84bSDavid du Colombier SDcheck = 0x02, /* check condition */ 1349ef1f84bSDavid du Colombier SDbusy = 0x08, /* busy */ 1359ef1f84bSDavid du Colombier 1369ef1f84bSDavid du Colombier SDmaxio = 2048*1024, 1379ef1f84bSDavid du Colombier SDnpart = 16, 1389ef1f84bSDavid du Colombier }; 1399ef1f84bSDavid du Colombier 1409ef1f84bSDavid du Colombier /* 1419ef1f84bSDavid du Colombier * Allow the default #defines for sdmalloc & sdfree to be overridden by 1429ef1f84bSDavid du Colombier * system-specific versions. This can be used to avoid extra copying 1439ef1f84bSDavid du Colombier * by making sure sd buffers are cache-aligned (some ARM systems) or 1449ef1f84bSDavid du Colombier * page-aligned (xen) for DMA. 1459ef1f84bSDavid du Colombier */ 1469ef1f84bSDavid du Colombier #ifndef sdmalloc 1479ef1f84bSDavid du Colombier #define sdmalloc(n) malloc(n) 1489ef1f84bSDavid du Colombier #define sdfree(p) free(p) 1499ef1f84bSDavid du Colombier #endif 1509ef1f84bSDavid du Colombier 1519ef1f84bSDavid du Colombier /* 1529ef1f84bSDavid du Colombier * mmc/sd/sdio host controller interface 1539ef1f84bSDavid du Colombier */ 1549ef1f84bSDavid du Colombier 1559ef1f84bSDavid du Colombier struct SDio { 1569ef1f84bSDavid du Colombier char *name; 1579ef1f84bSDavid du Colombier int (*init)(void); 1589ef1f84bSDavid du Colombier void (*enable)(void); 1599ef1f84bSDavid du Colombier int (*inquiry)(char*, int); 1609ef1f84bSDavid du Colombier int (*cmd)(u32int, u32int, u32int*); 1619ef1f84bSDavid du Colombier void (*iosetup)(int, void*, int, int); 1629ef1f84bSDavid du Colombier void (*io)(int, uchar*, int); 1639ef1f84bSDavid du Colombier }; 1649ef1f84bSDavid du Colombier 1659ef1f84bSDavid du Colombier extern SDio sdio; 1669ef1f84bSDavid du Colombier 1679ef1f84bSDavid du Colombier /* devsd.c */ 1689ef1f84bSDavid du Colombier extern void sdadddevs(SDev*); 1699ef1f84bSDavid du Colombier extern void sdaddconf(SDunit*); 1709ef1f84bSDavid du Colombier extern void sdaddallconfs(void (*f)(SDunit*)); 1719ef1f84bSDavid du Colombier extern void sdaddpart(SDunit*, char*, uvlong, uvlong); 1729ef1f84bSDavid du Colombier extern int sdsetsense(SDreq*, int, int, int, int); 1739ef1f84bSDavid du Colombier extern int sdmodesense(SDreq*, uchar*, void*, int); 1749ef1f84bSDavid du Colombier extern int sdfakescsi(SDreq*, void*, int); 175*465c1891SDavid du Colombier extern int sdfakescsirw(SDreq*, uvlong*, int*, int*); 1769ef1f84bSDavid du Colombier 1779ef1f84bSDavid du Colombier /* sdscsi.c */ 1789ef1f84bSDavid du Colombier extern int scsiverify(SDunit*); 1799ef1f84bSDavid du Colombier extern int scsionline(SDunit*); 1809ef1f84bSDavid du Colombier extern long scsibio(SDunit*, int, int, void*, long, uvlong); 1819ef1f84bSDavid du Colombier extern SDev* scsiid(SDev*, SDifc*); 182a58eaef0SDavid du Colombier extern void scsilbacount(uchar *, int, uvlong*, ulong*); 1839ef1f84bSDavid du Colombier 1849ef1f84bSDavid du Colombier /* 1859ef1f84bSDavid du Colombier * hardware info about a device 1869ef1f84bSDavid du Colombier */ 1879ef1f84bSDavid du Colombier typedef struct { 1889ef1f84bSDavid du Colombier ulong port; 1899ef1f84bSDavid du Colombier int size; 1909ef1f84bSDavid du Colombier } Devport; 1919ef1f84bSDavid du Colombier 1929ef1f84bSDavid du Colombier struct DevConf 1939ef1f84bSDavid du Colombier { 1949ef1f84bSDavid du Colombier ulong intnum; /* interrupt number */ 1959ef1f84bSDavid du Colombier char *type; /* card type, malloced */ 1969ef1f84bSDavid du Colombier int nports; /* Number of ports */ 1979ef1f84bSDavid du Colombier Devport *ports; /* The ports themselves */ 1989ef1f84bSDavid du Colombier }; 199