diff options
Diffstat (limited to 'drivers/scsi/atp870u.c')
| -rw-r--r-- | drivers/scsi/atp870u.c | 179 |
1 files changed, 48 insertions, 131 deletions
diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 0ec41f34f46..a795d81ef87 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1,8 +1,8 @@ /* * Copyright (C) 1997 Wu Ching Chen * 2.1.x update (C) 1998 Krzysztof G. Baranowski - * 2.5.x update (C) 2002 Red Hat <alan@redhat.com> - * 2.6.x update (C) 2004 Red Hat <alan@redhat.com> + * 2.5.x update (C) 2002 Red Hat + * 2.6.x update (C) 2004 Red Hat * * Marcelo Tosatti <marcelo@conectiva.com.br> : SMP fixes * @@ -29,7 +29,7 @@ #include <linux/pci.h> #include <linux/blkdev.h> #include <linux/dma-mapping.h> -#include <asm/system.h> +#include <linux/slab.h> #include <asm/io.h> #include <scsi/scsi.h> @@ -44,7 +44,7 @@ static void send_s870(struct atp_unit *dev,unsigned char c); static void is885(struct atp_unit *dev, unsigned int wkport,unsigned char c); static void tscam_885(void); -static irqreturn_t atp870u_intr_handle(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) { unsigned long flags; unsigned short int tmpcip, id; @@ -471,18 +471,8 @@ go_42: /* * Complete the command */ - if (workreq->use_sg) { - pci_unmap_sg(dev->pdev, - (struct scatterlist *)workreq->request_buffer, - workreq->use_sg, - workreq->sc_data_direction); - } else if (workreq->request_bufflen && - workreq->sc_data_direction != DMA_NONE) { - pci_unmap_single(dev->pdev, - workreq->SCp.dma_handle, - workreq->request_bufflen, - workreq->sc_data_direction); - } + scsi_dma_unmap(workreq); + spin_lock_irqsave(dev->host->host_lock, flags); (*workreq->scsi_done) (workreq); #ifdef ED_DBGP @@ -614,7 +604,7 @@ handled: * * Queue a command to the ATP queue. Called with the host lock held. */ -static int atp870u_queuecommand(struct scsi_cmnd * req_p, +static int atp870u_queuecommand_lck(struct scsi_cmnd *req_p, void (*done) (struct scsi_cmnd *)) { unsigned char c; @@ -624,7 +614,7 @@ static int atp870u_queuecommand(struct scsi_cmnd * req_p, c = scmd_channel(req_p); req_p->sense_buffer[0]=0; - req_p->resid = 0; + scsi_set_resid(req_p, 0); if (scmd_channel(req_p) > 1) { req_p->result = 0x00040000; done(req_p); @@ -703,6 +693,8 @@ static int atp870u_queuecommand(struct scsi_cmnd * req_p, return 0; } +static DEF_SCSI_QCMD(atp870u_queuecommand) + /** * send_s870 - send a command to the controller * @host: host @@ -722,7 +714,6 @@ static void send_s870(struct atp_unit *dev,unsigned char c) unsigned short int tmpcip, w; unsigned long l, bttl = 0; unsigned int workport; - struct scatterlist *sgpnt; unsigned long sg_count; if (dev->in_snd[c] != 0) { @@ -758,7 +749,7 @@ static void send_s870(struct atp_unit *dev,unsigned char c) dev->quhd[c] = 0; } workreq = dev->quereq[c][dev->quhd[c]]; - if (dev->id[c][scmd_id(workreq)].curr_req == 0) { + if (dev->id[c][scmd_id(workreq)].curr_req == NULL) { dev->id[c][scmd_id(workreq)].curr_req = workreq; dev->last_cmd[c] = scmd_id(workreq); goto cmd_subp; @@ -793,6 +784,8 @@ oktosend: } printk("\n"); #endif + l = scsi_bufflen(workreq); + if (dev->dev_id == ATP885_DEVID) { j = inb(dev->baseport + 0x29) & 0xfe; outb(j, dev->baseport + 0x29); @@ -800,12 +793,11 @@ oktosend: } if (workreq->cmnd[0] == READ_CAPACITY) { - if (workreq->request_bufflen > 8) { - workreq->request_bufflen = 0x08; - } + if (l > 8) + l = 8; } if (workreq->cmnd[0] == 0x00) { - workreq->request_bufflen = 0; + l = 0; } tmport = workport + 0x1b; @@ -852,40 +844,8 @@ oktosend: #ifdef ED_DBGP printk("dev->id[%d][%d].devsp = %2x\n",c,target_id,dev->id[c][target_id].devsp); #endif - /* - * Figure out the transfer size - */ - if (workreq->use_sg) { -#ifdef ED_DBGP - printk("Using SGL\n"); -#endif - l = 0; - - sgpnt = (struct scatterlist *) workreq->request_buffer; - sg_count = pci_map_sg(dev->pdev, sgpnt, workreq->use_sg, - workreq->sc_data_direction); - - for (i = 0; i < workreq->use_sg; i++) { - if (sgpnt[i].length == 0 || workreq->use_sg > ATP870U_SCATTER) { - panic("Foooooooood fight!"); - } - l += sgpnt[i].length; - } -#ifdef ED_DBGP - printk( "send_s870: workreq->use_sg %d, sg_count %d l %8ld\n", workreq->use_sg, sg_count, l); -#endif - } else if(workreq->request_bufflen && workreq->sc_data_direction != PCI_DMA_NONE) { -#ifdef ED_DBGP - printk("Not using SGL\n"); -#endif - workreq->SCp.dma_handle = pci_map_single(dev->pdev, workreq->request_buffer, - workreq->request_bufflen, - workreq->sc_data_direction); - l = workreq->request_bufflen; -#ifdef ED_DBGP - printk( "send_s870: workreq->use_sg %d, l %8ld\n", workreq->use_sg, l); -#endif - } else l = 0; + + sg_count = scsi_dma_map(workreq); /* * Write transfer size */ @@ -938,16 +898,16 @@ oktosend: * a linear chain. */ - if (workreq->use_sg) { - sgpnt = (struct scatterlist *) workreq->request_buffer; + if (l) { + struct scatterlist *sgpnt; i = 0; - for (j = 0; j < workreq->use_sg; j++) { - bttl = sg_dma_address(&sgpnt[j]); - l=sg_dma_len(&sgpnt[j]); + scsi_for_each_sg(workreq, sgpnt, sg_count, j) { + bttl = sg_dma_address(sgpnt); + l=sg_dma_len(sgpnt); #ifdef ED_DBGP - printk("1. bttl %x, l %x\n",bttl, l); + printk("1. bttl %x, l %x\n",bttl, l); #endif - while (l > 0x10000) { + while (l > 0x10000) { (((u16 *) (prd))[i + 3]) = 0x0000; (((u16 *) (prd))[i + 2]) = 0x0000; (((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl); @@ -965,32 +925,6 @@ oktosend: printk("prd %4x %4x %4x %4x\n",(((unsigned short int *)prd)[0]),(((unsigned short int *)prd)[1]),(((unsigned short int *)prd)[2]),(((unsigned short int *)prd)[3])); printk("2. bttl %x, l %x\n",bttl, l); #endif - } else { - /* - * For a linear request write a chain of blocks - */ - bttl = workreq->SCp.dma_handle; - l = workreq->request_bufflen; - i = 0; -#ifdef ED_DBGP - printk("3. bttl %x, l %x\n",bttl, l); -#endif - while (l > 0x10000) { - (((u16 *) (prd))[i + 3]) = 0x0000; - (((u16 *) (prd))[i + 2]) = 0x0000; - (((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl); - l -= 0x10000; - bttl += 0x10000; - i += 0x04; - } - (((u16 *) (prd))[i + 3]) = cpu_to_le16(0x8000); - (((u16 *) (prd))[i + 2]) = cpu_to_le16(l); - (((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl); -#ifdef ED_DBGP - printk("prd %4x %4x %4x %4x\n",(((unsigned short int *)prd)[0]),(((unsigned short int *)prd)[1]),(((unsigned short int *)prd)[2]),(((unsigned short int *)prd)[3])); - printk("4. bttl %x, l %x\n",bttl, l); -#endif - } tmpcip += 4; #ifdef ED_DBGP @@ -1239,7 +1173,16 @@ wait_io1: outw(val, tmport); outb(2, 0x80); TCM_SYNC: - udelay(0x800); + /* + * The funny division into multiple delays is to accomodate + * arches like ARM where udelay() multiplies its argument by + * a large number to initialize a loop counter. To avoid + * overflow, the maximum supported udelay is 2000 microseconds. + * + * XXX it would be more polite to find a way to use msleep() + */ + mdelay(2); + udelay(48); if ((inb(tmport) & 0x80) == 0x00) { /* bsy ? */ outw(0, tmport--); outb(0, tmport); @@ -1293,7 +1236,7 @@ TCM_5: /* isolation complete.. */ printk(" \n%x %x %x %s\n ",assignid_map,mbuf[0],mbuf[1],&mbuf[2]); */ i = 15; j = mbuf[0]; - if ((j & 0x20) != 0) { /* bit5=1:ID upto 7 */ + if ((j & 0x20) != 0) { /* bit5=1:ID up to 7 */ i = 7; } if ((j & 0x06) == 0) { /* IDvalid? */ @@ -2636,7 +2579,7 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (pci_enable_device(pdev)) goto err_eio; - if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { + if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { printk(KERN_INFO "atp870u: use 32bit DMA mask.\n"); } else { printk(KERN_ERR "atp870u: DMA mask required but not available.\n"); @@ -2648,7 +2591,7 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) * this than via the PCI device table */ if (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610) { - error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atpdev->chip_ver); + atpdev->chip_ver = pdev->revision; if (atpdev->chip_ver < 2) goto err_eio; } @@ -2667,7 +2610,7 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) base_io &= 0xfffffff8; if ((ent->device == ATP880_DEVID1)||(ent->device == ATP880_DEVID2)) { - error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atpdev->chip_ver); + atpdev->chip_ver = pdev->revision; pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);//JCC082803 host_id = inb(base_io + 0x39); @@ -3156,38 +3099,14 @@ static const char *atp870u_info(struct Scsi_Host *notused) return buffer; } -#define BLS buffer + len + size -static int atp870u_proc_info(struct Scsi_Host *HBAptr, char *buffer, - char **start, off_t offset, int length, int inout) +static int atp870u_show_info(struct seq_file *m, struct Scsi_Host *HBAptr) { - static u8 buff[512]; - int size = 0; - int len = 0; - off_t begin = 0; - off_t pos = 0; - - if (inout) - return -EINVAL; - if (offset == 0) - memset(buff, 0, sizeof(buff)); - size += sprintf(BLS, "ACARD AEC-671X Driver Version: 2.6+ac\n"); - len += size; - pos = begin + len; - size = 0; - - size += sprintf(BLS, "\n"); - size += sprintf(BLS, "Adapter Configuration:\n"); - size += sprintf(BLS, " Base IO: %#.4lx\n", HBAptr->io_port); - size += sprintf(BLS, " IRQ: %d\n", HBAptr->irq); - len += size; - pos = begin + len; - - *start = buffer + (offset - begin); /* Start of wanted data */ - len -= (offset - begin); /* Start slop */ - if (len > length) { - len = length; /* Ending slop */ - } - return (len); + seq_printf(m, "ACARD AEC-671X Driver Version: 2.6+ac\n"); + seq_printf(m, "\n"); + seq_printf(m, "Adapter Configuration:\n"); + seq_printf(m, " Base IO: %#.4lx\n", HBAptr->io_port); + seq_printf(m, " IRQ: %d\n", HBAptr->irq); + return 0; } @@ -3225,8 +3144,6 @@ static void atp870u_remove (struct pci_dev *pdev) atp870u_free_tables(pshost); printk(KERN_INFO "scsi_host_put : %p\n",pshost); scsi_host_put(pshost); - printk(KERN_INFO "pci_set_drvdata : %p\n",pdev); - pci_set_drvdata(pdev, NULL); } MODULE_LICENSE("GPL"); @@ -3234,7 +3151,7 @@ static struct scsi_host_template atp870u_template = { .module = THIS_MODULE, .name = "atp870u" /* name */, .proc_name = "atp870u", - .proc_info = atp870u_proc_info, + .show_info = atp870u_show_info, .info = atp870u_info /* info */, .queuecommand = atp870u_queuecommand /* queuecommand */, .eh_abort_handler = atp870u_abort /* abort */, @@ -3267,7 +3184,7 @@ static struct pci_driver atp870u_driver = { .id_table = atp870u_id_table, .name = "atp870u", .probe = atp870u_probe, - .remove = __devexit_p(atp870u_remove), + .remove = atp870u_remove, }; static int __init atp870u_init(void) |
