* Added proper detection of the AHA-1640 (MCA version of AHA-1540)
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <linux/init.h>
#include <linux/spinlock.h>
-#include <linux/pci.h>
#include <linux/isapnp.h>
#include <linux/blkdev.h>
#include <linux/mca.h>
#include "aha1542.h"
#define SCSI_BUF_PA(address) isa_virt_to_bus(address)
-#define SCSI_SG_PA(sgent) (isa_page_to_bus((sgent)->page) + (sgent)->offset)
-
-static void BAD_DMA(void *address, unsigned int length)
-{
- printk(KERN_CRIT "buf vaddress %p paddress 0x%lx length %d\n",
- address,
- SCSI_BUF_PA(address),
- length);
- panic("Buffer at physical address > 16Mb used for aha1542");
-}
+#define SCSI_SG_PA(sgent) (isa_page_to_bus(sg_page((sgent))) + (sgent)->offset)
static void BAD_SG_DMA(Scsi_Cmnd * SCpnt,
- struct scatterlist *sgpnt,
+ struct scatterlist *sgp,
int nseg,
int badseg)
{
printk(KERN_CRIT "sgpnt[%d:%d] page %p/0x%llx length %u\n",
- badseg, nseg,
- page_address(sgpnt[badseg].page) + sgpnt[badseg].offset,
- (unsigned long long)SCSI_SG_PA(&sgpnt[badseg]),
- sgpnt[badseg].length);
+ badseg, nseg, sg_virt(sgp),
+ (unsigned long long)SCSI_SG_PA(sgp),
+ sgp->length);
/*
* Not safe to continue.
static void setup_mailboxes(int base_io, struct Scsi_Host *shpnt);
static int aha1542_restart(struct Scsi_Host *shost);
-static void aha1542_intr_handle(struct Scsi_Host *shost, void *dev_id, struct pt_regs *regs);
-static irqreturn_t do_aha1542_intr_handle(int irq, void *dev_id,
- struct pt_regs *regs);
+static void aha1542_intr_handle(struct Scsi_Host *shost, void *dev_id);
+static irqreturn_t do_aha1542_intr_handle(int irq, void *dev_id);
#define aha1542_intr_reset(base) outb(IRST, CONTROL(base))
}
/* A quick wrapper for do_aha1542_intr_handle to grab the spin lock */
-static irqreturn_t do_aha1542_intr_handle(int irq, void *dev_id,
- struct pt_regs *regs)
+static irqreturn_t do_aha1542_intr_handle(int irq, void *dev_id)
{
unsigned long flags;
struct Scsi_Host *shost;
panic("Splunge!");
spin_lock_irqsave(shost->host_lock, flags);
- aha1542_intr_handle(shost, dev_id, regs);
+ aha1542_intr_handle(shost, dev_id);
spin_unlock_irqrestore(shost->host_lock, flags);
return IRQ_HANDLED;
}
/* A "high" level interrupt handler */
-static void aha1542_intr_handle(struct Scsi_Host *shost, void *dev_id, struct pt_regs *regs)
+static void aha1542_intr_handle(struct Scsi_Host *shost, void *dev_id)
{
void (*my_done) (Scsi_Cmnd *) = NULL;
int errstatus, mbi, mbo, mbistatus;
return;
}
my_done = SCtmp->scsi_done;
- if (SCtmp->host_scribble) {
- kfree(SCtmp->host_scribble);
- SCtmp->host_scribble = NULL;
- }
+ kfree(SCtmp->host_scribble);
+ SCtmp->host_scribble = NULL;
/* Fetch the sense data, and tuck it away, in the required slot. The
Adaptec automatically fetches it, and there is no guarantee that
we will still have it in the cdb when we come back */
if (ccb[mbo].tarstat == 2)
memcpy(SCtmp->sense_buffer, &ccb[mbo].cdb[ccb[mbo].cdblen],
- sizeof(SCtmp->sense_buffer));
+ SCSI_SENSE_BUFFERSIZE);
/* is there mail :-) */
unchar target = SCpnt->device->id;
unchar lun = SCpnt->device->lun;
unsigned long flags;
- void *buff = SCpnt->request_buffer;
- int bufflen = SCpnt->request_bufflen;
+ int bufflen = scsi_bufflen(SCpnt);
int mbo;
struct mailbox *mb;
struct ccb *ccb;
#if 0
/* scsi_request_sense() provides a buffer of size 256,
so there is no reason to expect equality */
- if (bufflen != sizeof(SCpnt->sense_buffer))
+ if (bufflen != SCSI_SENSE_BUFFERSIZE)
printk(KERN_CRIT "aha1542: Wrong buffer length supplied "
"for request sense (%d)\n", bufflen);
#endif
memcpy(ccb[mbo].cdb, cmd, ccb[mbo].cdblen);
- if (SCpnt->use_sg) {
- struct scatterlist *sgpnt;
+ if (bufflen) {
+ struct scatterlist *sg;
struct chain *cptr;
#ifdef DEBUG
unsigned char *ptr;
#endif
- int i;
+ int i, sg_count = scsi_sg_count(SCpnt);
ccb[mbo].op = 2; /* SCSI Initiator Command w/scatter-gather */
- SCpnt->host_scribble = (unsigned char *) kmalloc(512, GFP_KERNEL | GFP_DMA);
- sgpnt = (struct scatterlist *) SCpnt->request_buffer;
+ SCpnt->host_scribble = kmalloc(sizeof(*cptr)*sg_count,
+ GFP_KERNEL | GFP_DMA);
cptr = (struct chain *) SCpnt->host_scribble;
if (cptr == NULL) {
/* free the claimed mailbox slot */
HOSTDATA(SCpnt->device->host)->SCint[mbo] = NULL;
return SCSI_MLQUEUE_HOST_BUSY;
}
- for (i = 0; i < SCpnt->use_sg; i++) {
- if (sgpnt[i].length == 0 || SCpnt->use_sg > 16 ||
- (((int) sgpnt[i].offset) & 1) || (sgpnt[i].length & 1)) {
- unsigned char *ptr;
- printk(KERN_CRIT "Bad segment list supplied to aha1542.c (%d, %d)\n", SCpnt->use_sg, i);
- for (i = 0; i < SCpnt->use_sg; i++) {
- printk(KERN_CRIT "%d: %p %d\n", i,
- (page_address(sgpnt[i].page) +
- sgpnt[i].offset),
- sgpnt[i].length);
- };
- printk(KERN_CRIT "cptr %x: ", (unsigned int) cptr);
- ptr = (unsigned char *) &cptr[i];
- for (i = 0; i < 18; i++)
- printk("%02x ", ptr[i]);
- panic("Foooooooood fight!");
- };
- any2scsi(cptr[i].dataptr, SCSI_SG_PA(&sgpnt[i]));
- if (SCSI_SG_PA(&sgpnt[i]) + sgpnt[i].length - 1 > ISA_DMA_THRESHOLD)
- BAD_SG_DMA(SCpnt, sgpnt, SCpnt->use_sg, i);
- any2scsi(cptr[i].datalen, sgpnt[i].length);
+ scsi_for_each_sg(SCpnt, sg, sg_count, i) {
+ any2scsi(cptr[i].dataptr, SCSI_SG_PA(sg));
+ if (SCSI_SG_PA(sg) + sg->length - 1 > ISA_DMA_THRESHOLD)
+ BAD_SG_DMA(SCpnt, scsi_sglist(SCpnt), sg_count, i);
+ any2scsi(cptr[i].datalen, sg->length);
};
- any2scsi(ccb[mbo].datalen, SCpnt->use_sg * sizeof(struct chain));
+ any2scsi(ccb[mbo].datalen, sg_count * sizeof(struct chain));
any2scsi(ccb[mbo].dataptr, SCSI_BUF_PA(cptr));
#ifdef DEBUG
printk("cptr %x: ", cptr);
} else {
ccb[mbo].op = 0; /* SCSI Initiator Command */
SCpnt->host_scribble = NULL;
- any2scsi(ccb[mbo].datalen, bufflen);
- if (buff && SCSI_BUF_PA(buff + bufflen - 1) > ISA_DMA_THRESHOLD)
- BAD_DMA(buff, bufflen);
- any2scsi(ccb[mbo].dataptr, SCSI_BUF_PA(buff));
+ any2scsi(ccb[mbo].datalen, 0);
+ any2scsi(ccb[mbo].dataptr, 0);
};
ccb[mbo].idlun = (target & 7) << 5 | direction | (lun & 7); /*SCSI Target Id */
ccb[mbo].rsalen = 16;
int count=setup_idx;
- get_options(str, sizeof(ints)/sizeof(int), ints);
+ get_options(str, ARRAY_SIZE(ints), ints);
aha1542_setup(str,ints);
return count<setup_idx;
#endif
/* return non-zero on detection */
-static int __init aha1542_detect(Scsi_Host_Template * tpnt)
+static int __init aha1542_detect(struct scsi_host_template * tpnt)
{
unsigned char dma_chan;
unsigned char irq_level;
int slot = 0;
int pos = 0;
- for (indx = 0; (slot != MCA_NOTFOUND) &&
- (indx < sizeof(bases)/sizeof(bases[0])); indx++) {
+ for (indx = 0; (slot != MCA_NOTFOUND) && (indx < ARRAY_SIZE(bases)); indx++) {
if (bases[indx])
continue;
if (slot == MCA_NOTFOUND)
break;
-
/* Found one */
pos = mca_read_stored_pos(slot, 3);
-
+
/* Decode address */
if (pos & 0x80) {
if (pos & 0x02) {
mca_set_adapter_name(slot, "Adapter AHA-1640");
mca_set_adapter_procfn(slot, NULL, NULL);
mca_mark_as_used(slot);
-
+
/* Go on */
slot++;
}
-
+
}
#endif
/*
* Hunt for ISA Plug'n'Pray Adaptecs (AHA1535)
*/
-
+
if(isapnp)
{
struct pnp_dev *pdev = NULL;
- for(indx = 0; indx <sizeof(bases)/sizeof(bases[0]);indx++)
- {
+ for(indx = 0; indx < ARRAY_SIZE(bases); indx++) {
if(bases[indx])
continue;
pdev = pnp_find_dev(NULL, ISAPNP_VENDOR('A', 'D', 'P'),
/*
* Activate the PnP card
*/
-
+
if(pnp_device_attach(pdev)<0)
continue;
-
+
if(pnp_activate_dev(pdev)<0) {
pnp_device_detach(pdev);
continue;
}
-
+
if(!pnp_port_valid(pdev, 0)) {
pnp_device_detach(pdev);
continue;
}
-
+
bases[indx] = pnp_port_start(pdev, 0);
-
+
/* The card can be queried for its DMA, we have
the DMA set up that is enough */
-
+
printk(KERN_INFO "ISAPnP found an AHA1535 at I/O 0x%03X\n", bases[indx]);
}
}
- for (indx = 0; indx < sizeof(bases) / sizeof(bases[0]); indx++)
+ for (indx = 0; indx < ARRAY_SIZE(bases); indx++)
if (bases[indx] != 0 && request_region(bases[indx], 4, "aha1542")) {
shpnt = scsi_register(tpnt,
sizeof(struct aha1542_hostdata));
*/
aha1542_out(SCpnt->device->host->io_port, &ahacmd, 1);
- printk(KERN_WARNING "aha1542.c: Trying device reset for target %d\n", SCpnt->device->id);
+ scmd_printk(KERN_WARNING, SCpnt,
+ "Trying device reset for target\n");
return SUCCESS;
HOSTDATA(SCpnt->host)->SCint[i]->target == SCpnt->target) {
Scsi_Cmnd *SCtmp;
SCtmp = HOSTDATA(SCpnt->host)->SCint[i];
- if (SCtmp->host_scribble) {
- kfree(SCtmp->host_scribble);
- SCtmp->host_scribble = NULL;
- }
+ kfree(SCtmp->host_scribble);
+ SCtmp->host_scribble = NULL;
HOSTDATA(SCpnt->host)->SCint[i] = NULL;
HOSTDATA(SCpnt->host)->mb[i].status = 0;
}
* check for timeout, and if we are doing something like this
* we are pretty desperate anyways.
*/
- spin_unlock_irq(SCpnt->device->host->host_lock);
ssleep(4);
+
spin_lock_irq(SCpnt->device->host->host_lock);
WAIT(STATUS(SCpnt->device->host->io_port),
*/
continue;
}
- if (SCtmp->host_scribble) {
- kfree(SCtmp->host_scribble);
- SCtmp->host_scribble = NULL;
- }
+ kfree(SCtmp->host_scribble);
+ SCtmp->host_scribble = NULL;
HOSTDATA(SCpnt->device->host)->SCint[i] = NULL;
HOSTDATA(SCpnt->device->host)->mb[i].status = 0;
}
}
+ spin_unlock_irq(SCpnt->device->host->host_lock);
return SUCCESS;
fail:
+ spin_unlock_irq(SCpnt->device->host->host_lock);
return FAILED;
}
* check for timeout, and if we are doing something like this
* we are pretty desperate anyways.
*/
- spin_unlock_irq(SCpnt->device->host->host_lock);
ssleep(4);
spin_lock_irq(SCpnt->device->host->host_lock);
*/
continue;
}
- if (SCtmp->host_scribble) {
- kfree(SCtmp->host_scribble);
- SCtmp->host_scribble = NULL;
- }
+ kfree(SCtmp->host_scribble);
+ SCtmp->host_scribble = NULL;
HOSTDATA(SCpnt->device->host)->SCint[i] = NULL;
HOSTDATA(SCpnt->device->host)->mb[i].status = 0;
}
}
+ spin_unlock_irq(SCpnt->device->host->host_lock);
return SUCCESS;
fail:
+ spin_unlock_irq(SCpnt->device->host->host_lock);
return FAILED;
}
Scsi_Cmnd *SCtmp;
SCtmp = HOSTDATA(SCpnt->host)->SCint[i];
SCtmp->result = DID_RESET << 16;
- if (SCtmp->host_scribble) {
- kfree(SCtmp->host_scribble);
- SCtmp->host_scribble = NULL;
- }
+ kfree(SCtmp->host_scribble);
+ SCtmp->host_scribble = NULL;
printk(KERN_WARNING "Sending DID_RESET for target %d\n", SCpnt->target);
SCtmp->scsi_done(SCpnt);
Scsi_Cmnd *SCtmp;
SCtmp = HOSTDATA(SCpnt->host)->SCint[i];
SCtmp->result = DID_RESET << 16;
- if (SCtmp->host_scribble) {
- kfree(SCtmp->host_scribble);
- SCtmp->host_scribble = NULL;
- }
+ kfree(SCtmp->host_scribble);
+ SCtmp->host_scribble = NULL;
printk(KERN_WARNING "Sending DID_RESET for target %d\n", SCpnt->target);
SCtmp->scsi_done(SCpnt);
MODULE_LICENSE("GPL");
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.proc_name = "aha1542",
.name = "Adaptec 1542",
.detect = aha1542_detect,