#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/init.h>
-#include <linux/reboot.h>
-#include <linux/vmalloc.h>
#include <linux/blkdev.h>
#include <linux/blkpg.h>
#include <linux/kref.h>
#include <asm/uaccess.h>
-#include "scsi.h"
-#include "hosts.h"
-
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_dbg.h>
+#include <scsi/scsi_device.h>
#include <scsi/scsi_driver.h>
+#include <scsi/scsi_eh.h>
+#include <scsi/scsi_host.h>
#include <scsi/scsi_ioctl.h>
+#include <scsi/scsi_request.h>
#include <scsi/scsicam.h>
#include "scsi_logging.h"
goto out;
sdkp = scsi_disk(disk);
if (!kref_get(&sdkp->kref))
- sdkp = NULL;
+ goto out_sdkp;
+ if (scsi_device_get(sdkp->device))
+ goto out_put;
+ up(&sd_ref_sem);
+ return sdkp;
+
+ out_put:
+ kref_put(&sdkp->kref);
+ out_sdkp:
+ sdkp = NULL;
out:
up(&sd_ref_sem);
return sdkp;
static void scsi_disk_put(struct scsi_disk *sdkp)
{
down(&sd_ref_sem);
+ scsi_device_put(sdkp->device);
kref_put(&sdkp->kref);
up(&sd_ref_sem);
}
sector_t block;
struct scsi_device *sdp = SCpnt->device;
- timeout = SD_TIMEOUT;
- if (SCpnt->device->type != TYPE_DISK)
- timeout = SD_MOD_TIMEOUT;
+ timeout = sdp->timeout;
/*
* these are already setup, just copy cdb basically
return 0;
}
-static int sd_hdio_getgeo(struct block_device *bdev, struct hd_geometry *loc)
+static int sd_hdio_getgeo(struct block_device *bdev, struct hd_geometry __user *loc)
{
struct scsi_disk *sdkp = scsi_disk(bdev->bd_disk);
struct scsi_device *sdp = sdkp->device;
if (put_user(diskinfo[2], &loc->cylinders))
return -EFAULT;
if (put_user((unsigned)get_start_sect(bdev),
- (unsigned long *)&loc->start))
+ (unsigned long __user *)&loc->start))
return -EFAULT;
return 0;
}
struct block_device *bdev = inode->i_bdev;
struct gendisk *disk = bdev->bd_disk;
struct scsi_device *sdp = scsi_disk(disk)->device;
+ void __user *p = (void __user *)arg;
int error;
SCSI_LOG_IOCTL(1, printk("sd_ioctl: disk=%s, cmd=0x%x\n",
if (cmd == HDIO_GETGEO) {
if (!arg)
return -EINVAL;
- return sd_hdio_getgeo(bdev, (struct hd_geometry *)arg);
+ return sd_hdio_getgeo(bdev, p);
}
/*
switch (cmd) {
case SCSI_IOCTL_GET_IDLUN:
case SCSI_IOCTL_GET_BUS_NUMBER:
- return scsi_ioctl(sdp, cmd, (void *)arg);
+ return scsi_ioctl(sdp, cmd, p);
default:
- error = scsi_cmd_ioctl(disk, cmd, arg);
+ error = scsi_cmd_ioctl(filp, disk, cmd, p);
if (error != -ENOTTY)
return error;
}
- return scsi_ioctl(sdp, cmd, (void *)arg);
+ return scsi_ioctl(sdp, cmd, p);
}
static void set_media_not_present(struct scsi_disk *sdkp)
good_bytes = 0;
break;
- case RECOVERED_ERROR:
+ case RECOVERED_ERROR: /* an error occurred, but it recovered */
+ case NO_SENSE: /* LLDD got sense data */
/*
- * An error occurred, but it recovered. Inform the
- * user, but make sure that it's not treated as a
- * hard error.
+ * Inform the user, but make sure that it's not treated
+ * as a hard error.
*/
- print_sense("sd", SCpnt);
+ scsi_print_sense("sd", SCpnt);
SCpnt->result = 0;
SCpnt->sense_buffer[0] = 0x0;
good_bytes = this_count;
* probably pointless to loop */
if(!spintime) {
printk(KERN_NOTICE "%s: Unit Not Ready, sense:\n", diskname);
- print_req_sense("", SRpnt);
+ scsi_print_req_sense("", SRpnt);
}
break;
}
driver_byte(the_result));
if (driver_byte(the_result) & DRIVER_SENSE)
- print_req_sense("sd", SRpnt);
+ scsi_print_req_sense("sd", SRpnt);
else
printk("%s : sense not available. \n", diskname);
if ((sdp->type != TYPE_DISK) && (sdp->type != TYPE_MOD))
goto out;
- if ((error = scsi_device_get(sdp)) != 0)
- goto out;
-
SCSI_LOG_HLQUEUE(3, printk("sd_attach: scsi device: <%d,%d,%d,%d>\n",
sdp->host->host_no, sdp->channel, sdp->id, sdp->lun));
error = -ENOMEM;
sdkp = kmalloc(sizeof(*sdkp), GFP_KERNEL);
if (!sdkp)
- goto out_put_sdev;
+ goto out;
memset (sdkp, 0, sizeof(*sdkp));
kref_init(&sdkp->kref, scsi_disk_release);
sdkp->index = index;
sdkp->openers = 0;
+ if (!sdp->timeout) {
+ if (sdp->type == TYPE_DISK)
+ sdp->timeout = SD_TIMEOUT;
+ else
+ sdp->timeout = SD_MOD_TIMEOUT;
+ }
+
devno = make_sd_dev(index, 0);
gd->major = MAJOR(devno);
gd->first_minor = MINOR(devno);
put_disk(gd);
out_free:
kfree(sdkp);
-out_put_sdev:
- scsi_device_put(sdp);
out:
return error;
}
del_gendisk(sdkp->disk);
sd_shutdown(dev);
- scsi_disk_put(sdkp);
+ down(&sd_ref_sem);
+ kref_put(&sdkp->kref);
+ up(&sd_ref_sem);
return 0;
}
static void scsi_disk_release(struct kref *kref)
{
struct scsi_disk *sdkp = to_scsi_disk(kref);
- struct scsi_device *sdev = sdkp->device;
struct gendisk *disk = sdkp->disk;
spin_lock(&sd_index_lock);
put_disk(disk);
kfree(sdkp);
-
- scsi_device_put(sdev);
}
/*
status_byte(res), msg_byte(res),
host_byte(res), driver_byte(res));
if (driver_byte(res) & DRIVER_SENSE)
- print_req_sense("sd", sreq);
+ scsi_print_req_sense("sd", sreq);
}
scsi_release_request(sreq);