/* aha152x.c -- Adaptec AHA-152x driver
- * Author: Jürgen E. Fischer, fischer@norbit.de
- * Copyright 1993-2004 Jürgen E. Fischer
+ * Author: Jürgen E. Fischer, fischer@norbit.de
+ * Copyright 1993-2004 Jürgen E. Fischer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
**************************************************************************/
#include <linux/module.h>
-#include <linux/sched.h>
#include <asm/irq.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/blkdev.h>
#include <asm/system.h>
+#include <linux/completion.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/wait.h>
#include <linux/isapnp.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
-#include <asm/semaphore.h>
+#include <linux/list.h>
+#include <linux/slab.h>
#include <scsi/scsicam.h>
#include "scsi.h"
#include <scsi/scsi_dbg.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_transport_spi.h>
+#include <scsi/scsi_eh.h>
#include "aha152x.h"
+static LIST_HEAD(aha152x_host_list);
+
/* DEFINES */
#define DO_LOCK(flags) \
do { \
if(spin_is_locked(&QLOCK)) { \
- DPRINTK(debug_intr, DEBUG_LEAD "(%s:%d) already locked at %s:%d\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__, QLOCKER, QLOCKERL); \
+ DPRINTK(debug_intr, DEBUG_LEAD "(%s:%d) already locked at %s:%d\n", CMDINFO(CURRENT_SC), __func__, __LINE__, QLOCKER, QLOCKERL); \
} \
- DPRINTK(debug_locks, DEBUG_LEAD "(%s:%d) locking\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__); \
+ DPRINTK(debug_locking, DEBUG_LEAD "(%s:%d) locking\n", CMDINFO(CURRENT_SC), __func__, __LINE__); \
spin_lock_irqsave(&QLOCK,flags); \
- DPRINTK(debug_locks, DEBUG_LEAD "(%s:%d) locked\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__); \
- QLOCKER=__FUNCTION__; \
+ DPRINTK(debug_locking, DEBUG_LEAD "(%s:%d) locked\n", CMDINFO(CURRENT_SC), __func__, __LINE__); \
+ QLOCKER=__func__; \
QLOCKERL=__LINE__; \
} while(0)
#define DO_UNLOCK(flags) \
do { \
- DPRINTK(debug_locks, DEBUG_LEAD "(%s:%d) unlocking (locked at %s:%d)\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__, QLOCKER, QLOCKERL); \
+ DPRINTK(debug_locking, DEBUG_LEAD "(%s:%d) unlocking (locked at %s:%d)\n", CMDINFO(CURRENT_SC), __func__, __LINE__, QLOCKER, QLOCKERL); \
spin_unlock_irqrestore(&QLOCK,flags); \
- DPRINTK(debug_locks, DEBUG_LEAD "(%s:%d) unlocked\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__); \
+ DPRINTK(debug_locking, DEBUG_LEAD "(%s:%d) unlocked\n", CMDINFO(CURRENT_SC), __func__, __LINE__); \
QLOCKER="(not locked)"; \
QLOCKERL=0; \
} while(0)
(cmd) ? ((cmd)->device->id & 0x0f) : -1, \
(cmd) ? ((cmd)->device->lun & 0x07) : -1
+static inline void
+CMD_INC_RESID(struct scsi_cmnd *cmd, int inc)
+{
+ scsi_set_resid(cmd, scsi_get_resid(cmd) + inc);
+}
+
#define DELAY_DEFAULT 1000
#if defined(PCMCIA)
#else
#define IRQ_MIN 9
#if defined(__PPC)
-#define IRQ_MAX (NR_IRQS-1)
+#define IRQ_MAX (nr_irqs-1)
#else
#define IRQ_MAX 12
#endif
check_condition = 0x0800, /* requesting sense after CHECK CONDITION */
};
-MODULE_AUTHOR("Jürgen Fischer");
+MODULE_AUTHOR("Jürgen Fischer");
MODULE_DESCRIPTION(AHA152X_REVID);
MODULE_LICENSE("GPL");
#endif /* !PCMCIA */
-static int registered_count=0;
-static struct Scsi_Host *aha152x_host[2];
static struct scsi_host_template aha152x_driver_template;
/*
#ifdef __ISAPNP__
struct pnp_dev *pnpdev;
#endif
+ struct list_head host_list;
};
*/
struct aha152x_scdata {
Scsi_Cmnd *next; /* next sc in queue */
- struct semaphore *sem; /* semaphore to block on */
- unsigned char cmd_len;
- unsigned char cmnd[MAX_COMMAND_SIZE];
- unsigned short use_sg;
- unsigned request_bufflen;
- void *request_buffer;
+ struct completion *done;/* semaphore to block on */
+ struct scsi_eh_save ses;
};
-
/* access macros for hostdata */
#define HOSTDATA(shpnt) ((struct aha152x_hostdata *) &shpnt->hostdata)
#define SCDATA(SCpnt) ((struct aha152x_scdata *) (SCpnt)->host_scribble)
#define SCNEXT(SCpnt) SCDATA(SCpnt)->next
-#define SCSEM(SCpnt) SCDATA(SCpnt)->sem
+#define SCSEM(SCpnt) SCDATA(SCpnt)->done
-#define SG_ADDRESS(buffer) ((char *) (page_address((buffer)->page)+(buffer)->offset))
+#define SG_ADDRESS(buffer) ((char *) sg_virt((buffer)))
/* state handling */
static void seldi_run(struct Scsi_Host *shpnt);
};
/* setup & interrupt */
-static irqreturn_t intr(int irq, void *dev_id, struct pt_regs *);
+static irqreturn_t intr(int irq, void *dev_id);
static void reset_ports(struct Scsi_Host *shpnt);
static void aha152x_error(struct Scsi_Host *shpnt, char *msg);
static void done(struct Scsi_Host *shpnt, int error);
return ptr;
}
-static inline struct Scsi_Host *lookup_irq(int irqno)
+static irqreturn_t swintr(int irqno, void *dev_id)
{
- int i;
-
- for(i=0; i<ARRAY_SIZE(aha152x_host); i++)
- if(aha152x_host[i] && aha152x_host[i]->irq==irqno)
- return aha152x_host[i];
-
- return NULL;
-}
-
-static irqreturn_t swintr(int irqno, void *dev_id, struct pt_regs *regs)
-{
- struct Scsi_Host *shpnt = lookup_irq(irqno);
-
- if (!shpnt) {
- printk(KERN_ERR "aha152x: catched software interrupt %d for unknown controller.\n", irqno);
- return IRQ_NONE;
- }
+ struct Scsi_Host *shpnt = dev_id;
HOSTDATA(shpnt)->swint++;
return NULL;
}
- /* need to have host registered before triggering any interrupt */
- aha152x_host[registered_count] = shpnt;
-
memset(HOSTDATA(shpnt), 0, sizeof *HOSTDATA(shpnt));
+ INIT_LIST_HEAD(&HOSTDATA(shpnt)->host_list);
+
+ /* need to have host registered before triggering any interrupt */
+ list_add_tail(&HOSTDATA(shpnt)->host_list, &aha152x_host_list);
shpnt->io_port = setup->io_port;
shpnt->n_io_port = IO_RANGE;
scsi_scan_host(shpnt);
- registered_count++;
-
return shpnt;
out_host_put:
- aha152x_host[registered_count]=NULL;
+ list_del(&HOSTDATA(shpnt)->host_list);
scsi_host_put(shpnt);
return NULL;
void aha152x_release(struct Scsi_Host *shpnt)
{
- if(!shpnt)
+ if (!shpnt)
return;
+ scsi_remove_host(shpnt);
if (shpnt->irq)
free_irq(shpnt->irq, shpnt);
pnp_device_detach(HOSTDATA(shpnt)->pnpdev);
#endif
- scsi_remove_host(shpnt);
+ list_del(&HOSTDATA(shpnt)->host_list);
scsi_host_put(shpnt);
}
/*
* Queue a command and setup interrupts for a free bus.
*/
-static int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct semaphore *sem, int phase, void (*done)(Scsi_Cmnd *))
+static int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct completion *complete,
+ int phase, void (*done)(Scsi_Cmnd *))
{
struct Scsi_Host *shpnt = SCpnt->device->host;
unsigned long flags;
#if defined(AHA152X_DEBUG)
if (HOSTDATA(shpnt)->debug & debug_queue) {
printk(INFO_LEAD "queue: %p; cmd_len=%d pieces=%d size=%u cmnd=",
- CMDINFO(SCpnt), SCpnt, SCpnt->cmd_len, SCpnt->use_sg, SCpnt->request_bufflen);
+ CMDINFO(SCpnt), SCpnt, SCpnt->cmd_len,
+ scsi_sg_count(SCpnt), scsi_bufflen(SCpnt));
__scsi_print_command(SCpnt->cmnd);
}
#endif
SCpnt->scsi_done = done;
- SCpnt->resid = SCpnt->request_bufflen;
SCpnt->SCp.phase = not_issued | phase;
- SCpnt->SCp.Status = CHECK_CONDITION;
+ SCpnt->SCp.Status = 0x1; /* Ilegal status by SCSI standard */
SCpnt->SCp.Message = 0;
SCpnt->SCp.have_data_in = 0;
SCpnt->SCp.sent_command = 0;
if(SCpnt->SCp.phase & (resetting|check_condition)) {
- if(SCpnt->host_scribble==0 || SCSEM(SCpnt) || SCNEXT(SCpnt)) {
+ if (!SCpnt->host_scribble || SCSEM(SCpnt) || SCNEXT(SCpnt)) {
printk(ERR_LEAD "cannot reuse command\n", CMDINFO(SCpnt));
return FAILED;
}
} else {
- struct aha152x_scdata *sc;
-
SCpnt->host_scribble = kmalloc(sizeof(struct aha152x_scdata), GFP_ATOMIC);
- if(SCpnt->host_scribble==0) {
+ if(!SCpnt->host_scribble) {
printk(ERR_LEAD "allocation failed\n", CMDINFO(SCpnt));
return FAILED;
}
-
- sc = SCDATA(SCpnt);
- memcpy(sc->cmnd, SCpnt->cmnd, sizeof(sc->cmnd));
- sc->request_buffer = SCpnt->request_buffer;
- sc->request_bufflen = SCpnt->request_bufflen;
- sc->use_sg = SCpnt->use_sg;
- sc->cmd_len = SCpnt->cmd_len;
}
SCNEXT(SCpnt) = NULL;
- SCSEM(SCpnt) = sem;
+ SCSEM(SCpnt) = complete;
/* setup scratch area
SCp.ptr : buffer pointer
SCp.buffer : next buffer
SCp.buffers_residual : left buffers in list
SCp.phase : current state of the command */
- if (SCpnt->use_sg) {
- SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->request_buffer;
- SCpnt->SCp.ptr = SG_ADDRESS(SCpnt->SCp.buffer);
- SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
- SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
- } else {
- SCpnt->SCp.ptr = (char *) SCpnt->request_buffer;
- SCpnt->SCp.this_residual = SCpnt->request_bufflen;
+
+ if ((phase & resetting) || !scsi_sglist(SCpnt)) {
+ SCpnt->SCp.ptr = NULL;
+ SCpnt->SCp.this_residual = 0;
+ scsi_set_resid(SCpnt, 0);
SCpnt->SCp.buffer = NULL;
SCpnt->SCp.buffers_residual = 0;
+ } else {
+ scsi_set_resid(SCpnt, scsi_bufflen(SCpnt));
+ SCpnt->SCp.buffer = scsi_sglist(SCpnt);
+ SCpnt->SCp.ptr = SG_ADDRESS(SCpnt->SCp.buffer);
+ SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
+ SCpnt->SCp.buffers_residual = scsi_sg_count(SCpnt) - 1;
}
DO_LOCK(flags);
DPRINTK(debug_eh, INFO_LEAD "reset_done called\n", CMDINFO(SCpnt));
#endif
if(SCSEM(SCpnt)) {
- up(SCSEM(SCpnt));
+ complete(SCSEM(SCpnt));
} else {
- printk(KERN_ERR "aha152x: reset_done w/o semaphore\n");
+ printk(KERN_ERR "aha152x: reset_done w/o completion\n");
}
}
return FAILED;
}
-static void timer_expired(unsigned long p)
-{
- Scsi_Cmnd *SCp = (Scsi_Cmnd *)p;
- struct semaphore *sem = SCSEM(SCp);
- struct Scsi_Host *shpnt = SCp->device->host;
- unsigned long flags;
-
- /* remove command from issue queue */
- DO_LOCK(flags);
- remove_SC(&ISSUE_SC, SCp);
- DO_UNLOCK(flags);
-
- up(sem);
-}
-
/*
* Reset a device
*
static int aha152x_device_reset(Scsi_Cmnd * SCpnt)
{
struct Scsi_Host *shpnt = SCpnt->device->host;
- DECLARE_MUTEX_LOCKED(sem);
- struct timer_list timer;
+ DECLARE_COMPLETION(done);
int ret, issued, disconnected;
+ unsigned char old_cmd_len = SCpnt->cmd_len;
unsigned long flags;
+ unsigned long timeleft;
#if defined(AHA152X_DEBUG)
if(HOSTDATA(shpnt)->debug & debug_eh) {
}
DO_LOCK(flags);
- issued = remove_SC(&ISSUE_SC, SCpnt)==0;
+ issued = remove_SC(&ISSUE_SC, SCpnt) == NULL;
disconnected = issued && remove_SC(&DISCONNECTED_SC, SCpnt);
DO_UNLOCK(flags);
SCpnt->cmd_len = 0;
- SCpnt->use_sg = 0;
- SCpnt->request_buffer = NULL;
- SCpnt->request_bufflen = 0;
-
- init_timer(&timer);
- timer.data = (unsigned long) SCpnt;
- timer.expires = jiffies + 100*HZ; /* 10s */
- timer.function = (void (*)(unsigned long)) timer_expired;
-
- aha152x_internal_queue(SCpnt, &sem, resetting, reset_done);
- add_timer(&timer);
- down(&sem);
- del_timer(&timer);
-
- SCpnt->cmd_len = SCpnt->old_cmd_len;
- SCpnt->use_sg = SCpnt->old_use_sg;
- SCpnt->request_buffer = SCpnt->buffer;
- SCpnt->request_bufflen = SCpnt->bufflen;
+
+ aha152x_internal_queue(SCpnt, &done, resetting, reset_done);
+
+ timeleft = wait_for_completion_timeout(&done, 100*HZ);
+ if (!timeleft) {
+ /* remove command from issue queue */
+ DO_LOCK(flags);
+ remove_SC(&ISSUE_SC, SCpnt);
+ DO_UNLOCK(flags);
+ }
+
+ SCpnt->cmd_len = old_cmd_len;
DO_LOCK(flags);
* Run service completions on the card with interrupts enabled.
*
*/
-static void run(void)
+static void run(struct work_struct *work)
{
- int i;
- for (i = 0; i<ARRAY_SIZE(aha152x_host); i++) {
- is_complete(aha152x_host[i]);
+ struct aha152x_hostdata *hd;
+
+ list_for_each_entry(hd, &aha152x_host_list, host_list) {
+ struct Scsi_Host *shost = container_of((void *)hd, struct Scsi_Host, hostdata);
+
+ is_complete(shost);
}
}
* Interrupt handler
*
*/
-static irqreturn_t intr(int irqno, void *dev_id, struct pt_regs *regs)
+static irqreturn_t intr(int irqno, void *dev_id)
{
- struct Scsi_Host *shpnt = lookup_irq(irqno);
+ struct Scsi_Host *shpnt = dev_id;
unsigned long flags;
unsigned char rev, dmacntrl0;
- if (!shpnt) {
- printk(KERN_ERR "aha152x: catched interrupt %d for unknown controller.\n", irqno);
- return IRQ_NONE;
- }
-
/*
* Read a couple of registers that are known to not be all 1's. If
* we read all 1's (-1), that means that either:
HOSTDATA(shpnt)->service=1;
/* Poke the BH handler */
- INIT_WORK(&aha152x_tq, (void *) run, NULL);
+ INIT_WORK(&aha152x_tq, run);
schedule_work(&aha152x_tq);
}
DO_UNLOCK(flags);
/* target sent DISCONNECT */
DPRINTK(debug_selection, DEBUG_LEAD "target disconnected at %d/%d\n",
CMDINFO(CURRENT_SC),
- CURRENT_SC->resid,
- CURRENT_SC->request_bufflen);
+ scsi_get_resid(CURRENT_SC),
+ scsi_bufflen(CURRENT_SC));
#if defined(AHA152X_STAT)
HOSTDATA(shpnt)->disconnections++;
#endif
}
#endif
- /* restore old command */
- memcpy(cmd->cmnd, sc->cmnd, sizeof(sc->cmnd));
- cmd->request_buffer = sc->request_buffer;
- cmd->request_bufflen = sc->request_bufflen;
- cmd->use_sg = sc->use_sg;
- cmd->cmd_len = sc->cmd_len;
+ scsi_eh_restore_cmnd(cmd, &sc->ses);
- cmd->SCp.Status = 0x02;
+ cmd->SCp.Status = SAM_STAT_CHECK_CONDITION;
HOSTDATA(shpnt)->commands--;
if (!HOSTDATA(shpnt)->commands)
SETPORT(PORTA, 0); /* turn led off */
- } else if(DONE_SC->SCp.Status==0x02) {
+ } else if(DONE_SC->SCp.Status==SAM_STAT_CHECK_CONDITION) {
#if defined(AHA152X_STAT)
HOSTDATA(shpnt)->busfree_with_check_condition++;
#endif
DPRINTK(debug_eh, ERR_LEAD "CHECK CONDITION found\n", CMDINFO(DONE_SC));
#endif
- if(!(DONE_SC->SCp.Status & not_issued)) {
+ if(!(DONE_SC->SCp.phase & not_issued)) {
+ struct aha152x_scdata *sc;
Scsi_Cmnd *ptr = DONE_SC;
DONE_SC=NULL;
#if 0
DPRINTK(debug_eh, ERR_LEAD "requesting sense\n", CMDINFO(ptr));
#endif
- ptr->cmnd[0] = REQUEST_SENSE;
- ptr->cmnd[1] = 0;
- ptr->cmnd[2] = 0;
- ptr->cmnd[3] = 0;
- ptr->cmnd[4] = sizeof(ptr->sense_buffer);
- ptr->cmnd[5] = 0;
- ptr->cmd_len = 6;
- ptr->use_sg = 0;
- ptr->request_buffer = ptr->sense_buffer;
- ptr->request_bufflen = sizeof(ptr->sense_buffer);
-
+ sc = SCDATA(ptr);
+ /* It was allocated in aha152x_internal_queue? */
+ BUG_ON(!sc);
+ scsi_eh_prep_cmnd(ptr, &sc->ses, NULL, 0, ~0);
+
DO_UNLOCK(flags);
aha152x_internal_queue(ptr, NULL, check_condition, ptr->scsi_done);
DO_LOCK(flags);
DATA_LEN=0;
DPRINTK(debug_datai,
DEBUG_LEAD "datai_init: request_bufflen=%d resid=%d\n",
- CMDINFO(CURRENT_SC), CURRENT_SC->request_bufflen, CURRENT_SC->resid);
+ CMDINFO(CURRENT_SC), scsi_bufflen(CURRENT_SC),
+ scsi_get_resid(CURRENT_SC));
}
static void datai_run(struct Scsi_Host *shpnt)
static void datai_end(struct Scsi_Host *shpnt)
{
- CURRENT_SC->resid -= GETSTCNT();
+ CMD_INC_RESID(CURRENT_SC, -GETSTCNT());
DPRINTK(debug_datai,
DEBUG_LEAD "datai_end: request_bufflen=%d resid=%d stcnt=%d\n",
- CMDINFO(CURRENT_SC), CURRENT_SC->request_bufflen, CURRENT_SC->resid, GETSTCNT());
+ CMDINFO(CURRENT_SC), scsi_bufflen(CURRENT_SC),
+ scsi_get_resid(CURRENT_SC), GETSTCNT());
SETPORT(SXFRCTL0, CH1|CLRSTCNT);
SETPORT(DMACNTRL0, 0);
SETPORT(SIMODE0, 0);
SETPORT(SIMODE1, ENSCSIPERR | ENSCSIRST | ENPHASEMIS | ENBUSFREE );
- DATA_LEN = CURRENT_SC->resid;
+ DATA_LEN = scsi_get_resid(CURRENT_SC);
DPRINTK(debug_datao,
DEBUG_LEAD "datao_init: request_bufflen=%d; resid=%d\n",
- CMDINFO(CURRENT_SC), CURRENT_SC->request_bufflen, CURRENT_SC->resid);
+ CMDINFO(CURRENT_SC), scsi_bufflen(CURRENT_SC),
+ scsi_get_resid(CURRENT_SC));
}
static void datao_run(struct Scsi_Host *shpnt)
SETPORT(DMACNTRL0,WRITE_READ|ENDMA|_8BIT);
SETPORT(DATAPORT, *CURRENT_SC->SCp.ptr++);
CURRENT_SC->SCp.this_residual--;
- CURRENT_SC->resid--;
+ CMD_INC_RESID(CURRENT_SC, -1);
SETPORT(DMACNTRL0,WRITE_READ|ENDMA);
}
outsw(DATAPORT, CURRENT_SC->SCp.ptr, data_count);
CURRENT_SC->SCp.ptr += 2 * data_count;
CURRENT_SC->SCp.this_residual -= 2 * data_count;
- CURRENT_SC->resid -= 2 * data_count;
+ CMD_INC_RESID(CURRENT_SC, -2 * data_count);
}
if(CURRENT_SC->SCp.this_residual==0 && CURRENT_SC->SCp.buffers_residual>0) {
static void datao_end(struct Scsi_Host *shpnt)
{
if(TESTLO(DMASTAT, DFIFOEMP)) {
- int data_count = (DATA_LEN - CURRENT_SC->resid) - GETSTCNT();
+ int data_count = (DATA_LEN - scsi_get_resid(CURRENT_SC)) -
+ GETSTCNT();
DPRINTK(debug_datao, DEBUG_LEAD "datao: %d bytes to resend (%d written, %d transferred)\n",
CMDINFO(CURRENT_SC),
data_count,
- DATA_LEN-CURRENT_SC->resid,
+ DATA_LEN - scsi_get_resid(CURRENT_SC),
GETSTCNT());
- CURRENT_SC->resid += data_count;
+ CMD_INC_RESID(CURRENT_SC, data_count);
- if(CURRENT_SC->use_sg) {
- data_count -= CURRENT_SC->SCp.ptr - SG_ADDRESS(CURRENT_SC->SCp.buffer);
- while(data_count>0) {
- CURRENT_SC->SCp.buffer--;
- CURRENT_SC->SCp.buffers_residual++;
- data_count -= CURRENT_SC->SCp.buffer->length;
- }
- CURRENT_SC->SCp.ptr = SG_ADDRESS(CURRENT_SC->SCp.buffer) - data_count;
- CURRENT_SC->SCp.this_residual = CURRENT_SC->SCp.buffer->length + data_count;
- } else {
- CURRENT_SC->SCp.ptr -= data_count;
- CURRENT_SC->SCp.this_residual += data_count;
+ data_count -= CURRENT_SC->SCp.ptr -
+ SG_ADDRESS(CURRENT_SC->SCp.buffer);
+ while(data_count>0) {
+ CURRENT_SC->SCp.buffer--;
+ CURRENT_SC->SCp.buffers_residual++;
+ data_count -= CURRENT_SC->SCp.buffer->length;
}
+ CURRENT_SC->SCp.ptr = SG_ADDRESS(CURRENT_SC->SCp.buffer) -
+ data_count;
+ CURRENT_SC->SCp.this_residual = CURRENT_SC->SCp.buffer->length +
+ data_count;
}
DPRINTK(debug_datao, DEBUG_LEAD "datao_end: request_bufflen=%d; resid=%d; stcnt=%d\n",
CMDINFO(CURRENT_SC),
- CURRENT_SC->request_bufflen,
- CURRENT_SC->resid,
+ scsi_bufflen(CURRENT_SC),
+ scsi_get_resid(CURRENT_SC),
GETSTCNT());
SETPORT(SXFRCTL0, CH1|CLRCH1|CLRSTCNT);
__scsi_print_command(ptr->cmnd);
printk(KERN_DEBUG "); request_bufflen=%d; resid=%d; phase |",
- ptr->request_bufflen, ptr->resid);
+ scsi_bufflen(ptr), scsi_get_resid(ptr));
if (ptr->SCp.phase & not_issued)
printk("not issued|");
SPRINTF("0x%02x ", ptr->cmnd[i]);
SPRINTF("); resid=%d; residual=%d; buffers=%d; phase |",
- ptr->resid, ptr->SCp.this_residual, ptr->SCp.buffers_residual);
+ scsi_get_resid(ptr), ptr->SCp.this_residual,
+ ptr->SCp.buffers_residual);
if (ptr->SCp.phase & not_issued)
SPRINTF("not issued|");
PDEBUG(debug_datai, "data in");
PDEBUG(debug_datao, "data out");
PDEBUG(debug_eh, "eh");
- PDEBUG(debug_locks, "locks");
+ PDEBUG(debug_locking, "locks");
PDEBUG(debug_phases, "phases");
SPRINTF("\n");
return thislength < length ? thislength : length;
}
+static int aha152x_adjust_queue(struct scsi_device *device)
+{
+ blk_queue_bounce_limit(device->request_queue, BLK_BOUNCE_HIGH);
+ return 0;
+}
+
static struct scsi_host_template aha152x_driver_template = {
.module = THIS_MODULE,
.name = AHA152X_REVID,
.sg_tablesize = SG_ALL,
.cmd_per_lun = 1,
.use_clustering = DISABLE_CLUSTERING,
+ .slave_alloc = aha152x_adjust_queue,
};
#if !defined(PCMCIA)
if (i == ARRAY_SIZE(ports))
return 0;
- if ( request_region(setup->io_port, IO_RANGE, "aha152x")==0 ) {
+ if (!request_region(setup->io_port, IO_RANGE, "aha152x")) {
printk(KERN_ERR "aha152x: io port 0x%x busy.\n", setup->io_port);
return 0;
}
iounmap(p);
}
if (!ok && setup_count == 0)
- return 0;
+ return -ENODEV;
printk(KERN_INFO "aha152x: BIOS test: passed, ");
#else
if ((setup_count == 1) && (setup[0].io_port == ports[i]))
continue;
- if ( request_region(ports[i], IO_RANGE, "aha152x")==0 ) {
+ if (!request_region(ports[i], IO_RANGE, "aha152x")) {
printk(KERN_ERR "aha152x: io port 0x%x busy.\n", ports[i]);
continue;
}
#endif
}
- return registered_count>0;
+ return 0;
}
static void __exit aha152x_exit(void)
{
- int i;
+ struct aha152x_hostdata *hd, *tmp;
+
+ list_for_each_entry_safe(hd, tmp, &aha152x_host_list, host_list) {
+ struct Scsi_Host *shost = container_of((void *)hd, struct Scsi_Host, hostdata);
- for(i=0; i<ARRAY_SIZE(setup); i++) {
- aha152x_release(aha152x_host[i]);
- aha152x_host[i]=NULL;
+ aha152x_release(shost);
}
}