Commit d567aa42 authored by James Bottomley's avatar James Bottomley

SCSI: atp870u update

From: 	Zwane Mwaikambo <zwane@arm.linux.org.uk>
parent 7f3999c8
...@@ -42,50 +42,6 @@ ...@@ -42,50 +42,6 @@
static unsigned short int sync_idu; static unsigned short int sync_idu;
#define MAX_ATP 16
struct atp_unit {
unsigned long ioport;
unsigned long irq;
unsigned long pciport;
unsigned char last_cmd;
unsigned char in_snd;
unsigned char in_int;
unsigned char quhdu;
unsigned char quendu;
unsigned char scam_on;
unsigned char global_map;
unsigned char chip_veru;
unsigned char host_idu;
int working;
unsigned short wide_idu;
unsigned short active_idu;
unsigned short ultra_map;
unsigned short async;
unsigned short deviceid;
unsigned char ata_cdbu[16];
unsigned char sp[16];
Scsi_Cmnd *querequ[qcnt];
struct atp_id {
unsigned char dirctu;
unsigned char devspu;
unsigned char devtypeu;
unsigned long prdaddru;
unsigned long tran_lenu;
unsigned long last_lenu;
unsigned char *prd_posu;
unsigned char *prd_tableu;
dma_addr_t prd_phys;
Scsi_Cmnd *curr_req;
} id[16];
struct Scsi_Host *host;
struct pci_dev *pdev;
};
static struct Scsi_Host *atp_host[MAX_ATP];
static void send_s870(struct Scsi_Host *);
static irqreturn_t atp870u_intr_handle(int irq, void *dev_id, static irqreturn_t atp870u_intr_handle(int irq, void *dev_id,
struct pt_regs *regs) struct pt_regs *regs)
{ {
...@@ -878,7 +834,7 @@ static void tscam(struct Scsi_Host *host) ...@@ -878,7 +834,7 @@ static void tscam(struct Scsi_Host *host)
unsigned long n; unsigned long n;
unsigned short int m, assignid_map, val; unsigned short int m, assignid_map, val;
unsigned char mbuf[33], quintet[2]; unsigned char mbuf[33], quintet[2];
struct atp_unit *dev = (struct atp_unit *)host->hostdata; struct atp_unit *dev = (struct atp_unit *)&host->hostdata;
static unsigned char g2q_tab[8] = { static unsigned char g2q_tab[8] = {
0x38, 0x31, 0x32, 0x2b, 0x34, 0x2d, 0x2e, 0x27 0x38, 0x31, 0x32, 0x2b, 0x34, 0x2d, 0x2e, 0x27
}; };
...@@ -2253,15 +2209,31 @@ static void is880(struct Scsi_Host *host, unsigned int wkport) ...@@ -2253,15 +2209,31 @@ static void is880(struct Scsi_Host *host, unsigned int wkport)
} }
} }
static void atp870u_free_tables(struct Scsi_Host *host)
static void atp870u_init_tables(struct Scsi_Host *host)
{ {
struct atp_unit *dev = (struct atp_unit *)&host->hostdata; struct atp_unit *atp_dev = (struct atp_unit *)&host->hostdata;
int k; int k;
for (k = 0; k < 16; k++) { for (k = 0; k < 16; k++) {
/* FIXME */ if (!atp_dev->id[k].prd_tableu)
continue;
pci_free_consistent(atp_dev->pdev, 1024, atp_dev->id[k].prd_tableu,
atp_dev->id[k].prd_phys);
atp_dev->id[k].prd_tableu = NULL;
}
}
static int atp870u_init_tables(struct Scsi_Host *host)
{
struct atp_unit *dev = (struct atp_unit *)&host->hostdata;
int k, i;
for (i = k = 0; k < 16; k++) {
dev->id[k].prd_tableu = pci_alloc_consistent(dev->pdev, 1024, &dev->id[k].prd_phys); dev->id[k].prd_tableu = pci_alloc_consistent(dev->pdev, 1024, &dev->id[k].prd_phys);
if (!dev->id[k].prd_tableu) {
atp870u_free_tables(host);
return -ENOMEM;
}
dev->id[k].devspu = 0x20; dev->id[k].devspu = 0x20;
dev->id[k].devtypeu = 0; dev->id[k].devtypeu = 0;
dev->id[k].curr_req = NULL; dev->id[k].curr_req = NULL;
...@@ -2282,293 +2254,294 @@ static void atp870u_init_tables(struct Scsi_Host *host) ...@@ -2282,293 +2254,294 @@ static void atp870u_init_tables(struct Scsi_Host *host)
dev->id[k].curr_req = 0; dev->id[k].curr_req = 0;
dev->sp[k] = 0x04; dev->sp[k] = 0x04;
} }
return 0;
} }
/* return non-zero on detection */ /* return non-zero on detection */
static int atp870u_detect(Scsi_Host_Template * tpnt) static int atp870u_probe(struct pci_dev *dev, const struct pci_device_id *ent)
{ {
unsigned char irq, h, k, m; unsigned char k, m;
unsigned long flags; unsigned long flags;
unsigned int base_io, error, tmport; unsigned int base_io, error, tmport;
struct pci_dev *pdev[MAX_ATP]; unsigned char host_id;
unsigned char chip_ver[MAX_ATP], host_id; unsigned short n;
unsigned short dev_id[MAX_ATP], n; struct Scsi_Host *shpnt;
struct Scsi_Host *shpnt = NULL; struct atp_unit atp_dev, *p;
int card = 0; static int count;
int count = 0;
if (pci_enable_device(dev))
static unsigned short devid[9] = { return -EIO;
0x8081, 0x8002, 0x8010, 0x8020, 0x8030, 0x8040, 0x8050, 0x8060, 0
}; if (pci_set_dma_mask(dev, 0xFFFFFFFFUL)) {
printk(KERN_ERR "atp870u: 32bit DMA mask required but not available.\n");
return -EIO;
}
memset(&atp_dev, 0, sizeof atp_dev);
/*
* It's probably easier to weed out some revisions like
* this than via the PCI device table
*/
if (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610) {
error = pci_read_config_byte(dev, PCI_CLASS_REVISION, &atp_dev.chip_veru);
if (atp_dev.chip_veru < 2)
return -EIO;
}
printk(KERN_INFO "aec671x_detect: \n"); switch (ent->device) {
tpnt->proc_name = "atp870u"; case 0x8081:
case PCI_DEVICE_ID_ARTOP_AEC7612UW:
case PCI_DEVICE_ID_ARTOP_AEC7612SUW:
atp_dev.chip_veru = 0x04;
default:
break;
}
for (h = 0; devid[h]; h++) { base_io = pci_resource_start(dev, 0);
struct pci_dev *dev = NULL;
while((dev = pci_find_device(0x1191, devid[h], dev))!=NULL)
{
if(pci_enable_device(dev))
continue;
if(pci_set_dma_mask(dev, 0xFFFFFFFFUL)) if (ent->device != 0x8081) {
{ error = pci_read_config_byte(dev, 0x49, &host_id);
printk(KERN_ERR "atp870u: 32bit DMA mask required but not available.\n"); base_io &= 0xfffffff8;
continue;
}
chip_ver[card] = 0;
dev_id[card] = devid[h];
if (devid[h] == 0x8002) { printk(KERN_INFO " ACARD AEC-671X PCI Ultra/W SCSI-3 Host Adapter: %d "
error = pci_read_config_byte(dev, 0x08, &chip_ver[card]); "IO:%x, IRQ:%d.\n", count, base_io, dev->irq);
if (chip_ver[card] < 2) {
continue; atp_dev.unit = count;
} atp_dev.ioport = base_io;
} atp_dev.pciport = base_io + 0x20;
if (devid[h] == 0x8010 || devid[h] == 0x8081 || devid[h] == 0x8050) { atp_dev.deviceid = ent->device;
chip_ver[card] = 0x04; host_id &= 0x07;
} atp_dev.host_idu = host_id;
pdev[card] = dev; tmport = base_io + 0x22;
card++; atp_dev.scam_on = inb(tmport);
if (card == MAX_ATP) tmport += 0x0b;
break; atp_dev.global_map = inb(tmport++);
atp_dev.ultra_map = inw(tmport);
if (atp_dev.ultra_map == 0) {
atp_dev.scam_on = 0x00;
atp_dev.global_map = 0x20;
atp_dev.ultra_map = 0xffff;
} }
}
for (h = 0; h < card; h++) {
struct atp_unit tmp, *dev;
/* Found an atp870u/w. */ shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit));
base_io = pci_resource_start(pdev[h], 0); if (!shpnt)
irq = pdev[h]->irq; return -ENOMEM;
if (dev_id[h] != 0x8081) { p = (struct atp_unit *)&shpnt->hostdata;
error = pci_read_config_byte(pdev[h], 0x49, &host_id);
atp_dev.host = shpnt;
atp_dev.pdev = dev;
pci_set_drvdata(dev, p);
memcpy(p, &atp_dev, sizeof atp_dev);
if (atp870u_init_tables(shpnt) < 0)
goto unregister;
base_io &= 0xfffffff8; if (request_irq(dev->irq, atp870u_intr_handle, SA_SHIRQ, "atp870u", shpnt)) {
printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", dev->irq);
goto free_tables;
}
if (check_region(base_io, 0x40) != 0) { spin_lock_irqsave(shpnt->host_lock, flags);
return 0; if (atp_dev.chip_veru > 0x07) { /* check if atp876 chip then enable terminator */
} tmport = base_io + 0x3e;
printk(KERN_INFO " ACARD AEC-671X PCI Ultra/W SCSI-3 Host Adapter: %d IO:%x, IRQ:%d.\n", h, base_io, irq); outb(0x00, tmport);
}
tmp.ioport = base_io;
tmp.pciport = base_io + 0x20; tmport = base_io + 0x3a;
tmp.deviceid = dev_id[h]; k = (inb(tmport) & 0xf3) | 0x10;
host_id &= 0x07; outb(k, tmport);
tmp.host_idu = host_id; outb((k & 0xdf), tmport);
tmp.chip_veru = chip_ver[h]; mdelay(32);
outb(k, tmport);
tmport = base_io + 0x22; mdelay(32);
tmp.scam_on = inb(tmport); tmport = base_io;
tmport += 0x0b; outb((host_id | 0x08), tmport);
tmp.global_map = inb(tmport++); tmport += 0x18;
tmp.ultra_map = inw(tmport); outb(0, tmport);
if (tmp.ultra_map == 0) { tmport += 0x07;
tmp.scam_on = 0x00; while ((inb(tmport) & 0x80) == 0)
tmp.global_map = 0x20; mdelay(1);
tmp.ultra_map = 0xffff;
}
shpnt = scsi_register(tpnt, sizeof(struct atp_unit));
if (shpnt == NULL)
return count;
tmp.host = shpnt;
tmp.pdev = pdev[h];
/* Save the atp_unit data */
memcpy(&shpnt->hostdata, &tmp, sizeof(tmp));
atp870u_init_tables(shpnt);
spin_lock_irqsave(shpnt->host_lock, flags);
if (request_irq(irq, atp870u_intr_handle, SA_SHIRQ, "atp870u", shpnt)) {
printk(KERN_ERR "Unable to allocate IRQ for Acard controller.\n");
goto unregister;
}
if (chip_ver[h] > 0x07) { /* check if atp876 chip *//* then enable terminator */ tmport -= 0x08;
tmport = base_io + 0x3e; inb(tmport);
outb(0x00, tmport); tmport = base_io + 1;
} outb(8, tmport++);
outb(0x7f, tmport);
tmport = base_io + 0x11;
outb(0x20, tmport);
tmport = base_io + 0x3a; tscam(shpnt);
k = (inb(tmport) & 0xf3) | 0x10; is870(shpnt, base_io);
outb(k, tmport); tmport = base_io + 0x3a;
outb((k & 0xdf), tmport); outb((inb(tmport) & 0xef), tmport);
mdelay(32); tmport++;
outb(k, tmport); outb((inb(tmport) | 0x20), tmport);
mdelay(32); } else {
tmport = base_io; base_io &= 0xfffffff8;
outb((host_id | 0x08), tmport); host_id = inb(base_io + 0x39);
tmport += 0x18; host_id >>= 0x04;
outb(0, tmport);
tmport += 0x07; printk(KERN_INFO " ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: %d"
while ((inb(tmport) & 0x80) == 0); " IO:%x, IRQ:%d.\n", count, base_io, dev->irq);
tmport -= 0x08; atp_dev.ioport = base_io + 0x40;
inb(tmport); atp_dev.pciport = base_io + 0x28;
tmport = base_io + 1; atp_dev.deviceid = ent->device;
outb(8, tmport++); atp_dev.host_idu = host_id;
outb(0x7f, tmport);
tmport = base_io + 0x11; tmport = base_io + 0x22;
outb(0x20, tmport); atp_dev.scam_on = inb(tmport);
tmport += 0x13;
tscam(shpnt); atp_dev.global_map = inb(tmport);
is870(shpnt, base_io); tmport += 0x07;
tmport = base_io + 0x3a; atp_dev.ultra_map = inw(tmport);
outb((inb(tmport) & 0xef), tmport);
tmport++;
outb((inb(tmport) | 0x20), tmport);
} else {
base_io &= 0xfffffff8;
if (check_region(base_io, 0x60) != 0) { n = 0x3f09;
return 0;
}
host_id = inb(base_io + 0x39);
host_id >>= 0x04;
printk(KERN_INFO " ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: %d IO:%x, IRQ:%d.\n", h, base_io, irq);
tmp.ioport = base_io + 0x40;
tmp.pciport = base_io + 0x28;
tmp.deviceid = dev_id[h];
tmp.host_idu = host_id;
tmp.chip_veru = chip_ver[h];
tmport = base_io + 0x22;
tmp.scam_on = inb(tmport);
tmport += 0x13;
tmp.global_map = inb(tmport);
tmport += 0x07;
tmp.ultra_map = inw(tmport);
n = 0x3f09;
next_fblk: next_fblk:
if (n >= 0x4000) { if (n >= 0x4000)
goto flash_ok; goto flash_ok;
}
m = 0; m = 0;
outw(n, base_io + 0x34); outw(n, base_io + 0x34);
n += 0x0002; n += 0x0002;
if (inb(base_io + 0x30) == 0xff) { if (inb(base_io + 0x30) == 0xff)
goto flash_ok; goto flash_ok;
}
tmp.sp[m++] = inb(base_io + 0x30); atp_dev.sp[m++] = inb(base_io + 0x30);
tmp.sp[m++] = inb(base_io + 0x31); atp_dev.sp[m++] = inb(base_io + 0x31);
tmp.sp[m++] = inb(base_io + 0x32); atp_dev.sp[m++] = inb(base_io + 0x32);
tmp.sp[m++] = inb(base_io + 0x33); atp_dev.sp[m++] = inb(base_io + 0x33);
outw(n, base_io + 0x34); outw(n, base_io + 0x34);
n += 0x0002; n += 0x0002;
tmp.sp[m++] = inb(base_io + 0x30); atp_dev.sp[m++] = inb(base_io + 0x30);
tmp.sp[m++] = inb(base_io + 0x31); atp_dev.sp[m++] = inb(base_io + 0x31);
tmp.sp[m++] = inb(base_io + 0x32); atp_dev.sp[m++] = inb(base_io + 0x32);
tmp.sp[m++] = inb(base_io + 0x33); atp_dev.sp[m++] = inb(base_io + 0x33);
outw(n, base_io + 0x34); outw(n, base_io + 0x34);
n += 0x0002; n += 0x0002;
tmp.sp[m++] = inb(base_io + 0x30); atp_dev.sp[m++] = inb(base_io + 0x30);
tmp.sp[m++] = inb(base_io + 0x31); atp_dev.sp[m++] = inb(base_io + 0x31);
tmp.sp[m++] = inb(base_io + 0x32); atp_dev.sp[m++] = inb(base_io + 0x32);
tmp.sp[m++] = inb(base_io + 0x33); atp_dev.sp[m++] = inb(base_io + 0x33);
outw(n, base_io + 0x34); outw(n, base_io + 0x34);
n += 0x0002; n += 0x0002;
tmp.sp[m++] = inb(base_io + 0x30); atp_dev.sp[m++] = inb(base_io + 0x30);
tmp.sp[m++] = inb(base_io + 0x31); atp_dev.sp[m++] = inb(base_io + 0x31);
tmp.sp[m++] = inb(base_io + 0x32); atp_dev.sp[m++] = inb(base_io + 0x32);
tmp.sp[m++] = inb(base_io + 0x33); atp_dev.sp[m++] = inb(base_io + 0x33);
n += 0x0018; n += 0x0018;
goto next_fblk; goto next_fblk;
flash_ok: flash_ok:
outw(0, base_io + 0x34); outw(0, base_io + 0x34);
tmp.ultra_map = 0; atp_dev.ultra_map = 0;
tmp.async = 0; atp_dev.async = 0;
for (k = 0; k < 16; k++) { for (k = 0; k < 16; k++) {
n = 1; n = 1;
n = n << k; n = n << k;
if (tmp.sp[k] > 1) { if (atp_dev.sp[k] > 1) {
tmp.ultra_map |= n; atp_dev.ultra_map |= n;
} else { } else {
if (tmp.sp[k] == 0) { if (atp_dev.sp[k] == 0)
tmp.async |= n; atp_dev.async |= n;
} }
} }
} atp_dev.async = ~(atp_dev.async);
tmp.async = ~(tmp.async); outb(atp_dev.global_map, base_io + 0x35);
outb(tmp.global_map, base_io + 0x35);
shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit));
shpnt = scsi_register(tpnt, sizeof(struct atp_unit)); if (!shpnt)
if (shpnt == NULL) return -ENOMEM;
return count;
p = (struct atp_unit *)&shpnt->hostdata;
tmp.pdev = pdev[h];
memcpy(&shpnt->hostdata, &tmp, sizeof(tmp)); atp_dev.host = shpnt;
atp_dev.pdev = dev;
atp870u_init_tables(shpnt); pci_set_drvdata(dev, p);
memcpy(p, &atp_dev, sizeof atp_dev);
spin_lock_irqsave(shpnt->host_lock, flags); if (atp870u_init_tables(shpnt) < 0) {
if (request_irq(irq, atp870u_intr_handle, SA_SHIRQ, "atp870u", shpnt)) { printk(KERN_ERR "Unable to allocate tables for Acard controller\n");
printk(KERN_ERR "Unable to allocate IRQ for Acard controller.\n"); goto unregister;
goto unregister; }
}
if (request_irq(dev->irq, atp870u_intr_handle, SA_SHIRQ, "atp870u", shpnt)) {
printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", dev->irq);
goto free_tables;
}
spin_lock_irqsave(shpnt->host_lock, flags);
tmport = base_io + 0x38;
k = inb(tmport) & 0x80;
outb(k, tmport);
tmport += 0x03;
outb(0x20, tmport);
mdelay(32);
outb(0, tmport);
mdelay(32);
tmport = base_io + 0x5b;
inb(tmport);
tmport -= 0x04;
inb(tmport);
tmport = base_io + 0x40;
outb((host_id | 0x08), tmport);
tmport += 0x18;
outb(0, tmport);
tmport += 0x07;
while ((inb(tmport) & 0x80) == 0)
mdelay(1);
tmport -= 0x08;
inb(tmport);
tmport = base_io + 0x41;
outb(8, tmport++);
outb(0x7f, tmport);
tmport = base_io + 0x51;
outb(0x20, tmport);
tmport = base_io + 0x38; tscam(shpnt);
k = inb(tmport) & 0x80; is880(shpnt, base_io);
outb(k, tmport); tmport = base_io + 0x38;
tmport += 0x03; outb(0xb0, tmport);
outb(0x20, tmport); }
mdelay(32);
outb(0, tmport);
mdelay(32);
tmport = base_io + 0x5b;
inb(tmport);
tmport -= 0x04;
inb(tmport);
tmport = base_io + 0x40;
outb((host_id | 0x08), tmport);
tmport += 0x18;
outb(0, tmport);
tmport += 0x07;
while ((inb(tmport) & 0x80) == 0);
tmport -= 0x08;
inb(tmport);
tmport = base_io + 0x41;
outb(8, tmport++);
outb(0x7f, tmport);
tmport = base_io + 0x51;
outb(0x20, tmport);
tscam(shpnt); if (p->chip_veru == 4)
is880(shpnt, base_io); shpnt->max_id = 16;
tmport = base_io + 0x38;
outb(0xb0, tmport);
}
dev = (struct atp_unit *)&shpnt->hostdata; shpnt->this_id = host_id;
shpnt->unique_id = base_io;
atp_host[h] = shpnt; shpnt->io_port = base_io;
if (dev->chip_veru == 4) { if (ent->device == 0x8081) {
shpnt->max_id = 16; shpnt->n_io_port = 0x60; /* Number of bytes of I/O space used */
} } else {
shpnt->this_id = host_id; shpnt->n_io_port = 0x40; /* Number of bytes of I/O space used */
shpnt->unique_id = base_io; }
shpnt->io_port = base_io; shpnt->irq = dev->irq;
if (dev_id[h] == 0x8081) { spin_unlock_irqrestore(shpnt->host_lock, flags);
shpnt->n_io_port = 0x60; /* Number of bytes of I/O space used */ if (ent->device == 0x8081) {
} else { if (!request_region(base_io, 0x60, "atp870u"))
shpnt->n_io_port = 0x40; /* Number of bytes of I/O space used */ goto request_io_fail;
} } else {
shpnt->irq = irq; if (!request_region(base_io, 0x40, "atp870u"))
spin_unlock_irqrestore(shpnt->host_lock, flags); goto request_io_fail;
if (dev_id[h] == 0x8081) {
request_region(base_io, 0x60, "atp870u"); /* Register the IO ports that we use */
} else {
request_region(base_io, 0x40, "atp870u"); /* Register the IO ports that we use */
}
count++;
continue;
unregister:
scsi_unregister(shpnt);
spin_unlock_irqrestore(shpnt->host_lock, flags);
continue;
} }
return count; count++;
if (scsi_add_host(shpnt, &dev->dev))
goto scsi_add_fail;
scsi_scan_host(shpnt);
return 0;
scsi_add_fail:
if (ent->device == 0x8081)
release_region(base_io, 0x60);
else
release_region(base_io, 0x40);
request_io_fail:
free_irq(dev->irq, shpnt);
free_tables:
atp870u_free_tables(shpnt);
unregister:
scsi_host_put(shpnt);
return -1;
} }
/* The abort command does not leave the device in a clean state where /* The abort command does not leave the device in a clean state where
...@@ -2684,25 +2657,26 @@ static int atp870u_biosparam(struct scsi_device *sdev, ...@@ -2684,25 +2657,26 @@ static int atp870u_biosparam(struct scsi_device *sdev,
return 0; return 0;
} }
static void atp870u_remove(struct pci_dev *pdev)
static int atp870u_release(struct Scsi_Host *pshost)
{ {
struct atp_unit *dev = (struct atp_unit *)&pshost->hostdata; struct atp_unit *atp_dev = pci_get_drvdata(pdev);
int k; struct Scsi_Host *pshost = atp_dev->host;
scsi_remove_host(pshost);
free_irq(pshost->irq, pshost); free_irq(pshost->irq, pshost);
release_region(pshost->io_port, pshost->n_io_port); release_region(pshost->io_port, pshost->n_io_port);
scsi_unregister(pshost); atp870u_free_tables(pshost);
for (k = 0; k < 16; k++) scsi_host_put(pshost);
pci_free_consistent(dev->pdev, 1024, dev->id[k].prd_tableu, dev->id[k].prd_phys); pci_set_drvdata(pdev, NULL);
return 0;
} }
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
static Scsi_Host_Template driver_template = { static Scsi_Host_Template atp870u_template = {
.module = THIS_MODULE,
.name = "atp870u",
.proc_name = "atp870u",
.proc_info = atp870u_proc_info, .proc_info = atp870u_proc_info,
.detect = atp870u_detect,
.release = atp870u_release,
.info = atp870u_info, .info = atp870u_info,
.queuecommand = atp870u_queuecommand, .queuecommand = atp870u_queuecommand,
.eh_abort_handler = atp870u_abort, .eh_abort_handler = atp870u_abort,
...@@ -2713,4 +2687,39 @@ static Scsi_Host_Template driver_template = { ...@@ -2713,4 +2687,39 @@ static Scsi_Host_Template driver_template = {
.cmd_per_lun = ATP870U_CMDLUN, .cmd_per_lun = ATP870U_CMDLUN,
.use_clustering = ENABLE_CLUSTERING, .use_clustering = ENABLE_CLUSTERING,
}; };
#include "scsi_module.c"
static struct pci_device_id atp870u_id_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, 0x8081) },
{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7610) },
{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612UW) },
{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612U) },
{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612S) },
{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612D) },
{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612SUW) },
{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_8060) },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, atp870u_id_table);
static struct pci_driver atp870u_driver = {
.id_table = atp870u_id_table,
.name = "atp870u",
.probe = atp870u_probe,
.remove = __devexit_p(atp870u_remove),
};
static int __init atp870u_init(void)
{
pci_register_driver(&atp870u_driver);
return 0;
}
static void __exit atp870u_exit(void)
{
pci_unregister_driver(&atp870u_driver);
}
module_init(atp870u_init);
module_exit(atp870u_exit);
#ifndef _ATP870U_H #ifndef _ATP870U_H
#define _ATP870U_H
/* $Id: atp870u.h,v 1.0 1997/05/07 15:09:00 root Exp root $ /* $Id: atp870u.h,v 1.0 1997/05/07 15:09:00 root Exp root $
...@@ -14,20 +15,57 @@ ...@@ -14,20 +15,57 @@
/* I/O Port */ /* I/O Port */
#define MAX_CDB 12 #define MAX_CDB 12
#define MAX_SENSE 14 #define MAX_SENSE 14
#define qcnt 32
#define ATP870U_SCATTER 128
#define ATP870U_CMDLUN 1
struct atp_unit {
unsigned long ioport;
unsigned long pciport;
unsigned char last_cmd;
unsigned char in_snd;
unsigned char in_int;
unsigned char quhdu;
unsigned char quendu;
unsigned char scam_on;
unsigned char global_map;
unsigned char chip_veru;
unsigned char host_idu;
volatile int working;
unsigned short wide_idu;
unsigned short active_idu;
unsigned short ultra_map;
unsigned short async;
unsigned short deviceid;
unsigned char ata_cdbu[16];
unsigned char sp[16];
Scsi_Cmnd *querequ[qcnt];
struct atp_id {
unsigned char dirctu;
unsigned char devspu;
unsigned char devtypeu;
unsigned long prdaddru;
unsigned long tran_lenu;
unsigned long last_lenu;
unsigned char *prd_posu;
unsigned char *prd_tableu;
dma_addr_t prd_phys;
Scsi_Cmnd *curr_req;
} id[16];
struct Scsi_Host *host;
struct pci_dev *pdev;
unsigned int unit;
};
static int atp870u_detect(Scsi_Host_Template *);
static int atp870u_queuecommand(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *)); static int atp870u_queuecommand(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
static int atp870u_abort(Scsi_Cmnd *); static int atp870u_abort(Scsi_Cmnd *);
static int atp870u_biosparam(struct scsi_device *, struct block_device *, static int atp870u_biosparam(struct scsi_device *, struct block_device *,
sector_t, int *); sector_t, int *);
static int atp870u_release(struct Scsi_Host *); static void send_s870(struct Scsi_Host *);
#define qcnt 32
#define ATP870U_SCATTER 128
#define ATP870U_CMDLUN 1
extern const char *atp870u_info(struct Scsi_Host *); extern const char *atp870u_info(struct Scsi_Host *);
static Scsi_Host_Template atp870u_template;
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment