patch-2.4.0-test8 linux/drivers/scsi/sd.c
Next file: linux/drivers/scsi/sr.c
Previous file: linux/drivers/scsi/scsi_scan.c
Back to the patch index
Back to the overall index
- Lines: 193
- Date:
Thu Sep 7 08:56:00 2000
- Orig file:
v2.4.0-test7/linux/drivers/scsi/sd.c
- Orig date:
Mon Jul 10 16:47:24 2000
diff -u --recursive --new-file v2.4.0-test7/linux/drivers/scsi/sd.c linux/drivers/scsi/sd.c
@@ -19,6 +19,9 @@
* scsi disks using eight major numbers.
*
* Modified by Richard Gooch rgooch@atnf.csiro.au to support devfs.
+ *
+ * Modified by Torben Mathiasen tmm@image.dk
+ * Resource allocation fixes in sd_init and cleanups.
*/
#include <linux/config.h>
@@ -957,17 +960,23 @@
/* FLOPTICAL */
/*
- * for removable scsi disk ( FLOPTICAL ) we have to recognise
- * the Write Protect Flag. This flag is kept in the Scsi_Disk struct
- * and tested at open !
+ * For removable scsi disk ( FLOPTICAL ) we have to recognise
+ * the Write Protect Flag. This flag is kept in the Scsi_Disk
+ * struct and tested at open !
* Daniel Roche ( dan@lectra.fr )
+ *
+ * Changed to get all pages (0x3f) rather than page 1 to
+ * get around devices which do not have a page 1. Since
+ * we're only interested in the header anyway, this should
+ * be fine.
+ * -- Matthew Dharm (mdharm-scsi@one-eyed-alien.net)
*/
memset((void *) &cmd[0], 0, 8);
cmd[0] = MODE_SENSE;
cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0;
- cmd[2] = 1; /* page code 1 ?? */
- cmd[4] = 12;
+ cmd[2] = 0x3f; /* Get all pages */
+ cmd[4] = 8; /* But we only want the 8 byte header */
SRpnt->sr_cmd_len = 0;
SRpnt->sr_sense_buffer[0] = 0;
SRpnt->sr_sense_buffer[2] = 0;
@@ -1033,16 +1042,24 @@
if (rscsi_disks)
return 0;
- rscsi_disks = (Scsi_Disk *)
- kmalloc(sd_template.dev_max * sizeof(Scsi_Disk), GFP_ATOMIC);
+ rscsi_disks = kmalloc(sd_template.dev_max * sizeof(Scsi_Disk), GFP_ATOMIC);
+ if (!rscsi_disks)
+ goto cleanup_devfs;
memset(rscsi_disks, 0, sd_template.dev_max * sizeof(Scsi_Disk));
/* for every (necessary) major: */
- sd_sizes = (int *) kmalloc((sd_template.dev_max << 4) * sizeof(int), GFP_ATOMIC);
+ sd_sizes = kmalloc((sd_template.dev_max << 4) * sizeof(int), GFP_ATOMIC);
+ if (!sd_sizes)
+ goto cleanup_disks;
memset(sd_sizes, 0, (sd_template.dev_max << 4) * sizeof(int));
- sd_blocksizes = (int *) kmalloc((sd_template.dev_max << 4) * sizeof(int), GFP_ATOMIC);
- sd_hardsizes = (int *) kmalloc((sd_template.dev_max << 4) * sizeof(int), GFP_ATOMIC);
+ sd_blocksizes = kmalloc((sd_template.dev_max << 4) * sizeof(int), GFP_ATOMIC);
+ if (!sd_blocksizes)
+ goto cleanup_sizes;
+
+ sd_hardsizes = kmalloc((sd_template.dev_max << 4) * sizeof(int), GFP_ATOMIC);
+ if (!sd_hardsizes)
+ goto cleanup_blocksizes;
for (i = 0; i < sd_template.dev_max << 4; i++) {
sd_blocksizes[i] = 1024;
@@ -1053,22 +1070,29 @@
blksize_size[SD_MAJOR(i)] = sd_blocksizes + i * (SCSI_DISKS_PER_MAJOR << 4);
hardsect_size[SD_MAJOR(i)] = sd_hardsizes + i * (SCSI_DISKS_PER_MAJOR << 4);
}
- sd = (struct hd_struct *) kmalloc((sd_template.dev_max << 4) *
+ sd = kmalloc((sd_template.dev_max << 4) *
sizeof(struct hd_struct),
GFP_ATOMIC);
+ if (!sd)
+ goto cleanup_sd;
memset(sd, 0, (sd_template.dev_max << 4) * sizeof(struct hd_struct));
if (N_USED_SD_MAJORS > 1)
- sd_gendisks = (struct gendisk *)
- kmalloc(N_USED_SD_MAJORS * sizeof(struct gendisk), GFP_ATOMIC);
+ sd_gendisks = kmalloc(N_USED_SD_MAJORS * sizeof(struct gendisk), GFP_ATOMIC);
+ if (!sd_gendisks)
+ goto cleanup_sd_gendisks;
for (i = 0; i < N_USED_SD_MAJORS; i++) {
sd_gendisks[i] = sd_gendisk;
sd_gendisks[i].de_arr = kmalloc (SCSI_DISKS_PER_MAJOR * sizeof *sd_gendisks[i].de_arr,
GFP_ATOMIC);
+ if (!sd_gendisks[i].de_arr)
+ goto cleanup_gendisks_de_arr;
memset (sd_gendisks[i].de_arr, 0,
SCSI_DISKS_PER_MAJOR * sizeof *sd_gendisks[i].de_arr);
sd_gendisks[i].flags = kmalloc (SCSI_DISKS_PER_MAJOR * sizeof *sd_gendisks[i].flags,
GFP_ATOMIC);
+ if (!sd_gendisks[i].flags)
+ goto cleanup_gendisks_flags;
memset (sd_gendisks[i].flags, 0,
SCSI_DISKS_PER_MAJOR * sizeof *sd_gendisks[i].flags);
sd_gendisks[i].major = SD_MAJOR(i);
@@ -1085,6 +1109,31 @@
LAST_SD_GENDISK.next = NULL;
return 0;
+
+cleanup_gendisks_flags:
+ kfree(sd_gendisks[i].de_arr);
+cleanup_gendisks_de_arr:
+ while (--i >= 0 ) {
+ kfree(sd_gendisks[i].de_arr);
+ kfree(sd_gendisks[i].flags);
+ }
+ kfree(sd_gendisks);
+cleanup_sd_gendisks:
+ kfree(sd);
+cleanup_sd:
+ kfree(sd_hardsizes);
+cleanup_blocksizes:
+ kfree(sd_blocksizes);
+cleanup_sizes:
+ kfree(sd_sizes);
+cleanup_disks:
+ kfree(rscsi_disks);
+cleanup_devfs:
+ for (i = 0; i < N_USED_SD_MAJORS; i++) {
+ devfs_unregister_blkdev(SD_MAJOR(i), "sd");
+ }
+ sd_registered--;
+ return 1;
}
@@ -1286,14 +1335,12 @@
return;
}
-#ifdef MODULE
-
-int init_module(void)
+int init_sd(void)
{
- sd_template.module = &__this_module;
+ sd_template.module = THIS_MODULE;
return scsi_register_module(MODULE_SCSI_DEV, &sd_template);
}
-void cleanup_module(void)
+void exit_sd(void)
{
struct gendisk **prev_sdgd_link;
struct gendisk *sdgd;
@@ -1307,10 +1354,10 @@
sd_registered--;
if (rscsi_disks != NULL) {
- kfree((char *) rscsi_disks);
- kfree((char *) sd_sizes);
- kfree((char *) sd_blocksizes);
- kfree((char *) sd_hardsizes);
+ kfree(rscsi_disks);
+ kfree(sd_sizes);
+ kfree(sd_blocksizes);
+ kfree(sd_hardsizes);
kfree((char *) sd);
/*
@@ -1340,23 +1387,6 @@
if (sd_gendisks != &sd_gendisk)
kfree(sd_gendisks);
}
-#endif /* MODULE */
-/*
- * Overrides for Emacs so that we almost follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
+module_init(init_sd);
+module_exit(exit_sd);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)