Scsi* openscsi(char *dev) { Scsi *s; int rawfd, ctlfd, l, n; char *name, *p, buf[512]; l = strlen(dev)+1+3+1; name = malloc(l); if(name == nil) return nil; snprint(name, l, "%s/raw", dev); if((rawfd = open(name, ORDWR)) < 0) { free(name); return nil; } snprint(name, l, "%s/ctl", dev); if((ctlfd = open(name, ORDWR)) < 0) { free(name); Error: close(rawfd); return nil; } free(name); n = readn(ctlfd, buf, sizeof buf); close(ctlfd); if(n <= 0) goto Error; if(strncmp(buf, "inquiry ", 8) != 0 || (p = strchr(buf, '\n')) == nil) goto Error; *p = '\0'; if((p = strdup(buf+8)) == nil) goto Error; s = malloc(sizeof(*s)); if(s == nil) { Error1: free(p); goto Error; } memset(s, 0, sizeof(*s)); s->rawfd = rawfd; s->inquire = p; s->changetime = time(0); if(scsiready(s) < 0) goto Error1; return s; }
Drive* mmcprobe(Scsi *scsi) { Mmcaux *aux; Drive *drive; uchar buf[Pagesz]; int cap, n; if (vflag) print("mmcprobe: inquiry: %s\n", scsi->inquire); drive = emalloc(sizeof(Drive)); drive->Scsi = *scsi; drive->Dev = mmcdev; aux = emalloc(sizeof(Mmcaux)); drive->aux = aux; scsiready(drive); drive->type = getdevtype(drive); if (drive->type != TypeCD) { werrstr("not an mmc device"); free(aux); free(drive); return nil; } /* * drive is an mmc device; learn what we can about it * (as opposed to the disc in it). */ start(drive, 1); /* attempt to read CD capabilities page, but it's now legacy */ if(mmcgetpage10(drive, Pagcapmechsts, buf) >= 0) aux->pagecmdsz = 10; else if(mmcgetpage6(drive, Pagcapmechsts, buf) >= 0) aux->pagecmdsz = 6; else { if (vflag) fprint(2, "no Pagcapmechsts mode page!\n"); werrstr("can't read mode page %d!", Pagcapmechsts); free(aux); free(drive); return nil; } cap = 0; if(buf[Capwrite] & (Capcdr|Capcdrw|Capdvdr|Capdvdram) || buf[Capmisc] & Caprw) cap |= Cwrite; if(buf[Capmisc] & Capcdda) /* CD-DA commands supported? */ cap |= Ccdda; /* not used anywhere else */ // print("read %d max %d\n", biges(buf+14), biges(buf+8)); // print("write %d max %d\n", biges(buf+20), biges(buf+18)); /* cache optional page 05 (write parameter page) */ if(/* (cap & Cwrite) && */ mmcgetpage(drive, Pagwrparams, aux->page05) >= 0) { aux->page05ok = 1; cap |= Cwrite; if (vflag) fprint(2, "mmcprobe: got page 5, assuming drive can write\n"); } else { if (vflag) fprint(2, "no Pagwrparams mode page!\n"); cap &= ~Cwrite; } drive->cap = cap; mmcgetspeed(drive); /* * we can't actually control caching much. * see SBC-2 §6.3.3 but also MMC-6 §7.6. */ n = mmcgetpage(drive, Pagcache, buf); if (n >= 3) { /* n == 255; buf[1] == 10 (10 bytes after buf[1]) */ buf[0] &= 077; /* clear reserved bits, MMC-6 §7.2.3 */ assert(buf[0] == Pagcache); assert(buf[1] >= 10); buf[2] = Ccwce; if (mmcsetpage(drive, Pagcache, buf) < 0) if (vflag) print("mmcprobe: cache control NOT set\n"); } return drive; }
Drive* mmcprobe(Scsi *scsi) { Mmcaux *aux; Drive *drive; uint8_t buf[Pagesz]; int cap; if (vflag) print("mmcprobe: inquiry: %s\n", scsi->inquire); drive = emalloc(sizeof(Drive)); drive->scsi = *scsi; drive->Dev = mmcdev; drive->invistrack = -1; getinvistrack(drive); aux = emalloc(sizeof(Mmcaux)); drive->aux = aux; scsiready(&drive->scsi); drive->type = getdevtype(drive); if (drive->type != TypeCD) { werrstr("not an mmc device"); free(aux); free(drive); return nil; } /* * drive is an mmc device; learn what we can about it * (as opposed to the disc in it). */ start(drive, 1); /* attempt to read CD capabilities page, but it's now legacy */ if(mmcgetpage10(drive, Pagcapmechsts, buf) >= 0) aux->pagecmdsz = 10; else if(mmcgetpage6(drive, Pagcapmechsts, buf) >= 0) aux->pagecmdsz = 6; else { if (vflag) fprint(2, "no Pagcapmechsts mode page!\n"); werrstr("can't read mode page %d!", Pagcapmechsts); free(aux); free(drive); return nil; } cap = 0; if(buf[Capwrite] & (Capcdr|Capcdrw|Capdvdr|Capdvdram) || buf[Capmisc] & Caprw) cap |= Cwrite; if(buf[Capmisc] & Capcdda) /* CD-DA commands supported? */ cap |= Ccdda; /* not used anywhere else */ /* cache optional page 05 (write parameter page) */ if(/* (cap & Cwrite) && */ mmcgetpage(drive, Pagwrparams, aux->page05) >= 0) { aux->page05ok = 1; cap |= Cwrite; if (vflag) fprint(2, "mmcprobe: got page 5, assuming drive can write\n"); } else { if (vflag) fprint(2, "no Pagwrparams mode page!\n"); cap &= ~Cwrite; } drive->cap = cap; mmcgetspeed(drive); setcaching(drive); return drive; }
Scsi* openscsi(char *dev) { Scsi *s; int rawfd, ctlfd, l, n; char *name, *p, buf[512]; l = strlen(dev)+1+3+1; name = malloc(l); if(name == nil) return nil; snprint(name, l, "%s/raw", dev); if((rawfd = open(name, ORDWR)) < 0) { free(name); return nil; } snprint(name, l, "%s/ctl", dev); if((ctlfd = open(name, ORDWR)) < 0) { Error: free(name); close(rawfd); return nil; } n = readn(ctlfd, buf, sizeof buf); close(ctlfd); if(n <= 0) { if(n == 0) werrstr("eof on %s", name); goto Error; } if(strncmp(buf, "inquiry ", 8) != 0 || (p = strchr(buf, '\n')) == nil) { werrstr("inquiry mal-formatted in %s", name); goto Error; } *p = '\0'; free(name); name = nil; if((p = strdup(buf+8)) == nil) goto Error; s = mallocz(sizeof(*s), 1); if(s == nil) { Error1: free(p); goto Error; } s->rawfd = rawfd; s->inquire = p; s->changetime = time(0); if(scsiready(s) < 0) goto Error1; return s; }