aboutsummaryrefslogtreecommitdiff
path: root/drivers/scsi/atp870u.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/atp870u.c')
-rw-r--r--drivers/scsi/atp870u.c179
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)