aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/ide-scsi.c120
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 */
137static 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
178static void ide_scsi_hex_dump(u8 *data, int len) 133static 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
350static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive) 305static 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
433static void idescsi_add_settings(ide_drive_t *drive) 388#define ide_scsi_devset_get(name, field) \
434{ 389static 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); 396static 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}
447static inline void idescsi_add_settings(ide_drive_t *drive) { ; } 402
403#define ide_scsi_devset_rw_field(_name, _field) \
404ide_scsi_devset_get(_name, _field); \
405ide_scsi_devset_set(_name, _field); \
406IDE_DEVSET(_name, DS_SYNC, get_##_name, set_##_name);
407
408ide_devset_rw_field(bios_cyl, bios_cyl);
409ide_devset_rw_field(bios_head, bios_head);
410ide_devset_rw_field(bios_sect, bios_sect);
411
412ide_scsi_devset_rw_field(transform, transform);
413ide_scsi_devset_rw_field(log, log);
414
415static 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 */
453static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi) 428static 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
467static void ide_scsi_remove(ide_drive_t *drive) 442static 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;