1 /* 2 * Storage Device. 3 */ 4 #include <diskcmd.h> 5 6 typedef struct SDev SDev; 7 typedef struct SDifc SDifc; 8 typedef struct SDio SDio; 9 typedef struct SDpart SDpart; 10 typedef struct SDperm SDperm; 11 typedef struct SDreq SDreq; 12 typedef struct SDunit SDunit; 13 14 struct SDperm { 15 char* name; 16 char* user; 17 ulong perm; 18 }; 19 20 struct SDpart { 21 uvlong start; 22 uvlong end; 23 SDperm; 24 int valid; 25 ulong vers; 26 }; 27 28 struct SDunit { 29 SDev* dev; 30 int subno; 31 uchar inquiry[255]; /* format follows SCSI spec */ 32 uchar sense[18]; /* format follows SCSI spec */ 33 SDperm; 34 35 QLock ctl; 36 uvlong sectors; 37 ulong secsize; 38 SDpart* part; /* nil or array of size npart */ 39 int npart; 40 ulong vers; 41 SDperm ctlperm; 42 43 QLock raw; /* raw read or write in progress */ 44 ulong rawinuse; /* really just a test-and-set */ 45 int state; 46 SDreq* req; 47 SDperm rawperm; 48 }; 49 50 /* 51 * Each controller is represented by a SDev. 52 */ 53 struct SDev { 54 Ref r; /* Number of callers using device */ 55 SDifc* ifc; /* pnp/legacy */ 56 void* ctlr; 57 int idno; 58 char name[8]; 59 SDev* next; 60 61 QLock; /* enable/disable */ 62 int enabled; 63 int nunit; /* Number of units */ 64 QLock unitlock; /* `Loading' of units */ 65 int* unitflg; /* Unit flags */ 66 SDunit**unit; 67 }; 68 69 struct SDifc { 70 char* name; 71 72 SDev* (*pnp)(void); 73 SDev* (*legacy)(int, int); 74 int (*enable)(SDev*); 75 int (*disable)(SDev*); 76 77 int (*verify)(SDunit*); 78 int (*online)(SDunit*); 79 int (*rio)(SDreq*); 80 int (*rctl)(SDunit*, char*, int); 81 int (*wctl)(SDunit*, Cmdbuf*); 82 83 long (*bio)(SDunit*, int, int, void*, long, uvlong); 84 SDev* (*probe)(DevConf*); 85 void (*clear)(SDev*); 86 char* (*rtopctl)(SDev*, char*, char*); 87 int (*wtopctl)(SDev*, Cmdbuf*); 88 }; 89 90 struct SDreq { 91 SDunit* unit; 92 int lun; 93 int write; 94 uchar cmd[16]; 95 int clen; 96 void* data; 97 int dlen; 98 99 int flags; 100 101 int status; 102 long rlen; 103 uchar sense[256]; 104 }; 105 106 enum { 107 SDnosense = 0x00000001, 108 SDvalidsense = 0x00010000, 109 110 SDinq0periphqual= 0xe0, 111 SDinq0periphtype= 0x1f, 112 SDinq1removable = 0x80, 113 114 /* periphtype values */ 115 SDperdisk = 0, /* Direct access (disk) */ 116 SDpertape = 1, /* Sequential eg, tape */ 117 SDperpr = 2, /* Printer */ 118 SDperworm = 4, /* Worm */ 119 SDpercd = 5, /* CD-ROM */ 120 SDpermo = 7, /* rewriteable MO */ 121 SDperjuke = 8, /* medium-changer */ 122 }; 123 124 enum { 125 SDretry = -5, /* internal to controllers */ 126 SDmalloc = -4, 127 SDeio = -3, 128 SDtimeout = -2, 129 SDnostatus = -1, 130 131 SDok = 0, 132 133 SDcheck = 0x02, /* check condition */ 134 SDbusy = 0x08, /* busy */ 135 136 SDmaxio = 2048*1024, 137 SDnpart = 16, 138 }; 139 140 /* 141 * Allow the default #defines for sdmalloc & sdfree to be overridden by 142 * system-specific versions. This can be used to avoid extra copying 143 * by making sure sd buffers are cache-aligned (some ARM systems) or 144 * page-aligned (xen) for DMA. 145 */ 146 #ifndef sdmalloc 147 #define sdmalloc(n) malloc(n) 148 #define sdfree(p) free(p) 149 #endif 150 151 /* 152 * mmc/sd/sdio host controller interface 153 */ 154 155 struct SDio { 156 char *name; 157 int (*init)(void); 158 void (*enable)(void); 159 int (*inquiry)(char*, int); 160 int (*cmd)(u32int, u32int, u32int*); 161 void (*iosetup)(int, void*, int, int); 162 void (*io)(int, uchar*, int); 163 }; 164 165 extern SDio sdio; 166 167 /* devsd.c */ 168 extern void sdadddevs(SDev*); 169 extern void sdaddconf(SDunit*); 170 extern void sdaddallconfs(void (*f)(SDunit*)); 171 extern void sdaddpart(SDunit*, char*, uvlong, uvlong); 172 extern int sdsetsense(SDreq*, int, int, int, int); 173 extern int sdmodesense(SDreq*, uchar*, void*, int); 174 extern int sdfakescsi(SDreq*, void*, int); 175 extern int sdfakescsirw(SDreq*, uvlong*, int*, int*); 176 177 /* sdscsi.c */ 178 extern int scsiverify(SDunit*); 179 extern int scsionline(SDunit*); 180 extern long scsibio(SDunit*, int, int, void*, long, uvlong); 181 extern SDev* scsiid(SDev*, SDifc*); 182 extern void scsilbacount(uchar *, int, uvlong*, ulong*); 183