static int mmcgetpage(Drive *drive, int page, void *v) { Mmcaux *aux; aux = drive->aux; switch(aux->pagecmdsz) { case 10: return mmcgetpage10(drive, page, v); case 6: return mmcgetpage6(drive, page, v); default: assert(0); } return -1; }
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; }