X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fscsi%2Fatp870u.c;h=27136a20add95adf26e88de0ae673b0c04d9a93c;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=5737a9d1f0eef48c48ae540824bb456dfd34a193;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 5737a9d1f..27136a20a 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1,9 +1,8 @@ -/* $Id: atp870u.c,v 1.0 1997/05/07 15:22:00 root Exp root $ - * linux/kernel/atp870u.c - * +/* * Copyright (C) 1997 Wu Ching Chen * 2.1.x update (C) 1998 Krzysztof G. Baranowski * 2.5.x update (C) 2002 Red Hat + * 2.6.x update (C) 2004 Red Hat * * Marcelo Tosatti : SMP fixes * @@ -28,20 +27,19 @@ #include #include #include -#include - #include #include -#include "scsi.h" -#include "hosts.h" +#include +#include +#include +#include + #include "atp870u.h" -/* - * static const char RCSid[] = "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/atp870u.c,v 1.0 1997/05/07 15:22:00 root Exp root $"; - */ +static struct scsi_host_template atp870u_template; +static void send_s870(struct Scsi_Host *host); -static unsigned short int sync_idu; static irqreturn_t atp870u_intr_handle(int irq, void *dev_id, struct pt_regs *regs) @@ -50,7 +48,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id, unsigned short int tmpcip, id; unsigned char i, j, target_id, lun; unsigned char *prd; - Scsi_Cmnd *workrequ; + struct scsi_cmnd *workrequ; unsigned int workportu, tmport; unsigned long adrcntu, k; int errstus; @@ -126,9 +124,11 @@ stop_dma: /* * Issue more commands */ + spin_lock_irqsave(dev->host->host_lock, flags); if (((dev->quhdu != dev->quendu) || (dev->last_cmd != 0xff)) && (dev->in_snd == 0)) { send_s870(host); } + spin_unlock_irqrestore(dev->host->host_lock, flags); /* * Done */ @@ -345,17 +345,25 @@ go_42: * Complete the command */ - if(workrequ->use_sg) - pci_unmap_sg(dev->pdev, (struct scatterlist *)workrequ->buffer, workrequ->use_sg, scsi_to_pci_dma_dir(workrequ->sc_data_direction)); - else if(workrequ->request_bufflen && workrequ->sc_data_direction != SCSI_DATA_NONE) - pci_unmap_single(dev->pdev, workrequ->SCp.dma_handle, workrequ->request_bufflen, scsi_to_pci_dma_dir(workrequ->sc_data_direction)); + if (workrequ->use_sg) { + pci_unmap_sg(dev->pdev, + (struct scatterlist *)workrequ->buffer, + workrequ->use_sg, + workrequ->sc_data_direction); + } else if (workrequ->request_bufflen && + workrequ->sc_data_direction != DMA_NONE) { + pci_unmap_single(dev->pdev, + workrequ->SCp.dma_handle, + workrequ->request_bufflen, + workrequ->sc_data_direction); + } spin_lock_irqsave(dev->host->host_lock, flags); (*workrequ->scsi_done) (workrequ); /* * Clear it off the queue */ - dev->id[target_id].curr_req = 0; + dev->id[target_id].curr_req = NULL; dev->working--; spin_unlock_irqrestore(dev->host->host_lock, flags); /* @@ -371,9 +379,11 @@ go_42: /* * If there is stuff to send and nothing going then send it */ + spin_lock_irqsave(dev->host->host_lock, flags); if (((dev->last_cmd != 0xff) || (dev->quhdu != dev->quendu)) && (dev->in_snd == 0)) { send_s870(host); } + spin_unlock_irqrestore(dev->host->host_lock, flags); dev->in_int = 0; goto out; } @@ -443,9 +453,17 @@ out: return IRQ_HANDLED; } -static int atp870u_queuecommand(Scsi_Cmnd * req_p, void (*done) (Scsi_Cmnd *)) +/** + * atp870u_queuecommand - Queue SCSI command + * @req_p: request block + * @done: completion function + * + * Queue a command to the ATP queue. Called with the host lock held. + */ + +static int atp870u_queuecommand(struct scsi_cmnd *req_p, + void (*done) (struct scsi_cmnd *)) { - unsigned long flags; unsigned short int m; unsigned int tmport; struct Scsi_Host *host; @@ -484,7 +502,6 @@ static int atp870u_queuecommand(Scsi_Cmnd * req_p, void (*done) (Scsi_Cmnd *)) * Count new command */ - spin_lock_irqsave(host->host_lock, flags); dev->quendu++; if (dev->quendu >= qcnt) { dev->quendu = 0; @@ -498,24 +515,31 @@ static int atp870u_queuecommand(Scsi_Cmnd * req_p, void (*done) (Scsi_Cmnd *)) } dev->quendu--; req_p->result = 0x00020000; - spin_unlock_irqrestore(host->host_lock, flags); done(req_p); return 0; } dev->querequ[dev->quendu] = req_p; tmport = dev->ioport + 0x1c; - spin_unlock_irqrestore(host->host_lock, flags); if ((inb(tmport) == 0) && (dev->in_int == 0) && (dev->in_snd == 0)) { send_s870(host); } return 0; } +/** + * send_s870 - send a command to the controller + * @host: host + * + * On entry there is work queued to be done. We move some of that work to the + * controller itself. + * + * Caller holds the host lock. + */ + static void send_s870(struct Scsi_Host *host) { unsigned int tmport; - Scsi_Cmnd *workrequ; - unsigned long flags; + struct scsi_cmnd *workrequ; unsigned int i; unsigned char j, target_id; unsigned char *prd; @@ -527,10 +551,7 @@ static void send_s870(struct Scsi_Host *host) struct atp_unit *dev = (struct atp_unit *)&host->hostdata; int sg_count; - spin_lock_irqsave(host->host_lock, flags); - if (dev->in_snd != 0) { - spin_unlock_irqrestore(host->host_lock, flags); return; } dev->in_snd = 1; @@ -543,13 +564,11 @@ static void send_s870(struct Scsi_Host *host) dev->last_cmd = 0xff; if (dev->quhdu == dev->quendu) { dev->in_snd = 0; - spin_unlock_irqrestore(dev->host->host_lock, flags); return; } } if ((dev->last_cmd != 0xff) && (dev->working != 0)) { dev->in_snd = 0; - spin_unlock_irqrestore(dev->host->host_lock, flags); return; } dev->working++; @@ -567,7 +586,6 @@ static void send_s870(struct Scsi_Host *host) dev->quhdu = j; dev->working--; dev->in_snd = 0; - spin_unlock_irqrestore(host->host_lock, flags); return; cmd_subp: workportu = dev->ioport; @@ -582,7 +600,6 @@ cmd_subp: abortsnd: dev->last_cmd |= 0x40; dev->in_snd = 0; - spin_unlock_irqrestore(dev->host->host_lock, flags); return; oktosend: memcpy(&dev->ata_cdbu[0], &workrequ->cmnd[0], workrequ->cmd_len); @@ -637,7 +654,8 @@ oktosend: if (workrequ->use_sg) { l = 0; sgpnt = (struct scatterlist *) workrequ->request_buffer; - sg_count = pci_map_sg(dev->pdev, sgpnt, workrequ->use_sg, scsi_to_pci_dma_dir(workrequ->sc_data_direction)); + sg_count = pci_map_sg(dev->pdev, sgpnt, workrequ->use_sg, + workrequ->sc_data_direction); for (i = 0; i < workrequ->use_sg; i++) { if (sgpnt[i].length == 0 || workrequ->use_sg > ATP870U_SCATTER) { panic("Foooooooood fight!"); @@ -645,7 +663,10 @@ oktosend: l += sgpnt[i].length; } } else if(workrequ->request_bufflen && workrequ->sc_data_direction != PCI_DMA_NONE) { - workrequ->SCp.dma_handle = pci_map_single(dev->pdev, workrequ->request_buffer, workrequ->request_bufflen, scsi_to_pci_dma_dir(workrequ->sc_data_direction)); + workrequ->SCp.dma_handle = pci_map_single(dev->pdev, + workrequ->request_buffer, + workrequ->request_bufflen, + workrequ->sc_data_direction); l = workrequ->request_bufflen; } else l = 0; @@ -667,7 +688,7 @@ oktosend: /* * Check transfer direction */ - if (workrequ->sc_data_direction == SCSI_DATA_WRITE) { + if (workrequ->sc_data_direction == DMA_TO_DEVICE) { outb((unsigned char) (j | 0x20), tmport++); } else { outb(j, tmport++); @@ -684,7 +705,6 @@ oktosend: dev->last_cmd |= 0x40; } dev->in_snd = 0; - spin_unlock_irqrestore(host->host_lock, flags); return; } tmpcip = dev->pciport; @@ -760,7 +780,7 @@ oktosend: } tmport = workportu + 0x1c; - if (workrequ->sc_data_direction == SCSI_DATA_WRITE) { + if (workrequ->sc_data_direction == DMA_TO_DEVICE) { dev->id[target_id].dirctu = 0x20; if (inb(tmport) == 0) { tmport = workportu + 0x18; @@ -770,7 +790,6 @@ oktosend: dev->last_cmd |= 0x40; } dev->in_snd = 0; - spin_unlock_irqrestore(host->host_lock, flags); return; } if (inb(tmport) == 0) { @@ -781,9 +800,6 @@ oktosend: dev->last_cmd |= 0x40; } dev->in_snd = 0; - spin_unlock_irqrestore(host->host_lock, flags); - return; - } static unsigned char fun_scam(struct atp_unit *dev, unsigned short int *val) @@ -1069,7 +1085,7 @@ G2Q_QUIN: /* k=binID#, */ } -void is870(struct Scsi_Host *host, unsigned int wkport) +static void is870(struct Scsi_Host *host, unsigned int wkport) { unsigned int tmport; unsigned char i, j, k, rmb, n; @@ -1083,7 +1099,6 @@ void is870(struct Scsi_Host *host, unsigned int wkport) static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 }; struct atp_unit *dev = (struct atp_unit *)&host->hostdata; - sync_idu = 0; tmport = wkport + 0x3a; outb((unsigned char) (inb(tmport) | 0x10), tmport); @@ -1577,7 +1592,6 @@ static void is880(struct Scsi_Host *host, unsigned int wkport) static unsigned char u3[9] = { 0x80, 1, 6, 4, 0x09, 00, 0x0e, 0x01, 0x02 }; struct atp_unit *dev = (struct atp_unit *)&host->hostdata; - sync_idu = 0; lvdmode = inb(wkport + 0x3f) & 0x40; for (i = 0; i < 16; i++) { @@ -2249,14 +2263,14 @@ static int atp870u_init_tables(struct Scsi_Host *host) dev->in_snd = 0; dev->in_int = 0; for (k = 0; k < qcnt; k++) { - dev->querequ[k] = 0; + dev->querequ[k] = NULL; } for (k = 0; k < 16; k++) { - dev->id[k].curr_req = 0; + dev->id[k].curr_req = NULL; dev->sp[k] = 0x04; } return 0; -} +} /* return non-zero on detection */ static int atp870u_probe(struct pci_dev *dev, const struct pci_device_id *ent) @@ -2549,10 +2563,10 @@ unregister: it is available to be used again. Until this gets worked out, we will leave it commented out. */ -int atp870u_abort(Scsi_Cmnd * SCpnt) +static int atp870u_abort(struct scsi_cmnd * SCpnt) { unsigned char j, k; - Scsi_Cmnd *workrequ; + struct scsi_cmnd *workrequ; unsigned int tmport; struct atp_unit *dev = (struct atp_unit *)&SCpnt->device->host->hostdata; @@ -2588,7 +2602,7 @@ int atp870u_abort(Scsi_Cmnd * SCpnt) return SUCCESS; } -const char *atp870u_info(struct Scsi_Host *notused) +static const char *atp870u_info(struct Scsi_Host *notused) { static char buffer[128]; @@ -2597,13 +2611,9 @@ const char *atp870u_info(struct Scsi_Host *notused) return buffer; } -int atp870u_set_info(char *buffer, int length, struct Scsi_Host *HBAptr) -{ - return -ENOSYS; /* Currently this is a no-op */ -} - #define BLS buffer + len + size -int atp870u_proc_info(struct Scsi_Host *HBAptr, char *buffer, char **start, off_t offset, int length, int inout) +static int atp870u_proc_info(struct Scsi_Host *HBAptr, char *buffer, + char **start, off_t offset, int length, int inout) { static u8 buff[512]; int size = 0; @@ -2611,9 +2621,8 @@ int atp870u_proc_info(struct Scsi_Host *HBAptr, char *buffer, char **start, off_ off_t begin = 0; off_t pos = 0; - if (inout == TRUE) { /* Has data been written to the file? */ - return (atp870u_set_info(buffer, length, HBAptr)); - } + if (inout) + return -ENOSYS; if (offset == 0) { memset(buff, 0, sizeof(buff)); } @@ -2673,7 +2682,7 @@ static void atp870u_remove(struct pci_dev *pdev) MODULE_LICENSE("GPL"); -static Scsi_Host_Template atp870u_template = { +static struct scsi_host_template atp870u_template = { .module = THIS_MODULE, .name = "atp870u", .proc_name = "atp870u", @@ -2712,8 +2721,7 @@ static struct pci_driver atp870u_driver = { static int __init atp870u_init(void) { - pci_register_driver(&atp870u_driver); - return 0; + return pci_module_init(&atp870u_driver); } static void __exit atp870u_exit(void)