static void finddisctype(Drive *drive, int first, int last) { char *ty; /* deduce disc type */ drive->mmctype = Mmcnone; drive->dvdtype = nil; getdvdstruct(drive); getconf(drive); getbdstruct(drive); if (Desperate) bdguess(drive); if (drive->mmctype == Mmcnone) drive->mmctype = Mmccd; /* by default */ if (drive->recordable == Yes || drive->erasable == Yes) drive->writeok = Yes; if (vflag) { fprint(2, "writeok %d", drive->writeok); if (drive->recordable != Unset) fprint(2, " recordable %d", drive->recordable); if (drive->erasable != Unset) fprint(2, " erasable %d", drive->erasable); fprint(2, "\n"); fprint(2, "first %d last ", first); if (last == Maxresptracks) print("TBD\n"); else print("%d\n", last); ty = disctype(drive); fprint(2, "it's a %s disc.", ty); free(ty); if (drive->mmctype == Mmcbd && drive->laysfx == nil) fprint(2, " (number of layers isn't known yet.)"); fprint(2, "\n\n"); } }
/* this gets called a lot from main.c's 9P routines */ static int mmcgettoc(Drive *drive) { int i, n, first, last; uchar resp[1024]; Mmcaux *aux; /* * if someone has swapped the cd, * mmcreadtoc will get ``medium changed'' and the * scsi routines will set nchange and changetime in the * scsi device. */ mmcreadtoc(drive, 0, 0, resp, sizeof(resp)); if(drive->Scsi.changetime == 0) { /* no media present */ drive->mmctype = Mmcnone; drive->ntrack = 0; return 0; } /* * if the disc doesn't appear to be have been changed, and there * is a disc in this drive, there's nothing to do (the common case). */ if(drive->nchange == drive->Scsi.nchange && drive->changetime != 0) return 0; /* * the disc in the drive may have just been changed, * so rescan it and relearn all about it. */ drive->ntrack = 0; drive->nameok = 0; drive->nchange = drive->Scsi.nchange; drive->changetime = drive->Scsi.changetime; drive->writeok = drive->erasable = drive->recordable = drive->blank = 0; drive->erasableset = drive->recordableset = drive->blankset = 0; aux = drive->aux; aux->mmcnwa = 0; aux->nropen = aux->nwopen = 0; aux->ntotby = aux->ntotbk = 0; for(i=0; i<nelem(drive->track); i++){ memset(&drive->track[i].mbeg, 0, sizeof(Msf)); memset(&drive->track[i].mend, 0, sizeof(Msf)); } /* * TODO: set read ahead, MMC-6 ยง6.37, seems to control caching. */ /* * find number of tracks */ if((n = mmcreadtoc(drive, Msfbit, 0, resp, sizeof(resp))) < 4) { /* * on a blank disc in a cd-rw, use readdiscinfo * to find the track info. */ if(getdiscinfo(drive, resp, sizeof(resp)) < 7) return -1; assert((resp[2] & 0340) == 0); /* data type 0 */ if(resp[4] != 1) print("multi-session disc %d\n", resp[4]); first = resp[3]; last = resp[6]; if(vflag) print("blank disc %d %d\n", first, last); /* the assumption of blankness may be unwarranted */ drive->writeok = drive->blank = drive->blankset = 1; } else { first = resp[2]; last = resp[3]; if(n >= 4+8*(last-first+2)) { /* resp[4 + i*8 + 2] is track # */ /* <=: track[last-first+1] = end */ for(i=0; i<=last-first+1; i++) drive->track[i].mbeg = rdmsf(resp+4+i*8+5); for(i=0; i<last-first+1; i++) drive->track[i].mend = drive->track[i+1].mbeg; } } drive->mmctype = Mmcnone; drive->dvdtype = nil; getdvdstruct(drive); getbdstruct(drive); if (drive->mmctype == Mmcnone) drive->mmctype = Mmccd; /* by default */ if (drive->recordable || drive->erasable) drive->writeok = 1; if (vflag) { fprint(2, "writeok %d", drive->writeok); /* drive->blank is never used and hard to figure out */ // if (drive->blankset) // fprint(2, " blank %d", drive->blank); if (drive->recordableset) fprint(2, " recordable %d", drive->recordable); if (drive->erasableset) fprint(2, " erasable %d", drive->erasable); fprint(2, "\n"); print("first %d last %d\n", first, last); } if(first == 0 && last == 0) first = 1; if(first <= 0 || first >= Maxtrack) { werrstr("first table %d not in range", first); return -1; } if(last <= 0 || last >= Maxtrack) { werrstr("last table %d not in range", last); return -1; } if(drive->cap & Cwrite) /* CDR drives are easy */ for(i = first; i <= last; i++) mmctrackinfo(drive, i, i - first); else /* * otherwise we need to infer endings from the * beginnings of other tracks. */ mmcinfertracks(drive, first, last); drive->firsttrack = first; drive->ntrack = last+1-first; return 0; }