* [PATCH] ide-scsi changes for new mid level api and error handling in 2.5.52
@ 2002-12-21 22:46 Willem Riede
2002-12-22 1:59 ` Douglas Gilbert
0 siblings, 1 reply; 5+ messages in thread
From: Willem Riede @ 2002-12-21 22:46 UTC (permalink / raw
To: linux-scsi
[-- Attachment #1: Type: text/plain, Size: 652 bytes --]
Here is my proposal for bringing ide-scsi in line with the current kernel.
The attached patch does:
1. Change from old style initialization to the new hotplug initialization model.
It involves declaring both a parent device and bus kernel object, which feels
a bit awkward, but hey, it works.
2. Make ide-scsi request sense itself when CHECK_CONDITION is asserted. This
change particularly makes ide-scsi run much smoother on my test box.
3. Implement eh_abort_handler and eh_device_reset_handler. I have no real way
to thoroughly test these new routines, so for this part particularly I ask
for peer review.
Thanks, Willem Riede.
[-- Attachment #2: ide-scsi.patch --]
[-- Type: text/plain, Size: 9598 bytes --]
--- drivers/scsi/ide-scsi.c Mon Dec 9 21:46:12 2002
+++ /home/wriede/develop/ide-scsi.c Sat Dec 21 17:32:48 2002
@@ -28,9 +28,10 @@
* Ver 0.8 Feb 05 99 Optical media need translation too. Reverse 0.7.
* Ver 0.9 Jul 04 99 Fix a bug in SG_SET_TRANSFORM.
* Ver 0.91 Jun 10 02 Fix "off by one" error in transforms
+ * Ver 0.92 Dec 31 02 Implement new SCSI mid level API
*/
-#define IDESCSI_VERSION "0.9"
+#define IDESCSI_VERSION "0.92"
#include <linux/module.h>
#include <linux/config.h>
@@ -259,6 +260,42 @@
printk("]\n");
}
+static int idescsi_check_condition(ide_drive_t *drive, struct request *failed_command)
+{
+ idescsi_scsi_t *scsi = drive->driver_data;
+ idescsi_pc_t *pc;
+ struct request *rq;
+ u8 *buf;
+
+ /* stuff a sense request in front of our current request */
+ pc = kmalloc (sizeof (idescsi_pc_t), GFP_ATOMIC);
+ rq = kmalloc (sizeof (struct request), GFP_ATOMIC);
+ buf = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_ATOMIC);
+ if (pc == NULL || rq == NULL || buf == NULL) {
+ if (pc) kfree(pc);
+ if (rq) kfree(rq);
+ if (buf) kfree(buf);
+ return -ENOMEM;
+ }
+ memset (pc, 0, sizeof (idescsi_pc_t));
+ memset (buf, 0, SCSI_SENSE_BUFFERSIZE);
+ ide_init_drive_cmd(rq);
+ rq->special = (char *) pc;
+ pc->rq = rq;
+ pc->buffer = buf;
+ pc->c[0] = REQUEST_SENSE;
+ pc->c[4] = pc->request_transfer = pc->buffer_size = SCSI_SENSE_BUFFERSIZE;
+ rq->flags = REQ_SENSE;
+ pc->timeout = jiffies + WAIT_READY;
+ /* NOTE! Save the failed packet command in "rq->buffer" */
+ rq->buffer = (void *) failed_command->special;
+ if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) {
+ printk ("ide-scsi: %s: queue cmd = ", drive->name);
+ hexdump(pc->c, 6);
+ }
+ return ide_do_drive_cmd(drive, rq, ide_preempt);
+}
+
static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs)
{
idescsi_scsi_t *scsi = drive->driver_data;
@@ -269,19 +306,35 @@
u8 *scsi_buf;
unsigned long flags;
- if (!(rq->flags & REQ_SPECIAL)) {
+ if (!(rq->flags & (REQ_SPECIAL|REQ_SENSE))) {
ide_end_request(drive, uptodate, nrsecs);
return 0;
}
ide_end_drive_cmd (drive, 0, 0);
- if (rq->errors >= ERROR_MAX) {
+ if (rq->flags & REQ_SENSE) {
+ idescsi_pc_t *opc = (idescsi_pc_t *) rq->buffer;
+ if (log) {
+ printk ("ide-scsi: %s: wrap up check %lu, rst = ", drive->name, opc->scsi_cmd->serial_number);
+ hexdump(pc->buffer,16);
+ }
+ memcpy((void *) opc->scsi_cmd->sense_buffer, pc->buffer, SCSI_SENSE_BUFFERSIZE);
+ kfree(pc->buffer);
+ kfree(pc);
+ kfree(rq);
+ pc = opc;
+ rq = pc->rq;
+ pc->scsi_cmd->result = (CHECK_CONDITION << 1) | (DID_OK << 16);
+ } else if (rq->errors >= ERROR_MAX) {
pc->scsi_cmd->result = DID_ERROR << 16;
if (log)
printk ("ide-scsi: %s: I/O error for %lu\n", drive->name, pc->scsi_cmd->serial_number);
} else if (rq->errors) {
- pc->scsi_cmd->result = (CHECK_CONDITION << 1) | (DID_OK << 16);
if (log)
printk ("ide-scsi: %s: check condition for %lu\n", drive->name, pc->scsi_cmd->serial_number);
+ if (!idescsi_check_condition(drive, rq))
+ /* we started a request sense, so we'll be back, exit for now */
+ return 0;
+ pc->scsi_cmd->result = (CHECK_CONDITION << 1) | (DID_OK << 16);
} else {
pc->scsi_cmd->result = DID_OK << 16;
idescsi_transform_pc2 (drive, pc);
@@ -489,11 +542,11 @@
static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *rq, sector_t block)
{
#if IDESCSI_DEBUG_LOG
- printk (KERN_INFO "rq_status: %d, dev: %s, cmd: %d, errors: %d\n",rq->rq_status, rq->rq_disk->disk_name,rq->cmd,rq->errors);
- printk (KERN_INFO "sector: %ld, nr_sectors: %ld, current_nr_sectors: %ld\n",rq->sector,rq->nr_sectors,rq->current_nr_sectors);
+ printk (KERN_INFO "rq_status: %d, dev: %s, cmd: %x, errors: %d\n",rq->rq_status, rq->rq_disk->disk_name,rq->cmd[0],rq->errors);
+ printk (KERN_INFO "sector: %ld, nr_sectors: %ld, current_nr_sectors: %d\n",rq->sector,rq->nr_sectors,rq->current_nr_sectors);
#endif /* IDESCSI_DEBUG_LOG */
- if (rq->flags & REQ_SPECIAL) {
+ if (rq->flags & (REQ_SPECIAL|REQ_SENSE)) {
return idescsi_issue_pc (drive, (idescsi_pc_t *) rq->special);
}
blk_dump_rq_flags(rq, "ide-scsi: unsup command");
@@ -629,35 +682,10 @@
return 1;
}
-int idescsi_detect (Scsi_Host_Template *host_template)
+int idescsi_slave_configure(Scsi_Device * sdp)
{
- struct Scsi_Host *host;
- int id;
- int last_lun = 0;
-
- host_template->proc_name = "ide-scsi";
- host = scsi_register(host_template, 0);
- if(host == NULL)
- return 0;
-
- for (id = 0; id < MAX_HWIFS * MAX_DRIVES && idescsi_drives[id]; id++)
- last_lun = IDE_MAX(last_lun, idescsi_drives[id]->last_lun);
- host->max_id = id;
- host->max_lun = last_lun + 1;
- host->can_queue = host->cmd_per_lun * id;
- return 1;
-}
-
-int idescsi_release (struct Scsi_Host *host)
-{
- ide_drive_t *drive;
- int id;
-
- for (id = 0; id < MAX_HWIFS * MAX_DRIVES; id++) {
- drive = idescsi_drives[id];
- if (drive)
- DRIVER(drive)->busy--;
- }
+ /* Configure detected device */
+ scsi_adjust_queue_depth(sdp, MSG_SIMPLE_TAG, sdp->host->cmd_per_lun);
return 0;
}
@@ -832,17 +860,67 @@
if (rq) kfree (rq);
cmd->result = DID_ERROR << 16;
done(cmd);
- return 0;
+ return 1;
}
int idescsi_abort (Scsi_Cmnd *cmd)
{
- return SCSI_ABORT_SNOOZE;
+ int countdown = 8;
+ unsigned long flags;
+ ide_drive_t *drive = idescsi_drives[cmd->target];
+ idescsi_scsi_t *scsi;
+
+ printk (KERN_ERR "ide-scsi: abort called for %lu\n", cmd->serial_number);
+ if (drive && (scsi = drive->driver_data))
+ while (countdown--) {
+ /* is cmd active?
+ * need to lock so this stuff doesn't change under us */
+ spin_lock_irqsave(&ide_lock, flags);
+ if (scsi->pc && scsi->pc->scsi_cmd->serial_number == cmd->serial_number) {
+ /* yep - let's give it some more time -
+ * we can do that, we're in _our_ error kernel thread */
+ spin_unlock_irqrestore(&ide_lock, flags);
+ scsi_sleep(HZ);
+ continue;
+ }
+ /* no, but is it queued in the ide subsystem? */
+ if (elv_queue_empty(&drive->queue)) {
+ spin_unlock_irqrestore(&ide_lock, flags);
+ return SUCCESS;
+ }
+ spin_unlock_irqrestore(&ide_lock, flags);
+ schedule_timeout(HZ/10);
+ }
+ return FAILED;
}
-int idescsi_reset (Scsi_Cmnd *cmd, unsigned int resetflags)
+int idescsi_reset (Scsi_Cmnd *cmd)
{
- return SCSI_RESET_SUCCESS;
+ unsigned long flags;
+ struct request *req;
+ ide_drive_t *drive = idescsi_drives[cmd->target];
+
+ printk (KERN_ERR "ide-scsi: reset called for %lu\n", cmd->serial_number);
+ /* first null the handler for the drive and let any process
+ * doing IO (on another CPU) run to (partial) completion
+ * the lock prevents processing new requests */
+ spin_lock_irqsave(&ide_lock, flags);
+ while (HWGROUP(drive)->handler) {
+ HWGROUP(drive)->handler = NULL;
+ schedule_timeout(1);
+ }
+ /* now nuke the drive queue */
+ while ((req = elv_next_request(&drive->queue))) {
+ blkdev_dequeue_request(req);
+ end_that_request_last(req);
+ }
+ /* FIXME - this will probably leak memory */
+ HWGROUP(drive)->rq = NULL;
+ if (drive->driver_data) ((idescsi_scsi_t *)drive->driver_data)->pc = NULL;
+ spin_unlock_irqrestore(&ide_lock, flags);
+ /* finally, reset the drive (and its partner on the bus...) */
+ ide_do_reset (drive);
+ return SUCCESS;
}
static int idescsi_bios(struct scsi_device *sdev, struct block_device *bdev,
@@ -859,32 +937,69 @@
}
static Scsi_Host_Template idescsi_template = {
- .module = THIS_MODULE,
- .name = "idescsi",
- .detect = idescsi_detect,
- .release = idescsi_release,
- .info = idescsi_info,
- .ioctl = idescsi_ioctl,
- .queuecommand = idescsi_queue,
- .bios_param = idescsi_bios,
- .can_queue = 10,
- .this_id = -1,
- .sg_tablesize = 256,
- .cmd_per_lun = 5,
- .use_clustering = DISABLE_CLUSTERING,
- .emulated = 1,
+ .module = THIS_MODULE,
+ .name = "idescsi",
+ .info = idescsi_info,
+ .slave_configure = idescsi_slave_configure,
+ .ioctl = idescsi_ioctl,
+ .queuecommand = idescsi_queue,
+ .eh_abort_handler = idescsi_abort,
+ .eh_device_reset_handler = idescsi_reset,
+ .bios_param = idescsi_bios,
+ .can_queue = 40,
+ .this_id = -1,
+ .sg_tablesize = 256,
+ .cmd_per_lun = 5,
+ .max_sectors = 128,
+ .use_clustering = DISABLE_CLUSTERING,
+ .emulated = 1,
+};
+
+static struct Scsi_Host *idescsi_host;
+
+static struct device idescsi_primary = {
+ .name = "Ide-scsi Parent",
+ .bus_id = "ide-scsi",
+};
+static struct bus_type idescsi_emu_bus = {
+ .name = "ide-scsi",
};
static int __init init_idescsi_module(void)
{
+ int id;
+ int last_lun = 0;
+
ide_register_driver(&idescsi_driver);
- scsi_register_host(&idescsi_template);
+ device_register(&idescsi_primary);
+ bus_register (&idescsi_emu_bus);
+ idescsi_template.proc_name = "ide-scsi";
+ idescsi_host = scsi_register(&idescsi_template, 0);
+ if(idescsi_host == NULL)
+ return 1;
+
+ for (id = 0; id < MAX_HWIFS * MAX_DRIVES && idescsi_drives[id]; id++)
+ last_lun = IDE_MAX(last_lun, idescsi_drives[id]->last_lun);
+ idescsi_host->max_id = id;
+ idescsi_host->max_lun = last_lun + 1;
+ scsi_add_host(idescsi_host, &idescsi_primary);
return 0;
}
static void __exit exit_idescsi_module(void)
{
- scsi_unregister_host(&idescsi_template);
+ ide_drive_t *drive;
+ int id;
+
+ scsi_remove_host(idescsi_host);
+ for (id = 0; id < MAX_HWIFS * MAX_DRIVES; id++) {
+ drive = idescsi_drives[id];
+ if (drive)
+ DRIVER(drive)->busy--;
+ }
+ scsi_unregister (idescsi_host);
+ device_unregister(&idescsi_primary);
+ bus_unregister (&idescsi_emu_bus);
ide_unregister_driver(&idescsi_driver);
}
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] ide-scsi changes for new mid level api and error handling in 2.5.52
2002-12-21 22:46 [PATCH] ide-scsi changes for new mid level api and error handling in 2.5.52 Willem Riede
@ 2002-12-22 1:59 ` Douglas Gilbert
2002-12-22 17:14 ` Willem Riede
0 siblings, 1 reply; 5+ messages in thread
From: Douglas Gilbert @ 2002-12-22 1:59 UTC (permalink / raw
To: wrlk; +Cc: linux-scsi, andmike
Willem Riede wrote:
> Here is my proposal for bringing ide-scsi in line with the current kernel.
>
> The attached patch does:
>
> 1. Change from old style initialization to the new hotplug initialization model.
> It involves declaring both a parent device and bus kernel object, which feels
> a bit awkward, but hey, it works.
>
> 2. Make ide-scsi request sense itself when CHECK_CONDITION is asserted. This
> change particularly makes ide-scsi run much smoother on my test box.
>
> 3. Implement eh_abort_handler and eh_device_reset_handler. I have no real way
> to thoroughly test these new routines, so for this part particularly I ask
> for peer review.
Willem,
Good work.
I tried it out with an ATAPI cdrom and it worked fine.
Tried a few error conditions (e.g. purposely reading
past the end of the cdrom) and it reacted properly.
The introduction of a new sysfs bus type: "ide-scsi" to
add to scsi_debug's "pseudo" seems a bit messy. It will
do for now; hopefully Mike Anderson will come up with
some coherent sysfs naming scheme for drivers
that bridge to another protocol stack (e.g. ide-scsi,
usb-storage and ieee1394/sbp2).
BTW Willem's patch is against lk 2.5.52 .
Doug Gilbert
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] ide-scsi changes for new mid level api and error handling in 2.5.52
2002-12-22 1:59 ` Douglas Gilbert
@ 2002-12-22 17:14 ` Willem Riede
2002-12-23 19:05 ` Andre Hedrick
0 siblings, 1 reply; 5+ messages in thread
From: Willem Riede @ 2002-12-22 17:14 UTC (permalink / raw
To: linux-scsi
On 2002.12.21 20:59 Douglas Gilbert wrote:
> Willem Riede wrote:
> > Here is my proposal for bringing ide-scsi in line with the current kernel.
> >
> > The attached patch does:
> >
>
> Willem,
> Good work.
>
Thanks.
>
> BTW Willem's patch is against lk 2.5.52 .
>
Right. And next to this ide-scsi patch, you will also want
the one line fix to ide.c I posted earlier.
http://marc.theaimsgroup.com/?l=linux-scsi&m=104017636631422&w=2
Regards, Willem Riede.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] ide-scsi changes for new mid level api and error handling in 2.5.52
2002-12-22 17:14 ` Willem Riede
@ 2002-12-23 19:05 ` Andre Hedrick
2002-12-25 21:30 ` Alan Cox
0 siblings, 1 reply; 5+ messages in thread
From: Andre Hedrick @ 2002-12-23 19:05 UTC (permalink / raw
To: Willem Riede; +Cc: linux-scsi
There are a few changes I have to fix the ordering of the driver for clean
DMA ATAPI. These are test on ia64 Itanium 2 from HP.
I will look at the changes again but I agree w/ Doug about the nice job.
Cheers,
On Sun, 22 Dec 2002, Willem Riede wrote:
> On 2002.12.21 20:59 Douglas Gilbert wrote:
> > Willem Riede wrote:
> > > Here is my proposal for bringing ide-scsi in line with the current kernel.
> > >
> > > The attached patch does:
> > >
> >
> > Willem,
> > Good work.
> >
> Thanks.
> >
> > BTW Willem's patch is against lk 2.5.52 .
> >
> Right. And next to this ide-scsi patch, you will also want
> the one line fix to ide.c I posted earlier.
>
> http://marc.theaimsgroup.com/?l=linux-scsi&m=104017636631422&w=2
>
> Regards, Willem Riede.
> -
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
Andre Hedrick
LAD Storage Consulting Group
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] ide-scsi changes for new mid level api and error handling in 2.5.52
2002-12-23 19:05 ` Andre Hedrick
@ 2002-12-25 21:30 ` Alan Cox
0 siblings, 0 replies; 5+ messages in thread
From: Alan Cox @ 2002-12-25 21:30 UTC (permalink / raw
To: Andre Hedrick; +Cc: Willem Riede, linux-scsi
On Mon, 2002-12-23 at 19:05, Andre Hedrick wrote:
>
> There are a few changes I have to fix the ordering of the driver for clean
> DMA ATAPI. These are test on ia64 Itanium 2 from HP.
Actually the fixes from HP have been in the base 2.4 and 2.5 IDE for
several weeks
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2002-12-25 21:30 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-12-21 22:46 [PATCH] ide-scsi changes for new mid level api and error handling in 2.5.52 Willem Riede
2002-12-22 1:59 ` Douglas Gilbert
2002-12-22 17:14 ` Willem Riede
2002-12-23 19:05 ` Andre Hedrick
2002-12-25 21:30 ` Alan Cox
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.