-/* $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 <alan@redhat.com>
+ * 2.6.x update (C) 2004 Red Hat <alan@redhat.com>
*
* Marcelo Tosatti <marcelo@conectiva.com.br> : SMP fixes
*
#include <linux/spinlock.h>
#include <linux/pci.h>
#include <linux/blkdev.h>
-#include <linux/stat.h>
-
#include <asm/system.h>
#include <asm/io.h>
-#include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
+
#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)
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;
/*
* 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
*/
* 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);
/*
/*
* 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;
}
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;
* Count new command
*/
- spin_lock_irqsave(host->host_lock, flags);
dev->quendu++;
if (dev->quendu >= qcnt) {
dev->quendu = 0;
}
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;
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;
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++;
dev->quhdu = j;
dev->working--;
dev->in_snd = 0;
- spin_unlock_irqrestore(host->host_lock, flags);
return;
cmd_subp:
workportu = dev->ioport;
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);
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!");
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;
/*
* 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++);
dev->last_cmd |= 0x40;
}
dev->in_snd = 0;
- spin_unlock_irqrestore(host->host_lock, flags);
return;
}
tmpcip = dev->pciport;
}
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;
dev->last_cmd |= 0x40;
}
dev->in_snd = 0;
- spin_unlock_irqrestore(host->host_lock, flags);
return;
}
if (inb(tmport) == 0) {
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)
}
-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;
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);
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++) {
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)
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;
return SUCCESS;
}
-const char *atp870u_info(struct Scsi_Host *notused)
+static const char *atp870u_info(struct Scsi_Host *notused)
{
static char buffer[128];
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;
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));
}
MODULE_LICENSE("GPL");
-static Scsi_Host_Template atp870u_template = {
+static struct scsi_host_template atp870u_template = {
.module = THIS_MODULE,
.name = "atp870u",
.proc_name = "atp870u",
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)