X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fscsi%2Fqlogicfas408.c;h=de7b3bc2cbc975ecbbd12658ea95b8d9e00714f5;hb=65fecc77f3c47c5e8758d133b8ec47dcc16ed207;hp=575f8a8fcf34a4540816aa152d4a298506c2685a;hpb=3471c288036bf0835a82d0b1bbce2002f6e68390;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/scsi/qlogicfas408.c b/drivers/scsi/qlogicfas408.c index 575f8a8..de7b3bc 100644 --- a/drivers/scsi/qlogicfas408.c +++ b/drivers/scsi/qlogicfas408.c @@ -209,7 +209,7 @@ static int ql_wai(struct qlogicfas408_priv *priv) * caller must hold host lock */ -static void ql_icmd(Scsi_Cmnd * cmd) +static void ql_icmd(struct scsi_cmnd *cmd) { struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); int qbase = priv->qbase; @@ -243,7 +243,7 @@ static void ql_icmd(Scsi_Cmnd * cmd) /**/ outb(qlcfg5, qbase + 5); /* select timer */ outb(qlcfg9 & 7, qbase + 9); /* prescaler */ /* outb(0x99, qbase + 5); */ - outb(cmd->device->id, qbase + 4); + outb(scmd_id(cmd), qbase + 4); for (i = 0; i < cmd->cmd_len; i++) outb(cmd->cmnd[i], qbase + 2); @@ -256,7 +256,7 @@ static void ql_icmd(Scsi_Cmnd * cmd) * Process scsi command - usually after interrupt */ -static unsigned int ql_pcmd(Scsi_Cmnd * cmd) +static unsigned int ql_pcmd(struct scsi_cmnd *cmd) { unsigned int i, j; unsigned long k; @@ -265,8 +265,6 @@ static unsigned int ql_pcmd(Scsi_Cmnd * cmd) unsigned int message; /* scsi returned message */ unsigned int phase; /* recorded scsi phase */ unsigned int reqlen; /* total length of transfer */ - struct scatterlist *sglist; /* scatter-gather list pointer */ - unsigned int sgcount; /* sg counter */ char *buf; struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); int qbase = priv->qbase; @@ -301,9 +299,10 @@ static unsigned int ql_pcmd(Scsi_Cmnd * cmd) if (inb(qbase + 7) & 0x1f) /* if some bytes in fifo */ outb(1, qbase + 3); /* clear fifo */ /* note that request_bufflen is the total xfer size when sg is used */ - reqlen = cmd->request_bufflen; + reqlen = scsi_bufflen(cmd); /* note that it won't work if transfers > 16M are requested */ if (reqlen && !((phase = inb(qbase + 4)) & 6)) { /* data phase */ + struct scatterlist *sg; rtrc(2) outb(reqlen, qbase); /* low-mid xfer cnt */ outb(reqlen >> 8, qbase + 1); /* low-mid xfer cnt */ @@ -311,23 +310,16 @@ static unsigned int ql_pcmd(Scsi_Cmnd * cmd) outb(0x90, qbase + 3); /* command do xfer */ /* PIO pseudo DMA to buffer or sglist */ REG1; - if (!cmd->use_sg) - ql_pdma(priv, phase, cmd->request_buffer, - cmd->request_bufflen); - else { - sgcount = cmd->use_sg; - sglist = cmd->request_buffer; - while (sgcount--) { - if (priv->qabort) { - REG0; - return ((priv->qabort == 1 ? - DID_ABORT : DID_RESET) << 16); - } - buf = page_address(sglist->page) + sglist->offset; - if (ql_pdma(priv, phase, buf, sglist->length)) - break; - sglist++; + + scsi_for_each_sg(cmd, sg, scsi_sg_count(cmd), i) { + if (priv->qabort) { + REG0; + return ((priv->qabort == 1 ? + DID_ABORT : DID_RESET) << 16); } + buf = sg_virt(sg); + if (ql_pdma(priv, phase, buf, sg->length)) + break; } REG0; rtrc(2) @@ -405,10 +397,10 @@ static unsigned int ql_pcmd(Scsi_Cmnd * cmd) * Interrupt handler */ -static void ql_ihandl(int irq, void *dev_id, struct pt_regs *regs) +static void ql_ihandl(void *dev_id) { - Scsi_Cmnd *icmd; - struct Scsi_Host *host = (struct Scsi_Host *)dev_id; + struct scsi_cmnd *icmd; + struct Scsi_Host *host = dev_id; struct qlogicfas408_priv *priv = get_priv_by_host(host); int qbase = priv->qbase; REG0; @@ -432,13 +424,13 @@ static void ql_ihandl(int irq, void *dev_id, struct pt_regs *regs) (icmd->scsi_done) (icmd); } -irqreturn_t qlogicfas408_ihandl(int irq, void *dev_id, struct pt_regs *regs) +irqreturn_t qlogicfas408_ihandl(int irq, void *dev_id) { unsigned long flags; struct Scsi_Host *host = dev_id; spin_lock_irqsave(host->host_lock, flags); - ql_ihandl(irq, dev_id, regs); + ql_ihandl(dev_id); spin_unlock_irqrestore(host->host_lock, flags); return IRQ_HANDLED; } @@ -447,10 +439,11 @@ irqreturn_t qlogicfas408_ihandl(int irq, void *dev_id, struct pt_regs *regs) * Queued command */ -int qlogicfas408_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) +int qlogicfas408_queuecommand(struct scsi_cmnd *cmd, + void (*done) (struct scsi_cmnd *)) { struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); - if (cmd->device->id == priv->qinitid) { + if (scmd_id(cmd) == priv->qinitid) { cmd->result = DID_BAD_TARGET << 16; done(cmd); return 0; @@ -470,9 +463,8 @@ int qlogicfas408_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) * Return bios parameters */ -int qlogicfas408_biosparam(struct scsi_device * disk, - struct block_device *dev, - sector_t capacity, int ip[]) +int qlogicfas408_biosparam(struct scsi_device *disk, struct block_device *dev, + sector_t capacity, int ip[]) { /* This should mimic the DOS Qlogic driver's behavior exactly */ ip[0] = 0x40; @@ -494,7 +486,7 @@ int qlogicfas408_biosparam(struct scsi_device * disk, * Abort a command in progress */ -int qlogicfas408_abort(Scsi_Cmnd * cmd) +int qlogicfas408_abort(struct scsi_cmnd *cmd) { struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); priv->qabort = 1; @@ -508,11 +500,17 @@ int qlogicfas408_abort(Scsi_Cmnd * cmd) * the PCMCIA qlogic_stub code. This wants fixing */ -int qlogicfas408_bus_reset(Scsi_Cmnd * cmd) +int qlogicfas408_bus_reset(struct scsi_cmnd *cmd) { struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); + unsigned long flags; + priv->qabort = 2; + + spin_lock_irqsave(cmd->device->host->host_lock, flags); ql_zap(priv); + spin_unlock_irqrestore(cmd->device->host->host_lock, flags); + return SUCCESS; }