$NetBSD: patch-cg,v 1.5 2001/01/08 23:04:58 itohy Exp $ --- interface/scsi_interface.c.orig Tue Dec 14 13:28:03 1999 +++ interface/scsi_interface.c Mon Jan 8 09:11:38 2001 @@ -32,6 +32,7 @@ #endif static int look_for_dougg(cdrom_drive *d){ +#ifdef __linux__ /* are we using the new SG driver by Doug Gilbert? If so, our memory strategy will be different. */ int reserved,table; @@ -78,6 +79,9 @@ } return(1); +#else + return(0); +#endif } static void find_bloody_big_buff_size(cdrom_drive *d){ @@ -142,6 +146,7 @@ } +#ifdef __linux__ static void clear_garbage(cdrom_drive *d){ fd_set fdset; struct timeval tv; @@ -172,20 +177,28 @@ flag=1; } } +#endif /* process a complete scsi command. */ static int handle_scsi_cmd(cdrom_drive *d, unsigned int cmd_len, unsigned int in_size, unsigned int out_size, - unsigned char bytefill, + unsigned int bfill, int bytecheck){ + unsigned char bytefill = bfill; int status = 0; +#ifdef __linux__ struct sg_header *sg_hd=(struct sg_header *)d->sg; long writebytes=SG_OFF+cmd_len+in_size; +#endif +#ifdef __NetBSD__ + scsireq_t *sreq = (scsireq_t *)d->sg; +#endif /* generic scsi device services */ +#ifdef __linux__ /* clear out any possibly preexisting garbage */ clear_garbage(d); @@ -291,11 +304,53 @@ if(errno==0)errno=EIO; return(TR_EREAD); } +#endif /* __linux__ */ + +#ifdef __NetBSD__ + if (in_size && out_size) { + warnx("handle_scsi_cmd: in and out is not supported"); + abort(); + } + memset(sreq, 0, sizeof(scsireq_t)); + sreq->cmdlen = cmd_len; + memcpy(sreq->cmd, d->sg_buffer, cmd_len); + if (in_size) { + sreq->flags = SCCMD_WRITE; + sreq->databuf = d->sg_buffer + cmd_len; + sreq->datalen = in_size; + } + if (out_size) { + sreq->flags = SCCMD_READ; + sreq->databuf = d->sg_buffer; + sreq->datalen = out_size; + if(bytecheck) + memset(d->sg_buffer, bytefill, out_size); + } + sreq->senselen = SENSEBUFLEN; + sreq->timeout = 60000; /* 60s */ - if(sg_hd->sense_buffer[0]){ + status = ioctl(d->cdda_fd, SCIOCCOMMAND, (void *) sreq); + if (status < 0) + return(TR_ILLEGAL); +#endif + +#ifdef __linux__ + if(sg_hd->sense_buffer[0]) +#endif +#ifdef __NetBSD__ + if (sreq->sense[0]) +#endif + { +#ifdef __linux__ char key=sg_hd->sense_buffer[2]&0xf; char ASC=sg_hd->sense_buffer[12]; char ASCQ=sg_hd->sense_buffer[13]; +#endif +#ifdef __NetBSD__ + char key = sreq->sense[2]&0xf; + char ASC = sreq->sense[12]; + char ASCQ = sreq->sense[13]; +#endif switch(key){ case 0: if(errno==0)errno=EIO; @@ -333,9 +388,20 @@ commands still get through. Perhaps no data comes back even though the target reports success? */ - if(bytecheck && in_size+cmd_lensg_buffer[i]!=bytefill){ flag=1; break; @@ -667,6 +733,23 @@ return(tracks); } +/* Set operating speed */ +static int scsi_setspeed(cdrom_drive *d, int speed) +{ + if (speed == 0) + speed = 0xffff; /* maximum speed */ + else if (speed < 176) + speed *= 176; + + memset(d->sg_buffer, 0, 12); + d->sg_buffer[0] = 0xbb; /* set speed */ + d->sg_buffer[2] = speed >> 8; + d->sg_buffer[3] = speed; + d->sg_buffer[4] = -1; + d->sg_buffer[5] = -1; + return handle_scsi_cmd(d, 12, 0, 0, 0, 0); +} + /* These do one 'extra' copy in the name of clean code */ static int i_read_28 (cdrom_drive *d, void *p, long begin, long sectors){ @@ -840,16 +923,29 @@ while(1) { if((err=map(d,(p?buffer:NULL),begin,sectors))){ if(d->report_all){ +#ifdef __linux__ struct sg_header *sg_hd=(struct sg_header *)d->sg; +#endif +#ifdef __NetBSD__ + scsireq_t *sreq=(scsireq_t *)d->sg; +#endif char b[256]; sprintf(b,"scsi_read error: sector=%ld length=%ld retry=%d\n", begin,sectors,retry_count); cdmessage(d,b); sprintf(b," Sense key: %x ASC: %x ASCQ: %x\n", +#ifdef __linux__ (int)(sg_hd->sense_buffer[2]&0xf), (int)(sg_hd->sense_buffer[12]), - (int)(sg_hd->sense_buffer[13])); + (int)(sg_hd->sense_buffer[13]) +#endif +#ifdef __NetBSD__ + (int)(sreq->sense[2]&0xf), + (int)(sreq->sense[12]), + (int)(sreq->sense[13]) +#endif + ); cdmessage(d,b); sprintf(b," Transport error: %s\n",strerror_tr[err]); cdmessage(d,b); @@ -859,9 +955,17 @@ fprintf(stderr,"scsi_read error: sector=%ld length=%ld retry=%d\n", begin,sectors,retry_count); fprintf(stderr," Sense key: %x ASC: %x ASCQ: %x\n", +#ifdef __linux__ (int)(sg_hd->sense_buffer[2]&0xf), (int)(sg_hd->sense_buffer[12]), - (int)(sg_hd->sense_buffer[13])); + (int)(sg_hd->sense_buffer[13]) +#endif +#ifdef __NetBSD__ + (int)(sreq->sense[2]&0xf), + (int)(sreq->sense[12]), + (int)(sreq->sense[13]) +#endif + ); fprintf(stderr," Transport error: %s\n",strerror_tr[err]); fprintf(stderr," System error: %s\n",strerror(errno)); } @@ -1377,6 +1481,11 @@ if(reportp) cdmessage(d,"\tDrive appears to be Mt. Fuji ATAPI C/DVD\n"); return(1); + case 0x32: + /* Toshiba DVD */ + if(reportp) + cdmessage(d,"\tDrive appears to be Toshiba ATAPI C/DVD\n"); + return(1); default: if(reportp) switch(d->inqbytes[3]&0x0f){ @@ -1537,7 +1646,7 @@ d->read_toc = (!memcmp(d->drive_model, "IMS", 3) && !d->is_atapi) ? scsi_read_toc2 : scsi_read_toc; - d->set_speed = NULL; + d->set_speed = scsi_setspeed; if(!d->is_atapi){