*/
static int
arxescsi_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length,
- int host_no, int inout)
+ int inout)
{
struct arxescsi_info *info;
char *p = buffer;
.proc_info = arxescsi_proc_info,
.name = "ARXE SCSI card",
.info = arxescsi_info,
- .queuecommand = fas216_queue_command,
+ .queuecommand = fas216_noqueue_command,
.eh_host_reset_handler = fas216_eh_host_reset,
.eh_bus_reset_handler = fas216_eh_bus_reset,
.eh_device_reset_handler = fas216_eh_device_reset,
printk(" dma={ transfer_type=%X setup=%p pseudo=%p stop=%p }\n",
info->dma.transfer_type, info->dma.setup,
info->dma.pseudo, info->dma.stop);
- printk(" magic_end=%lX }\n", info->magic_end);
+ printk(" internal_done=%X magic_end=%lX }\n",
+ info->internal_done, info->magic_end);
}
#ifdef CHECK_STRUCTURE
return result;
}
+/**
+ * fas216_internal_done - trigger restart of a waiting thread in fas216_noqueue_command
+ * @SCpnt: Command to wake
+ *
+ * Trigger restart of a waiting thread in fas216_command
+ */
+static void fas216_internal_done(Scsi_Cmnd *SCpnt)
+{
+ FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
+
+ fas216_checkmagic(info);
+
+ info->internal_done = 1;
+}
+
+/**
+ * fas216_noqueue_command - process a command for the adapter.
+ * @SCpnt: Command to queue
+ *
+ * Queue a command for adapter to process.
+ * Returns: scsi result code.
+ * Notes: io_request_lock is held, interrupts are disabled.
+ */
+int fas216_noqueue_command(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
+{
+ FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
+
+ fas216_checkmagic(info);
+
+ /*
+ * We should only be using this if we don't have an interrupt.
+ * Provide some "incentive" to use the queueing code.
+ */
+ BUG_ON(info->scsi.irq != NO_IRQ);
+
+ info->internal_done = 0;
+ fas216_queue_command(SCpnt, fas216_internal_done);
+
+ /*
+ * This wastes time, since we can't return until the command is
+ * complete. We can't sleep either since we may get re-entered!
+ * However, we must re-enable interrupts, or else we'll be
+ * waiting forever.
+ */
+ spin_unlock_irq(info->host->host_lock);
+
+ while (!info->internal_done) {
+ /*
+ * If we don't have an IRQ, then we must poll the card for
+ * it's interrupt, and use that to call this driver's
+ * interrupt routine. That way, we keep the command
+ * progressing. Maybe we can add some inteligence here
+ * and go to sleep if we know that the device is going
+ * to be some time (eg, disconnected).
+ */
+ if (fas216_readb(info, REG_STAT) & STAT_INT) {
+ spin_lock_irq(info->host->host_lock);
+ fas216_intr(info);
+ spin_unlock_irq(info->host->host_lock);
+ }
+ }
+
+ spin_lock_irq(info->host->host_lock);
+
+ done(SCpnt);
+
+ return 0;
+}
+
/*
* Error handler timeout function. Indicate that we timed out,
* and wake up any error handler process so it can continue.
EXPORT_SYMBOL(fas216_init);
EXPORT_SYMBOL(fas216_add);
EXPORT_SYMBOL(fas216_queue_command);
-EXPORT_SYMBOL(fas216_command);
+EXPORT_SYMBOL(fas216_noqueue_command);
EXPORT_SYMBOL(fas216_intr);
EXPORT_SYMBOL(fas216_remove);
EXPORT_SYMBOL(fas216_release);
} dma;
/* miscellaneous */
+ int internal_done; /* flag to indicate request done */
unsigned long magic_end;
} FAS216_Info;
*/
extern int fas216_queue_command (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+/* Function: int fas216_noqueue_command (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
+ * Purpose : queue a command for adapter to process, and process it to completion.
+ * Params : SCpnt - Command to queue
+ * done - done function to call once command is complete
+ * Returns : 0 - success, else error
+ */
+extern int fas216_noqueue_command (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+
/* Function: irqreturn_t fas216_intr (FAS216_Info *info)
* Purpose : handle interrupts from the interface to progress a command
* Params : info - interface to service