src/cdrom/bsdi/SDL_syscdrom.c
branchSDL-1.3
changeset 1668 4da1ee79c9af
parent 1662 782fd950bd46
equal deleted inserted replaced
1667:1fddae038bc8 1668:4da1ee79c9af
    50 
    50 
    51 #define	FRAMES_PER_SECOND	75
    51 #define	FRAMES_PER_SECOND	75
    52 #define	FRAMES_PER_MINUTE	(FRAMES_PER_SECOND * 60)
    52 #define	FRAMES_PER_MINUTE	(FRAMES_PER_SECOND * 60)
    53 
    53 
    54 int
    54 int
    55 msf_to_frame (int minute, int second, int frame)
    55 msf_to_frame(int minute, int second, int frame)
    56 {
    56 {
    57     return (minute * FRAMES_PER_MINUTE + second * FRAMES_PER_SECOND + frame);
    57     return (minute * FRAMES_PER_MINUTE + second * FRAMES_PER_SECOND + frame);
    58 }
    58 }
    59 
    59 
    60 void
    60 void
    61 frame_to_msf (int frame, int *minp, int *secp, int *framep)
    61 frame_to_msf(int frame, int *minp, int *secp, int *framep)
    62 {
    62 {
    63     *minp = frame / FRAMES_PER_MINUTE;
    63     *minp = frame / FRAMES_PER_MINUTE;
    64     *secp = (frame % FRAMES_PER_MINUTE) / FRAMES_PER_SECOND;
    64     *secp = (frame % FRAMES_PER_MINUTE) / FRAMES_PER_SECOND;
    65     *framep = frame % FRAMES_PER_SECOND;
    65     *framep = frame % FRAMES_PER_SECOND;
    66 }
    66 }
    71 /* A list of available CD-ROM drives */
    71 /* A list of available CD-ROM drives */
    72 static char *SDL_cdlist[MAX_DRIVES];
    72 static char *SDL_cdlist[MAX_DRIVES];
    73 static dev_t SDL_cdmode[MAX_DRIVES];
    73 static dev_t SDL_cdmode[MAX_DRIVES];
    74 
    74 
    75 /* The system-dependent CD control functions */
    75 /* The system-dependent CD control functions */
    76 static const char *SDL_SYS_CDName (int drive);
    76 static const char *SDL_SYS_CDName(int drive);
    77 static int SDL_SYS_CDOpen (int drive);
    77 static int SDL_SYS_CDOpen(int drive);
    78 static int SDL_SYS_CDGetTOC (SDL_CD * cdrom);
    78 static int SDL_SYS_CDGetTOC(SDL_CD * cdrom);
    79 static CDstatus SDL_SYS_CDStatus (SDL_CD * cdrom, int *position);
    79 static CDstatus SDL_SYS_CDStatus(SDL_CD * cdrom, int *position);
    80 static int SDL_SYS_CDPlay (SDL_CD * cdrom, int start, int length);
    80 static int SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length);
    81 static int SDL_SYS_CDPause (SDL_CD * cdrom);
    81 static int SDL_SYS_CDPause(SDL_CD * cdrom);
    82 static int SDL_SYS_CDResume (SDL_CD * cdrom);
    82 static int SDL_SYS_CDResume(SDL_CD * cdrom);
    83 static int SDL_SYS_CDStop (SDL_CD * cdrom);
    83 static int SDL_SYS_CDStop(SDL_CD * cdrom);
    84 static int SDL_SYS_CDEject (SDL_CD * cdrom);
    84 static int SDL_SYS_CDEject(SDL_CD * cdrom);
    85 static void SDL_SYS_CDClose (SDL_CD * cdrom);
    85 static void SDL_SYS_CDClose(SDL_CD * cdrom);
    86 
    86 
    87 typedef struct scsi_cdb cdb_t;
    87 typedef struct scsi_cdb cdb_t;
    88 
    88 
    89 static int
    89 static int
    90 scsi_cmd (int fd,
    90 scsi_cmd(int fd,
    91           struct scsi_cdb *cdb,
    91          struct scsi_cdb *cdb,
    92           int cdblen,
    92          int cdblen,
    93           int rw, caddr_t data, int datalen, struct scsi_user_cdb *sus)
    93          int rw, caddr_t data, int datalen, struct scsi_user_cdb *sus)
    94 {
    94 {
    95     int scsistatus;
    95     int scsistatus;
    96     unsigned char *cp;
    96     unsigned char *cp;
    97     struct scsi_user_cdb suc;
    97     struct scsi_user_cdb suc;
    98 
    98 
   102     if (rw != SUC_READ && rw != SUC_WRITE)
   102     if (rw != SUC_READ && rw != SUC_WRITE)
   103         return (-1);
   103         return (-1);
   104 
   104 
   105     suc.suc_flags = rw;
   105     suc.suc_flags = rw;
   106     suc.suc_cdblen = cdblen;
   106     suc.suc_cdblen = cdblen;
   107     bcopy (cdb, suc.suc_cdb, cdblen);
   107     bcopy(cdb, suc.suc_cdb, cdblen);
   108     suc.suc_datalen = datalen;
   108     suc.suc_datalen = datalen;
   109     suc.suc_data = data;
   109     suc.suc_data = data;
   110     suc.suc_timeout = 10;       /* 10 secs max for TUR or SENSE */
   110     suc.suc_timeout = 10;       /* 10 secs max for TUR or SENSE */
   111     if (ioctl (fd, SCSIRAWCDB, &suc) == -1)
   111     if (ioctl(fd, SCSIRAWCDB, &suc) == -1)
   112         return (-11);
   112         return (-11);
   113     scsistatus = suc.suc_sus.sus_status;
   113     scsistatus = suc.suc_sus.sus_status;
   114     cp = suc.suc_sus.sus_sense;
   114     cp = suc.suc_sus.sus_sense;
   115 
   115 
   116 /*
   116 /*
   117  * If a place to copy the sense data back to has been provided then the
   117  * If a place to copy the sense data back to has been provided then the
   118  * caller is responsible for checking the errors and printing any information
   118  * caller is responsible for checking the errors and printing any information
   119  * out if the status was not successful.
   119  * out if the status was not successful.
   120 */
   120 */
   121     if (scsistatus != 0 && !sus) {
   121     if (scsistatus != 0 && !sus) {
   122         fprintf (stderr, "scsistatus = %x cmd = %x\n", scsistatus, cdb[0]);
   122         fprintf(stderr, "scsistatus = %x cmd = %x\n", scsistatus, cdb[0]);
   123         fprintf (stderr,
   123         fprintf(stderr,
   124                  "sense %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n",
   124                 "sense %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n",
   125                  cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7],
   125                 cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7],
   126                  cp[8], cp[9], cp[10], cp[11], cp[12], cp[13], cp[14],
   126                 cp[8], cp[9], cp[10], cp[11], cp[12], cp[13], cp[14], cp[15]);
   127                  cp[15]);
       
   128         return (1);
   127         return (1);
   129     }
   128     }
   130     if (sus)
   129     if (sus)
   131         bcopy (&suc, sus, sizeof (struct scsi_user_cdb));
   130         bcopy(&suc, sus, sizeof(struct scsi_user_cdb));
   132     if (scsistatus)
   131     if (scsistatus)
   133         return (1);             /* Return non-zero for unsuccessful status */
   132         return (1);             /* Return non-zero for unsuccessful status */
   134     return (0);
   133     return (0);
   135 }
   134 }
   136 
   135 
   137 /* request vendor brand and model */
   136 /* request vendor brand and model */
   138 unsigned char *
   137 unsigned char *
   139 Inquiry (int fd)
   138 Inquiry(int fd)
   140 {
   139 {
   141     static struct scsi_cdb6 cdb = {
   140     static struct scsi_cdb6 cdb = {
   142         0x12,
   141         0x12,
   143         0, 0, 0,
   142         0, 0, 0,
   144         56,
   143         56,
   145         0
   144         0
   146     };
   145     };
   147     static unsigned char Inqbuffer[56];
   146     static unsigned char Inqbuffer[56];
   148 
   147 
   149     if (scsi_cmd (fd, (cdb_t *) & cdb, 6, SUC_READ, Inqbuffer,
   148     if (scsi_cmd(fd, (cdb_t *) & cdb, 6, SUC_READ, Inqbuffer,
   150                   sizeof (Inqbuffer), 0))
   149                  sizeof(Inqbuffer), 0))
   151         return ("\377");
   150         return ("\377");
   152     return (Inqbuffer);
   151     return (Inqbuffer);
   153 }
   152 }
   154 
   153 
   155 #define ADD_SENSECODE 12
   154 #define ADD_SENSECODE 12
   156 #define ADD_SC_QUALIFIER 13
   155 #define ADD_SC_QUALIFIER 13
   157 
   156 
   158 int
   157 int
   159 TestForMedium (int fd)
   158 TestForMedium(int fd)
   160 {
   159 {
   161     int sts, asc, ascq;
   160     int sts, asc, ascq;
   162     struct scsi_user_cdb sus;
   161     struct scsi_user_cdb sus;
   163     static struct scsi_cdb6 cdb = {
   162     static struct scsi_cdb6 cdb = {
   164         CMD_TEST_UNIT_READY,    /* command */
   163         CMD_TEST_UNIT_READY,    /* command */
   167         0,                      /* reserved */
   166         0,                      /* reserved */
   168         0,                      /* reserved */
   167         0,                      /* reserved */
   169         0                       /* reserved */
   168         0                       /* reserved */
   170     };
   169     };
   171 
   170 
   172   again:sts = scsi_cmd (fd, (cdb_t *) & cdb, 6, SUC_READ, 0, 0, &sus);
   171   again:sts = scsi_cmd(fd, (cdb_t *) & cdb, 6, SUC_READ, 0, 0, &sus);
   173     asc = sus.suc_sus.sus_sense[ADD_SENSECODE];
   172     asc = sus.suc_sus.sus_sense[ADD_SENSECODE];
   174     ascq = sus.suc_sus.sus_sense[ADD_SC_QUALIFIER];
   173     ascq = sus.suc_sus.sus_sense[ADD_SC_QUALIFIER];
   175     if (asc == 0x3a && ascq == 0x0)     /* no medium */
   174     if (asc == 0x3a && ascq == 0x0)     /* no medium */
   176         return (0);
   175         return (0);
   177     if (asc == 0x28 && ascq == 0x0)     /* medium changed */
   176     if (asc == 0x28 && ascq == 0x0)     /* medium changed */
   178         goto again;
   177         goto again;
   179     if (asc == 0x4 && ascq == 0x1) {    /* coming ready */
   178     if (asc == 0x4 && ascq == 0x1) {    /* coming ready */
   180         sleep (2);
   179         sleep(2);
   181         goto again;
   180         goto again;
   182     }
   181     }
   183     return (1);
   182     return (1);
   184 }
   183 }
   185 
   184 
   186 /* Check a drive to see if it is a CD-ROM */
   185 /* Check a drive to see if it is a CD-ROM */
   187 static int
   186 static int
   188 CheckDrive (char *drive, struct stat *stbuf)
   187 CheckDrive(char *drive, struct stat *stbuf)
   189 {
   188 {
   190     int is_cd = 0, cdfd;
   189     int is_cd = 0, cdfd;
   191     char *p;
   190     char *p;
   192 
   191 
   193     /* If it doesn't exist, return -1 */
   192     /* If it doesn't exist, return -1 */
   194     if (stat (drive, stbuf) < 0) {
   193     if (stat(drive, stbuf) < 0) {
   195         return (-1);
   194         return (-1);
   196     }
   195     }
   197 
   196 
   198     /* If it does exist, verify that it's an available CD-ROM */
   197     /* If it does exist, verify that it's an available CD-ROM */
   199     cdfd = open (drive, (O_RDONLY | O_EXCL | O_NONBLOCK), 0);
   198     cdfd = open(drive, (O_RDONLY | O_EXCL | O_NONBLOCK), 0);
   200     if (cdfd >= 0) {
   199     if (cdfd >= 0) {
   201         p = Inquiry (cdfd);
   200         p = Inquiry(cdfd);
   202         if (*p == TYPE_ROM)
   201         if (*p == TYPE_ROM)
   203             is_cd = 1;
   202             is_cd = 1;
   204         close (cdfd);
   203         close(cdfd);
   205     }
   204     }
   206     return (is_cd);
   205     return (is_cd);
   207 }
   206 }
   208 
   207 
   209 /* Add a CD-ROM drive to our list of valid drives */
   208 /* Add a CD-ROM drive to our list of valid drives */
   210 static void
   209 static void
   211 AddDrive (char *drive, struct stat *stbuf)
   210 AddDrive(char *drive, struct stat *stbuf)
   212 {
   211 {
   213     int i;
   212     int i;
   214 
   213 
   215     if (SDL_numcds < MAX_DRIVES) {
   214     if (SDL_numcds < MAX_DRIVES) {
   216         /* Check to make sure it's not already in our list.
   215         /* Check to make sure it's not already in our list.
   217            This can happen when we see a drive via symbolic link.
   216            This can happen when we see a drive via symbolic link.
   218          */
   217          */
   219         for (i = 0; i < SDL_numcds; ++i) {
   218         for (i = 0; i < SDL_numcds; ++i) {
   220             if (stbuf->st_rdev == SDL_cdmode[i]) {
   219             if (stbuf->st_rdev == SDL_cdmode[i]) {
   221 #ifdef DEBUG_CDROM
   220 #ifdef DEBUG_CDROM
   222                 fprintf (stderr, "Duplicate drive detected: %s == %s\n",
   221                 fprintf(stderr, "Duplicate drive detected: %s == %s\n",
   223                          drive, SDL_cdlist[i]);
   222                         drive, SDL_cdlist[i]);
   224 #endif
   223 #endif
   225                 return;
   224                 return;
   226             }
   225             }
   227         }
   226         }
   228 
   227 
   229         /* Add this drive to our list */
   228         /* Add this drive to our list */
   230         i = SDL_numcds;
   229         i = SDL_numcds;
   231         SDL_cdlist[i] = SDL_strdup (drive);
   230         SDL_cdlist[i] = SDL_strdup(drive);
   232         if (SDL_cdlist[i] == NULL) {
   231         if (SDL_cdlist[i] == NULL) {
   233             SDL_OutOfMemory ();
   232             SDL_OutOfMemory();
   234             return;
   233             return;
   235         }
   234         }
   236         SDL_cdmode[i] = stbuf->st_rdev;
   235         SDL_cdmode[i] = stbuf->st_rdev;
   237         ++SDL_numcds;
   236         ++SDL_numcds;
   238 #ifdef DEBUG_CDROM
   237 #ifdef DEBUG_CDROM
   239         fprintf (stderr, "Added CD-ROM drive: %s\n", drive);
   238         fprintf(stderr, "Added CD-ROM drive: %s\n", drive);
   240 #endif
   239 #endif
   241     }
   240     }
   242 }
   241 }
   243 
   242 
   244 int
   243 int
   245 SDL_SYS_CDInit (void)
   244 SDL_SYS_CDInit(void)
   246 {
   245 {
   247     /* checklist: /dev/rsr?c */
   246     /* checklist: /dev/rsr?c */
   248     static char *checklist[] = {
   247     static char *checklist[] = {
   249         "?0 rsr?", NULL
   248         "?0 rsr?", NULL
   250     };
   249     };
   264     SDL_CDcaps.Stop = SDL_SYS_CDStop;
   263     SDL_CDcaps.Stop = SDL_SYS_CDStop;
   265     SDL_CDcaps.Eject = SDL_SYS_CDEject;
   264     SDL_CDcaps.Eject = SDL_SYS_CDEject;
   266     SDL_CDcaps.Close = SDL_SYS_CDClose;
   265     SDL_CDcaps.Close = SDL_SYS_CDClose;
   267 
   266 
   268     /* Look in the environment for our CD-ROM drive list */
   267     /* Look in the environment for our CD-ROM drive list */
   269     SDLcdrom = SDL_getenv ("SDL_CDROM");        /* ':' separated list of devices */
   268     SDLcdrom = SDL_getenv("SDL_CDROM"); /* ':' separated list of devices */
   270     if (SDLcdrom != NULL) {
   269     if (SDLcdrom != NULL) {
   271         char *cdpath, *delim;
   270         char *cdpath, *delim;
   272         size_t len = SDL_strlen (SDLcdrom) + 1;
   271         size_t len = SDL_strlen(SDLcdrom) + 1;
   273         cdpath = SDL_stack_alloc (char, len);
   272         cdpath = SDL_stack_alloc(char, len);
   274         if (cdpath != NULL) {
   273         if (cdpath != NULL) {
   275             SDL_strlcpy (cdpath, SDLcdrom, len);
   274             SDL_strlcpy(cdpath, SDLcdrom, len);
   276             SDLcdrom = cdpath;
   275             SDLcdrom = cdpath;
   277             do {
   276             do {
   278                 delim = SDL_strchr (SDLcdrom, ':');
   277                 delim = SDL_strchr(SDLcdrom, ':');
   279                 if (delim) {
   278                 if (delim) {
   280                     *delim++ = '\0';
   279                     *delim++ = '\0';
   281                 }
   280                 }
   282                 if (CheckDrive (SDLcdrom, &stbuf) > 0) {
   281                 if (CheckDrive(SDLcdrom, &stbuf) > 0) {
   283                     AddDrive (SDLcdrom, &stbuf);
   282                     AddDrive(SDLcdrom, &stbuf);
   284                 }
   283                 }
   285                 if (delim) {
   284                 if (delim) {
   286                     SDLcdrom = delim;
   285                     SDLcdrom = delim;
   287                 } else {
   286                 } else {
   288                     SDLcdrom = NULL;
   287                     SDLcdrom = NULL;
   289                 }
   288                 }
   290             }
   289             }
   291             while (SDLcdrom);
   290             while (SDLcdrom);
   292             SDL_stack_free (cdpath);
   291             SDL_stack_free(cdpath);
   293         }
   292         }
   294 
   293 
   295         /* If we found our drives, there's nothing left to do */
   294         /* If we found our drives, there's nothing left to do */
   296         if (SDL_numcds > 0) {
   295         if (SDL_numcds > 0) {
   297             return (0);
   296             return (0);
   302     for (i = 0; checklist[i]; ++i) {
   301     for (i = 0; checklist[i]; ++i) {
   303         if (checklist[i][0] == '?') {
   302         if (checklist[i][0] == '?') {
   304             char *insert;
   303             char *insert;
   305             exists = 1;
   304             exists = 1;
   306             for (j = checklist[i][1]; exists; ++j) {
   305             for (j = checklist[i][1]; exists; ++j) {
   307                 SDL_snprintf (drive, SDL_arraysize (drive), "/dev/%sc",
   306                 SDL_snprintf(drive, SDL_arraysize(drive), "/dev/%sc",
   308                               &checklist[i][3]);
   307                              &checklist[i][3]);
   309                 insert = SDL_strchr (drive, '?');
   308                 insert = SDL_strchr(drive, '?');
   310                 if (insert != NULL) {
   309                 if (insert != NULL) {
   311                     *insert = j;
   310                     *insert = j;
   312                 }
   311                 }
   313                 switch (CheckDrive (drive, &stbuf)) {
   312                 switch (CheckDrive(drive, &stbuf)) {
   314                     /* Drive exists and is a CD-ROM */
   313                     /* Drive exists and is a CD-ROM */
   315                 case 1:
   314                 case 1:
   316                     AddDrive (drive, &stbuf);
   315                     AddDrive(drive, &stbuf);
   317                     break;
   316                     break;
   318                     /* Drive exists, but isn't a CD-ROM */
   317                     /* Drive exists, but isn't a CD-ROM */
   319                 case 0:
   318                 case 0:
   320                     break;
   319                     break;
   321                     /* Drive doesn't exist */
   320                     /* Drive doesn't exist */
   323                     exists = 0;
   322                     exists = 0;
   324                     break;
   323                     break;
   325                 }
   324                 }
   326             }
   325             }
   327         } else {
   326         } else {
   328             SDL_snprintf (drive, SDL_arraysize (drive), "/dev/%s",
   327             SDL_snprintf(drive, SDL_arraysize(drive), "/dev/%s",
   329                           checklist[i]);
   328                          checklist[i]);
   330             if (CheckDrive (drive, &stbuf) > 0) {
   329             if (CheckDrive(drive, &stbuf) > 0) {
   331                 AddDrive (drive, &stbuf);
   330                 AddDrive(drive, &stbuf);
   332             }
   331             }
   333         }
   332         }
   334     }
   333     }
   335     return (0);
   334     return (0);
   336 }
   335 }
   337 
   336 
   338 static const char *
   337 static const char *
   339 SDL_SYS_CDName (int drive)
   338 SDL_SYS_CDName(int drive)
   340 {
   339 {
   341     return (SDL_cdlist[drive]);
   340     return (SDL_cdlist[drive]);
   342 }
   341 }
   343 
   342 
   344 static int
   343 static int
   345 SDL_SYS_CDOpen (int drive)
   344 SDL_SYS_CDOpen(int drive)
   346 {
   345 {
   347     return (open (SDL_cdlist[drive], O_RDONLY | O_NONBLOCK | O_EXCL, 0));
   346     return (open(SDL_cdlist[drive], O_RDONLY | O_NONBLOCK | O_EXCL, 0));
   348 }
   347 }
   349 
   348 
   350 static int
   349 static int
   351 SDL_SYS_CDGetTOC (SDL_CD * cdrom)
   350 SDL_SYS_CDGetTOC(SDL_CD * cdrom)
   352 {
   351 {
   353     u_char cdb[10], buf[4], *p, *toc;
   352     u_char cdb[10], buf[4], *p, *toc;
   354     struct scsi_user_cdb sus;
   353     struct scsi_user_cdb sus;
   355     int i, sts, first_track, last_track, ntracks, toc_size;
   354     int i, sts, first_track, last_track, ntracks, toc_size;
   356 
   355 
   357     bzero (cdb, sizeof (cdb));
   356     bzero(cdb, sizeof(cdb));
   358     cdb[0] = 0x43;              /* Read TOC */
   357     cdb[0] = 0x43;              /* Read TOC */
   359     cdb[1] = 0x2;               /* MSF */
   358     cdb[1] = 0x2;               /* MSF */
   360     cdb[8] = 4;                 /* size TOC header */
   359     cdb[8] = 4;                 /* size TOC header */
   361     sts = scsi_cmd (cdrom->id, (cdb_t *) cdb, 10, SUC_READ, buf, 4, &sus);
   360     sts = scsi_cmd(cdrom->id, (cdb_t *) cdb, 10, SUC_READ, buf, 4, &sus);
   362     if (sts < 0)
   361     if (sts < 0)
   363         return (-1);
   362         return (-1);
   364     first_track = buf[2];
   363     first_track = buf[2];
   365     last_track = buf[3];
   364     last_track = buf[3];
   366     ntracks = last_track - first_track + 1;
   365     ntracks = last_track - first_track + 1;
   367     cdrom->numtracks = ntracks;
   366     cdrom->numtracks = ntracks;
   368     toc_size = 4 + (ntracks + 1) * 8;
   367     toc_size = 4 + (ntracks + 1) * 8;
   369     toc = (u_char *) SDL_malloc (toc_size);
   368     toc = (u_char *) SDL_malloc(toc_size);
   370     if (toc == NULL)
   369     if (toc == NULL)
   371         return (-1);
   370         return (-1);
   372     bzero (cdb, sizeof (cdb));
   371     bzero(cdb, sizeof(cdb));
   373     cdb[0] = 0x43;
   372     cdb[0] = 0x43;
   374     cdb[1] = 0x2;
   373     cdb[1] = 0x2;
   375     cdb[6] = first_track;
   374     cdb[6] = first_track;
   376     cdb[7] = toc_size >> 8;
   375     cdb[7] = toc_size >> 8;
   377     cdb[8] = toc_size & 0xff;
   376     cdb[8] = toc_size & 0xff;
   378     sts = scsi_cmd (cdrom->id, (cdb_t *) cdb, 10, SUC_READ, toc, toc_size,
   377     sts = scsi_cmd(cdrom->id, (cdb_t *) cdb, 10, SUC_READ, toc, toc_size,
   379                     &sus);
   378                    &sus);
   380     if (sts < 0) {
   379     if (sts < 0) {
   381         SDL_free (toc);
   380         SDL_free(toc);
   382         return (-1);
   381         return (-1);
   383     }
   382     }
   384 
   383 
   385     for (i = 0, p = toc + 4; i <= ntracks; i++, p += 8) {
   384     for (i = 0, p = toc + 4; i <= ntracks; i++, p += 8) {
   386         if (i == ntracks)
   385         if (i == ntracks)
   389             cdrom->track[i].id = first_track + i;
   388             cdrom->track[i].id = first_track + i;
   390         if (p[1] & 0x20)
   389         if (p[1] & 0x20)
   391             cdrom->track[i].type = SDL_DATA_TRACK;
   390             cdrom->track[i].type = SDL_DATA_TRACK;
   392         else
   391         else
   393             cdrom->track[i].type = SDL_AUDIO_TRACK;
   392             cdrom->track[i].type = SDL_AUDIO_TRACK;
   394         cdrom->track[i].offset = msf_to_frame (p[5], p[6], p[7]);
   393         cdrom->track[i].offset = msf_to_frame(p[5], p[6], p[7]);
   395         cdrom->track[i].length = 0;
   394         cdrom->track[i].length = 0;
   396         if (i > 0)
   395         if (i > 0)
   397             cdrom->track[i - 1].length = cdrom->track[i].offset -
   396             cdrom->track[i - 1].length = cdrom->track[i].offset -
   398                 cdrom->track[i - 1].offset;
   397                 cdrom->track[i - 1].offset;
   399     }
   398     }
   400     SDL_free (toc);
   399     SDL_free(toc);
   401     return (0);
   400     return (0);
   402 }
   401 }
   403 
   402 
   404 /* Get CD-ROM status */
   403 /* Get CD-ROM status */
   405 static CDstatus
   404 static CDstatus
   406 SDL_SYS_CDStatus (SDL_CD * cdrom, int *position)
   405 SDL_SYS_CDStatus(SDL_CD * cdrom, int *position)
   407 {
   406 {
   408     CDstatus status;
   407     CDstatus status;
   409     u_char cdb[10], buf[16];
   408     u_char cdb[10], buf[16];
   410     int sts;
   409     int sts;
   411     struct scsi_user_cdb sus;
   410     struct scsi_user_cdb sus;
   412 
   411 
   413     bzero (cdb, sizeof (cdb));
   412     bzero(cdb, sizeof(cdb));
   414     cdb[0] = 0x42;              /* read subq */
   413     cdb[0] = 0x42;              /* read subq */
   415     cdb[1] = 0x2;               /* MSF */
   414     cdb[1] = 0x2;               /* MSF */
   416     cdb[2] = 0x40;              /* q channel */
   415     cdb[2] = 0x40;              /* q channel */
   417     cdb[3] = 1;                 /* current pos */
   416     cdb[3] = 1;                 /* current pos */
   418     cdb[7] = sizeof (buf) >> 8;
   417     cdb[7] = sizeof(buf) >> 8;
   419     cdb[8] = sizeof (buf) & 0xff;
   418     cdb[8] = sizeof(buf) & 0xff;
   420     sts = scsi_cmd (cdrom->id, (cdb_t *) cdb, 10, SUC_READ, buf, sizeof (buf),
   419     sts = scsi_cmd(cdrom->id, (cdb_t *) cdb, 10, SUC_READ, buf, sizeof(buf),
   421                     &sus);
   420                    &sus);
   422     if (sts < 0)
   421     if (sts < 0)
   423         return (-1);
   422         return (-1);
   424     if (sts) {
   423     if (sts) {
   425         if (TestForMedium (cdrom->id) == 0)
   424         if (TestForMedium(cdrom->id) == 0)
   426             status = CD_TRAYEMPTY;
   425             status = CD_TRAYEMPTY;
   427         else
   426         else
   428             status = CD_ERROR;
   427             status = CD_ERROR;
   429     } else {
   428     } else {
   430         switch (buf[1]) {
   429         switch (buf[1]) {
   444             break;
   443             break;
   445         }
   444         }
   446     }
   445     }
   447     if (position) {
   446     if (position) {
   448         if (status == CD_PLAYING || (status == CD_PAUSED))
   447         if (status == CD_PLAYING || (status == CD_PAUSED))
   449             *position = msf_to_frame (buf[9], buf[10], buf[11]);
   448             *position = msf_to_frame(buf[9], buf[10], buf[11]);
   450         else
   449         else
   451             *position = 0;
   450             *position = 0;
   452     }
   451     }
   453     return (status);
   452     return (status);
   454 }
   453 }
   455 
   454 
   456 /* Start play */
   455 /* Start play */
   457 static int
   456 static int
   458 SDL_SYS_CDPlay (SDL_CD * cdrom, int start, int length)
   457 SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length)
   459 {
   458 {
   460     u_char cdb[10];
   459     u_char cdb[10];
   461     int sts, minute, second, frame, eminute, esecond, eframe;
   460     int sts, minute, second, frame, eminute, esecond, eframe;
   462     struct scsi_user_cdb sus;
   461     struct scsi_user_cdb sus;
   463 
   462 
   464     bzero (cdb, sizeof (cdb));
   463     bzero(cdb, sizeof(cdb));
   465     cdb[0] = 0x47;              /* Play */
   464     cdb[0] = 0x47;              /* Play */
   466     frame_to_msf (start, &minute, &second, &frame);
   465     frame_to_msf(start, &minute, &second, &frame);
   467     frame_to_msf (start + length, &eminute, &esecond, &eframe);
   466     frame_to_msf(start + length, &eminute, &esecond, &eframe);
   468     cdb[3] = minute;
   467     cdb[3] = minute;
   469     cdb[4] = second;
   468     cdb[4] = second;
   470     cdb[5] = frame;
   469     cdb[5] = frame;
   471     cdb[6] = eminute;
   470     cdb[6] = eminute;
   472     cdb[7] = esecond;
   471     cdb[7] = esecond;
   473     cdb[8] = eframe;
   472     cdb[8] = eframe;
   474     sts = scsi_cmd (cdrom->id, (cdb_t *) cdb, 10, SUC_READ, 0, 0, &sus);
   473     sts = scsi_cmd(cdrom->id, (cdb_t *) cdb, 10, SUC_READ, 0, 0, &sus);
   475     return (sts);
   474     return (sts);
   476 }
   475 }
   477 
   476 
   478 static int
   477 static int
   479 pauseresume (SDL_CD * cdrom, int flag)
   478 pauseresume(SDL_CD * cdrom, int flag)
   480 {
   479 {
   481     u_char cdb[10];
   480     u_char cdb[10];
   482     struct scsi_user_cdb sus;
   481     struct scsi_user_cdb sus;
   483 
   482 
   484     bzero (cdb, sizeof (cdb));
   483     bzero(cdb, sizeof(cdb));
   485     cdb[0] = 0x4b;
   484     cdb[0] = 0x4b;
   486     cdb[8] = flag & 0x1;
   485     cdb[8] = flag & 0x1;
   487     return (scsi_cmd (cdrom->id, (cdb_t *) cdb, 10, SUC_READ, 0, 0, &sus));
   486     return (scsi_cmd(cdrom->id, (cdb_t *) cdb, 10, SUC_READ, 0, 0, &sus));
   488 }
   487 }
   489 
   488 
   490 /* Pause play */
   489 /* Pause play */
   491 static int
   490 static int
   492 SDL_SYS_CDPause (SDL_CD * cdrom)
   491 SDL_SYS_CDPause(SDL_CD * cdrom)
   493 {
   492 {
   494     return (pauseresume (cdrom, 0));
   493     return (pauseresume(cdrom, 0));
   495 }
   494 }
   496 
   495 
   497 /* Resume play */
   496 /* Resume play */
   498 static int
   497 static int
   499 SDL_SYS_CDResume (SDL_CD * cdrom)
   498 SDL_SYS_CDResume(SDL_CD * cdrom)
   500 {
   499 {
   501     return (pauseresume (cdrom, 1));
   500     return (pauseresume(cdrom, 1));
   502 }
   501 }
   503 
   502 
   504 /* Stop play */
   503 /* Stop play */
   505 static int
   504 static int
   506 SDL_SYS_CDStop (SDL_CD * cdrom)
   505 SDL_SYS_CDStop(SDL_CD * cdrom)
   507 {
   506 {
   508     u_char cdb[6];
   507     u_char cdb[6];
   509     struct scsi_user_cdb sus;
   508     struct scsi_user_cdb sus;
   510 
   509 
   511     bzero (cdb, sizeof (cdb));
   510     bzero(cdb, sizeof(cdb));
   512     cdb[0] = 0x1b;              /* stop */
   511     cdb[0] = 0x1b;              /* stop */
   513     cdb[1] = 1;                 /* immediate */
   512     cdb[1] = 1;                 /* immediate */
   514     return (scsi_cmd (cdrom->id, (cdb_t *) cdb, 6, SUC_READ, 0, 0, &sus));
   513     return (scsi_cmd(cdrom->id, (cdb_t *) cdb, 6, SUC_READ, 0, 0, &sus));
   515 }
   514 }
   516 
   515 
   517 /* Eject the CD-ROM */
   516 /* Eject the CD-ROM */
   518 static int
   517 static int
   519 SDL_SYS_CDEject (SDL_CD * cdrom)
   518 SDL_SYS_CDEject(SDL_CD * cdrom)
   520 {
   519 {
   521     u_char cdb[6];
   520     u_char cdb[6];
   522     struct scsi_user_cdb sus;
   521     struct scsi_user_cdb sus;
   523 
   522 
   524     bzero (cdb, sizeof (cdb));
   523     bzero(cdb, sizeof(cdb));
   525     cdb[0] = 0x1b;              /* stop */
   524     cdb[0] = 0x1b;              /* stop */
   526     cdb[1] = 1;                 /* immediate */
   525     cdb[1] = 1;                 /* immediate */
   527     cdb[4] = 2;                 /* eject */
   526     cdb[4] = 2;                 /* eject */
   528     return (scsi_cmd (cdrom->id, (cdb_t *) cdb, 6, SUC_READ, 0, 0, &sus));
   527     return (scsi_cmd(cdrom->id, (cdb_t *) cdb, 6, SUC_READ, 0, 0, &sus));
   529 }
   528 }
   530 
   529 
   531 /* Close the CD-ROM handle */
   530 /* Close the CD-ROM handle */
   532 static void
   531 static void
   533 SDL_SYS_CDClose (SDL_CD * cdrom)
   532 SDL_SYS_CDClose(SDL_CD * cdrom)
   534 {
   533 {
   535     close (cdrom->id);
   534     close(cdrom->id);
   536 }
   535 }
   537 
   536 
   538 void
   537 void
   539 SDL_SYS_CDQuit (void)
   538 SDL_SYS_CDQuit(void)
   540 {
   539 {
   541     int i;
   540     int i;
   542 
   541 
   543     if (SDL_numcds > 0) {
   542     if (SDL_numcds > 0) {
   544         for (i = 0; i < SDL_numcds; ++i) {
   543         for (i = 0; i < SDL_numcds; ++i) {
   545             SDL_free (SDL_cdlist[i]);
   544             SDL_free(SDL_cdlist[i]);
   546         }
   545         }
   547     }
   546     }
   548     SDL_numcds = 0;
   547     SDL_numcds = 0;
   549 }
   548 }
   550 
   549