patch-2.4.7 linux/drivers/scsi/sr.c
Next file: linux/drivers/scsi/sr_ioctl.c
Previous file: linux/drivers/scsi/sg.c
Back to the patch index
Back to the overall index
- Lines: 186
- Date:
Thu Jul 5 11:28:17 2001
- Orig file:
v2.4.6/linux/drivers/scsi/sr.c
- Orig date:
Sat Apr 28 11:28:08 2001
diff -u --recursive --new-file v2.4.6/linux/drivers/scsi/sr.c linux/drivers/scsi/sr.c
@@ -88,6 +88,7 @@
static int *sr_sizes;
static int *sr_blocksizes;
+static int *sr_hardsizes;
static int sr_open(struct cdrom_device_info *, int);
void get_sectorsize(int);
@@ -262,7 +263,7 @@
static int sr_scatter_pad(Scsi_Cmnd *SCpnt, int s_size)
{
struct scatterlist *sg, *old_sg = NULL;
- int i, fsize, bsize, sg_ent;
+ int i, fsize, bsize, sg_ent, sg_count;
char *front, *back;
back = front = NULL;
@@ -290,17 +291,24 @@
/*
* extend or allocate new scatter-gather table
*/
- if (SCpnt->use_sg)
+ sg_count = SCpnt->use_sg;
+ if (sg_count)
old_sg = (struct scatterlist *) SCpnt->request_buffer;
else {
- SCpnt->use_sg = 1;
+ sg_count = 1;
sg_ent++;
}
- SCpnt->sglist_len = ((sg_ent * sizeof(struct scatterlist)) + 511) & ~511;
- if ((sg = scsi_malloc(SCpnt->sglist_len)) == NULL)
+ i = ((sg_ent * sizeof(struct scatterlist)) + 511) & ~511;
+ if ((sg = scsi_malloc(i)) == NULL)
goto no_mem;
+ /*
+ * no more failing memory allocs possible, we can safely assign
+ * SCpnt values now
+ */
+ SCpnt->sglist_len = i;
+ SCpnt->use_sg = sg_count;
memset(sg, 0, SCpnt->sglist_len);
i = 0;
@@ -343,12 +351,12 @@
static int sr_init_command(Scsi_Cmnd * SCpnt)
{
- int dev, devm, block, this_count, s_size;
+ int dev, devm, block=0, this_count, s_size;
devm = MINOR(SCpnt->request.rq_dev);
dev = DEVICE_NR(SCpnt->request.rq_dev);
- SCSI_LOG_HLQUEUE(1, printk("Doing sr request, dev = %d\n", devm));
+ SCSI_LOG_HLQUEUE(1, printk("Doing sr request, dev = %d, block = %d\n", devm, block));
if (dev >= sr_template.nr_dev ||
!scsi_CDs[dev].device ||
@@ -415,7 +423,8 @@
(SCpnt->request.cmd == WRITE) ? "writing" : "reading",
this_count, SCpnt->request.nr_sectors));
- SCpnt->cmnd[1] = (SCpnt->lun << 5) & 0xe0;
+ SCpnt->cmnd[1] = (SCpnt->device->scsi_level <= SCSI_2) ?
+ ((SCpnt->lun << 5) & 0xe0) : 0;
if (this_count > 0xffff)
this_count = 0xffff;
@@ -501,11 +510,7 @@
if (SDp->type != TYPE_ROM && SDp->type != TYPE_WORM)
return 0;
-
- printk("Detected scsi CD-ROM sr%d at scsi%d, channel %d, id %d, lun %d\n",
- sr_template.dev_noticed++,
- SDp->host->host_no, SDp->channel, SDp->id, SDp->lun);
-
+ sr_template.dev_noticed++;
return 1;
}
@@ -534,6 +539,9 @@
sr_template.nr_dev++;
if (sr_template.nr_dev > sr_template.dev_max)
panic("scsi_devices corrupt (sr)");
+
+ printk("Attached scsi CD-ROM sr%d at scsi%d, channel %d, id %d, lun %d\n",
+ i, SDp->host->host_no, SDp->channel, SDp->id, SDp->lun);
return 0;
}
@@ -564,7 +572,8 @@
retries = 3;
do {
cmd[0] = READ_CAPACITY;
- cmd[1] = (scsi_CDs[i].device->lun << 5) & 0xe0;
+ cmd[1] = (scsi_CDs[i].device->scsi_level <= SCSI_2) ?
+ ((scsi_CDs[i].device->lun << 5) & 0xe0) : 0;
memset((void *) &cmd[2], 0, 8);
SRpnt->sr_request.rq_status = RQ_SCSI_BUSY; /* Mark as really busy */
SRpnt->sr_cmd_len = 0;
@@ -593,7 +602,7 @@
} else {
#if 0
if (cdrom_get_last_written(MKDEV(MAJOR_NR, i),
- (long *) &scsi_CDs[i].capacity))
+ &scsi_CDs[i].capacity))
#endif
scsi_CDs[i].capacity = 1 + ((buffer[0] << 24) |
(buffer[1] << 16) |
@@ -656,8 +665,14 @@
};
buffer = (unsigned char *) scsi_malloc(512);
+ if (!buffer)
+ {
+ printk(KERN_ERR "sr: out of memory.\n");
+ return;
+ }
cmd[0] = MODE_SENSE;
- cmd[1] = (scsi_CDs[i].device->lun << 5) & 0xe0;
+ cmd[1] = (scsi_CDs[i].device->scsi_level <= SCSI_2) ?
+ ((scsi_CDs[i].device->lun << 5) & 0xe0) : 0;
cmd[2] = 0x2a;
cmd[4] = 128;
cmd[3] = cmd[5] = 0;
@@ -734,7 +749,8 @@
Scsi_Device *device = scsi_CDs[MINOR(cdi->dev)].device;
/* set the LUN */
- cgc->cmd[1] |= device->lun << 5;
+ if (device->scsi_level <= SCSI_2)
+ cgc->cmd[1] |= device->lun << 5;
cgc->stat = sr_do_ioctl(MINOR(cdi->dev), cgc->cmd, cgc->buffer, cgc->buflen, cgc->quiet, cgc->data_direction, cgc->sense);
@@ -775,16 +791,21 @@
if (!sr_blocksizes)
goto cleanup_sizes;
+ sr_hardsizes = kmalloc(sr_template.dev_max * sizeof(int), GFP_ATOMIC);
+ if (!sr_hardsizes)
+ goto cleanup_blocksizes;
/*
* These are good guesses for the time being.
- * Don't set sr_hardsizes here! That will prevent reading anything smaller.
*/
for (i = 0; i < sr_template.dev_max; i++) {
sr_blocksizes[i] = 2048;
+ sr_hardsizes[i] = 2048;
}
blksize_size[MAJOR_NR] = sr_blocksizes;
+ hardsect_size[MAJOR_NR] = sr_hardsizes;
return 0;
-
+cleanup_blocksizes:
+ kfree(sr_blocksizes);
cleanup_sizes:
kfree(sr_sizes);
cleanup_cds:
@@ -830,6 +851,10 @@
scsi_CDs[i].cdi.dev = MKDEV(MAJOR_NR, i);
scsi_CDs[i].cdi.mask = 0;
scsi_CDs[i].cdi.capacity = 1;
+ /*
+ * FIXME: someone needs to handle a get_capabilities
+ * failure properly ??
+ */
get_capabilities(i);
sr_vendor_init(i);
@@ -903,8 +928,11 @@
kfree(sr_blocksizes);
sr_blocksizes = NULL;
+ kfree(sr_hardsizes);
+ sr_hardsizes = NULL;
}
blksize_size[MAJOR_NR] = NULL;
+ hardsect_size[MAJOR_NR] = NULL;
blk_size[MAJOR_NR] = NULL;
read_ahead[MAJOR_NR] = 0;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)