2011-10-29 11:28:08 +00:00
|
|
|
--- interface/scsi_interface.c.orig 2001-03-23 17:15:46.000000000 -0800
|
|
|
|
+++ interface/scsi_interface.c 2011-10-17 21:33:00.000000000 -0700
|
2003-01-10 01:06:33 +00:00
|
|
|
@@ -3,6 +3,8 @@
|
|
|
|
* Original interface.c Copyright (C) 1994-1997
|
|
|
|
* Eissfeldt heiko@colossus.escape.de
|
|
|
|
* Current blenderization Copyright (C) 1998-1999 Monty xiphmont@mit.edu
|
|
|
|
+ * FreeBSD porting (c) 2003
|
|
|
|
+ * Simon 'corecode' Schubert <corecode@corecode.ath.cx>
|
|
|
|
*
|
|
|
|
* Generic SCSI interface specific code.
|
|
|
|
*
|
2011-10-29 11:28:08 +00:00
|
|
|
@@ -23,6 +25,7 @@
|
2003-01-10 01:06:33 +00:00
|
|
|
int table,reserved;
|
|
|
|
char buffer[256];
|
|
|
|
|
|
|
|
+#ifdef Linux
|
|
|
|
/* maximum transfer size? */
|
|
|
|
if(ioctl(d->cdda_fd,SG_GET_RESERVED_SIZE,&reserved)){
|
|
|
|
/* Up, guess not. */
|
2011-10-29 11:28:08 +00:00
|
|
|
@@ -59,8 +62,17 @@
|
2003-01-10 01:06:33 +00:00
|
|
|
cdmessage(d,"\tCouldn't disable command queue! Continuing anyway...\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
+#elif defined(__FreeBSD__)
|
|
|
|
+ d->nsectors = 26; /* FreeBSD only supports 64K I/O transfer size */
|
|
|
|
+ d->bigbuff = d->nsectors * CD_FRAMESIZE_RAW;
|
|
|
|
+
|
|
|
|
+ sprintf(buffer,"\tSetting default read size to %d sectors (%d bytes).\n\n",
|
|
|
|
+ d->nsectors,d->nsectors*CD_FRAMESIZE_RAW);
|
|
|
|
+ cdmessage(d,buffer);
|
|
|
|
+#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
+#ifdef Linux
|
|
|
|
static void reset_scsi(cdrom_drive *d){
|
|
|
|
int arg;
|
|
|
|
d->enable_cdda(d,0);
|
2011-10-29 11:28:08 +00:00
|
|
|
@@ -74,6 +86,30 @@
|
2003-01-10 01:06:33 +00:00
|
|
|
d->enable_cdda(d,1);
|
|
|
|
}
|
|
|
|
|
|
|
|
+#elif defined(__FreeBSD__)
|
|
|
|
+static void reset_scsi(cdrom_drive *d) {
|
|
|
|
+ d->enable_cdda(d,0);
|
|
|
|
+
|
|
|
|
+ d->ccb->ccb_h.func_code = XPT_RESET_DEV;
|
|
|
|
+ d->ccb->ccb_h.timeout = 5000;
|
|
|
|
+
|
|
|
|
+ cdmessage(d, "sending SCSI reset... ");
|
|
|
|
+ if (cam_send_ccb(d->dev, d->ccb)) {
|
|
|
|
+ cdmessage(d, "error sending XPT_RESET_DEV CCB");
|
|
|
|
+ } else {
|
|
|
|
+
|
|
|
|
+ if (((d->ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) ||
|
|
|
|
+ ((d->ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))
|
|
|
|
+ cdmessage(d,"OK\n");
|
|
|
|
+ else
|
|
|
|
+ cdmessage(d,"FAILED\n");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ d->enable_cdda(d,1);
|
|
|
|
+}
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+#ifdef Linux
|
|
|
|
static void clear_garbage(cdrom_drive *d){
|
|
|
|
fd_set fdset;
|
|
|
|
struct timeval tv;
|
2011-10-29 11:28:08 +00:00
|
|
|
@@ -104,8 +140,10 @@
|
2003-01-10 01:06:33 +00:00
|
|
|
flag=1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
+#endif
|
|
|
|
|
|
|
|
/* process a complete scsi command. */
|
|
|
|
+#ifdef Linux
|
|
|
|
static int handle_scsi_cmd(cdrom_drive *d,
|
|
|
|
unsigned int cmd_len,
|
|
|
|
unsigned int in_size,
|
2011-10-29 11:28:08 +00:00
|
|
|
@@ -284,6 +322,95 @@
|
2003-01-10 01:06:33 +00:00
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
+#elif defined(__FreeBSD__)
|
|
|
|
+static int handle_scsi_cmd(cdrom_drive *d,
|
|
|
|
+ unsigned int cmd_len,
|
|
|
|
+ unsigned int out_size,
|
|
|
|
+ unsigned int in_size,
|
|
|
|
+ unsigned char bytefill,
|
|
|
|
+ int bytecheck) {
|
|
|
|
+ int result;
|
2011-10-29 11:28:08 +00:00
|
|
|
+ int error_code, sense_key, asc, ascq;
|
2003-01-10 01:06:33 +00:00
|
|
|
+
|
|
|
|
+ bzero(&d->ccb->csio, sizeof(d->ccb->csio));
|
|
|
|
+
|
|
|
|
+ memcpy(d->ccb->csio.cdb_io.cdb_bytes, d->sg_buffer, cmd_len);
|
2003-01-19 20:28:41 +00:00
|
|
|
+
|
|
|
|
+ if (bytecheck && out_size == 0)
|
|
|
|
+ memset(d->sg_buffer, bytefill, in_size);
|
|
|
|
+
|
2003-01-10 01:06:33 +00:00
|
|
|
+ cam_fill_csio(&d->ccb->csio,
|
2003-01-19 20:28:41 +00:00
|
|
|
+ /* retries */ 0,
|
2003-01-10 01:06:33 +00:00
|
|
|
+ /* cbfcnp */ NULL,
|
2003-01-19 20:28:41 +00:00
|
|
|
+ /* flags */ CAM_DEV_QFRZDIS | (out_size ? CAM_DIR_OUT : CAM_DIR_IN),
|
2003-01-10 01:06:33 +00:00
|
|
|
+ /* tag_action */ MSG_SIMPLE_Q_TAG,
|
|
|
|
+ /* data_ptr */ out_size ? d->sg_buffer + cmd_len : d->sg_buffer,
|
|
|
|
+ /* dxfer_len */ out_size ? out_size : in_size,
|
|
|
|
+ /* sense_len */ SSD_FULL_SIZE,
|
|
|
|
+ /* cdb_len */ cmd_len,
|
|
|
|
+ /* timeout */ 60000); /* XXX */
|
|
|
|
+
|
2003-01-19 20:28:41 +00:00
|
|
|
+ if ((result = cam_send_ccb(d->dev, d->ccb)) < 0 ||
|
|
|
|
+ (d->ccb->ccb_h.status & CAM_STATUS_MASK) == 0 /* hack? */)
|
2003-01-10 01:06:33 +00:00
|
|
|
+ return TR_EREAD;
|
|
|
|
+
|
2003-01-19 20:28:41 +00:00
|
|
|
+ if ((d->ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP &&
|
|
|
|
+ (d->ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_SCSI_STATUS_ERROR) {
|
|
|
|
+ fprintf (stderr, "\t\terror returned from SCSI command:\n"
|
|
|
|
+ "\t\tccb->ccb_h.status == %d\n", d->ccb->ccb_h.status);
|
2003-01-10 01:06:33 +00:00
|
|
|
+ errno = EIO;
|
|
|
|
+ return TR_UNKNOWN;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (d->ccb->csio.dxfer_len != in_size) {
|
|
|
|
+ errno = EIO;
|
|
|
|
+ return TR_EREAD;
|
|
|
|
+ }
|
|
|
|
+
|
2011-10-29 11:28:08 +00:00
|
|
|
+ scsi_extract_sense(&d->ccb->csio.sense_data, &error_code, &sense_key,
|
|
|
|
+ &asc, &ascq);
|
|
|
|
+
|
|
|
|
+ switch (error_code) {
|
|
|
|
+ case SSD_CURRENT_ERROR:
|
|
|
|
+ case SSD_DEFERRED_ERROR:
|
|
|
|
+#if (CAM_VERSION > 0x15)
|
|
|
|
+ case SSD_DESC_CURRENT_ERROR:
|
|
|
|
+ case SSD_DESC_DEFERRED_ERROR:
|
|
|
|
+#endif
|
|
|
|
+ switch (sense_key) {
|
2003-01-10 01:06:33 +00:00
|
|
|
+ case SSD_KEY_NO_SENSE:
|
|
|
|
+ errno = EIO;
|
|
|
|
+ return TR_UNKNOWN;
|
|
|
|
+ case SSD_KEY_RECOVERED_ERROR:
|
|
|
|
+ break;
|
|
|
|
+ case SSD_KEY_NOT_READY:
|
|
|
|
+ errno = EBUSY;
|
|
|
|
+ return TR_BUSY;
|
|
|
|
+ case SSD_KEY_MEDIUM_ERROR:
|
|
|
|
+ errno = EIO;
|
2011-10-29 11:28:08 +00:00
|
|
|
+ if ((asc == 0x0c) && (ascq == 0x09))
|
2003-01-10 01:06:33 +00:00
|
|
|
+ return TR_STREAMING;
|
|
|
|
+ else
|
|
|
|
+ return TR_MEDIUM;
|
|
|
|
+ case SSD_KEY_HARDWARE_ERROR:
|
|
|
|
+ errno = EIO;
|
|
|
|
+ return TR_FAULT;
|
|
|
|
+ case SSD_KEY_ILLEGAL_REQUEST:
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return TR_ILLEGAL;
|
|
|
|
+ default:
|
|
|
|
+ errno = EIO;
|
|
|
|
+ return TR_UNKNOWN;
|
|
|
|
+ }
|
2011-10-29 11:28:08 +00:00
|
|
|
+ default:
|
|
|
|
+ break;
|
2003-01-10 01:06:33 +00:00
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+
|
|
|
|
/* Group 1 (10b) command */
|
|
|
|
|
|
|
|
static int mode_sense_atapi(cdrom_drive *d,int size,int page){
|
2011-10-29 11:28:08 +00:00
|
|
|
@@ -833,30 +960,37 @@
|
2003-01-10 01:06:33 +00:00
|
|
|
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;
|
2011-10-29 11:28:08 +00:00
|
|
|
+#elif defined(__FreeBSD__)
|
|
|
|
+ int error_code, sense_key, asc, ascq;
|
2003-01-10 01:06:33 +00:00
|
|
|
+#endif
|
|
|
|
char b[256];
|
|
|
|
|
|
|
|
sprintf(b,"scsi_read error: sector=%ld length=%ld retry=%d\n",
|
|
|
|
begin,sectors,retry_count);
|
|
|
|
+ fputs(b, stderr);
|
|
|
|
cdmessage(d,b);
|
2011-10-29 11:28:08 +00:00
|
|
|
+#if defined(__FreeBSD__)
|
|
|
|
+ scsi_extract_sense(&d->ccb->csio.sense_data, &error_code, &sense_key,
|
|
|
|
+ &asc, &ascq);
|
|
|
|
+#endif
|
2003-01-10 01:06:33 +00:00
|
|
|
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]));
|
|
|
|
+#elif defined(__FreeBSD__)
|
2011-10-29 11:28:08 +00:00
|
|
|
+ sense_key, asc, ascq);
|
2003-01-10 01:06:33 +00:00
|
|
|
+#endif
|
|
|
|
+ fputs(b, stderr);
|
|
|
|
cdmessage(d,b);
|
|
|
|
sprintf(b," Transport error: %s\n",strerror_tr[err]);
|
|
|
|
+ fputs(b, stderr);
|
|
|
|
cdmessage(d,b);
|
|
|
|
sprintf(b," System error: %s\n",strerror(errno));
|
|
|
|
+ fputs(b, stderr);
|
|
|
|
cdmessage(d,b);
|
|
|
|
-
|
|
|
|
- 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",
|
|
|
|
- (int)(sg_hd->sense_buffer[2]&0xf),
|
|
|
|
- (int)(sg_hd->sense_buffer[12]),
|
|
|
|
- (int)(sg_hd->sense_buffer[13]));
|
|
|
|
- fprintf(stderr," Transport error: %s\n",strerror_tr[err]);
|
|
|
|
- fprintf(stderr," System error: %s\n",strerror(errno));
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!d->error_retry)return(-7);
|
2011-10-29 11:28:08 +00:00
|
|
|
@@ -1307,6 +1441,7 @@
|
2003-01-10 01:06:33 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
+#ifdef Linux
|
|
|
|
static int check_atapi(cdrom_drive *d){
|
|
|
|
int atapiret=-1;
|
|
|
|
int fd = d->cdda_fd; /* this is the correct fd (not ioctl_fd), as the
|
2011-10-29 11:28:08 +00:00
|
|
|
@@ -1333,6 +1468,53 @@
|
2003-01-10 01:06:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
+#elif defined(__FreeBSD__)
|
|
|
|
+static int
|
|
|
|
+check_atapi(cdrom_drive *d)
|
|
|
|
+{
|
|
|
|
+ bzero(&(&d->ccb->ccb_h)[1], sizeof(d->ccb->cpi) - sizeof(d->ccb->ccb_h));
|
|
|
|
+
|
|
|
|
+ d->ccb->ccb_h.func_code = XPT_PATH_INQ;
|
|
|
|
+
|
|
|
|
+ cdmessage(d, "\nChecking for ATAPICAM...\n");
|
|
|
|
+
|
|
|
|
+ if (cam_send_ccb(d->dev, d->ccb) < 0) {
|
|
|
|
+ cderror(d, "\terror sending XPT_PATH_INQ CCB: ");
|
|
|
|
+ cderror(d, cam_errbuf);
|
|
|
|
+ cderror(d, "\n");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ((d->ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
|
|
|
|
+ cderror(d, "\tXPT_PATH_INQ CCB failed: ");
|
|
|
|
+ cderror(d, cam_errbuf);
|
|
|
|
+ cderror(d, "\n");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * if the bus device name is `ata', we're (obviously)
|
|
|
|
+ * running ATAPICAM.
|
2010-12-04 17:39:15 +00:00
|
|
|
+ * same for the new ahci(4) and siis(4) drivers and future others
|
|
|
|
+ * which use SATA transport too...
|
2003-01-10 01:06:33 +00:00
|
|
|
+ */
|
|
|
|
+
|
2010-12-04 17:39:15 +00:00
|
|
|
+ if (strncmp(d->ccb->cpi.dev_name, "ata", 3) == 0 ||
|
|
|
|
+#if __FreeBSD_version >= 800102
|
|
|
|
+ d->ccb->cpi.transport == XPORT_SATA ||
|
|
|
|
+#endif
|
|
|
|
+ d->ccb->cpi.transport == XPORT_ATA) {
|
|
|
|
+ cdmessage(d, "\tDrive is ATAPI (using ATAPICAM or direct CAM (S)ATA transport)\n");
|
2003-01-10 01:06:33 +00:00
|
|
|
+ d->is_atapi = 1;
|
|
|
|
+ } else {
|
|
|
|
+ cdmessage(d, "\tDrive is SCSI\n");
|
|
|
|
+ d->is_atapi = 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return d->is_atapi;
|
|
|
|
+}
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
static int check_mmc(cdrom_drive *d){
|
|
|
|
char *b;
|
|
|
|
cdmessage(d,"\nChecking for MMC style command set...\n");
|
2011-10-29 11:28:08 +00:00
|
|
|
@@ -1379,6 +1561,7 @@
|
2003-01-10 01:06:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
+#ifdef Linux
|
|
|
|
/* request vendor brand and model */
|
|
|
|
unsigned char *scsi_inquiry(cdrom_drive *d){
|
|
|
|
memcpy(d->sg_buffer,(char[]){ 0x12,0,0,0,56,0},6);
|
2011-10-29 11:28:08 +00:00
|
|
|
@@ -1389,6 +1572,7 @@
|
2003-01-10 01:06:33 +00:00
|
|
|
}
|
|
|
|
return (d->sg_buffer);
|
|
|
|
}
|
|
|
|
+#endif
|
|
|
|
|
|
|
|
|
|
|
|
int scsi_init_drive(cdrom_drive *d){
|
2011-10-29 11:28:08 +00:00
|
|
|
@@ -1458,8 +1642,12 @@
|
2003-01-10 01:06:33 +00:00
|
|
|
check_fua_bit(d);
|
|
|
|
|
|
|
|
d->error_retry=1;
|
|
|
|
+#ifdef Linux
|
|
|
|
d->sg=realloc(d->sg,d->nsectors*CD_FRAMESIZE_RAW + SG_OFF + 128);
|
|
|
|
d->sg_buffer=d->sg+SG_OFF;
|
|
|
|
+#elif defined(__FreeBSD__)
|
|
|
|
+ d->sg_buffer = realloc(d->sg_buffer, d->nsectors * CD_FRAMESIZE_RAW);
|
|
|
|
+#endif
|
|
|
|
d->report_all=1;
|
|
|
|
return(0);
|
2013-02-01 15:04:00 +00:00
|
|
|
}
|