aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ide-scsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/ide-scsi.c')
-rw-r--r--drivers/scsi/ide-scsi.c44
1 files changed, 35 insertions, 9 deletions
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 805cccd042b67..2e2486b035dd9 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -98,6 +98,8 @@ typedef struct idescsi_pc_s {
typedef struct ide_scsi_obj {
ide_drive_t *drive;
+ ide_driver_t *driver;
+ struct gendisk *disk;
struct Scsi_Host *host;
idescsi_pc_t *pc; /* Current packet command */
@@ -108,7 +110,8 @@ typedef struct ide_scsi_obj {
static DECLARE_MUTEX(idescsi_ref_sem);
-#define ide_scsi_g(disk) ((disk)->private_data)
+#define ide_scsi_g(disk) \
+ container_of((disk)->private_data, struct ide_scsi_obj, driver)
static struct ide_scsi_obj *ide_scsi_get(struct gendisk *disk)
{
@@ -323,9 +326,12 @@ static int idescsi_check_condition(ide_drive_t *drive, struct request *failed_co
printk ("ide-scsi: %s: queue cmd = ", drive->name);
hexdump(pc->c, 6);
}
+ rq->rq_disk = scsi->disk;
return ide_do_drive_cmd(drive, rq, ide_preempt);
}
+static int idescsi_end_request(ide_drive_t *, int, int);
+
static ide_startstop_t
idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
{
@@ -334,7 +340,9 @@ idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
HWIF(drive)->OUTB(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG);
rq->errors++;
- DRIVER(drive)->end_request(drive, 0, 0);
+
+ idescsi_end_request(drive, 0, 0);
+
return ide_stopped;
}
@@ -346,7 +354,9 @@ idescsi_atapi_abort(ide_drive_t *drive, struct request *rq)
((idescsi_pc_t *) rq->special)->scsi_cmd->serial_number);
#endif
rq->errors |= ERROR_MAX;
- DRIVER(drive)->end_request(drive, 0, 0);
+
+ idescsi_end_request(drive, 0, 0);
+
return ide_stopped;
}
@@ -718,17 +728,20 @@ static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi)
static int idescsi_cleanup (ide_drive_t *drive)
{
struct Scsi_Host *scsihost = drive->driver_data;
- struct gendisk *g = drive->disk;
+ struct ide_scsi_obj *scsi = scsihost_to_idescsi(scsihost);
+ struct gendisk *g = scsi->disk;
if (ide_unregister_subdriver(drive))
return 1;
+ ide_unregister_region(g);
+
drive->driver_data = NULL;
g->private_data = NULL;
- g->fops = ide_fops;
+ put_disk(g);
scsi_remove_host(scsihost);
- ide_scsi_put(scsihost_to_idescsi(scsihost));
+ ide_scsi_put(scsi);
return 0;
}
@@ -910,6 +923,7 @@ static int idescsi_queue (struct scsi_cmnd *cmd,
rq->special = (char *) pc;
rq->flags = REQ_SPECIAL;
spin_unlock_irq(host->host_lock);
+ rq->rq_disk = scsi->disk;
(void) ide_do_drive_cmd (drive, rq, ide_end);
spin_lock_irq(host->host_lock);
return 0;
@@ -1085,9 +1099,9 @@ static int idescsi_attach(ide_drive_t *drive)
{
idescsi_scsi_t *idescsi;
struct Scsi_Host *host;
- struct gendisk *g = drive->disk;
+ struct gendisk *g;
static int warned;
- int err;
+ int err = -ENOMEM;
if (!warned && drive->media == ide_cdrom) {
printk(KERN_WARNING "ide-scsi is deprecated for cd burning! Use ide-cd and give dev=/dev/hdX as device\n");
@@ -1100,6 +1114,12 @@ static int idescsi_attach(ide_drive_t *drive)
!(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t))))
return 1;
+ g = alloc_disk(1 << PARTN_BITS);
+ if (!g)
+ goto out_host_put;
+
+ ide_init_disk(g, drive);
+
host->max_id = 1;
#if IDESCSI_DEBUG_LOG
@@ -1114,21 +1134,27 @@ static int idescsi_attach(ide_drive_t *drive)
drive->driver_data = host;
idescsi = scsihost_to_idescsi(host);
idescsi->drive = drive;
+ idescsi->driver = &idescsi_driver;
idescsi->host = host;
+ idescsi->disk = g;
+ g->private_data = &idescsi->driver;
err = ide_register_subdriver(drive, &idescsi_driver);
if (!err) {
idescsi_setup (drive, idescsi);
g->fops = &idescsi_ops;
- g->private_data = idescsi;
+ ide_register_region(g);
err = scsi_add_host(host, &drive->gendev);
if (!err) {
scsi_scan_host(host);
return 0;
}
/* fall through on error */
+ ide_unregister_region(g);
ide_unregister_subdriver(drive);
}
+ put_disk(g);
+out_host_put:
scsi_host_put(host);
return err;
}