#include <asm/uaccess.h>
#include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
#include <scsi/scsi_driver.h>
#include <scsi/scsi_ioctl.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(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)
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);
}
/*