2 #include "../port/lib.h"
8 #include "../port/error.h"
10 #include "../port/sd.h"
16 memset(r->cmd, 0, sizeof(r->cmd));
17 r->cmd[1] = r->lun<<5;
25 return r->unit->dev->ifc->rio(r);
29 scsiverify(SDunit* unit)
35 if((r = malloc(sizeof(SDreq))) == nil)
37 if((inquiry = sdmalloc(sizeof(unit->inquiry))) == nil){
44 memset(unit->inquiry, 0, sizeof(unit->inquiry));
47 r->cmd[1] = r->lun<<5;
55 if(unit->dev->ifc->rio(r) != SDok){
59 memmove(unit->inquiry, inquiry, r->dlen);
63 for(i = 0; i < 3; i++){
64 while((status = scsitest(r)) == SDbusy)
66 if(status == SDok || status != SDcheck)
68 if(!(r->flags & SDvalidsense))
70 if((r->sense[2] & 0x0F) != 0x02)
74 * Unit is 'not ready'.
75 * If it is in the process of becoming ready or needs
76 * an initialising command, set status so it will be spun-up
78 * If there's no medium, that's OK too, but don't
81 if(r->sense[12] == 0x04){
82 if(r->sense[13] == 0x02 || r->sense[13] == 0x01){
87 if(r->sense[12] == 0x3A)
93 * Try to ensure a direct-access device is spinning.
94 * Don't wait for completion, ignore the result.
96 if((unit->inquiry[0] & 0x1F) == 0){
97 memset(r->cmd, 0, sizeof(r->cmd));
100 r->cmd[1] = (r->lun<<5)|0x01;
108 unit->dev->ifc->rio(r);
113 if(status == SDok || status == SDcheck)
122 * Perform an I/O request, returning
125 * 1 no medium present
127 * The contents of r may be altered so the
128 * caller should re-initialise if necesary.
131 switch(r->unit->dev->ifc->rio(r)){
135 if(!(r->flags & SDvalidsense))
137 switch(r->sense[2] & 0x0F){
138 case 0x00: /* no sense */
139 case 0x01: /* recovered error */
141 case 0x06: /* check condition */
143 * 0x28 - not ready to ready transition,
144 * medium may have changed.
145 * 0x29 - power on or some type of reset.
147 if(r->sense[12] == 0x28 && r->sense[13] == 0)
149 if(r->sense[12] == 0x29)
152 case 0x02: /* not ready */
154 * If no medium present, bail out.
155 * If unit is becoming ready, rather than not
156 * not ready, wait a little then poke it again.
158 if(r->sense[12] == 0x3A)
160 if(r->sense[12] != 0x04 || r->sense[13] != 0x01)
165 tsleep(&up->sleep, return0, 0, 500);
183 r->cmd[1] = r->lun<<5;
207 return u[0]<<24 | u[1]<<16 | u[2]<<8 | u[3];
211 capreply(SDreq *r, ulong *secsize)
219 s = (uvlong)belong(u)<<32 | belong(u + 4);
231 scsionline(SDunit* unit)
240 if((r = malloc(sizeof *r)) == nil)
242 if((p = sdmalloc(32)) == nil){
250 r->lun = 0; /* ??? */
251 for(retries = 0; retries < 10; retries++){
253 * Read-capacity is mandatory for DA, WORM, CD-ROM and
254 * MO. It may return 'not ready' if type DA is not
255 * spun up, type MO or type CD-ROM are not loaded or just
256 * plain slow getting their act together after a reset.
261 memset(r->cmd, 0, sizeof r->cmd);
267 * ATAPI returns error and no sense information
268 * on media change / no media present.
275 s = capreply(r, &ss);
276 if(s == 0xffffffff && cap == cap10){
280 if(s == 0xffffffffffffffffLL)
284 * Some ATAPI CD readers lie about the block size.
285 * Since we don't read audio via this interface
286 * it's okay to always fudge this.
292 * Devices with removable media may return 0 sectors
293 * when they have empty media (e.g. sata dvd writers);
294 * if so, keep the count zero.
296 * Read-capacity returns the LBA of the last sector,
297 * therefore the number of sectors must be incremented.
302 ok = (unit->sectors != s) ? 2 : 1;
307 ok = (unit->sectors != 0) ? 2 : 1;
319 print("scsionline: %s: ok=%d retries=%d sectors=%llud secsize=%lud\n",
320 unit->name, ok, retries, unit->sectors, unit->secsize);
330 scsifmt10(SDreq *r, int write, int lun, ulong nb, uvlong bno)
353 scsifmt16(SDreq *r, int write, int lun, ulong nb, uvlong bno)
362 c[1] = lun<<5; /* so wrong */
382 scsibio(SDunit* unit, int lun, int write, void* data, long nb, uvlong bno)
387 r = smalloc(sizeof(SDreq));
393 scsifmt16(r, write, lun, nb, bno);
395 scsifmt10(r, write, lun, nb, bno);
397 r->dlen = nb*unit->secsize;
407 * scsi allows commands to return successfully
408 * but return sense data, indicating that the
409 * operation didn't proceed as expected.
410 * (confusing, no). this allows the raw commands
411 * to successfully return errors. but any sense
412 * data bio sees must be an error. bomb out.
414 if(r->status == SDok && r->rlen > 0
415 && ((r->flags & SDvalidsense) == 0 || r->sense[2] == 0)){
421 if(!(r->flags & SDvalidsense))
423 switch(r->sense[2] & 0x0F){
426 case 0x01: /* recovered error */
427 print("%s: recovered error at sector %llud\n",
431 case 0x06: /* check condition */
433 * Check for a removeable media change.
434 * If so, mark it by zapping the geometry info
435 * to force an online request.
437 if(r->sense[12] != 0x28 || r->sense[13] != 0)
439 if(unit->inquiry[1] & 0x80)
442 case 0x02: /* not ready */
444 * If unit is becoming ready,
445 * rather than not not ready, try again.
447 if(r->sense[12] == 0x04 && r->sense[13] == 0x01)
451 snprint(up->genbuf, sizeof up->genbuf, "%s %.2ux%.2ux%.2ux %lld",
452 Eio, r->sense[2], r->sense[12], r->sense[13], bno);