diff options
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/ide-scsi.c | 120 |
1 files changed, 47 insertions, 73 deletions
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 81c16cba5417..90212ac33be3 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c | |||
@@ -40,7 +40,6 @@ | |||
40 | #include <linux/ioport.h> | 40 | #include <linux/ioport.h> |
41 | #include <linux/blkdev.h> | 41 | #include <linux/blkdev.h> |
42 | #include <linux/errno.h> | 42 | #include <linux/errno.h> |
43 | #include <linux/hdreg.h> | ||
44 | #include <linux/slab.h> | 43 | #include <linux/slab.h> |
45 | #include <linux/ide.h> | 44 | #include <linux/ide.h> |
46 | #include <linux/scatterlist.h> | 45 | #include <linux/scatterlist.h> |
@@ -131,50 +130,6 @@ static inline idescsi_scsi_t *drive_to_idescsi(ide_drive_t *ide_drive) | |||
131 | return scsihost_to_idescsi(ide_drive->driver_data); | 130 | return scsihost_to_idescsi(ide_drive->driver_data); |
132 | } | 131 | } |
133 | 132 | ||
134 | /* | ||
135 | * PIO data transfer routine using the scatter gather table. | ||
136 | */ | ||
137 | static void ide_scsi_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, | ||
138 | unsigned int bcount, int write) | ||
139 | { | ||
140 | ide_hwif_t *hwif = drive->hwif; | ||
141 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; | ||
142 | xfer_func_t *xf = write ? tp_ops->output_data : tp_ops->input_data; | ||
143 | char *buf; | ||
144 | int count; | ||
145 | |||
146 | while (bcount) { | ||
147 | count = min(pc->sg->length - pc->b_count, bcount); | ||
148 | if (PageHighMem(sg_page(pc->sg))) { | ||
149 | unsigned long flags; | ||
150 | |||
151 | local_irq_save(flags); | ||
152 | buf = kmap_atomic(sg_page(pc->sg), KM_IRQ0) + | ||
153 | pc->sg->offset; | ||
154 | xf(drive, NULL, buf + pc->b_count, count); | ||
155 | kunmap_atomic(buf - pc->sg->offset, KM_IRQ0); | ||
156 | local_irq_restore(flags); | ||
157 | } else { | ||
158 | buf = sg_virt(pc->sg); | ||
159 | xf(drive, NULL, buf + pc->b_count, count); | ||
160 | } | ||
161 | bcount -= count; pc->b_count += count; | ||
162 | if (pc->b_count == pc->sg->length) { | ||
163 | if (!--pc->sg_cnt) | ||
164 | break; | ||
165 | pc->sg = sg_next(pc->sg); | ||
166 | pc->b_count = 0; | ||
167 | } | ||
168 | } | ||
169 | |||
170 | if (bcount) { | ||
171 | printk(KERN_ERR "%s: scatter gather table too small, %s\n", | ||
172 | drive->name, write ? "padding with zeros" | ||
173 | : "discarding data"); | ||
174 | ide_pad_transfer(drive, write, bcount); | ||
175 | } | ||
176 | } | ||
177 | |||
178 | static void ide_scsi_hex_dump(u8 *data, int len) | 133 | static void ide_scsi_hex_dump(u8 *data, int len) |
179 | { | 134 | { |
180 | print_hex_dump(KERN_CONT, "", DUMP_PREFIX_NONE, 16, 1, data, len, 0); | 135 | print_hex_dump(KERN_CONT, "", DUMP_PREFIX_NONE, 16, 1, data, len, 0); |
@@ -244,9 +199,9 @@ idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err) | |||
244 | { | 199 | { |
245 | ide_hwif_t *hwif = drive->hwif; | 200 | ide_hwif_t *hwif = drive->hwif; |
246 | 201 | ||
247 | if (hwif->tp_ops->read_status(hwif) & (BUSY_STAT | DRQ_STAT)) | 202 | if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ)) |
248 | /* force an abort */ | 203 | /* force an abort */ |
249 | hwif->tp_ops->exec_command(hwif, WIN_IDLEIMMEDIATE); | 204 | hwif->tp_ops->exec_command(hwif, ATA_CMD_IDLEIMMEDIATE); |
250 | 205 | ||
251 | rq->errors++; | 206 | rq->errors++; |
252 | 207 | ||
@@ -344,7 +299,7 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) | |||
344 | 299 | ||
345 | return ide_pc_intr(drive, pc, idescsi_pc_intr, get_timeout(pc), | 300 | return ide_pc_intr(drive, pc, idescsi_pc_intr, get_timeout(pc), |
346 | idescsi_expiry, NULL, NULL, NULL, | 301 | idescsi_expiry, NULL, NULL, NULL, |
347 | ide_scsi_io_buffers); | 302 | ide_io_buffers); |
348 | } | 303 | } |
349 | 304 | ||
350 | static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive) | 305 | static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive) |
@@ -430,21 +385,41 @@ static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *r | |||
430 | } | 385 | } |
431 | 386 | ||
432 | #ifdef CONFIG_IDE_PROC_FS | 387 | #ifdef CONFIG_IDE_PROC_FS |
433 | static void idescsi_add_settings(ide_drive_t *drive) | 388 | #define ide_scsi_devset_get(name, field) \ |
434 | { | 389 | static int get_##name(ide_drive_t *drive) \ |
435 | idescsi_scsi_t *scsi = drive_to_idescsi(drive); | 390 | { \ |
436 | 391 | idescsi_scsi_t *scsi = drive_to_idescsi(drive); \ | |
437 | /* | 392 | return scsi->field; \ |
438 | * drive setting name read/write data type min max mul_factor div_factor data pointer set function | 393 | } |
439 | */ | 394 | |
440 | ide_add_setting(drive, "bios_cyl", SETTING_RW, TYPE_INT, 0, 1023, 1, 1, &drive->bios_cyl, NULL); | 395 | #define ide_scsi_devset_set(name, field) \ |
441 | ide_add_setting(drive, "bios_head", SETTING_RW, TYPE_BYTE, 0, 255, 1, 1, &drive->bios_head, NULL); | 396 | static int set_##name(ide_drive_t *drive, int arg) \ |
442 | ide_add_setting(drive, "bios_sect", SETTING_RW, TYPE_BYTE, 0, 63, 1, 1, &drive->bios_sect, NULL); | 397 | { \ |
443 | ide_add_setting(drive, "transform", SETTING_RW, TYPE_INT, 0, 3, 1, 1, &scsi->transform, NULL); | 398 | idescsi_scsi_t *scsi = drive_to_idescsi(drive); \ |
444 | ide_add_setting(drive, "log", SETTING_RW, TYPE_INT, 0, 1, 1, 1, &scsi->log, NULL); | 399 | scsi->field = arg; \ |
445 | } | 400 | return 0; \ |
446 | #else | 401 | } |
447 | static inline void idescsi_add_settings(ide_drive_t *drive) { ; } | 402 | |
403 | #define ide_scsi_devset_rw_field(_name, _field) \ | ||
404 | ide_scsi_devset_get(_name, _field); \ | ||
405 | ide_scsi_devset_set(_name, _field); \ | ||
406 | IDE_DEVSET(_name, DS_SYNC, get_##_name, set_##_name); | ||
407 | |||
408 | ide_devset_rw_field(bios_cyl, bios_cyl); | ||
409 | ide_devset_rw_field(bios_head, bios_head); | ||
410 | ide_devset_rw_field(bios_sect, bios_sect); | ||
411 | |||
412 | ide_scsi_devset_rw_field(transform, transform); | ||
413 | ide_scsi_devset_rw_field(log, log); | ||
414 | |||
415 | static const struct ide_proc_devset idescsi_settings[] = { | ||
416 | IDE_PROC_DEVSET(bios_cyl, 0, 1023), | ||
417 | IDE_PROC_DEVSET(bios_head, 0, 255), | ||
418 | IDE_PROC_DEVSET(bios_sect, 0, 63), | ||
419 | IDE_PROC_DEVSET(log, 0, 1), | ||
420 | IDE_PROC_DEVSET(transform, 0, 3), | ||
421 | { 0 }, | ||
422 | }; | ||
448 | #endif | 423 | #endif |
449 | 424 | ||
450 | /* | 425 | /* |
@@ -452,7 +427,7 @@ static inline void idescsi_add_settings(ide_drive_t *drive) { ; } | |||
452 | */ | 427 | */ |
453 | static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi) | 428 | static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi) |
454 | { | 429 | { |
455 | if (drive->id && (drive->id->config & 0x0060) == 0x20) | 430 | if ((drive->id[ATA_ID_CONFIG] & 0x0060) == 0x20) |
456 | set_bit(IDE_AFLAG_DRQ_INTERRUPT, &drive->atapi_flags); | 431 | set_bit(IDE_AFLAG_DRQ_INTERRUPT, &drive->atapi_flags); |
457 | clear_bit(IDESCSI_SG_TRANSFORM, &scsi->transform); | 432 | clear_bit(IDESCSI_SG_TRANSFORM, &scsi->transform); |
458 | #if IDESCSI_DEBUG_LOG | 433 | #if IDESCSI_DEBUG_LOG |
@@ -461,7 +436,7 @@ static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi) | |||
461 | 436 | ||
462 | drive->pc_callback = ide_scsi_callback; | 437 | drive->pc_callback = ide_scsi_callback; |
463 | 438 | ||
464 | idescsi_add_settings(drive); | 439 | ide_proc_register_driver(drive, scsi->driver); |
465 | } | 440 | } |
466 | 441 | ||
467 | static void ide_scsi_remove(ide_drive_t *drive) | 442 | static void ide_scsi_remove(ide_drive_t *drive) |
@@ -503,12 +478,12 @@ static ide_driver_t idescsi_driver = { | |||
503 | .remove = ide_scsi_remove, | 478 | .remove = ide_scsi_remove, |
504 | .version = IDESCSI_VERSION, | 479 | .version = IDESCSI_VERSION, |
505 | .media = ide_scsi, | 480 | .media = ide_scsi, |
506 | .supports_dsc_overlap = 0, | ||
507 | .do_request = idescsi_do_request, | 481 | .do_request = idescsi_do_request, |
508 | .end_request = idescsi_end_request, | 482 | .end_request = idescsi_end_request, |
509 | .error = idescsi_atapi_error, | 483 | .error = idescsi_atapi_error, |
510 | #ifdef CONFIG_IDE_PROC_FS | 484 | #ifdef CONFIG_IDE_PROC_FS |
511 | .proc = idescsi_proc, | 485 | .proc = idescsi_proc, |
486 | .settings = idescsi_settings, | ||
512 | #endif | 487 | #endif |
513 | }; | 488 | }; |
514 | 489 | ||
@@ -811,6 +786,7 @@ static int ide_scsi_probe(ide_drive_t *drive) | |||
811 | struct gendisk *g; | 786 | struct gendisk *g; |
812 | static int warned; | 787 | static int warned; |
813 | int err = -ENOMEM; | 788 | int err = -ENOMEM; |
789 | u16 last_lun; | ||
814 | 790 | ||
815 | if (!warned && drive->media == ide_cdrom) { | 791 | if (!warned && drive->media == ide_cdrom) { |
816 | printk(KERN_WARNING "ide-scsi is deprecated for cd burning! Use ide-cd and give dev=/dev/hdX as device\n"); | 792 | printk(KERN_WARNING "ide-scsi is deprecated for cd burning! Use ide-cd and give dev=/dev/hdX as device\n"); |
@@ -821,7 +797,6 @@ static int ide_scsi_probe(ide_drive_t *drive) | |||
821 | return -ENODEV; | 797 | return -ENODEV; |
822 | 798 | ||
823 | if (!strstr("ide-scsi", drive->driver_req) || | 799 | if (!strstr("ide-scsi", drive->driver_req) || |
824 | !drive->present || | ||
825 | drive->media == ide_disk || | 800 | drive->media == ide_disk || |
826 | !(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t)))) | 801 | !(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t)))) |
827 | return -ENODEV; | 802 | return -ENODEV; |
@@ -836,12 +811,12 @@ static int ide_scsi_probe(ide_drive_t *drive) | |||
836 | 811 | ||
837 | host->max_id = 1; | 812 | host->max_id = 1; |
838 | 813 | ||
839 | if (drive->id->last_lun) | 814 | last_lun = drive->id[ATA_ID_LAST_LUN]; |
840 | debug_log("%s: id->last_lun=%u\n", drive->name, | 815 | if (last_lun) |
841 | drive->id->last_lun); | 816 | debug_log("%s: last_lun=%u\n", drive->name, last_lun); |
842 | 817 | ||
843 | if ((drive->id->last_lun & 0x7) != 7) | 818 | if ((last_lun & 7) != 7) |
844 | host->max_lun = (drive->id->last_lun & 0x7) + 1; | 819 | host->max_lun = (last_lun & 7) + 1; |
845 | else | 820 | else |
846 | host->max_lun = 1; | 821 | host->max_lun = 1; |
847 | 822 | ||
@@ -852,7 +827,6 @@ static int ide_scsi_probe(ide_drive_t *drive) | |||
852 | idescsi->host = host; | 827 | idescsi->host = host; |
853 | idescsi->disk = g; | 828 | idescsi->disk = g; |
854 | g->private_data = &idescsi->driver; | 829 | g->private_data = &idescsi->driver; |
855 | ide_proc_register_driver(drive, &idescsi_driver); | ||
856 | err = 0; | 830 | err = 0; |
857 | idescsi_setup(drive, idescsi); | 831 | idescsi_setup(drive, idescsi); |
858 | g->fops = &idescsi_ops; | 832 | g->fops = &idescsi_ops; |