Commit 755b8d21 authored by James Bottomley's avatar James Bottomley

Merge raven.il.steeleye.com:/home/jejb/BK/scsi-misc-2.5

into raven.il.steeleye.com:/home/jejb/BK/scsi-for-linus-2.5
parents 1d0619c5 a6257edd
...@@ -1346,6 +1346,7 @@ int ata_attach(ide_drive_t *drive) ...@@ -1346,6 +1346,7 @@ int ata_attach(ide_drive_t *drive)
spin_unlock(&drivers_lock); spin_unlock(&drivers_lock);
spin_lock(&drives_lock); spin_lock(&drives_lock);
list_add_tail(&drive->list, &ata_unused); list_add_tail(&drive->list, &ata_unused);
drive->gendev.driver = NULL;
spin_unlock(&drives_lock); spin_unlock(&drives_lock);
return 1; return 1;
} }
...@@ -2308,6 +2309,8 @@ void ide_unregister_driver(ide_driver_t *driver) ...@@ -2308,6 +2309,8 @@ void ide_unregister_driver(ide_driver_t *driver)
list_del(&driver->drivers); list_del(&driver->drivers);
spin_unlock(&drivers_lock); spin_unlock(&drivers_lock);
driver_unregister(&driver->gen_driver);
while(!list_empty(&driver->drives)) { while(!list_empty(&driver->drives)) {
drive = list_entry(driver->drives.next, ide_drive_t, list); drive = list_entry(driver->drives.next, ide_drive_t, list);
if (driver->cleanup(drive)) { if (driver->cleanup(drive)) {
......
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
#ifndef _53C700_H #ifndef _53C700_H
#define _53C700_H #define _53C700_H
#include <asm/io.h>
/* Turn on for general debugging---too verbose for normal use */ /* Turn on for general debugging---too verbose for normal use */
#undef NCR_700_DEBUG #undef NCR_700_DEBUG
/* Debug the tag queues, checking hash queue allocation and deallocation /* Debug the tag queues, checking hash queue allocation and deallocation
......
...@@ -964,6 +964,16 @@ config SCSI_SYM53C8XX_2 ...@@ -964,6 +964,16 @@ config SCSI_SYM53C8XX_2
Please read <file:drivers/scsi/sym53c8xx_2/Documentation.txt> for more Please read <file:drivers/scsi/sym53c8xx_2/Documentation.txt> for more
information. information.
config SCSI_ZALON
tristate "Zalon SCSI support"
depends on GSC && SCSI
help
The Zalon is a GSC/HSC bus interface chip that sits between the
PA-RISC processor and the NCR 53c720 SCSI controller on C100,
C110, J200, J210 and some D, K & R-class machines. It's also
used on the add-in Bluefish, Barracuda & Shrike SCSI cards.
Say Y here if you have one of these machines or cards.
config SCSI_SYM53C8XX_DMA_ADDRESSING_MODE config SCSI_SYM53C8XX_DMA_ADDRESSING_MODE
int "DMA addressing mode" int "DMA addressing mode"
depends on SCSI_SYM53C8XX_2 depends on SCSI_SYM53C8XX_2
...@@ -1068,7 +1078,7 @@ config SCSI_SYM53C8XX ...@@ -1068,7 +1078,7 @@ config SCSI_SYM53C8XX
config SCSI_NCR53C8XX_DEFAULT_TAGS config SCSI_NCR53C8XX_DEFAULT_TAGS
int "default tagged command queue depth" int "default tagged command queue depth"
depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX) depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX || SCSI_ZALON)
default "8" default "8"
---help--- ---help---
"Tagged command queuing" is a feature of SCSI-2 which improves "Tagged command queuing" is a feature of SCSI-2 which improves
...@@ -1094,7 +1104,7 @@ config SCSI_NCR53C8XX_DEFAULT_TAGS ...@@ -1094,7 +1104,7 @@ config SCSI_NCR53C8XX_DEFAULT_TAGS
config SCSI_NCR53C8XX_MAX_TAGS config SCSI_NCR53C8XX_MAX_TAGS
int "maximum number of queued commands" int "maximum number of queued commands"
depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX) depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX || SCSI_ZALON)
default "32" default "32"
---help--- ---help---
This option allows you to specify the maximum number of commands This option allows you to specify the maximum number of commands
...@@ -1111,7 +1121,7 @@ config SCSI_NCR53C8XX_MAX_TAGS ...@@ -1111,7 +1121,7 @@ config SCSI_NCR53C8XX_MAX_TAGS
config SCSI_NCR53C8XX_SYNC config SCSI_NCR53C8XX_SYNC
int "synchronous transfers frequency in MHz" int "synchronous transfers frequency in MHz"
depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX) depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX || SCSI_ZALON)
default "20" default "20"
---help--- ---help---
The SCSI Parallel Interface-2 Standard defines 5 classes of transfer The SCSI Parallel Interface-2 Standard defines 5 classes of transfer
...@@ -1145,7 +1155,7 @@ config SCSI_NCR53C8XX_SYNC ...@@ -1145,7 +1155,7 @@ config SCSI_NCR53C8XX_SYNC
config SCSI_NCR53C8XX_PROFILE config SCSI_NCR53C8XX_PROFILE
bool "enable profiling" bool "enable profiling"
depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX) depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX || SCSI_ZALON)
help help
This option allows you to enable profiling information gathering. This option allows you to enable profiling information gathering.
These statistics are not very accurate due to the low frequency These statistics are not very accurate due to the low frequency
...@@ -1156,7 +1166,7 @@ config SCSI_NCR53C8XX_PROFILE ...@@ -1156,7 +1166,7 @@ config SCSI_NCR53C8XX_PROFILE
config SCSI_NCR53C8XX_IOMAPPED config SCSI_NCR53C8XX_IOMAPPED
bool "use normal IO" bool "use normal IO"
depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX) depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX) && !SCSI_ZALON
help help
If you say Y here, the driver will use normal IO, as opposed to If you say Y here, the driver will use normal IO, as opposed to
memory mapped IO. Memory mapped IO has less latency than normal IO memory mapped IO. Memory mapped IO has less latency than normal IO
...@@ -1181,7 +1191,7 @@ config SCSI_NCR53C8XX_PQS_PDS ...@@ -1181,7 +1191,7 @@ config SCSI_NCR53C8XX_PQS_PDS
config SCSI_NCR53C8XX_NO_DISCONNECT config SCSI_NCR53C8XX_NO_DISCONNECT
bool "not allow targets to disconnect" bool "not allow targets to disconnect"
depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX) && SCSI_NCR53C8XX_DEFAULT_TAGS=0 depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX || SCSI_ZALON) && SCSI_NCR53C8XX_DEFAULT_TAGS=0
help help
This option is only provided for safety if you suspect some SCSI This option is only provided for safety if you suspect some SCSI
device of yours to not support properly the target-disconnect device of yours to not support properly the target-disconnect
...@@ -1191,7 +1201,7 @@ config SCSI_NCR53C8XX_NO_DISCONNECT ...@@ -1191,7 +1201,7 @@ config SCSI_NCR53C8XX_NO_DISCONNECT
config SCSI_NCR53C8XX_SYMBIOS_COMPAT config SCSI_NCR53C8XX_SYMBIOS_COMPAT
bool "assume boards are SYMBIOS compatible (EXPERIMENTAL)" bool "assume boards are SYMBIOS compatible (EXPERIMENTAL)"
depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX) && EXPERIMENTAL depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX || SCSI_ZALON) && EXPERIMENTAL
---help--- ---help---
This option allows you to enable some features depending on GPIO This option allows you to enable some features depending on GPIO
wiring. These General Purpose Input/Output pins can be used for wiring. These General Purpose Input/Output pins can be used for
......
...@@ -84,6 +84,7 @@ obj-$(CONFIG_SCSI_NCR53C7xx) += 53c7,8xx.o ...@@ -84,6 +84,7 @@ obj-$(CONFIG_SCSI_NCR53C7xx) += 53c7,8xx.o
obj-$(CONFIG_SCSI_SYM53C8XX_2) += sym53c8xx_2/ obj-$(CONFIG_SCSI_SYM53C8XX_2) += sym53c8xx_2/
obj-$(CONFIG_SCSI_SYM53C8XX) += sym53c8xx.o obj-$(CONFIG_SCSI_SYM53C8XX) += sym53c8xx.o
obj-$(CONFIG_SCSI_NCR53C8XX) += ncr53c8xx.o obj-$(CONFIG_SCSI_NCR53C8XX) += ncr53c8xx.o
obj-$(CONFIG_SCSI_ZALON) += zalon7xx.o
obj-$(CONFIG_SCSI_EATA_DMA) += eata_dma.o obj-$(CONFIG_SCSI_EATA_DMA) += eata_dma.o
obj-$(CONFIG_SCSI_EATA_PIO) += eata_pio.o obj-$(CONFIG_SCSI_EATA_PIO) += eata_pio.o
obj-$(CONFIG_SCSI_7000FASST) += wd7000.o obj-$(CONFIG_SCSI_7000FASST) += wd7000.o
...@@ -135,6 +136,7 @@ sd_mod-objs := sd.o ...@@ -135,6 +136,7 @@ sd_mod-objs := sd.o
sr_mod-objs := sr.o sr_ioctl.o sr_vendor.o sr_mod-objs := sr.o sr_ioctl.o sr_vendor.o
initio-objs := ini9100u.o i91uscsi.o initio-objs := ini9100u.o i91uscsi.o
a100u2w-objs := inia100.o i60uscsi.o a100u2w-objs := inia100.o i60uscsi.o
zalon7xx-objs := zalon.o ncr53c8xx.o
cpqfc-objs := cpqfcTSinit.o cpqfcTScontrol.o cpqfcTSi2c.o \ cpqfc-objs := cpqfcTSinit.o cpqfcTScontrol.o cpqfcTSi2c.o \
cpqfcTSworker.o cpqfcTStrigger.o cpqfcTSworker.o cpqfcTStrigger.o
......
...@@ -289,6 +289,7 @@ static int idescsi_check_condition(ide_drive_t *drive, struct request *failed_co ...@@ -289,6 +289,7 @@ static int idescsi_check_condition(ide_drive_t *drive, struct request *failed_co
pc->timeout = jiffies + WAIT_READY; pc->timeout = jiffies + WAIT_READY;
/* NOTE! Save the failed packet command in "rq->buffer" */ /* NOTE! Save the failed packet command in "rq->buffer" */
rq->buffer = (void *) failed_command->special; rq->buffer = (void *) failed_command->special;
pc->scsi_cmd = ((idescsi_pc_t *) failed_command->special)->scsi_cmd;
if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) { if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) {
printk ("ide-scsi: %s: queue cmd = ", drive->name); printk ("ide-scsi: %s: queue cmd = ", drive->name);
hexdump(pc->c, 6); hexdump(pc->c, 6);
...@@ -590,6 +591,7 @@ static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi, int id) ...@@ -590,6 +591,7 @@ static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi, int id)
set_bit(IDESCSI_LOG_CMD, &scsi->log); set_bit(IDESCSI_LOG_CMD, &scsi->log);
#endif /* IDESCSI_DEBUG_LOG */ #endif /* IDESCSI_DEBUG_LOG */
idescsi_add_settings(drive); idescsi_add_settings(drive);
DRIVER(drive)->busy--;
} }
static int idescsi_cleanup (ide_drive_t *drive) static int idescsi_cleanup (ide_drive_t *drive)
...@@ -876,7 +878,8 @@ int idescsi_abort (Scsi_Cmnd *cmd) ...@@ -876,7 +878,8 @@ int idescsi_abort (Scsi_Cmnd *cmd)
/* is cmd active? /* is cmd active?
* need to lock so this stuff doesn't change under us */ * need to lock so this stuff doesn't change under us */
spin_lock_irqsave(&ide_lock, flags); spin_lock_irqsave(&ide_lock, flags);
if (scsi->pc && scsi->pc->scsi_cmd->serial_number == cmd->serial_number) { if (scsi->pc && scsi->pc->scsi_cmd &&
scsi->pc->scsi_cmd->serial_number == cmd->serial_number) {
/* yep - let's give it some more time - /* yep - let's give it some more time -
* we can do that, we're in _our_ error kernel thread */ * we can do that, we're in _our_ error kernel thread */
spin_unlock_irqrestore(&ide_lock, flags); spin_unlock_irqrestore(&ide_lock, flags);
...@@ -995,7 +998,7 @@ static void __exit exit_idescsi_module(void) ...@@ -995,7 +998,7 @@ static void __exit exit_idescsi_module(void)
for (id = 0; id < MAX_HWIFS * MAX_DRIVES; id++) { for (id = 0; id < MAX_HWIFS * MAX_DRIVES; id++) {
drive = idescsi_drives[id]; drive = idescsi_drives[id];
if (drive) if (drive)
DRIVER(drive)->busy--; DRIVER(drive)->busy = 0;
} }
scsi_unregister (idescsi_host); scsi_unregister (idescsi_host);
device_unregister(&idescsi_primary); device_unregister(&idescsi_primary);
......
...@@ -178,12 +178,8 @@ ...@@ -178,12 +178,8 @@
#include <linux/stat.h> #include <linux/stat.h>
#include <linux/config.h> #include <linux/config.h>
#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) #include <linux/spinlock.h>
#include <linux/spinlock.h> #include <linux/init.h>
#include <linux/init.h>
#else
#include <asm/spinlock.h>
#endif
#include <linux/smp.h> #include <linux/smp.h>
...@@ -199,45 +195,10 @@ ...@@ -199,45 +195,10 @@
#define IPS_VERSION_HIGH "5.10" #define IPS_VERSION_HIGH "5.10"
#define IPS_VERSION_LOW ".13-BETA " #define IPS_VERSION_LOW ".13-BETA "
#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0)
struct proc_dir_entry proc_scsi_ips = {
0,
3, "ips",
S_IFDIR | S_IRUGO | S_IXUGO, 2
};
#endif
#if !defined(__i386__) && !defined(__ia64__) #if !defined(__i386__) && !defined(__ia64__)
#error "This driver has only been tested on the x86/ia64 platforms" #error "This driver has only been tested on the x86/ia64 platforms"
#endif #endif
#if LINUX_VERSION_CODE < LinuxVersionCode(2,2,0)
#error "This driver only works with kernel 2.2.0 and later"
#elif LINUX_VERSION_CODE <= LinuxVersionCode(2,3,18)
#define dma_addr_t uint32_t
static inline void *pci_alloc_consistent(struct pci_dev *dev,int size,
dma_addr_t *dmahandle) {
void * ptr = kmalloc(size, GFP_ATOMIC);
if(ptr){
*dmahandle = (uint32_t)virt_to_bus(ptr);
}
return ptr;
}
#define pci_free_consistent(a,size,address,dmahandle) kfree(address)
#define pci_map_sg(a,b,n,z) (n)
#define pci_unmap_sg(a,b,c,d)
#define pci_map_single(a,b,c,d) ((uint32_t)virt_to_bus(b))
#define pci_unmap_single(a,b,c,d)
#ifndef sg_dma_address
#define sg_dma_address(x) ((uint32_t)virt_to_bus((x)->address))
#define sg_dma_len(x) ((x)->length)
#endif
#define pci_unregister_driver(x)
#endif
#if LINUX_VERSION_CODE <= LinuxVersionCode(2,5,0) #if LINUX_VERSION_CODE <= LinuxVersionCode(2,5,0)
#define IPS_SG_ADDRESS(sg) ((sg)->address) #define IPS_SG_ADDRESS(sg) ((sg)->address)
#define IPS_LOCK_SAVE(lock,flags) spin_lock_irqsave(&io_request_lock,flags) #define IPS_LOCK_SAVE(lock,flags) spin_lock_irqsave(&io_request_lock,flags)
...@@ -289,7 +250,6 @@ static uint32_t MaxLiteCmds = 32; /* Max Active Cmds for a Li ...@@ -289,7 +250,6 @@ static uint32_t MaxLiteCmds = 32; /* Max Active Cmds for a Li
IPS_DEFINE_COMPAT_TABLE( Compatable ); /* Version Compatability Table */ IPS_DEFINE_COMPAT_TABLE( Compatable ); /* Version Compatability Table */
#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
/* This table describes any / all ServeRAID Adapters */ /* This table describes any / all ServeRAID Adapters */
static struct pci_device_id ips_pci_table[] __devinitdata = { static struct pci_device_id ips_pci_table[] __devinitdata = {
{ 0x1014, 0x002E, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, { 0x1014, 0x002E, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
...@@ -338,7 +298,6 @@ IPS_DEFINE_COMPAT_TABLE( Compatable ); /* Version Compatability Ta ...@@ -338,7 +298,6 @@ IPS_DEFINE_COMPAT_TABLE( Compatable ); /* Version Compatability Ta
.remove = __devexit_p(ips_remove_device), .remove = __devexit_p(ips_remove_device),
}; };
#endif
/* /*
* Necessary forward function protoypes * Necessary forward function protoypes
...@@ -497,6 +456,7 @@ static void ips_done(ips_ha_t *, ips_scb_t *); ...@@ -497,6 +456,7 @@ static void ips_done(ips_ha_t *, ips_scb_t *);
static void ips_free(ips_ha_t *); static void ips_free(ips_ha_t *);
static void ips_init_scb(ips_ha_t *, ips_scb_t *); static void ips_init_scb(ips_ha_t *, ips_scb_t *);
static void ips_freescb(ips_ha_t *, ips_scb_t *); static void ips_freescb(ips_ha_t *, ips_scb_t *);
static void ips_setup_funclist(ips_ha_t *);
static void ips_statinit(ips_ha_t *); static void ips_statinit(ips_ha_t *);
static void ips_statinit_memio(ips_ha_t *); static void ips_statinit_memio(ips_ha_t *);
static void ips_fix_ffdc_time(ips_ha_t *, ips_scb_t *, time_t); static void ips_fix_ffdc_time(ips_ha_t *, ips_scb_t *, time_t);
...@@ -533,9 +493,7 @@ static void ips_version_check(ips_ha_t *ha, int intr); ...@@ -533,9 +493,7 @@ static void ips_version_check(ips_ha_t *ha, int intr);
static int ips_abort_init(ips_ha_t *ha, struct Scsi_Host *sh, int index); static int ips_abort_init(ips_ha_t *ha, struct Scsi_Host *sh, int index);
static int ips_init_phase2( int index ); static int ips_init_phase2( int index );
#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr ); static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr );
#endif
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
/* Exported Functions */ /* Exported Functions */
...@@ -550,13 +508,8 @@ static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr ); ...@@ -550,13 +508,8 @@ static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr );
/* setup parameters to the driver */ /* setup parameters to the driver */
/* */ /* */
/****************************************************************************/ /****************************************************************************/
#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
static int static int
ips_setup(char *ips_str) { ips_setup(char *ips_str) {
#else
void
ips_setup(char *ips_str, int *dummy) {
#endif
int i; int i;
char *key; char *key;
...@@ -570,7 +523,6 @@ ips_setup(char *ips_str, int *dummy) { ...@@ -570,7 +523,6 @@ ips_setup(char *ips_str, int *dummy) {
}; };
/* Don't use strtok() anymore ( if 2.4 Kernel or beyond ) */ /* Don't use strtok() anymore ( if 2.4 Kernel or beyond ) */
#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
/* Search for value */ /* Search for value */
while ((key = strsep(&ips_str, ",."))) { while ((key = strsep(&ips_str, ",."))) {
if (!*key) if (!*key)
...@@ -598,43 +550,6 @@ ips_setup(char *ips_str, int *dummy) { ...@@ -598,43 +550,6 @@ ips_setup(char *ips_str, int *dummy) {
__setup("ips=", ips_setup); __setup("ips=", ips_setup);
#else
char *p;
char tokens[3] = {',', '.', 0};
for (key = strtok(ips_str, tokens); key; key = strtok(NULL, tokens)) {
p = key;
/* Search for value */
while ((p) && (*p != ':'))
p++;
if (p) {
*p = '\0';
value = p+1;
} else
value = NULL;
/*
* We now have key/value pairs.
* Update the variables
*/
for (i = 0; i < (sizeof(options) / sizeof(options[0])); i++) {
if (strnicmp(key, options[i].option_name, strlen(ips_str)) == 0) {
if (value)
*options[i].option_flag = simple_strtoul(value, NULL, 0);
else
*options[i].option_flag = options[i].option_value;
break;
}
}
}
}
#endif
/****************************************************************************/ /****************************************************************************/
/* */ /* */
/* Routine Name: ips_detect */ /* Routine Name: ips_detect */
...@@ -648,42 +563,12 @@ __setup("ips=", ips_setup); ...@@ -648,42 +563,12 @@ __setup("ips=", ips_setup);
/****************************************************************************/ /****************************************************************************/
int int
ips_detect(Scsi_Host_Template *SHT) { ips_detect(Scsi_Host_Template *SHT) {
struct Scsi_Host *sh;
ips_ha_t *ha;
uint32_t io_addr;
uint32_t mem_addr;
uint32_t io_len;
uint32_t mem_len;
uint16_t planer;
uint8_t revision_id;
uint8_t bus;
uint8_t func;
uint8_t irq;
uint16_t deviceID[2];
uint16_t subdevice_id;
int i;
int j;
uint32_t count;
char *ioremap_ptr;
char *mem_ptr;
struct pci_dev *dev[2];
struct pci_dev *morpheus = NULL;
struct pci_dev *trombone = NULL;
#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0)
uint32_t currbar;
uint32_t maskbar;
uint8_t barnum;
#endif
METHOD_TRACE("ips_detect", 1); METHOD_TRACE("ips_detect", 1);
#ifdef MODULE #ifdef MODULE
if (ips) if (ips)
#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
ips_setup(ips); ips_setup(ips);
#else
ips_setup(ips, NULL);
#endif
#endif #endif
/* If Booting from the ServeRAID Manager CD, Allocate a large Flash */ /* If Booting from the ServeRAID Manager CD, Allocate a large Flash */
...@@ -697,69 +582,8 @@ ips_detect(Scsi_Host_Template *SHT) { ...@@ -697,69 +582,8 @@ ips_detect(Scsi_Host_Template *SHT) {
} }
SHT->proc_info = ips_proc_info; SHT->proc_info = ips_proc_info;
#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0)
SHT->proc_dir = &proc_scsi_ips;
#else
SHT->proc_name = "ips"; SHT->proc_name = "ips";
#endif
#if defined(CONFIG_PCI)
/* initalize number of controllers */
ips_num_controllers = 0;
ips_next_controller = 0;
ips_released_controllers = 0;
if (!pci_present())
return (0);
morpheus = pci_find_device(IPS_VENDORID, IPS_DEVICEID_MORPHEUS, morpheus);
trombone = pci_find_device(IPS_VENDORID, IPS_DEVICEID_COPPERHEAD, trombone);
/* determine which controller to probe first */
if (!morpheus) {
/* we only have trombone */
dev[0] = trombone;
dev[1] = NULL;
deviceID[0] = IPS_DEVICEID_COPPERHEAD;
} else if (!trombone) {
/* we only have morpheus */
dev[0] = morpheus;
dev[1] = NULL;
deviceID[0] = IPS_DEVICEID_MORPHEUS;
} else {
/* we have both in the system */
if (trombone->bus->number < morpheus->bus->number) {
dev[0] = trombone;
dev[1] = morpheus;
deviceID[0] = IPS_DEVICEID_COPPERHEAD;
deviceID[1] = IPS_DEVICEID_MORPHEUS;
} else if (trombone->bus->number > morpheus->bus->number) {
dev[0] = morpheus;
dev[1] = trombone;
deviceID[0] = IPS_DEVICEID_MORPHEUS;
deviceID[1] = IPS_DEVICEID_COPPERHEAD;
} else {
/* further detection required */
if (trombone->devfn < morpheus->devfn) {
dev[0] = trombone;
dev[1] = morpheus;
deviceID[0] = IPS_DEVICEID_COPPERHEAD;
deviceID[1] = IPS_DEVICEID_MORPHEUS;
} else {
dev[0] = morpheus;
dev[1] = trombone;
deviceID[0] = IPS_DEVICEID_MORPHEUS;
deviceID[1] = IPS_DEVICEID_COPPERHEAD;
}
}
}
/**********************************************************************************/
/* For Kernel Versions 2.4 or greater, use new PCI ( Hot Pluggable ) architecture */
/**********************************************************************************/
#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
#if LINUX_VERSION_CODE < LinuxVersionCode(2,5,0) #if LINUX_VERSION_CODE < LinuxVersionCode(2,5,0)
spin_unlock_irq(&io_request_lock); spin_unlock_irq(&io_request_lock);
#endif #endif
...@@ -779,485 +603,64 @@ ips_detect(Scsi_Host_Template *SHT) { ...@@ -779,485 +603,64 @@ ips_detect(Scsi_Host_Template *SHT) {
register_reboot_notifier(&ips_notifier); register_reboot_notifier(&ips_notifier);
return (ips_num_controllers); return (ips_num_controllers);
#endif }
/* Now scan the controllers */
for (i = 0; i < 2; i++) {
if (!dev[i])
break;
do {
if (ips_next_controller >= IPS_MAX_ADAPTERS)
break;
#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
if (pci_enable_device(dev[i]))
break;
#endif
/* stuff that we get in dev */
irq = dev[i]->irq;
bus = dev[i]->bus->number;
func = dev[i]->devfn;
/* Init MEM/IO addresses to 0 */
mem_addr = 0;
io_addr = 0;
mem_len = 0;
io_len = 0;
for (j = 0; j < 2; j++) {
#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
if (!pci_resource_start(dev[i], j))
break;
if (pci_resource_flags(dev[i], j) & IORESOURCE_IO) {
io_addr = pci_resource_start(dev[i], j);
io_len = pci_resource_len(dev[i], j);
} else {
mem_addr = pci_resource_start(dev[i], j);
mem_len = pci_resource_len(dev[i], j);
}
#else
if (!dev[i]->base_address[j])
break;
if ((dev[i]->base_address[j] & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) {
barnum = PCI_BASE_ADDRESS_0 + (j * 4);
io_addr = dev[i]->base_address[j] & PCI_BASE_ADDRESS_IO_MASK;
/* Get Size */
pci_read_config_dword(dev[i], barnum, &currbar);
pci_write_config_dword(dev[i], barnum, ~0);
pci_read_config_dword(dev[i], barnum, &maskbar);
pci_write_config_dword(dev[i], barnum, currbar);
io_len = ~(maskbar & PCI_BASE_ADDRESS_IO_MASK) + 1;
} else {
barnum = PCI_BASE_ADDRESS_0 + (j * 4);
mem_addr = dev[i]->base_address[j] & PCI_BASE_ADDRESS_MEM_MASK;
/* Get Size */
pci_read_config_dword(dev[i], barnum, &currbar);
pci_write_config_dword(dev[i], barnum, ~0);
pci_read_config_dword(dev[i], barnum, &maskbar);
pci_write_config_dword(dev[i], barnum, currbar);
mem_len = ~(maskbar & PCI_BASE_ADDRESS_MEM_MASK) + 1;
}
#endif
}
/* setup memory mapped area (if applicable) */
if (mem_addr) {
uint32_t base;
uint32_t offs;
DEBUG_VAR(1, "(%s%d) detect, Memory region %x, size: %d",
ips_name, ips_next_controller, mem_addr, mem_len);
#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
if (!request_mem_region(mem_addr, mem_len, "ips")) {
/* Couldn't allocate io space */
printk(KERN_WARNING "(%s%d) couldn't allocate IO space %x len %d.\n",
ips_name, ips_next_controller, io_addr, io_len);
ips_next_controller++;
continue;
}
#endif
base = mem_addr & PAGE_MASK;
offs = mem_addr - base;
ioremap_ptr = ioremap(base, PAGE_SIZE);
mem_ptr = ioremap_ptr + offs;
} else {
ioremap_ptr = NULL;
mem_ptr = NULL;
}
/* setup I/O mapped area (if applicable) */
if (io_addr) {
DEBUG_VAR(1, "(%s%d) detect, IO region %x, size: %d",
ips_name, ips_next_controller, io_addr, io_len);
if (!request_region(io_addr, io_len, "ips")) {
/* Couldn't allocate io space */
printk(KERN_WARNING "(%s%d) couldn't allocate IO space %x len %d.\n",
ips_name, ips_next_controller, io_addr, io_len);
ips_next_controller++;
continue;
}
}
/* get planer status */
if (pci_read_config_word(dev[i], 0x04, &planer)) {
printk(KERN_WARNING "(%s%d) can't get planer status.\n",
ips_name, ips_next_controller);
ips_next_controller++;
continue;
}
/* check to see if an onboard planer controller is disabled */
if (!(planer & 0x000C)) {
DEBUG_VAR(1, "(%s%d) detect, Onboard ServeRAID disabled by BIOS",
ips_name, ips_next_controller);
ips_next_controller++;
continue;
}
DEBUG_VAR(1, "(%s%d) detect bus %d, func %x, irq %d, io %x, mem: %x, ptr: %p",
ips_name, ips_next_controller, bus, func, irq, io_addr, mem_addr, mem_ptr);
/* get the revision ID */
if (pci_read_config_byte(dev[i], PCI_REVISION_ID, &revision_id)) {
printk(KERN_WARNING "(%s%d) can't get revision id.\n",
ips_name, ips_next_controller);
ips_next_controller++;
continue;
}
#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0)
/* get the subdevice id */
if (pci_read_config_word(dev[i], PCI_SUBSYSTEM_ID, &subdevice_id)) {
printk(KERN_WARNING "(%s%d) can't get subdevice id.\n",
ips_name, ips_next_controller);
ips_next_controller++;
continue;
}
#else
subdevice_id = dev[i]->subsystem_device;
#endif
/* found a controller */
sh = scsi_register(SHT, sizeof(ips_ha_t));
if (sh == NULL) {
printk(KERN_WARNING "(%s%d) Unable to register controller with SCSI subsystem - skipping controller\n",
ips_name, ips_next_controller);
ips_next_controller++;
continue;
}
ha = IPS_HA(sh);
memset(ha, 0, sizeof(ips_ha_t));
ips_sh[ips_next_controller] = sh;
ips_ha[ips_next_controller] = ha;
ips_num_controllers++;
ha->active = 1;
ha->enq = kmalloc(sizeof(IPS_ENQ), GFP_KERNEL);
if (!ha->enq) {
printk(KERN_WARNING "(%s%d) Unable to allocate host inquiry structure - skipping contoller\n",
ips_name, ips_next_controller);
ha->active = 0;
ips_free(ha);
scsi_unregister(sh);
ips_ha[ips_next_controller] = 0;
ips_sh[ips_next_controller] = 0;
ips_next_controller++;
ips_num_controllers--;
continue;
}
ha->adapt = kmalloc(sizeof(IPS_ADAPTER), GFP_KERNEL);
if (!ha->adapt) {
printk(KERN_WARNING "(%s%d) Unable to allocate host adapt structure - skipping controller\n",
ips_name, ips_next_controller);
ha->active = 0;
ips_free(ha);
scsi_unregister(sh);
ips_ha[ips_next_controller] = 0;
ips_sh[ips_next_controller] = 0;
ips_next_controller++;
ips_num_controllers--;
continue;
}
ha->conf = kmalloc(sizeof(IPS_CONF), GFP_KERNEL);
if (!ha->conf) {
printk(KERN_WARNING "(%s%d) Unable to allocate host conf structure - skipping controller\n",
ips_name, ips_next_controller);
ha->active = 0;
ips_free(ha);
scsi_unregister(sh);
ips_ha[ips_next_controller] = 0;
ips_sh[ips_next_controller] = 0;
ips_next_controller++;
ips_num_controllers--;
continue;
}
ha->nvram = kmalloc(sizeof(IPS_NVRAM_P5), GFP_KERNEL);
if (!ha->nvram) {
printk(KERN_WARNING "(%s%d) Unable to allocate host nvram structure - skipping controller\n",
ips_name, ips_next_controller);
ha->active = 0;
ips_free(ha);
scsi_unregister(sh);
ips_ha[ips_next_controller] = 0;
ips_sh[ips_next_controller] = 0;
ips_next_controller++;
ips_num_controllers--;
continue;
}
ha->subsys = kmalloc(sizeof(IPS_SUBSYS), GFP_KERNEL);
if (!ha->subsys) {
printk(KERN_WARNING "(%s%d) Unable to allocate host subsystem structure - skipping controller\n",
ips_name, ips_next_controller);
ha->active = 0;
ips_free(ha);
scsi_unregister(sh);
ips_ha[ips_next_controller] = 0;
ips_sh[ips_next_controller] = 0;
ips_next_controller++;
ips_num_controllers--;
continue;
}
ha->dummy = kmalloc(sizeof(IPS_IO_CMD), GFP_KERNEL);
if (!ha->dummy) {
printk(KERN_WARNING "(%s%d) Unable to allocate host dummy structure - skipping controller\n",
ips_name, ips_next_controller);
ha->active = 0;
ips_free(ha);
scsi_unregister(sh);
ips_ha[ips_next_controller] = 0;
ips_sh[ips_next_controller] = 0;
ips_next_controller++;
ips_num_controllers--;
continue;
}
for (count = PAGE_SIZE, ha->ioctl_order = 0;
count < ips_ioctlsize;
ha->ioctl_order++, count <<= 1);
ha->ioctl_data = (char *) __get_free_pages(GFP_KERNEL, ha->ioctl_order);
ha->ioctl_datasize = count;
if (!ha->ioctl_data) {
printk(KERN_WARNING "(%s%d) Unable to allocate ioctl data\n",
ips_name, ips_next_controller);
ha->ioctl_data = NULL;
ha->ioctl_order = 0;
ha->ioctl_datasize = 0;
}
/* Store away needed values for later use */
sh->io_port = io_addr;
sh->n_io_port = io_addr ? 255 : 0;
sh->unique_id = (io_addr) ? io_addr : mem_addr;
sh->irq = irq;
//sh->select_queue_depths = ips_select_queue_depth;
sh->sg_tablesize = sh->hostt->sg_tablesize;
sh->can_queue = sh->hostt->can_queue;
sh->cmd_per_lun = sh->hostt->cmd_per_lun;
sh->unchecked_isa_dma = sh->hostt->unchecked_isa_dma;
sh->use_clustering = sh->hostt->use_clustering;
#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,7)
sh->max_sectors = 128;
#endif
#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0)
sh->wish_block = FALSE;
#endif
/* Store info in HA structure */
ha->irq = irq;
ha->io_addr = io_addr;
ha->io_len = io_len;
ha->mem_addr = mem_addr;
ha->mem_len = mem_len;
ha->mem_ptr = mem_ptr;
ha->ioremap_ptr = ioremap_ptr;
ha->host_num = ips_next_controller;
ha->revision_id = revision_id;
ha->slot_num = PCI_SLOT(dev[i]->devfn);
ha->device_id = deviceID[i];
ha->subdevice_id = subdevice_id;
ha->pcidev = dev[i];
/*
* Setup Functions
*/
if (IPS_IS_MORPHEUS(ha)) {
/* morpheus */
ha->func.isintr = ips_isintr_morpheus;
ha->func.isinit = ips_isinit_morpheus;
ha->func.issue = ips_issue_i2o_memio;
ha->func.init = ips_init_morpheus;
ha->func.statupd = ips_statupd_morpheus;
ha->func.reset = ips_reset_morpheus;
ha->func.intr = ips_intr_morpheus;
ha->func.enableint = ips_enable_int_morpheus;
} else if (IPS_USE_MEMIO(ha)) {
/* copperhead w/MEMIO */
ha->func.isintr = ips_isintr_copperhead_memio;
ha->func.isinit = ips_isinit_copperhead_memio;
ha->func.init = ips_init_copperhead_memio;
ha->func.statupd = ips_statupd_copperhead_memio;
ha->func.statinit = ips_statinit_memio;
ha->func.reset = ips_reset_copperhead_memio;
ha->func.intr = ips_intr_copperhead;
ha->func.erasebios = ips_erase_bios_memio;
ha->func.programbios = ips_program_bios_memio;
ha->func.verifybios = ips_verify_bios_memio;
ha->func.enableint = ips_enable_int_copperhead_memio;
if (IPS_USE_I2O_DELIVER(ha))
ha->func.issue = ips_issue_i2o_memio;
else
ha->func.issue = ips_issue_copperhead_memio;
} else {
/* copperhead */
ha->func.isintr = ips_isintr_copperhead;
ha->func.isinit = ips_isinit_copperhead;
ha->func.init = ips_init_copperhead;
ha->func.statupd = ips_statupd_copperhead;
ha->func.statinit = ips_statinit;
ha->func.reset = ips_reset_copperhead;
ha->func.intr = ips_intr_copperhead;
ha->func.erasebios = ips_erase_bios;
ha->func.programbios = ips_program_bios;
ha->func.verifybios = ips_verify_bios;
ha->func.enableint = ips_enable_int_copperhead;
if (IPS_USE_I2O_DELIVER(ha))
ha->func.issue = ips_issue_i2o;
else
ha->func.issue = ips_issue_copperhead;
}
/*
* Initialize the card if it isn't already
*/
if (!(*ha->func.isinit)(ha)) {
if (!(*ha->func.init)(ha)) {
/*
* Initialization failed
*/
printk(KERN_WARNING "(%s%d) unable to initialize controller - skipping controller\n",
ips_name, ips_next_controller);
ha->active = 0;
ips_free(ha);
scsi_unregister(sh);
ips_ha[ips_next_controller] = 0;
ips_sh[ips_next_controller] = 0;
ips_next_controller++;
ips_num_controllers--;
continue;
}
}
/* install the interrupt handler */
if (request_irq(irq, do_ipsintr, SA_SHIRQ, ips_name, ha)) {
printk(KERN_WARNING "(%s%d) unable to install interrupt handler - skipping controller\n",
ips_name, ips_next_controller);
ha->active = 0;
ips_free(ha);
scsi_unregister(sh);
ips_ha[ips_next_controller] = 0;
ips_sh[ips_next_controller] = 0;
ips_next_controller++;
ips_num_controllers--;
continue;
}
/*
* Allocate a temporary SCB for initialization
*/
ha->max_cmds = 1;
if (!ips_allocatescbs(ha)) {
/* couldn't allocate a temp SCB */
printk(KERN_WARNING "(%s%d) unable to allocate CCBs - skipping contoller\n",
ips_name, ips_next_controller);
ha->active = 0;
ips_free(ha);
scsi_unregister(sh);
ips_ha[ips_next_controller] = 0;
ips_sh[ips_next_controller] = 0;
free_irq(ha->irq, ha);
ips_next_controller++;
ips_num_controllers--;
continue;
}
ips_next_controller++; /****************************************************************************/
} while ((dev[i] = pci_find_device(IPS_VENDORID, deviceID[i], dev[i]))); /* configure the function pointers to use the functions that will work */
} /* with the found version of the adapter */
/****************************************************************************/
static void ips_setup_funclist(ips_ha_t *ha){
/* /*
* Do Phase 2 Initialization * Setup Functions
* Controller init
*/ */
for (i = 0; i < ips_next_controller; i++) { if (IPS_IS_MORPHEUS(ha)) {
/* morpheus / marco / sebring */
if (ips_ha[i] == 0) { ha->func.isintr = ips_isintr_morpheus;
printk(KERN_WARNING "(%s%d) ignoring bad controller\n", ips_name, i); ha->func.isinit = ips_isinit_morpheus;
continue; ha->func.issue = ips_issue_i2o_memio;
} ha->func.init = ips_init_morpheus;
ha->func.statupd = ips_statupd_morpheus;
if (ips_init_phase2(i) != SUCCESS) ha->func.reset = ips_reset_morpheus;
ips_num_controllers--; ha->func.intr = ips_intr_morpheus;
ha->func.enableint = ips_enable_int_morpheus;
} else if (IPS_USE_MEMIO(ha)) {
/* copperhead w/MEMIO */
ha->func.isintr = ips_isintr_copperhead_memio;
ha->func.isinit = ips_isinit_copperhead_memio;
ha->func.init = ips_init_copperhead_memio;
ha->func.statupd = ips_statupd_copperhead_memio;
ha->func.statinit = ips_statinit_memio;
ha->func.reset = ips_reset_copperhead_memio;
ha->func.intr = ips_intr_copperhead;
ha->func.erasebios = ips_erase_bios_memio;
ha->func.programbios = ips_program_bios_memio;
ha->func.verifybios = ips_verify_bios_memio;
ha->func.enableint = ips_enable_int_copperhead_memio;
if (IPS_USE_I2O_DELIVER(ha))
ha->func.issue = ips_issue_i2o_memio;
else
ha->func.issue = ips_issue_copperhead_memio;
} else {
/* copperhead */
ha->func.isintr = ips_isintr_copperhead;
ha->func.isinit = ips_isinit_copperhead;
ha->func.init = ips_init_copperhead;
ha->func.statupd = ips_statupd_copperhead;
ha->func.statinit = ips_statinit;
ha->func.reset = ips_reset_copperhead;
ha->func.intr = ips_intr_copperhead;
ha->func.erasebios = ips_erase_bios;
ha->func.programbios = ips_program_bios;
ha->func.verifybios = ips_verify_bios;
ha->func.enableint = ips_enable_int_copperhead;
if (IPS_USE_I2O_DELIVER(ha))
ha->func.issue = ips_issue_i2o;
else
ha->func.issue = ips_issue_copperhead;
} }
if (ips_num_controllers > 0)
register_reboot_notifier(&ips_notifier);
return (ips_num_controllers);
#else
/* No PCI -- No ServeRAID */
return (0);
#endif /* CONFIG_PCI */
} }
/****************************************************************************/ /****************************************************************************/
...@@ -1282,9 +685,7 @@ ips_release(struct Scsi_Host *sh) { ...@@ -1282,9 +685,7 @@ ips_release(struct Scsi_Host *sh) {
if (i == IPS_MAX_ADAPTERS) { if (i == IPS_MAX_ADAPTERS) {
printk(KERN_WARNING "(%s) release, invalid Scsi_Host pointer.\n", printk(KERN_WARNING "(%s) release, invalid Scsi_Host pointer.\n",
ips_name); ips_name);
#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
BUG(); BUG();
#endif
return (FALSE); return (FALSE);
} }
...@@ -3303,7 +2704,7 @@ ips_next(ips_ha_t *ha, int intr) { ...@@ -3303,7 +2704,7 @@ ips_next(ips_ha_t *ha, int intr) {
sg = SC->request_buffer; sg = SC->request_buffer;
scb->sg_count = pci_map_sg(ha->pcidev, sg, SC->use_sg, scb->sg_count = pci_map_sg(ha->pcidev, sg, SC->use_sg,
IPS_DMA_DIR(scb)); scsi_to_pci_dma_dir(SC->sc_data_direction));
scb->flags |= IPS_SCB_MAP_SG; scb->flags |= IPS_SCB_MAP_SG;
if (scb->sg_count == 1) { if (scb->sg_count == 1) {
if (sg_dma_len(sg) > ha->max_xfer) { if (sg_dma_len(sg) > ha->max_xfer) {
...@@ -3363,7 +2764,8 @@ ips_next(ips_ha_t *ha, int intr) { ...@@ -3363,7 +2764,8 @@ ips_next(ips_ha_t *ha, int intr) {
scb->dcdb.transfer_length = scb->data_len; scb->dcdb.transfer_length = scb->data_len;
scb->data_busaddr = pci_map_single(ha->pcidev, SC->request_buffer, scb->data_busaddr = pci_map_single(ha->pcidev, SC->request_buffer,
scb->data_len, IPS_DMA_DIR(scb)); scb->data_len,
scsi_to_pci_dma_dir(SC->sc_data_direction));
scb->flags |= IPS_SCB_MAP_SINGLE; scb->flags |= IPS_SCB_MAP_SINGLE;
scb->sg_len = 0; scb->sg_len = 0;
} else { } else {
...@@ -4957,10 +4359,8 @@ ips_free(ips_ha_t *ha) { ...@@ -4957,10 +4359,8 @@ ips_free(ips_ha_t *ha) {
ha->mem_ptr = NULL; ha->mem_ptr = NULL;
} }
#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
if (ha->mem_addr) if (ha->mem_addr)
release_mem_region(ha->mem_addr, ha->mem_len); release_mem_region(ha->mem_addr, ha->mem_len);
#endif
ha->mem_addr = 0; ha->mem_addr = 0;
} }
...@@ -5489,6 +4889,29 @@ ips_init_morpheus(ips_ha_t *ha) { ...@@ -5489,6 +4889,29 @@ ips_init_morpheus(ips_ha_t *ha) {
Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0); Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
if (Post == 0x4F00) { /* If Flashing the Battery PIC */
printk(KERN_WARNING "Flashing Battery PIC, Please wait ...\n" );
/* Clear the interrupt bit */
Isr = (uint32_t) IPS_BIT_I960_MSG0I;
writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
for (i = 0; i < 120; i++) { /* Wait Up to 2 Min. for Completion */
Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
if (Post != 0x4F00)
break;
/* Delay for 1 Second */
MDELAY(IPS_ONE_SEC);
}
if (i >= 120) {
printk(KERN_WARNING "(%s%d) timeout waiting for Battery PIC Flash\n",
ips_name, ha->host_num);
return (0);
}
}
/* Clear the interrupt bit */ /* Clear the interrupt bit */
Isr = (uint32_t) IPS_BIT_I960_MSG0I; Isr = (uint32_t) IPS_BIT_I960_MSG0I;
writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR); writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
...@@ -6144,8 +5567,7 @@ ips_write_driver_status(ips_ha_t *ha, int intr) { ...@@ -6144,8 +5567,7 @@ ips_write_driver_status(ips_ha_t *ha, int intr) {
if (le32_to_cpu(ha->nvram->signature) != IPS_NVRAM_P5_SIG) { if (le32_to_cpu(ha->nvram->signature) != IPS_NVRAM_P5_SIG) {
DEBUG_VAR(1, "(%s%d) NVRAM page 5 has an invalid signature: %X.", DEBUG_VAR(1, "(%s%d) NVRAM page 5 has an invalid signature: %X.",
ips_name, ha->host_num, ha->nvram->signature); ips_name, ha->host_num, ha->nvram->signature);
ha->nvram->signature = IPS_NVRAM_P5_SIG;
return (1);
} }
DEBUG_VAR(2, "(%s%d) Ad Type: %d, Ad Slot: %d, BIOS: %c%c%c%c %c%c%c%c.", DEBUG_VAR(2, "(%s%d) Ad Type: %d, Ad Slot: %d, BIOS: %c%c%c%c %c%c%c%c.",
...@@ -7186,10 +6608,8 @@ static int ips_get_version_info(ips_ha_t *ha, IPS_VERSION_DATA *Buffer, int intr ...@@ -7186,10 +6608,8 @@ static int ips_get_version_info(ips_ha_t *ha, IPS_VERSION_DATA *Buffer, int intr
#if defined (MODULE) || (LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0))
static Scsi_Host_Template driver_template = IPS; static Scsi_Host_Template driver_template = IPS;
#include "scsi_module.c" #include "scsi_module.c"
#endif
static int ips_abort_init(ips_ha_t *ha, struct Scsi_Host *sh, int index){ static int ips_abort_init(ips_ha_t *ha, struct Scsi_Host *sh, int index){
ha->active = 0; ha->active = 0;
...@@ -7200,7 +6620,6 @@ static int ips_abort_init(ips_ha_t *ha, struct Scsi_Host *sh, int index){ ...@@ -7200,7 +6620,6 @@ static int ips_abort_init(ips_ha_t *ha, struct Scsi_Host *sh, int index){
return -1; return -1;
} }
#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* Routine Name: ips_remove_device */ /* Routine Name: ips_remove_device */
...@@ -7285,6 +6704,7 @@ static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr ) ...@@ -7285,6 +6704,7 @@ static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr )
dma_addr_t dma_address; dma_addr_t dma_address;
char *ioremap_ptr; char *ioremap_ptr;
char *mem_ptr; char *mem_ptr;
uint32_t IsDead;
METHOD_TRACE("ips_init_phase1", 1); METHOD_TRACE("ips_init_phase1", 1);
index = IPS_MAX_ADAPTERS; index = IPS_MAX_ADAPTERS;
...@@ -7382,7 +6802,7 @@ static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr ) ...@@ -7382,7 +6802,7 @@ static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr )
return ips_abort_init(ha, sh, index); return ips_abort_init(ha, sh, index);
} }
ha->adapt = pci_alloc_consistent(ha->pcidev, sizeof(IPS_ADAPTER) + ha->adapt = pci_alloc_consistent(pci_dev, sizeof(IPS_ADAPTER) +
sizeof(IPS_IO_CMD), &dma_address); sizeof(IPS_IO_CMD), &dma_address);
if (!ha->adapt) { if (!ha->adapt) {
printk(KERN_WARNING "Unable to allocate host adapt & dummy structures\n"); printk(KERN_WARNING "Unable to allocate host adapt & dummy structures\n");
...@@ -7460,54 +6880,15 @@ static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr ) ...@@ -7460,54 +6880,15 @@ static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr )
/* /*
* Setup Functions * Setup Functions
*/ */
if (IPS_IS_MORPHEUS(ha)) { ips_setup_funclist(ha);
/* morpheus */
ha->func.isintr = ips_isintr_morpheus;
ha->func.isinit = ips_isinit_morpheus;
ha->func.issue = ips_issue_i2o_memio;
ha->func.init = ips_init_morpheus;
ha->func.statupd = ips_statupd_morpheus;
ha->func.reset = ips_reset_morpheus;
ha->func.intr = ips_intr_morpheus;
ha->func.enableint = ips_enable_int_morpheus;
} else if (IPS_USE_MEMIO(ha)) {
/* copperhead w/MEMIO */
ha->func.isintr = ips_isintr_copperhead_memio;
ha->func.isinit = ips_isinit_copperhead_memio;
ha->func.init = ips_init_copperhead_memio;
ha->func.statupd = ips_statupd_copperhead_memio;
ha->func.statinit = ips_statinit_memio;
ha->func.reset = ips_reset_copperhead_memio;
ha->func.intr = ips_intr_copperhead;
ha->func.erasebios = ips_erase_bios_memio;
ha->func.programbios = ips_program_bios_memio;
ha->func.verifybios = ips_verify_bios_memio;
ha->func.enableint = ips_enable_int_copperhead_memio;
if (IPS_USE_I2O_DELIVER(ha))
ha->func.issue = ips_issue_i2o_memio;
else
ha->func.issue = ips_issue_copperhead_memio;
} else {
/* copperhead */
ha->func.isintr = ips_isintr_copperhead;
ha->func.isinit = ips_isinit_copperhead;
ha->func.init = ips_init_copperhead;
ha->func.statupd = ips_statupd_copperhead;
ha->func.statinit = ips_statinit;
ha->func.reset = ips_reset_copperhead;
ha->func.intr = ips_intr_copperhead;
ha->func.erasebios = ips_erase_bios;
ha->func.programbios = ips_program_bios;
ha->func.verifybios = ips_verify_bios;
ha->func.enableint = ips_enable_int_copperhead;
if (IPS_USE_I2O_DELIVER(ha))
ha->func.issue = ips_issue_i2o;
else
ha->func.issue = ips_issue_copperhead;
}
if ( IPS_IS_MORPHEUS( ha ) ) {
/* If Morpheus appears dead, reset it */
IsDead = readl( ha->mem_ptr + IPS_REG_I960_MSG1 );
if ( IsDead == 0xDEADBEEF ) {
ips_reset_morpheus( ha );
}
}
/* /*
* Initialize the card if it isn't already * Initialize the card if it isn't already
*/ */
...@@ -7542,7 +6923,6 @@ static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr ) ...@@ -7542,7 +6923,6 @@ static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr )
return SUCCESS; return SUCCESS;
} }
#endif
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* Routine Name: ips_init_phase2 */ /* Routine Name: ips_init_phase2 */
......
...@@ -349,28 +349,9 @@ ...@@ -349,28 +349,9 @@
#define IPS_SCSI_MP3_Removeable 0x04 #define IPS_SCSI_MP3_Removeable 0x04
#define IPS_SCSI_MP3_AllocateSurface 0x08 #define IPS_SCSI_MP3_AllocateSurface 0x08
/*
* Configuration Structure Flags
*/
#define IPS_CFG_USEROPT_UPDATECOUNT(cfg) (((cfg)->UserOpt & 0xffff000) >> 16)
#define IPS_CFG_USEROPT_CONCURSTART(cfg) (((cfg)->UserOpt & 0xf000) >> 12)
#define IPS_CFG_USEROPT_STARTUPDELAY(cfg) (((cfg)->UserOpt & 0xf00) >> 8)
#define IPS_CFG_USEROPT_REARRANGE(cfg) ((cfg)->UserOpt & 0x80)
#define IPS_CFG_USEROPT_CDBOOT(cfg) ((cfg)->UserOpt & 0x40)
#define IPS_CFG_USEROPT_CLUSTER(cfg) ((cfg)->UserOpt & 0x20)
/*
* Host adapter Flags (bit numbers)
*/
#define IPS_IN_INTR 0
#define IPS_IN_ABORT 1
#define IPS_IN_RESET 2
/* /*
* SCB Flags * SCB Flags
*/ */
#define IPS_SCB_ACTIVE 0x00001
#define IPS_SCB_WAITING 0x00002
#define IPS_SCB_MAP_SG 0x00008 #define IPS_SCB_MAP_SG 0x00008
#define IPS_SCB_MAP_SINGLE 0X00010 #define IPS_SCB_MAP_SINGLE 0X00010
...@@ -381,7 +362,6 @@ ...@@ -381,7 +362,6 @@
#define IPS_COPPIOCCMD (('C'<<8) | 66) #define IPS_COPPIOCCMD (('C'<<8) | 66)
#define IPS_NUMCTRLS (('C'<<8) | 68) #define IPS_NUMCTRLS (('C'<<8) | 68)
#define IPS_CTRLINFO (('C'<<8) | 69) #define IPS_CTRLINFO (('C'<<8) | 69)
#define IPS_FLASHBIOS (('C'<<8) | 70)
/* flashing defines */ /* flashing defines */
#define IPS_FW_IMAGE 0x00 #define IPS_FW_IMAGE 0x00
...@@ -406,36 +386,7 @@ ...@@ -406,36 +386,7 @@
/* /*
* Scsi_Host Template * Scsi_Host Template
*/ */
#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0) #if LINUX_VERSION_CODE < LinuxVersionCode(2,5,0)
#define IPS { \
.module = NULL, \
.proc_info = NULL, \
.proc_dir = NULL, \
.name = NULL, \
.detect = ips_detect, \
.release = ips_release, \
.info = ips_info, \
.command = NULL, \
.queuecommand = ips_queue, \
.eh_strategy_handler = NULL, \
.eh_abort_handler = ips_eh_abort, \
.eh_device_reset_handler = NULL, \
.eh_bus_reset_handler = NULL, \
.eh_host_reset_handler = ips_eh_reset, \
.abort = NULL, \
.reset = NULL, \
.slave_attach = NULL, \
.bios_param = ips_biosparam,\
.can_queue = 0, \
.this_id = -1, \
.sg_tablesize = IPS_MAX_SG, \
.cmd_per_lun = 3, \
.present = 0, \
.unchecked_isa_dma = 0, \
.use_clustering = ENABLE_CLUSTERING, \
.use_new_eh_code = 1 \
}
#elif LINUX_VERSION_CODE < LinuxVersionCode(2,5,0)
#define IPS{ \ #define IPS{ \
.module = NULL, \ .module = NULL, \
.proc_info = NULL, \ .proc_info = NULL, \
...@@ -1005,19 +956,6 @@ typedef struct { ...@@ -1005,19 +956,6 @@ typedef struct {
int option_value; int option_value;
} IPS_OPTION; } IPS_OPTION;
typedef struct {
void *userbuffer;
uint32_t usersize;
void *kernbuffer;
uint32_t kernsize;
void *ha;
void *SC;
void *pt;
struct semaphore *sem;
uint32_t offset;
uint32_t retcode;
} IPS_FLASH_DATA;
/* /*
* Status Info * Status Info
*/ */
......
...@@ -50,8 +50,8 @@ ...@@ -50,8 +50,8 @@
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/parisc-device.h>
#include <asm/delay.h> #include <asm/delay.h>
#include <asm/gsc.h>
#include <linux/module.h> #include <linux/module.h>
......
...@@ -82,6 +82,7 @@ ...@@ -82,6 +82,7 @@
** Etc... ** Etc...
** **
** Supported NCR/SYMBIOS chips: ** Supported NCR/SYMBIOS chips:
** 53C720 (Wide, Fast SCSI-2, HP Zalon)
** 53C810 (8 bits, Fast SCSI-2, no rom BIOS) ** 53C810 (8 bits, Fast SCSI-2, no rom BIOS)
** 53C815 (8 bits, Fast SCSI-2, on board rom BIOS) ** 53C815 (8 bits, Fast SCSI-2, on board rom BIOS)
** 53C820 (Wide, Fast SCSI-2, no rom BIOS) ** 53C820 (Wide, Fast SCSI-2, no rom BIOS)
...@@ -130,6 +131,8 @@ ...@@ -130,6 +131,8 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/ioport.h> #include <linux/ioport.h>
...@@ -178,6 +181,24 @@ ...@@ -178,6 +181,24 @@
typedef u32 u_int32; typedef u32 u_int32;
typedef u64 u_int64; typedef u64 u_int64;
typedef u_long vm_offset_t; typedef u_long vm_offset_t;
#ifdef __hppa__
/*
* Yuck. Current plan is to use ncr58c8xx.c for non-pci big endian
* chips, and sym53c8xx.c for pci little endian chips. Define this
* here so it gets seen by sym53c8xx_defs.h, pulled in via ncr53c8xx.h.
*/
#define SCSI_NCR_BIG_ENDIAN
/* INTFLY interrupts don't always seem to get serviced atm..... */
#define SIMULATED_INTFLY
#endif
#if defined(CONFIG_SCSI_ZALON) || defined(CONFIG_SCSI_ZALON_MODULE)
#define ENABLE_SCSI_ZALON
#include <asm/parisc-device.h>
#include "zalon.h"
#endif
#include "ncr53c8xx.h" #include "ncr53c8xx.h"
/* /*
...@@ -379,6 +400,8 @@ static Scsi_Host_Template *the_template = NULL; ...@@ -379,6 +400,8 @@ static Scsi_Host_Template *the_template = NULL;
static void ncr53c8xx_intr(int irq, void *dev_id, struct pt_regs * regs); static void ncr53c8xx_intr(int irq, void *dev_id, struct pt_regs * regs);
static void ncr53c8xx_timeout(unsigned long np); static void ncr53c8xx_timeout(unsigned long np);
static int ncr53c8xx_proc_info(char *buffer, char **start, off_t offset,
int length, int hostno, int func);
#define initverbose (driver_setup.verbose) #define initverbose (driver_setup.verbose)
#define bootverbose (np->verbose) #define bootverbose (np->verbose)
...@@ -450,7 +473,8 @@ static u_char Tekram_sync[16] __initdata = ...@@ -450,7 +473,8 @@ static u_char Tekram_sync[16] __initdata =
#define SIR_RESEL_BAD_I_T_L (15) #define SIR_RESEL_BAD_I_T_L (15)
#define SIR_RESEL_BAD_I_T_L_Q (16) #define SIR_RESEL_BAD_I_T_L_Q (16)
#define SIR_DONE_OVERFLOW (17) #define SIR_DONE_OVERFLOW (17)
#define SIR_MAX (17) #define SIR_INTFLY (18)
#define SIR_MAX (18)
/*========================================================== /*==========================================================
** **
...@@ -622,6 +646,15 @@ struct tcb { ...@@ -622,6 +646,15 @@ struct tcb {
** negotiation of wide and synch transfer and device quirks. ** negotiation of wide and synch transfer and device quirks.
**---------------------------------------------------------------- **----------------------------------------------------------------
*/ */
#ifdef SCSI_NCR_BIG_ENDIAN
/*0*/ u_short period;
/*2*/ u_char sval;
/*3*/ u_char minsync;
/*0*/ u_char wval;
/*1*/ u_char widedone;
/*2*/ u_char quirks;
/*3*/ u_char maxoffs;
#else
/*0*/ u_char minsync; /*0*/ u_char minsync;
/*1*/ u_char sval; /*1*/ u_char sval;
/*2*/ u_short period; /*2*/ u_short period;
...@@ -629,6 +662,7 @@ struct tcb { ...@@ -629,6 +662,7 @@ struct tcb {
/*1*/ u_char quirks; /*1*/ u_char quirks;
/*2*/ u_char widedone; /*2*/ u_char widedone;
/*3*/ u_char wval; /*3*/ u_char wval;
#endif
#ifdef SCSI_NCR_INTEGRITY_CHECKING #ifdef SCSI_NCR_INTEGRITY_CHECKING
u_char ic_min_sync; u_char ic_min_sync;
...@@ -839,10 +873,17 @@ struct head { ...@@ -839,10 +873,17 @@ struct head {
/* /*
** Last four bytes (host) ** Last four bytes (host)
*/ */
#ifdef SCSI_NCR_BIG_ENDIAN
#define actualquirks phys.header.status[3]
#define host_status phys.header.status[2]
#define scsi_status phys.header.status[1]
#define parity_status phys.header.status[0]
#else
#define actualquirks phys.header.status[0] #define actualquirks phys.header.status[0]
#define host_status phys.header.status[1] #define host_status phys.header.status[1]
#define scsi_status phys.header.status[2] #define scsi_status phys.header.status[2]
#define parity_status phys.header.status[3] #define parity_status phys.header.status[3]
#endif
/* /*
** First four bytes (script) ** First four bytes (script)
...@@ -1026,8 +1067,8 @@ struct ncb { ...@@ -1026,8 +1067,8 @@ struct ncb {
** be used for probing adapter implementation differences. ** be used for probing adapter implementation differences.
**---------------------------------------------------------------- **----------------------------------------------------------------
*/ */
u_char sv_scntl0, sv_scntl3, sv_dmode, sv_dcntl, sv_ctest3, sv_ctest4, u_char sv_scntl0, sv_scntl3, sv_dmode, sv_dcntl, sv_ctest0, sv_ctest3,
sv_ctest5, sv_gpcntl, sv_stest2, sv_stest4; sv_ctest4, sv_ctest5, sv_gpcntl, sv_stest2, sv_stest4;
/*---------------------------------------------------------------- /*----------------------------------------------------------------
** Actual initial value of IO register bits used by the ** Actual initial value of IO register bits used by the
...@@ -1035,8 +1076,8 @@ struct ncb { ...@@ -1035,8 +1076,8 @@ struct ncb {
** features that are to be enabled. ** features that are to be enabled.
**---------------------------------------------------------------- **----------------------------------------------------------------
*/ */
u_char rv_scntl0, rv_scntl3, rv_dmode, rv_dcntl, rv_ctest3, rv_ctest4, u_char rv_scntl0, rv_scntl3, rv_dmode, rv_dcntl, rv_ctest0, rv_ctest3,
rv_ctest5, rv_stest2; rv_ctest4, rv_ctest5, rv_stest2;
/*---------------------------------------------------------------- /*----------------------------------------------------------------
** Targets management. ** Targets management.
...@@ -1078,7 +1119,7 @@ struct ncb { ...@@ -1078,7 +1119,7 @@ struct ncb {
** General controller parameters and configuration. ** General controller parameters and configuration.
**---------------------------------------------------------------- **----------------------------------------------------------------
*/ */
pcidev_t pdev; device_t dev;
u_short device_id; /* PCI device id */ u_short device_id; /* PCI device id */
u_char revision_id; /* PCI device revision id */ u_char revision_id; /* PCI device revision id */
u_char bus; /* PCI BUS number */ u_char bus; /* PCI BUS number */
...@@ -1158,7 +1199,7 @@ struct ncb { ...@@ -1158,7 +1199,7 @@ struct ncb {
*/ */
struct ccb *ccb; /* Global CCB */ struct ccb *ccb; /* Global CCB */
struct usrcmd user; /* Command from user */ struct usrcmd user; /* Command from user */
u_char release_stage; /* Synchronisation stage on release */ volatile u_char release_stage; /* Synchronisation stage on release */
#ifdef SCSI_NCR_INTEGRITY_CHECKING #ifdef SCSI_NCR_INTEGRITY_CHECKING
/*---------------------------------------------------------------- /*----------------------------------------------------------------
...@@ -1196,6 +1237,23 @@ struct ncb { ...@@ -1196,6 +1237,23 @@ struct ncb {
**---------------------------------------------------------- **----------------------------------------------------------
*/ */
/*
** For HP Zalon/53c720 systems, the Zalon interface
** between CPU and 53c720 does prefetches, which causes
** problems with self modifying scripts. The problem
** is overcome by calling a dummy subroutine after each
** modification, to force a refetch of the script on
** return from the subroutine.
*/
#ifdef ENABLE_SCSI_ZALON
#define PREFETCH_FLUSH_CNT 2
#define PREFETCH_FLUSH SCR_CALL, PADDRH (wait_dma),
#else
#define PREFETCH_FLUSH_CNT 0
#define PREFETCH_FLUSH
#endif
/* /*
** Script fragments which are loaded into the on-chip RAM ** Script fragments which are loaded into the on-chip RAM
** of 825A, 875 and 895 chips. ** of 825A, 875 and 895 chips.
...@@ -1204,7 +1262,7 @@ struct script { ...@@ -1204,7 +1262,7 @@ struct script {
ncrcmd start [ 5]; ncrcmd start [ 5];
ncrcmd startpos [ 1]; ncrcmd startpos [ 1];
ncrcmd select [ 6]; ncrcmd select [ 6];
ncrcmd select2 [ 9]; ncrcmd select2 [ 9 + PREFETCH_FLUSH_CNT];
ncrcmd loadpos [ 4]; ncrcmd loadpos [ 4];
ncrcmd send_ident [ 9]; ncrcmd send_ident [ 9];
ncrcmd prepare [ 6]; ncrcmd prepare [ 6];
...@@ -1220,7 +1278,7 @@ struct script { ...@@ -1220,7 +1278,7 @@ struct script {
ncrcmd setmsg [ 7]; ncrcmd setmsg [ 7];
ncrcmd cleanup [ 6]; ncrcmd cleanup [ 6];
ncrcmd complete [ 9]; ncrcmd complete [ 9];
ncrcmd cleanup_ok [ 8]; ncrcmd cleanup_ok [ 8 + PREFETCH_FLUSH_CNT];
ncrcmd cleanup0 [ 1]; ncrcmd cleanup0 [ 1];
#ifndef SCSI_NCR_CCB_DONE_SUPPORT #ifndef SCSI_NCR_CCB_DONE_SUPPORT
ncrcmd signal [ 12]; ncrcmd signal [ 12];
...@@ -1238,11 +1296,11 @@ struct script { ...@@ -1238,11 +1296,11 @@ struct script {
ncrcmd idle [ 2]; ncrcmd idle [ 2];
ncrcmd reselect [ 8]; ncrcmd reselect [ 8];
ncrcmd reselected [ 8]; ncrcmd reselected [ 8];
ncrcmd resel_dsa [ 6]; ncrcmd resel_dsa [ 6 + PREFETCH_FLUSH_CNT];
ncrcmd loadpos1 [ 4]; ncrcmd loadpos1 [ 4];
ncrcmd resel_lun [ 6]; ncrcmd resel_lun [ 6];
ncrcmd resel_tag [ 6]; ncrcmd resel_tag [ 6];
ncrcmd jump_to_nexus [ 4]; ncrcmd jump_to_nexus [ 4 + PREFETCH_FLUSH_CNT];
ncrcmd nexus_indirect [ 4]; ncrcmd nexus_indirect [ 4];
ncrcmd resel_notag [ 4]; ncrcmd resel_notag [ 4];
ncrcmd data_in [MAX_SCATTERL * 4]; ncrcmd data_in [MAX_SCATTERL * 4];
...@@ -1263,7 +1321,7 @@ struct scripth { ...@@ -1263,7 +1321,7 @@ struct scripth {
#endif #endif
ncrcmd select_no_atn [ 8]; ncrcmd select_no_atn [ 8];
ncrcmd cancel [ 4]; ncrcmd cancel [ 4];
ncrcmd skip [ 9]; ncrcmd skip [ 9 + PREFETCH_FLUSH_CNT];
ncrcmd skip2 [ 19]; ncrcmd skip2 [ 19];
ncrcmd par_err_data_in [ 6]; ncrcmd par_err_data_in [ 6];
ncrcmd par_err_other [ 4]; ncrcmd par_err_other [ 4];
...@@ -1296,9 +1354,10 @@ struct scripth { ...@@ -1296,9 +1354,10 @@ struct scripth {
ncrcmd bad_i_t_l_q [ 4]; ncrcmd bad_i_t_l_q [ 4];
ncrcmd bad_target [ 8]; ncrcmd bad_target [ 8];
ncrcmd bad_status [ 8]; ncrcmd bad_status [ 8];
ncrcmd start_ram [ 4]; ncrcmd start_ram [ 4 + PREFETCH_FLUSH_CNT];
ncrcmd start_ram0 [ 4]; ncrcmd start_ram0 [ 4];
ncrcmd sto_restart [ 5]; ncrcmd sto_restart [ 5];
ncrcmd wait_dma [ 2];
ncrcmd snooptest [ 9]; ncrcmd snooptest [ 9];
ncrcmd snoopend [ 2]; ncrcmd snoopend [ 2];
}; };
...@@ -1324,6 +1383,7 @@ static lcb_p ncr_setup_lcb (ncb_p np, u_char tn, u_char ln, ...@@ -1324,6 +1383,7 @@ static lcb_p ncr_setup_lcb (ncb_p np, u_char tn, u_char ln,
static void ncr_getclock (ncb_p np, int mult); static void ncr_getclock (ncb_p np, int mult);
static void ncr_selectclock (ncb_p np, u_char scntl3); static void ncr_selectclock (ncb_p np, u_char scntl3);
static ccb_p ncr_get_ccb (ncb_p np, u_char tn, u_char ln); static ccb_p ncr_get_ccb (ncb_p np, u_char tn, u_char ln);
static void ncr_chip_reset (ncb_p np, int delay);
static void ncr_init (ncb_p np, int reset, char * msg, u_long code); static void ncr_init (ncb_p np, int reset, char * msg, u_long code);
static int ncr_int_sbmc (ncb_p np); static int ncr_int_sbmc (ncb_p np);
static int ncr_int_par (ncb_p np); static int ncr_int_par (ncb_p np);
...@@ -1523,6 +1583,10 @@ static struct script script0 __initdata = { ...@@ -1523,6 +1583,10 @@ static struct script script0 __initdata = {
RADDR (dsa), RADDR (dsa),
PADDR (loadpos), PADDR (loadpos),
/* /*
** Flush script prefetch if required
*/
PREFETCH_FLUSH
/*
** then we do the actual copy. ** then we do the actual copy.
*/ */
SCR_COPY (sizeof (struct head)), SCR_COPY (sizeof (struct head)),
...@@ -1823,6 +1887,10 @@ static struct script script0 __initdata = { ...@@ -1823,6 +1887,10 @@ static struct script script0 __initdata = {
SCR_COPY_F (4), SCR_COPY_F (4),
RADDR (dsa), RADDR (dsa),
PADDR (cleanup0), PADDR (cleanup0),
/*
** Flush script prefetch if required
*/
PREFETCH_FLUSH
SCR_COPY (sizeof (struct head)), SCR_COPY (sizeof (struct head)),
NADDR (header), NADDR (header),
}/*-------------------------< CLEANUP0 >--------------------*/,{ }/*-------------------------< CLEANUP0 >--------------------*/,{
...@@ -1852,8 +1920,13 @@ static struct script script0 __initdata = { ...@@ -1852,8 +1920,13 @@ static struct script script0 __initdata = {
/* /*
** ... signal completion to the host ** ... signal completion to the host
*/ */
#ifdef SIMULATED_INTFLY
SCR_INT,
SIR_INTFLY,
#else
SCR_INT_FLY, SCR_INT_FLY,
0, 0,
#endif
/* /*
** Auf zu neuen Schandtaten! ** Auf zu neuen Schandtaten!
*/ */
...@@ -1872,8 +1945,13 @@ static struct script script0 __initdata = { ...@@ -1872,8 +1945,13 @@ static struct script script0 __initdata = {
SCR_INT, SCR_INT,
SIR_DONE_OVERFLOW, SIR_DONE_OVERFLOW,
}/*------------------------< DONE_END >---------------------*/,{ }/*------------------------< DONE_END >---------------------*/,{
#ifdef SIMULATED_INTFLY
SCR_INT,
SIR_INTFLY,
#else
SCR_INT_FLY, SCR_INT_FLY,
0, 0,
#endif
SCR_COPY (4), SCR_COPY (4),
RADDR (temp), RADDR (temp),
PADDR (done_pos), PADDR (done_pos),
...@@ -2051,6 +2129,10 @@ static struct script script0 __initdata = { ...@@ -2051,6 +2129,10 @@ static struct script script0 __initdata = {
RADDR (dsa), RADDR (dsa),
PADDR (loadpos1), PADDR (loadpos1),
/* /*
** Flush script prefetch if required
*/
PREFETCH_FLUSH
/*
** then we do the actual copy. ** then we do the actual copy.
*/ */
SCR_COPY (sizeof (struct head)), SCR_COPY (sizeof (struct head)),
...@@ -2112,6 +2194,10 @@ static struct script script0 __initdata = { ...@@ -2112,6 +2194,10 @@ static struct script script0 __initdata = {
SCR_COPY_F (4), SCR_COPY_F (4),
RADDR (temp), RADDR (temp),
PADDR (nexus_indirect), PADDR (nexus_indirect),
/*
** Flush script prefetch if required
*/
PREFETCH_FLUSH
SCR_COPY (4), SCR_COPY (4),
}/*-------------------------< NEXUS_INDIRECT >-------------------*/,{ }/*-------------------------< NEXUS_INDIRECT >-------------------*/,{
0, 0,
...@@ -2268,6 +2354,10 @@ static struct scripth scripth0 __initdata = { ...@@ -2268,6 +2354,10 @@ static struct scripth scripth0 __initdata = {
RADDR (dsa), RADDR (dsa),
PADDRH (skip2), PADDRH (skip2),
/* /*
** Flush script prefetch if required
*/
PREFETCH_FLUSH
/*
** then we do the actual copy. ** then we do the actual copy.
*/ */
SCR_COPY (sizeof (struct head)), SCR_COPY (sizeof (struct head)),
...@@ -2778,6 +2868,10 @@ static struct scripth scripth0 __initdata = { ...@@ -2778,6 +2868,10 @@ static struct scripth scripth0 __initdata = {
SCR_COPY_F (4), SCR_COPY_F (4),
RADDR (scratcha), RADDR (scratcha),
PADDRH (start_ram0), PADDRH (start_ram0),
/*
** Flush script prefetch if required
*/
PREFETCH_FLUSH
SCR_COPY (sizeof (struct script)), SCR_COPY (sizeof (struct script)),
}/*-------------------------< START_RAM0 >--------------------*/,{ }/*-------------------------< START_RAM0 >--------------------*/,{
0, 0,
...@@ -2795,6 +2889,17 @@ static struct scripth scripth0 __initdata = { ...@@ -2795,6 +2889,17 @@ static struct scripth scripth0 __initdata = {
PADDR (startpos), PADDR (startpos),
SCR_JUMP, SCR_JUMP,
PADDR (start), PADDR (start),
}/*-------------------------< WAIT_DMA >-------------------*/,{
/*
** For HP Zalon/53c720 systems, the Zalon interface
** between CPU and 53c720 does prefetches, which causes
** problems with self modifying scripts. The problem
** is overcome by calling a dummy subroutine after each
** modification, to force a refetch of the script on
** return from the subroutine.
*/
SCR_RETURN,
0,
}/*-------------------------< SNOOPTEST >-------------------*/,{ }/*-------------------------< SNOOPTEST >-------------------*/,{
/* /*
** Read the variable. ** Read the variable.
...@@ -3128,9 +3233,12 @@ static u_long div_10M[] = ...@@ -3128,9 +3233,12 @@ static u_long div_10M[] =
#define burst_length(bc) (!(bc))? 0 : 1 << (bc) #define burst_length(bc) (!(bc))? 0 : 1 << (bc)
/* /*
* Burst code from io register bits. * Burst code from io register bits. Burst enable is ctest0 for c720,
* ctest4 for others.
*/ */
#define burst_code(dmode, ctest4, ctest5) \ #define burst_code(dmode, ctest0, ctest4, ctest5) \
(np->device_id == PSEUDO_ZALON_720_ID) ? \
(ctest0) & 0x80? 0 : (((dmode) & 0xc0) >> 6) + 1 : \
(ctest4) & 0x80? 0 : (((dmode) & 0xc0) >> 6) + ((ctest5) & 0x04) + 1 (ctest4) & 0x80? 0 : (((dmode) & 0xc0) >> 6) + ((ctest5) & 0x04) + 1
/* /*
...@@ -3138,12 +3246,14 @@ static u_long div_10M[] = ...@@ -3138,12 +3246,14 @@ static u_long div_10M[] =
*/ */
static inline void ncr_init_burst(ncb_p np, u_char bc) static inline void ncr_init_burst(ncb_p np, u_char bc)
{ {
np->rv_ctest4 &= ~0x80; u_char *be = (np->device_id == PSEUDO_ZALON_720_ID) ?
&np->rv_ctest0 : &np->rv_ctest4;
*be &= ~0x80;
np->rv_dmode &= ~(0x3 << 6); np->rv_dmode &= ~(0x3 << 6);
np->rv_ctest5 &= ~0x4; np->rv_ctest5 &= ~0x4;
if (!bc) { if (!bc) {
np->rv_ctest4 |= 0x80; *be |= 0x80;
} }
else { else {
--bc; --bc;
...@@ -3220,6 +3330,7 @@ static int __init ncr_prepare_setting(ncb_p np, ncr_nvram *nvram) ...@@ -3220,6 +3330,7 @@ static int __init ncr_prepare_setting(ncb_p np, ncr_nvram *nvram)
np->sv_scntl3 = INB(nc_scntl3) & 0x07; np->sv_scntl3 = INB(nc_scntl3) & 0x07;
np->sv_dmode = INB(nc_dmode) & 0xce; np->sv_dmode = INB(nc_dmode) & 0xce;
np->sv_dcntl = INB(nc_dcntl) & 0xa8; np->sv_dcntl = INB(nc_dcntl) & 0xa8;
np->sv_ctest0 = INB(nc_ctest0) & 0x84;
np->sv_ctest3 = INB(nc_ctest3) & 0x01; np->sv_ctest3 = INB(nc_ctest3) & 0x01;
np->sv_ctest4 = INB(nc_ctest4) & 0x80; np->sv_ctest4 = INB(nc_ctest4) & 0x80;
np->sv_ctest5 = INB(nc_ctest5) & 0x24; np->sv_ctest5 = INB(nc_ctest5) & 0x24;
...@@ -3306,10 +3417,11 @@ static int __init ncr_prepare_setting(ncb_p np, ncr_nvram *nvram) ...@@ -3306,10 +3417,11 @@ static int __init ncr_prepare_setting(ncb_p np, ncr_nvram *nvram)
np->rv_scntl0 = np->sv_scntl0; np->rv_scntl0 = np->sv_scntl0;
np->rv_dmode = np->sv_dmode; np->rv_dmode = np->sv_dmode;
np->rv_dcntl = np->sv_dcntl; np->rv_dcntl = np->sv_dcntl;
np->rv_ctest0 = np->sv_ctest0;
np->rv_ctest3 = np->sv_ctest3; np->rv_ctest3 = np->sv_ctest3;
np->rv_ctest4 = np->sv_ctest4; np->rv_ctest4 = np->sv_ctest4;
np->rv_ctest5 = np->sv_ctest5; np->rv_ctest5 = np->sv_ctest5;
burst_max = burst_code(np->sv_dmode, np->sv_ctest4, np->sv_ctest5); burst_max = burst_code(np->sv_dmode, np->sv_ctest0, np->sv_ctest4, np->sv_ctest5);
#else #else
/* /*
...@@ -3317,7 +3429,7 @@ static int __init ncr_prepare_setting(ncb_p np, ncr_nvram *nvram) ...@@ -3317,7 +3429,7 @@ static int __init ncr_prepare_setting(ncb_p np, ncr_nvram *nvram)
*/ */
burst_max = driver_setup.burst_max; burst_max = driver_setup.burst_max;
if (burst_max == 255) if (burst_max == 255)
burst_max = burst_code(np->sv_dmode, np->sv_ctest4, np->sv_ctest5); burst_max = burst_code(np->sv_dmode, np->sv_ctest0, np->sv_ctest4, np->sv_ctest5);
if (burst_max > 7) if (burst_max > 7)
burst_max = 7; burst_max = 7;
if (burst_max > np->maxburst) if (burst_max > np->maxburst)
...@@ -3340,6 +3452,12 @@ static int __init ncr_prepare_setting(ncb_p np, ncr_nvram *nvram) ...@@ -3340,6 +3452,12 @@ static int __init ncr_prepare_setting(ncb_p np, ncr_nvram *nvram)
np->rv_ctest3 |= WRIE; /* Write and Invalidate */ np->rv_ctest3 |= WRIE; /* Write and Invalidate */
if (np->features & FE_DFS) if (np->features & FE_DFS)
np->rv_ctest5 |= DFS; /* Dma Fifo Size */ np->rv_ctest5 |= DFS; /* Dma Fifo Size */
if (np->features & FE_MUX)
np->rv_ctest4 |= MUX; /* Host bus multiplex mode */
if (np->features & FE_EA)
np->rv_dcntl |= EA; /* Enable ACK */
if (np->features & FE_EHP)
np->rv_ctest0 |= EHP; /* Even host parity */
/* /*
** Select some other ** Select some other
...@@ -3539,6 +3657,7 @@ ncr_attach (Scsi_Host_Template *tpnt, int unit, ncr_device *device) ...@@ -3539,6 +3657,7 @@ ncr_attach (Scsi_Host_Template *tpnt, int unit, ncr_device *device)
ncr_nvram *nvram = device->nvram; ncr_nvram *nvram = device->nvram;
int i; int i;
#ifndef ENABLE_SCSI_ZALON
printk(KERN_INFO "ncr53c%s-%d: rev 0x%x on pci bus %d device %d function %d " printk(KERN_INFO "ncr53c%s-%d: rev 0x%x on pci bus %d device %d function %d "
#ifdef __sparc__ #ifdef __sparc__
"irq %s\n", "irq %s\n",
...@@ -3552,6 +3671,7 @@ ncr_attach (Scsi_Host_Template *tpnt, int unit, ncr_device *device) ...@@ -3552,6 +3671,7 @@ ncr_attach (Scsi_Host_Template *tpnt, int unit, ncr_device *device)
__irq_itoa(device->slot.irq)); __irq_itoa(device->slot.irq));
#else #else
device->slot.irq); device->slot.irq);
#endif
#endif #endif
/* /*
...@@ -3564,11 +3684,11 @@ ncr_attach (Scsi_Host_Template *tpnt, int unit, ncr_device *device) ...@@ -3564,11 +3684,11 @@ ncr_attach (Scsi_Host_Template *tpnt, int unit, ncr_device *device)
/* /*
** Allocate the host control block. ** Allocate the host control block.
*/ */
np = __m_calloc_dma(device->pdev, sizeof(struct ncb), "NCB"); np = __m_calloc_dma(device->dev, sizeof(struct ncb), "NCB");
if (!np) if (!np)
goto attach_error; goto attach_error;
NCR_INIT_LOCK_NCB(np); NCR_INIT_LOCK_NCB(np);
np->pdev = device->pdev; np->dev = device->dev;
np->p_ncb = vtobus(np); np->p_ncb = vtobus(np);
host_data->ncb = np; host_data->ncb = np;
...@@ -3650,7 +3770,9 @@ ncr_attach (Scsi_Host_Template *tpnt, int unit, ncr_device *device) ...@@ -3650,7 +3770,9 @@ ncr_attach (Scsi_Host_Template *tpnt, int unit, ncr_device *device)
** Try to map the controller chip into iospace. ** Try to map the controller chip into iospace.
*/ */
#ifndef ENABLE_SCSI_ZALON
request_region(device->slot.io_port, 128, "ncr53c8xx"); request_region(device->slot.io_port, 128, "ncr53c8xx");
#endif
np->base_io = device->slot.io_port; np->base_io = device->slot.io_port;
#ifdef SCSI_NCR_NVRAM_SUPPORT #ifdef SCSI_NCR_NVRAM_SUPPORT
...@@ -3707,7 +3829,7 @@ ncr_attach (Scsi_Host_Template *tpnt, int unit, ncr_device *device) ...@@ -3707,7 +3829,7 @@ ncr_attach (Scsi_Host_Template *tpnt, int unit, ncr_device *device)
instance->dma_channel = 0; instance->dma_channel = 0;
instance->cmd_per_lun = MAX_TAGS; instance->cmd_per_lun = MAX_TAGS;
instance->can_queue = (MAX_START-4); instance->can_queue = (MAX_START-4);
scsi_set_pci_device(instance, device->pdev); scsi_set_device(instance, device->dev);
#ifdef SCSI_NCR_INTEGRITY_CHECKING #ifdef SCSI_NCR_INTEGRITY_CHECKING
np->check_integrity = 0; np->check_integrity = 0;
...@@ -3762,10 +3884,7 @@ ncr_attach (Scsi_Host_Template *tpnt, int unit, ncr_device *device) ...@@ -3762,10 +3884,7 @@ ncr_attach (Scsi_Host_Template *tpnt, int unit, ncr_device *device)
/* /*
** Reset chip. ** Reset chip.
*/ */
ncr_chip_reset(np, 100);
OUTB (nc_istat, SRST);
UDELAY (100);
OUTB (nc_istat, 0 );
/* /*
** Now check the cache handling of the pci chipset. ** Now check the cache handling of the pci chipset.
...@@ -3882,7 +4001,9 @@ ncr_attach (Scsi_Host_Template *tpnt, int unit, ncr_device *device) ...@@ -3882,7 +4001,9 @@ ncr_attach (Scsi_Host_Template *tpnt, int unit, ncr_device *device)
#ifdef DEBUG_NCR53C8XX #ifdef DEBUG_NCR53C8XX
printk(KERN_DEBUG "%s: releasing IO region %x[%d]\n", ncr_name(np), np->base_io, 128); printk(KERN_DEBUG "%s: releasing IO region %x[%d]\n", ncr_name(np), np->base_io, 128);
#endif #endif
#ifndef ENABLE_SCSI_ZALON
release_region(np->base_io, 128); release_region(np->base_io, 128);
#endif
} }
if (np->irq) { if (np->irq) {
#ifdef DEBUG_NCR53C8XX #ifdef DEBUG_NCR53C8XX
...@@ -3907,7 +4028,7 @@ ncr_attach (Scsi_Host_Template *tpnt, int unit, ncr_device *device) ...@@ -3907,7 +4028,7 @@ ncr_attach (Scsi_Host_Template *tpnt, int unit, ncr_device *device)
scsi_unregister(instance); scsi_unregister(instance);
return -1; return -1;
} }
/*========================================================== /*==========================================================
...@@ -4694,9 +4815,7 @@ static int ncr_reset_scsi_bus(ncb_p np, int enab_int, int settle_delay) ...@@ -4694,9 +4815,7 @@ static int ncr_reset_scsi_bus(ncb_p np, int enab_int, int settle_delay)
"command processing suspended for %d seconds\n", "command processing suspended for %d seconds\n",
ncr_name(np), settle_delay); ncr_name(np), settle_delay);
OUTB (nc_istat, SRST); ncr_chip_reset(np, 100);
UDELAY (100);
OUTB (nc_istat, 0);
UDELAY (2000); /* The 895 needs time for the bus mode to settle */ UDELAY (2000); /* The 895 needs time for the bus mode to settle */
if (enab_int) if (enab_int)
OUTW (nc_sien, RST); OUTW (nc_sien, RST);
...@@ -4705,7 +4824,8 @@ static int ncr_reset_scsi_bus(ncb_p np, int enab_int, int settle_delay) ...@@ -4705,7 +4824,8 @@ static int ncr_reset_scsi_bus(ncb_p np, int enab_int, int settle_delay)
** properly set IRQ mode, prior to resetting the bus. ** properly set IRQ mode, prior to resetting the bus.
*/ */
OUTB (nc_stest3, TE); OUTB (nc_stest3, TE);
OUTB (nc_dcntl, (np->rv_dcntl & IRQM)); if (np->device_id != PSEUDO_ZALON_720_ID)
OUTB (nc_dcntl, (np->rv_dcntl & IRQM));
OUTB (nc_scntl1, CRST); OUTB (nc_scntl1, CRST);
UDELAY (200); UDELAY (200);
...@@ -4912,6 +5032,10 @@ static int ncr_detach(ncb_p np) ...@@ -4912,6 +5032,10 @@ static int ncr_detach(ncb_p np)
lcb_p lp; lcb_p lp;
int target, lun; int target, lun;
int i; int i;
char inst_name[16];
/* Local copy so we don't access np after freeing it! */
strncpy(inst_name, ncr_name(np), 16);
printk("%s: releasing host resources\n", ncr_name(np)); printk("%s: releasing host resources\n", ncr_name(np));
...@@ -4958,12 +5082,11 @@ static int ncr_detach(ncb_p np) ...@@ -4958,12 +5082,11 @@ static int ncr_detach(ncb_p np)
*/ */
printk("%s: resetting chip\n", ncr_name(np)); printk("%s: resetting chip\n", ncr_name(np));
OUTB (nc_istat, SRST); ncr_chip_reset(np, 100);
UDELAY (100);
OUTB (nc_istat, 0 );
OUTB(nc_dmode, np->sv_dmode); OUTB(nc_dmode, np->sv_dmode);
OUTB(nc_dcntl, np->sv_dcntl); OUTB(nc_dcntl, np->sv_dcntl);
OUTB(nc_ctest0, np->sv_ctest0);
OUTB(nc_ctest3, np->sv_ctest3); OUTB(nc_ctest3, np->sv_ctest3);
OUTB(nc_ctest4, np->sv_ctest4); OUTB(nc_ctest4, np->sv_ctest4);
OUTB(nc_ctest5, np->sv_ctest5); OUTB(nc_ctest5, np->sv_ctest5);
...@@ -4986,7 +5109,9 @@ static int ncr_detach(ncb_p np) ...@@ -4986,7 +5109,9 @@ static int ncr_detach(ncb_p np)
#ifdef DEBUG_NCR53C8XX #ifdef DEBUG_NCR53C8XX
printk("%s: releasing IO region %x[%d]\n", ncr_name(np), np->base_io, 128); printk("%s: releasing IO region %x[%d]\n", ncr_name(np), np->base_io, 128);
#endif #endif
#ifndef ENABLE_SCSI_ZALON
release_region(np->base_io, 128); release_region(np->base_io, 128);
#endif
/* /*
** Free allocated ccb(s) ** Free allocated ccb(s)
...@@ -5031,7 +5156,7 @@ static int ncr_detach(ncb_p np) ...@@ -5031,7 +5156,7 @@ static int ncr_detach(ncb_p np)
m_free_dma(np->ccb, sizeof(struct ccb), "CCB"); m_free_dma(np->ccb, sizeof(struct ccb), "CCB");
m_free_dma(np, sizeof(struct ncb), "NCB"); m_free_dma(np, sizeof(struct ncb), "NCB");
printk("%s: host resources successfully released\n", ncr_name(np)); printk("%s: host resources successfully released\n", inst_name);
return 1; return 1;
} }
...@@ -5423,6 +5548,27 @@ void ncr_wakeup (ncb_p np, u_long code) ...@@ -5423,6 +5548,27 @@ void ncr_wakeup (ncb_p np, u_long code)
} }
} }
/*
** Reset ncr chip.
*/
/* Some initialisation must be done immediately following reset, for 53c720,
* at least. EA (dcntl bit 5) isn't set here as it is set once only in
* the _detect function.
*/
static void ncr_chip_reset(ncb_p np, int delay)
{
OUTB (nc_istat, SRST);
UDELAY (delay);
OUTB (nc_istat, 0 );
if (np->features & FE_EHP)
OUTB (nc_ctest0, EHP);
if (np->features & FE_MUX)
OUTB (nc_ctest4, MUX);
}
/*========================================================== /*==========================================================
** **
** **
...@@ -5469,6 +5615,7 @@ void ncr_init (ncb_p np, int reset, char * msg, u_long code) ...@@ -5469,6 +5615,7 @@ void ncr_init (ncb_p np, int reset, char * msg, u_long code)
np->squeueput = 0; np->squeueput = 0;
np->script0->startpos[0] = cpu_to_scr(NCB_SCRIPTH_PHYS (np, tryloop)); np->script0->startpos[0] = cpu_to_scr(NCB_SCRIPTH_PHYS (np, tryloop));
#ifdef SCSI_NCR_CCB_DONE_SUPPORT
/* /*
** Clear Done Queue ** Clear Done Queue
*/ */
...@@ -5477,6 +5624,7 @@ void ncr_init (ncb_p np, int reset, char * msg, u_long code) ...@@ -5477,6 +5624,7 @@ void ncr_init (ncb_p np, int reset, char * msg, u_long code)
np->scripth0->done_queue[5*i + 4] = np->scripth0->done_queue[5*i + 4] =
cpu_to_scr(NCB_SCRIPT_PHYS (np, done_end)); cpu_to_scr(NCB_SCRIPT_PHYS (np, done_end));
} }
#endif
/* /*
** Start at first entry. ** Start at first entry.
...@@ -5495,8 +5643,11 @@ void ncr_init (ncb_p np, int reset, char * msg, u_long code) ...@@ -5495,8 +5643,11 @@ void ncr_init (ncb_p np, int reset, char * msg, u_long code)
** Init chip. ** Init chip.
*/ */
OUTB (nc_istat, 0x00 ); /* Remove Reset, abort */ /*
UDELAY (2000); /* The 895 needs time for the bus mode to settle */ ** Remove reset; big delay because the 895 needs time for the
** bus mode to settle
*/
ncr_chip_reset(np, 2000);
OUTB (nc_scntl0, np->rv_scntl0 | 0xc0); OUTB (nc_scntl0, np->rv_scntl0 | 0xc0);
/* full arb., ena parity, par->ATN */ /* full arb., ena parity, par->ATN */
...@@ -5511,6 +5662,7 @@ void ncr_init (ncb_p np, int reset, char * msg, u_long code) ...@@ -5511,6 +5662,7 @@ void ncr_init (ncb_p np, int reset, char * msg, u_long code)
OUTB (nc_ctest5, np->rv_ctest5); /* Large fifo + large burst */ OUTB (nc_ctest5, np->rv_ctest5); /* Large fifo + large burst */
OUTB (nc_dcntl , NOCOM|np->rv_dcntl); /* Protect SFBR */ OUTB (nc_dcntl , NOCOM|np->rv_dcntl); /* Protect SFBR */
OUTB (nc_ctest0, np->rv_ctest0); /* 720: CDIS and EHP */
OUTB (nc_ctest3, np->rv_ctest3); /* Write and invalidate */ OUTB (nc_ctest3, np->rv_ctest3); /* Write and invalidate */
OUTB (nc_ctest4, np->rv_ctest4); /* Master parity checking */ OUTB (nc_ctest4, np->rv_ctest4); /* Master parity checking */
...@@ -7095,6 +7247,18 @@ void ncr_int_sir (ncb_p np) ...@@ -7095,6 +7247,18 @@ void ncr_int_sir (ncb_p np)
if (DEBUG_FLAGS & DEBUG_TINY) printk ("I#%d", num); if (DEBUG_FLAGS & DEBUG_TINY) printk ("I#%d", num);
switch (num) { switch (num) {
case SIR_INTFLY:
/*
** This is used for HP Zalon/53c720 where INTFLY
** operation is currently broken.
*/
ncr_wakeup_done(np);
#ifdef SCSI_NCR_CCB_DONE_SUPPORT
OUTL(nc_dsp, NCB_SCRIPT_PHYS (np, done_end) + 8);
#else
OUTL(nc_dsp, NCB_SCRIPT_PHYS (np, start));
#endif
return;
case SIR_RESEL_NO_MSG_IN: case SIR_RESEL_NO_MSG_IN:
case SIR_RESEL_NO_IDENTIFY: case SIR_RESEL_NO_IDENTIFY:
/* /*
...@@ -7841,15 +8005,23 @@ static void ncr_init_tcb (ncb_p np, u_char tn) ...@@ -7841,15 +8005,23 @@ static void ncr_init_tcb (ncb_p np, u_char tn)
*/ */
tp->getscr[0] = cpu_to_scr(copy_1); tp->getscr[0] = cpu_to_scr(copy_1);
tp->getscr[1] = cpu_to_scr(vtobus (&tp->sval)); tp->getscr[1] = cpu_to_scr(vtobus (&tp->sval));
#ifdef SCSI_NCR_BIG_ENDIAN
tp->getscr[2] = cpu_to_scr(ncr_reg_bus_addr(nc_sxfer) ^ 3);
#else
tp->getscr[2] = cpu_to_scr(ncr_reg_bus_addr(nc_sxfer)); tp->getscr[2] = cpu_to_scr(ncr_reg_bus_addr(nc_sxfer));
#endif
/* /*
** Load the timing register. ** Load the timing register.
** COPY @(tp->wval), @(scntl3) ** COPY @(tp->wval), @(scntl3)
*/ */
tp->getscr[3] = cpu_to_scr(copy_1); tp->getscr[3] = cpu_to_scr(copy_1);
tp->getscr[4] = cpu_to_scr(vtobus (&tp->wval)); tp->getscr[4] = cpu_to_scr(vtobus (&tp->wval));
#ifdef SCSI_NCR_BIG_ENDIAN
tp->getscr[5] = cpu_to_scr(ncr_reg_bus_addr(nc_scntl3) ^ 3);
#else
tp->getscr[5] = cpu_to_scr(ncr_reg_bus_addr(nc_scntl3)); tp->getscr[5] = cpu_to_scr(ncr_reg_bus_addr(nc_scntl3));
#endif
/* /*
** Get the IDENTIFY message and the lun. ** Get the IDENTIFY message and the lun.
...@@ -7878,10 +8050,17 @@ static void ncr_init_tcb (ncb_p np, u_char tn) ...@@ -7878,10 +8050,17 @@ static void ncr_init_tcb (ncb_p np, u_char tn)
/* /*
** These assert's should be moved at driver initialisations. ** These assert's should be moved at driver initialisations.
*/ */
#ifdef SCSI_NCR_BIG_ENDIAN
assert (( (offsetof(struct ncr_reg, nc_sxfer) ^
offsetof(struct tcb , sval )) &3) == 3);
assert (( (offsetof(struct ncr_reg, nc_scntl3) ^
offsetof(struct tcb , wval )) &3) == 3);
#else
assert (( (offsetof(struct ncr_reg, nc_sxfer) ^ assert (( (offsetof(struct ncr_reg, nc_sxfer) ^
offsetof(struct tcb , sval )) &3) == 0); offsetof(struct tcb , sval )) &3) == 0);
assert (( (offsetof(struct ncr_reg, nc_scntl3) ^ assert (( (offsetof(struct ncr_reg, nc_scntl3) ^
offsetof(struct tcb , wval )) &3) == 0); offsetof(struct tcb , wval )) &3) == 0);
#endif
} }
...@@ -8122,14 +8301,10 @@ static int ncr_scatter(ncb_p np, ccb_p cp, Scsi_Cmnd *cmd) ...@@ -8122,14 +8301,10 @@ static int ncr_scatter(ncb_p np, ccb_p cp, Scsi_Cmnd *cmd)
segment = 1; segment = 1;
} }
} }
else { else if (use_sg <= MAX_SCATTER) {
struct scatterlist *scatter = (struct scatterlist *)cmd->buffer; struct scatterlist *scatter = (struct scatterlist *)cmd->buffer;
use_sg = map_scsi_sg_data(np, cmd); use_sg = map_scsi_sg_data(np, cmd);
if (use_sg > MAX_SCATTER) {
unmap_scsi_data(np, cmd);
return -1;
}
data = &data[MAX_SCATTER - use_sg]; data = &data[MAX_SCATTER - use_sg];
while (segment < use_sg) { while (segment < use_sg) {
...@@ -8142,6 +8317,9 @@ static int ncr_scatter(ncb_p np, ccb_p cp, Scsi_Cmnd *cmd) ...@@ -8142,6 +8317,9 @@ static int ncr_scatter(ncb_p np, ccb_p cp, Scsi_Cmnd *cmd)
++segment; ++segment;
} }
} }
else {
return -1;
}
return segment; return segment;
} }
...@@ -8226,9 +8404,7 @@ static int __init ncr_snooptest (struct ncb* np) ...@@ -8226,9 +8404,7 @@ static int __init ncr_snooptest (struct ncb* np)
/* /*
** Reset ncr chip ** Reset ncr chip
*/ */
OUTB (nc_istat, SRST); ncr_chip_reset(np, 100);
UDELAY (100);
OUTB (nc_istat, 0 );
/* /*
** check for timeout ** check for timeout
*/ */
...@@ -8455,7 +8631,7 @@ static void __init ncr_getclock (ncb_p np, int mult) ...@@ -8455,7 +8631,7 @@ static void __init ncr_getclock (ncb_p np, int mult)
if (np->multiplier != mult || (scntl3 & 7) < 3 || !(scntl3 & 1)) { if (np->multiplier != mult || (scntl3 & 7) < 3 || !(scntl3 & 1)) {
unsigned f2; unsigned f2;
OUTB(nc_istat, SRST); UDELAY (5); OUTB(nc_istat, 0); ncr_chip_reset(np, 5);
(void) ncrgetfreq (np, 11); /* throw away first result */ (void) ncrgetfreq (np, 11); /* throw away first result */
f1 = ncrgetfreq (np, 11); f1 = ncrgetfreq (np, 11);
...@@ -9202,6 +9378,7 @@ __setup("ncr53c8xx=", ncr53c8xx_setup); ...@@ -9202,6 +9378,7 @@ __setup("ncr53c8xx=", ncr53c8xx_setup);
*/ */
static u_short ncr_chip_ids[] __initdata = { static u_short ncr_chip_ids[] __initdata = {
PSEUDO_ZALON_720_ID,
PCI_DEVICE_ID_NCR_53C810, PCI_DEVICE_ID_NCR_53C810,
PCI_DEVICE_ID_NCR_53C815, PCI_DEVICE_ID_NCR_53C815,
PCI_DEVICE_ID_NCR_53C820, PCI_DEVICE_ID_NCR_53C820,
...@@ -9216,6 +9393,74 @@ static u_short ncr_chip_ids[] __initdata = { ...@@ -9216,6 +9393,74 @@ static u_short ncr_chip_ids[] __initdata = {
PCI_DEVICE_ID_NCR_53C1510D PCI_DEVICE_ID_NCR_53C1510D
}; };
#ifdef ENABLE_SCSI_ZALON
/* Attach a 53c720 interfaced via Zalon chip on HP boxes. */
int zalon_attach(Scsi_Host_Template *tpnt, unsigned long io_port,
struct parisc_device *dev, int irq, int unit)
{
u_short device_id;
u_char revision;
int i;
ncr_chip *chip;
ncr_device device;
tpnt->proc_name = NAME53C8XX;
tpnt->proc_info = ncr53c8xx_proc_info;
#if defined(SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT) && defined(MODULE)
if (ncr53c8xx)
ncr53c8xx_setup(ncr53c8xx);
#endif
#ifdef SCSI_NCR_DEBUG_INFO_SUPPORT
ncr_debug = driver_setup.debug;
#endif
if (initverbose >= 2)
ncr_print_driver_setup();
memset(&device, 0, sizeof(ncr_device));
chip = 0;
device_id = PSEUDO_ZALON_720_ID;
revision = 0;
for (i = 0; i < sizeof(ncr_chip_table)/sizeof(ncr_chip_table[0]); i++) { if (device_id != ncr_chip_table[i].device_id)
continue;
chip = &device.chip;
memcpy(chip, &ncr_chip_table[i], sizeof(*chip));
chip->revision_id = revision;
break;
}
if (!chip) {
printk(NAME53C8XX ": not initializing, device not supported\n"); return -1;
}
/* Fix some features according to driver setup. */
driver_setup.diff_support = 2;
/* The following three are needed before any other access. */
writeb(0x20, io_port + 0x38); /* DCNTL_REG, EA */
writeb(0x04, io_port + 0x1b); /* CTEST0_REG, EHP */
writeb(0x80, io_port + 0x22); /* CTEST4_REG, MUX */
/* Initialise ncr_device structure with items required by ncr_attach. */
device.host_id = driver_setup.host_id;
device.dev = &dev->dev;
device.slot.bus = 0;
device.slot.device_fn = 0;
device.slot.base = (u_long)io_port;
device.slot.base_c = (u_long)io_port;
device.slot.base_2 = 0;
device.slot.base_2_c = 0;
device.slot.io_port = io_port;
device.slot.irq = irq;
device.attach_done = 0;
printk(KERN_INFO NAME53C8XX ": 53c%s detected\n", device.chip.name);
return ncr_attach(tpnt, unit, &device);
}
#endif
/*========================================================== /*==========================================================
** **
** Chip detection entry point. ** Chip detection entry point.
...@@ -9265,6 +9510,23 @@ MODULE_LICENSE("GPL"); ...@@ -9265,6 +9510,23 @@ MODULE_LICENSE("GPL");
static static
#endif #endif
#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) || defined(MODULE) #if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) || defined(MODULE)
#ifdef ENABLE_SCSI_ZALON
Scsi_Host_Template driver_template = {
.proc_name = "zalon720",
.detect = zalon7xx_detect,
.release = zalon7xx_release,
.info = ncr53c8xx_info,
.queuecommand = ncr53c8xx_queue_command,
.can_queue = SCSI_NCR_CAN_QUEUE,
.this_id = 7,
.sg_tablesize = SCSI_NCR_SG_TABLESIZE,
.cmd_per_lun = SCSI_NCR_CMD_PER_LUN,
.use_clustering = DISABLE_CLUSTERING,
};
#else
Scsi_Host_Template driver_template = NCR53C8XX; Scsi_Host_Template driver_template = NCR53C8XX;
#endif
#include "scsi_module.c" #include "scsi_module.c"
#endif #endif
...@@ -2,13 +2,13 @@ ...@@ -2,13 +2,13 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <asm/uaccess.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/blk.h> #include <linux/blk.h>
#include <linux/blkpg.h> #include <linux/blkpg.h>
#include <linux/cdrom.h> #include <linux/cdrom.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/uaccess.h>
#include "scsi.h" #include "scsi.h"
#include "hosts.h" #include "hosts.h"
......
...@@ -265,6 +265,7 @@ static inline struct xpt_quehead *xpt_remque_tail(struct xpt_quehead *head) ...@@ -265,6 +265,7 @@ static inline struct xpt_quehead *xpt_remque_tail(struct xpt_quehead *head)
#if LINUX_VERSION_CODE >= LinuxVersionCode(2,2,0) #if LINUX_VERSION_CODE >= LinuxVersionCode(2,2,0)
typedef struct pci_dev *pcidev_t; typedef struct pci_dev *pcidev_t;
typedef struct device *device_t;
#define PCIDEV_NULL (0) #define PCIDEV_NULL (0)
#define PciBusNumber(d) (d)->bus->number #define PciBusNumber(d) (d)->bus->number
#define PciDeviceFn(d) (d)->devfn #define PciDeviceFn(d) (d)->devfn
...@@ -312,6 +313,7 @@ pci_get_base_address(struct pci_dev *pdev, int index, u_long *base) ...@@ -312,6 +313,7 @@ pci_get_base_address(struct pci_dev *pdev, int index, u_long *base)
#else /* Incomplete emulation of current PCI code for pre-2.2 kernels */ #else /* Incomplete emulation of current PCI code for pre-2.2 kernels */
typedef unsigned int pcidev_t; typedef unsigned int pcidev_t;
typedef unsinged int device_t;
#define PCIDEV_NULL (~0u) #define PCIDEV_NULL (~0u)
#define PciBusNumber(d) ((d)>>8) #define PciBusNumber(d) ((d)>>8)
#define PciDeviceFn(d) ((d)&0xff) #define PciDeviceFn(d) ((d)&0xff)
...@@ -564,7 +566,7 @@ static void MDELAY(long ms) { while (ms--) UDELAY(1000); } ...@@ -564,7 +566,7 @@ static void MDELAY(long ms) { while (ms--) UDELAY(1000); }
#define MEMO_CLUSTER_MASK (MEMO_CLUSTER_SIZE-1) #define MEMO_CLUSTER_MASK (MEMO_CLUSTER_SIZE-1)
typedef u_long m_addr_t; /* Enough bits to bit-hack addresses */ typedef u_long m_addr_t; /* Enough bits to bit-hack addresses */
typedef pcidev_t m_bush_t; /* Something that addresses DMAable */ typedef struct device *m_bush_t; /* Something that addresses DMAable */
typedef struct m_link { /* Link between free memory chunks */ typedef struct m_link { /* Link between free memory chunks */
struct m_link *next; struct m_link *next;
...@@ -793,7 +795,7 @@ static m_addr_t ___dma_getp(m_pool_s *mp) ...@@ -793,7 +795,7 @@ static m_addr_t ___dma_getp(m_pool_s *mp)
vbp = __m_calloc(&mp0, sizeof(*vbp), "VTOB"); vbp = __m_calloc(&mp0, sizeof(*vbp), "VTOB");
if (vbp) { if (vbp) {
dma_addr_t daddr; dma_addr_t daddr;
vp = (m_addr_t) pci_alloc_consistent(mp->bush, vp = (m_addr_t) dma_alloc_coherent(mp->bush,
PAGE_SIZE<<MEMO_PAGE_ORDER, PAGE_SIZE<<MEMO_PAGE_ORDER,
&daddr); &daddr);
if (vp) { if (vp) {
...@@ -822,8 +824,8 @@ static void ___dma_freep(m_pool_s *mp, m_addr_t m) ...@@ -822,8 +824,8 @@ static void ___dma_freep(m_pool_s *mp, m_addr_t m)
if (*vbpp) { if (*vbpp) {
vbp = *vbpp; vbp = *vbpp;
*vbpp = (*vbpp)->next; *vbpp = (*vbpp)->next;
pci_free_consistent(mp->bush, PAGE_SIZE<<MEMO_PAGE_ORDER, dma_free_coherent(mp->bush, PAGE_SIZE<<MEMO_PAGE_ORDER,
(void *)vbp->vaddr, (dma_addr_t)vbp->baddr); (void *)vbp->vaddr, (dma_addr_t)vbp->baddr);
__m_free(&mp0, vbp, sizeof(*vbp), "VTOB"); __m_free(&mp0, vbp, sizeof(*vbp), "VTOB");
--mp->nump; --mp->nump;
} }
...@@ -917,11 +919,11 @@ static m_addr_t __vtobus(m_bush_t bush, void *m) ...@@ -917,11 +919,11 @@ static m_addr_t __vtobus(m_bush_t bush, void *m)
#endif /* SCSI_NCR_DYNAMIC_DMA_MAPPING */ #endif /* SCSI_NCR_DYNAMIC_DMA_MAPPING */
#define _m_calloc_dma(np, s, n) __m_calloc_dma(np->pdev, s, n) #define _m_calloc_dma(np, s, n) __m_calloc_dma(np->dev, s, n)
#define _m_free_dma(np, p, s, n) __m_free_dma(np->pdev, p, s, n) #define _m_free_dma(np, p, s, n) __m_free_dma(np->dev, p, s, n)
#define m_calloc_dma(s, n) _m_calloc_dma(np, s, n) #define m_calloc_dma(s, n) _m_calloc_dma(np, s, n)
#define m_free_dma(p, s, n) _m_free_dma(np, p, s, n) #define m_free_dma(p, s, n) _m_free_dma(np, p, s, n)
#define _vtobus(np, p) __vtobus(np->pdev, p) #define _vtobus(np, p) __vtobus(np->dev, p)
#define vtobus(p) _vtobus(np, p) #define vtobus(p) _vtobus(np, p)
/* /*
...@@ -932,10 +934,10 @@ static m_addr_t __vtobus(m_bush_t bush, void *m) ...@@ -932,10 +934,10 @@ static m_addr_t __vtobus(m_bush_t bush, void *m)
/* Linux versions prior to pci bus iommu kernel interface */ /* Linux versions prior to pci bus iommu kernel interface */
#define __unmap_scsi_data(pdev, cmd) do {; } while (0) #define __unmap_scsi_data(dev, cmd) do {; } while (0)
#define __map_scsi_single_data(pdev, cmd) (__vtobus(pdev,(cmd)->request_buffer)) #define __map_scsi_single_data(dev, cmd) (__vtobus(dev,(cmd)->request_buffer))
#define __map_scsi_sg_data(pdev, cmd) ((cmd)->use_sg) #define __map_scsi_sg_data(dev, cmd) ((cmd)->use_sg)
#define __sync_scsi_data(pdev, cmd) do {; } while (0) #define __sync_scsi_data(dev, cmd) do {; } while (0)
#define scsi_sg_dma_address(sc) vtobus((sc)->address) #define scsi_sg_dma_address(sc) vtobus((sc)->address)
#define scsi_sg_dma_len(sc) ((sc)->length) #define scsi_sg_dma_len(sc) ((sc)->length)
...@@ -948,31 +950,34 @@ static m_addr_t __vtobus(m_bush_t bush, void *m) ...@@ -948,31 +950,34 @@ static m_addr_t __vtobus(m_bush_t bush, void *m)
#define __data_mapped SCp.phase #define __data_mapped SCp.phase
#define __data_mapping SCp.have_data_in #define __data_mapping SCp.have_data_in
static void __unmap_scsi_data(pcidev_t pdev, Scsi_Cmnd *cmd) static void __unmap_scsi_data(device_t dev, Scsi_Cmnd *cmd)
{ {
int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction); enum dma_data_direction dma_dir =
(enum dma_data_direction)scsi_to_pci_dma_dir(cmd->sc_data_direction);
switch(cmd->__data_mapped) { switch(cmd->__data_mapped) {
case 2: case 2:
pci_unmap_sg(pdev, cmd->buffer, cmd->use_sg, dma_dir); dma_unmap_sg(dev, cmd->buffer, cmd->use_sg, dma_dir);
break; break;
case 1: case 1:
pci_unmap_single(pdev, cmd->__data_mapping, dma_unmap_single(dev, cmd->__data_mapping,
cmd->request_bufflen, dma_dir); cmd->request_bufflen, dma_dir);
break; break;
} }
cmd->__data_mapped = 0; cmd->__data_mapped = 0;
} }
static u_long __map_scsi_single_data(pcidev_t pdev, Scsi_Cmnd *cmd) static u_long __map_scsi_single_data(device_t dev, Scsi_Cmnd *cmd)
{ {
dma_addr_t mapping; dma_addr_t mapping;
int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction); enum dma_data_direction dma_dir =
(enum dma_data_direction)scsi_to_pci_dma_dir(cmd->sc_data_direction);
if (cmd->request_bufflen == 0) if (cmd->request_bufflen == 0)
return 0; return 0;
mapping = pci_map_single(pdev, cmd->request_buffer, mapping = dma_map_single(dev, cmd->request_buffer,
cmd->request_bufflen, dma_dir); cmd->request_bufflen, dma_dir);
cmd->__data_mapped = 1; cmd->__data_mapped = 1;
cmd->__data_mapping = mapping; cmd->__data_mapping = mapping;
...@@ -980,32 +985,34 @@ static u_long __map_scsi_single_data(pcidev_t pdev, Scsi_Cmnd *cmd) ...@@ -980,32 +985,34 @@ static u_long __map_scsi_single_data(pcidev_t pdev, Scsi_Cmnd *cmd)
return mapping; return mapping;
} }
static int __map_scsi_sg_data(pcidev_t pdev, Scsi_Cmnd *cmd) static int __map_scsi_sg_data(device_t dev, Scsi_Cmnd *cmd)
{ {
int use_sg; int use_sg;
int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction); enum dma_data_direction dma_dir =
(enum dma_data_direction)scsi_to_pci_dma_dir(cmd->sc_data_direction);
if (cmd->use_sg == 0) if (cmd->use_sg == 0)
return 0; return 0;
use_sg = pci_map_sg(pdev, cmd->buffer, cmd->use_sg, dma_dir); use_sg = dma_map_sg(dev, cmd->buffer, cmd->use_sg, dma_dir);
cmd->__data_mapped = 2; cmd->__data_mapped = 2;
cmd->__data_mapping = use_sg; cmd->__data_mapping = use_sg;
return use_sg; return use_sg;
} }
static void __sync_scsi_data(pcidev_t pdev, Scsi_Cmnd *cmd) static void __sync_scsi_data(device_t dev, Scsi_Cmnd *cmd)
{ {
int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction); enum dma_data_direction dma_dir =
(enum dma_data_direction)scsi_to_pci_dma_dir(cmd->sc_data_direction);
switch(cmd->__data_mapped) { switch(cmd->__data_mapped) {
case 2: case 2:
pci_dma_sync_sg(pdev, cmd->buffer, cmd->use_sg, dma_dir); dma_sync_sg(dev, cmd->buffer, cmd->use_sg, dma_dir);
break; break;
case 1: case 1:
pci_dma_sync_single(pdev, cmd->__data_mapping, dma_sync_single(dev, cmd->__data_mapping,
cmd->request_bufflen, dma_dir); cmd->request_bufflen, dma_dir);
break; break;
} }
} }
...@@ -1015,10 +1022,10 @@ static void __sync_scsi_data(pcidev_t pdev, Scsi_Cmnd *cmd) ...@@ -1015,10 +1022,10 @@ static void __sync_scsi_data(pcidev_t pdev, Scsi_Cmnd *cmd)
#endif /* SCSI_NCR_DYNAMIC_DMA_MAPPING */ #endif /* SCSI_NCR_DYNAMIC_DMA_MAPPING */
#define unmap_scsi_data(np, cmd) __unmap_scsi_data(np->pdev, cmd) #define unmap_scsi_data(np, cmd) __unmap_scsi_data(np->dev, cmd)
#define map_scsi_single_data(np, cmd) __map_scsi_single_data(np->pdev, cmd) #define map_scsi_single_data(np, cmd) __map_scsi_single_data(np->dev, cmd)
#define map_scsi_sg_data(np, cmd) __map_scsi_sg_data(np->pdev, cmd) #define map_scsi_sg_data(np, cmd) __map_scsi_sg_data(np->dev, cmd)
#define sync_scsi_data(np, cmd) __sync_scsi_data(np->pdev, cmd) #define sync_scsi_data(np, cmd) __sync_scsi_data(np->dev, cmd)
/*========================================================== /*==========================================================
** **
...@@ -1140,7 +1147,7 @@ typedef struct { ...@@ -1140,7 +1147,7 @@ typedef struct {
**========================================================== **==========================================================
*/ */
typedef struct { typedef struct {
pcidev_t pdev; device_t dev;
ncr_slot slot; ncr_slot slot;
ncr_chip chip; ncr_chip chip;
ncr_nvram *nvram; ncr_nvram *nvram;
...@@ -2486,7 +2493,7 @@ sym53c8xx_pci_init(Scsi_Host_Template *tpnt, pcidev_t pdev, ncr_device *device) ...@@ -2486,7 +2493,7 @@ sym53c8xx_pci_init(Scsi_Host_Template *tpnt, pcidev_t pdev, ncr_device *device)
/* /*
** Initialise ncr_device structure with items required by ncr_attach. ** Initialise ncr_device structure with items required by ncr_attach.
*/ */
device->pdev = pdev; device->dev = &pdev->dev;
device->slot.bus = PciBusNumber(pdev); device->slot.bus = PciBusNumber(pdev);
device->slot.device_fn = PciDeviceFn(pdev); device->slot.device_fn = PciDeviceFn(pdev);
device->slot.base = base; device->slot.base = base;
......
...@@ -51,6 +51,13 @@ ...@@ -51,6 +51,13 @@
** NVRAM detection and reading. ** NVRAM detection and reading.
** Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk> ** Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk>
** **
** Added support for MIPS big endian systems.
** Carsten Langgaard, carstenl@mips.com
** Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
**
** Added support for HP PARISC big endian systems.
** Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
**
******************************************************************************* *******************************************************************************
*/ */
...@@ -78,8 +85,10 @@ ...@@ -78,8 +85,10 @@
/* /*
* No more an option, enabled by default. * No more an option, enabled by default.
*/ */
#ifndef CONFIG_SCSI_NCR53C8XX_NVRAM_DETECT #ifndef ENABLE_SCSI_ZALON
#define CONFIG_SCSI_NCR53C8XX_NVRAM_DETECT # ifndef CONFIG_SCSI_NCR53C8XX_NVRAM_DETECT
# define CONFIG_SCSI_NCR53C8XX_NVRAM_DETECT
# endif
#endif #endif
/* /*
...@@ -181,6 +190,8 @@ ...@@ -181,6 +190,8 @@
#endif #endif
#elif defined(__sparc__) #elif defined(__sparc__)
#undef SCSI_NCR_IOMAPPED #undef SCSI_NCR_IOMAPPED
#elif defined(__hppa__) && defined(ENABLE_SCSI_ZALON)
#undef SCSI_NCR_IOMAPPED
#endif #endif
/* /*
...@@ -379,16 +390,24 @@ ...@@ -379,16 +390,24 @@
#define readb_raw readb #define readb_raw readb
#define writeb_raw writeb #define writeb_raw writeb
#if defined(__hppa__) #if defined(SCSI_NCR_BIG_ENDIAN)
#define readw_l2b(a) le16_to_cpu(readw(a)) #define readw_l2b __raw_readw
#define readl_l2b(a) le32_to_cpu(readl(a)) #define readl_l2b __raw_readl
#define writew_b2l(v,a) writew(cpu_to_le16(v),a) #define writew_b2l __raw_writew
#define writel_b2l(v,a) writel(cpu_to_le32(v),a) #define writel_b2l __raw_writel
#else /* Other bid-endian */ #define readw_raw __raw_readw
#define readl_raw(a) __raw_readl((unsigned long)(a))
#define writew_raw __raw_writew
#define writel_raw(v,a) __raw_writel(v,(unsigned long)(a))
#else /* Other big-endian */
#define readw_l2b readw #define readw_l2b readw
#define readl_l2b readl #define readl_l2b readl
#define writew_b2l writew #define writew_b2l writew
#define writel_b2l writel #define writel_b2l writel
#define readw_raw readw
#define readl_raw readl
#define writew_raw writew
#define writel_raw writel
#endif #endif
#else /* little endian */ #else /* little endian */
...@@ -417,9 +436,11 @@ ...@@ -417,9 +436,11 @@
#endif #endif
#endif #endif
#if !defined(__hppa__) && !defined(__mips__)
#ifdef SCSI_NCR_BIG_ENDIAN #ifdef SCSI_NCR_BIG_ENDIAN
#error "The NCR in BIG ENDIAN addressing mode is not (yet) supported" #error "The NCR in BIG ENDIAN addressing mode is not (yet) supported"
#endif #endif
#endif
/* /*
...@@ -572,10 +593,20 @@ ...@@ -572,10 +593,20 @@
#else #else
#ifdef ENABLE_SCSI_ZALON
/* Only 8 or 32 bit transfers allowed */
#define INW_OFF(o) (readb((char *)np->reg + ncr_offw(o)) << 8 | readb((char *)np->reg + ncr_offw(o) + 1))
#else
#define INW_OFF(o) readw_raw((char *)np->reg + ncr_offw(o)) #define INW_OFF(o) readw_raw((char *)np->reg + ncr_offw(o))
#endif
#define INL_OFF(o) readl_raw((char *)np->reg + (o)) #define INL_OFF(o) readl_raw((char *)np->reg + (o))
#ifdef ENABLE_SCSI_ZALON
/* Only 8 or 32 bit transfers allowed */
#define OUTW_OFF(o, val) do { writeb((char)((val) >> 8), (char *)np->reg + ncr_offw(o)); writeb((char)(val), (char *)np->reg + ncr_offw(o) + 1); } while (0)
#else
#define OUTW_OFF(o, val) writew_raw((val), (char *)np->reg + ncr_offw(o)) #define OUTW_OFF(o, val) writew_raw((val), (char *)np->reg + ncr_offw(o))
#endif
#define OUTL_OFF(o, val) writel_raw((val), (char *)np->reg + (o)) #define OUTL_OFF(o, val) writel_raw((val), (char *)np->reg + (o))
#endif #endif
...@@ -623,6 +654,10 @@ ...@@ -623,6 +654,10 @@
** NCR53C8XX Device Ids ** NCR53C8XX Device Ids
*/ */
#ifndef PSEUDO_ZALON_720_ID
#define PSEUDO_ZALON_720_ID 0x5a00
#endif
#ifndef PCI_DEVICE_ID_NCR_53C810 #ifndef PCI_DEVICE_ID_NCR_53C810
#define PCI_DEVICE_ID_NCR_53C810 1 #define PCI_DEVICE_ID_NCR_53C810 1
#endif #endif
...@@ -726,6 +761,9 @@ typedef struct { ...@@ -726,6 +761,9 @@ typedef struct {
#define FE_DAC (1<<24) /* Support DAC cycles (64 bit addressing) */ #define FE_DAC (1<<24) /* Support DAC cycles (64 bit addressing) */
#define FE_ISTAT1 (1<<25) /* Have ISTAT1, MBOX0, MBOX1 registers */ #define FE_ISTAT1 (1<<25) /* Have ISTAT1, MBOX0, MBOX1 registers */
#define FE_DAC_IN_USE (1<<26) /* Platform does DAC cycles */ #define FE_DAC_IN_USE (1<<26) /* Platform does DAC cycles */
#define FE_EHP (1<<27) /* 720: Even host parity */
#define FE_MUX (1<<28) /* 720: Multiplexed bus */
#define FE_EA (1<<29) /* 720: Enable Ack */
#define FE_CACHE_SET (FE_ERL|FE_CLSE|FE_WRIE|FE_ERMP) #define FE_CACHE_SET (FE_ERL|FE_CLSE|FE_WRIE|FE_ERMP)
#define FE_SCSI_SET (FE_WIDE|FE_ULTRA|FE_ULTRA2|FE_DBLR|FE_QUAD|F_CLK80) #define FE_SCSI_SET (FE_WIDE|FE_ULTRA|FE_ULTRA2|FE_DBLR|FE_QUAD|F_CLK80)
...@@ -747,6 +785,9 @@ typedef struct { ...@@ -747,6 +785,9 @@ typedef struct {
#define SCSI_NCR_CHIP_TABLE \ #define SCSI_NCR_CHIP_TABLE \
{ \ { \
{PSEUDO_ZALON_720_ID, 0x0f, "720", 3, 8, 4, \
FE_WIDE|FE_DIFF|FE_EHP|FE_MUX|FE_EA} \
, \
{PCI_DEVICE_ID_NCR_53C810, 0x0f, "810", 4, 8, 4, \ {PCI_DEVICE_ID_NCR_53C810, 0x0f, "810", 4, 8, 4, \
FE_ERL} \ FE_ERL} \
, \ , \
...@@ -819,6 +860,7 @@ typedef struct { ...@@ -819,6 +860,7 @@ typedef struct {
*/ */
#define SCSI_NCR_CHIP_IDS \ #define SCSI_NCR_CHIP_IDS \
{ \ { \
PSEUDO_ZALON_720_ID, \
PCI_DEVICE_ID_NCR_53C810, \ PCI_DEVICE_ID_NCR_53C810, \
PCI_DEVICE_ID_NCR_53C815, \ PCI_DEVICE_ID_NCR_53C815, \
PCI_DEVICE_ID_NCR_53C820, \ PCI_DEVICE_ID_NCR_53C820, \
...@@ -1170,6 +1212,7 @@ struct ncr_reg { ...@@ -1170,6 +1212,7 @@ struct ncr_reg {
/*17*/ u_char nc_mbox1; /* 896 and later cores only */ /*17*/ u_char nc_mbox1; /* 896 and later cores only */
/*18*/ u_char nc_ctest0; /*18*/ u_char nc_ctest0;
#define EHP 0x04 /* 720 even host parity */
/*19*/ u_char nc_ctest1; /*19*/ u_char nc_ctest1;
/*1a*/ u_char nc_ctest2; /*1a*/ u_char nc_ctest2;
...@@ -1187,6 +1230,7 @@ struct ncr_reg { ...@@ -1187,6 +1230,7 @@ struct ncr_reg {
/*20*/ u_char nc_dfifo; /*20*/ u_char nc_dfifo;
/*21*/ u_char nc_ctest4; /*21*/ u_char nc_ctest4;
#define MUX 0x80 /* 720 host bus multiplex mode */
#define BDIS 0x80 /* mod: burst disable */ #define BDIS 0x80 /* mod: burst disable */
#define MPEE 0x08 /* mod: master parity error enable */ #define MPEE 0x08 /* mod: master parity error enable */
...@@ -1219,6 +1263,7 @@ struct ncr_reg { ...@@ -1219,6 +1263,7 @@ struct ncr_reg {
#define CLSE 0x80 /* mod: cache line size enable */ #define CLSE 0x80 /* mod: cache line size enable */
#define PFF 0x40 /* cmd: pre-fetch flush */ #define PFF 0x40 /* cmd: pre-fetch flush */
#define PFEN 0x20 /* mod: pre-fetch enable */ #define PFEN 0x20 /* mod: pre-fetch enable */
#define EA 0x20 /* mod: 720 enable-ack */
#define SSM 0x10 /* mod: single step mode */ #define SSM 0x10 /* mod: single step mode */
#define IRQM 0x08 /* mod: irq mode (1 = totem pole !) */ #define IRQM 0x08 /* mod: irq mode (1 = totem pole !) */
#define STD 0x04 /* cmd: start dma mode */ #define STD 0x04 /* cmd: start dma mode */
...@@ -1261,6 +1306,7 @@ struct ncr_reg { ...@@ -1261,6 +1306,7 @@ struct ncr_reg {
/*4e*/ u_char nc_stest2; /*4e*/ u_char nc_stest2;
#define ROF 0x40 /* reset scsi offset (after gross error!) */ #define ROF 0x40 /* reset scsi offset (after gross error!) */
#define DIF 0x20 /* 720 SCSI differential mode */
#define EXT 0x02 /* extended filtering */ #define EXT 0x02 /* extended filtering */
/*4f*/ u_char nc_stest3; /*4f*/ u_char nc_stest3;
...@@ -1439,12 +1485,22 @@ struct scr_tblmove { ...@@ -1439,12 +1485,22 @@ struct scr_tblmove {
#define SCR_SEL_TBL 0x42000000 #define SCR_SEL_TBL 0x42000000
#define SCR_SEL_TBL_ATN 0x43000000 #define SCR_SEL_TBL_ATN 0x43000000
#ifdef SCSI_NCR_BIG_ENDIAN
struct scr_tblsel {
u_char sel_scntl3;
u_char sel_id;
u_char sel_sxfer;
u_char sel_scntl4;
};
#else
struct scr_tblsel { struct scr_tblsel {
u_char sel_scntl4; u_char sel_scntl4;
u_char sel_sxfer; u_char sel_sxfer;
u_char sel_id; u_char sel_id;
u_char sel_scntl3; u_char sel_scntl3;
}; };
#endif
#define SCR_JMP_REL 0x04000000 #define SCR_JMP_REL 0x04000000
#define SCR_ID(id) (((u_int32)(id)) << 16) #define SCR_ID(id) (((u_int32)(id)) << 16)
......
/*
* Zalon 53c7xx device driver.
* By Richard Hirst (rhirst@linuxcare.com)
*/
#include <linux/init.h>
#include <linux/types.h>
#include <linux/stat.h>
#include <linux/mm.h>
#include <linux/blk.h>
#include <linux/sched.h>
#include <linux/version.h>
#include <linux/config.h>
#include <linux/module.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/irq.h>
#include <asm/hardware.h>
#include <asm/delay.h>
#include <asm/io.h>
#include "../parisc/gsc.h"
#include "scsi.h"
#include "hosts.h"
/*
* ** Define the BSD style u_int32 and u_int64 type.
* ** Are in fact u_int32_t and u_int64_t :-)
* */
typedef u32 u_int32;
typedef u64 u_int64;
typedef u_long vm_offset_t;
#include "zalon.h"
/* hosts_* are kluges to pass info between the zalon7xx_detected()
** and the register_parisc_driver() callbacks.
*/
static Scsi_Host_Template *hosts_tptr;
static int hosts_used=0;
static int zalon_id = 0;
extern int zalon_attach(Scsi_Host_Template *tpnt,
unsigned long base_addr,
struct parisc_device *dev,
int irq_vector,
int unit
);
#if 0
/* FIXME:
* Is this function dead code? or is someone planning on using it in the
* future. The clock = (int) pdc_result[16] does not look correct to
* me ... I think it should be iodc_data[16]. Since this cause a compile
* error with the new encapsulated PDC, I'm not compiling in this function.
* - RB
*/
/* poke SCSI clock out of iodc data */
static u8 iodc_data[32] __attribute__ ((aligned (64)));
static unsigned long pdc_result[32] __attribute__ ((aligned (16))) ={0,0,0,0};
static int
lasi_scsi_clock(void * hpa, int defaultclock)
{
int clock, status;
status = pdc_iodc_read(&pdc_result, hpa, 0, &iodc_data, 32 );
if (status == PDC_RET_OK) {
clock = (int) pdc_result[16];
} else {
printk(KERN_WARNING "%s: pdc_iodc_read returned %d\n", __FUNCTION__, status);
clock = defaultclock;
}
printk(KERN_DEBUG "%s: SCSI clock %d\n", __FUNCTION__, clock);
return clock;
}
#endif
static int __init
zalon_scsi_callback(struct parisc_device *dev)
{
struct gsc_irq gsc_irq;
u32 zalon_vers;
int irq;
unsigned long zalon = dev->hpa;
__raw_writel(CMD_RESET, zalon + IO_MODULE_IO_COMMAND);
while (!(__raw_readl(zalon + IO_MODULE_IO_STATUS) & IOSTATUS_RY))
;
__raw_writel(IOIIDATA_MINT5EN | IOIIDATA_PACKEN | IOIIDATA_PREFETCHEN,
zalon + IO_MODULE_II_CDATA);
/* XXX: Save the Zalon version for bug workarounds? */
zalon_vers = __raw_readl(dev->hpa + IO_MODULE_II_CDATA) & 0x07000000;
zalon_vers >>= 24;
/* Setup the interrupts first.
** Later on request_irq() will register the handler.
*/
irq = gsc_alloc_irq(&gsc_irq);
printk("%s: Zalon vers field is 0x%x, IRQ %d\n", __FUNCTION__,
zalon_vers, irq);
__raw_writel(gsc_irq.txn_addr | gsc_irq.txn_data, dev->hpa + IO_MODULE_EIM);
if ( zalon_vers == 0)
printk(KERN_WARNING "%s: Zalon 1.1 or earlier\n", __FUNCTION__);
/*
** zalon_attach: returns -1 on failure, 0 on success
*/
hosts_used = zalon_attach(hosts_tptr, dev->hpa + GSC_SCSI_ZALON_OFFSET,
dev, irq, zalon_id);
if (hosts_used == 0)
zalon_id++;
hosts_used = (hosts_used == 0);
return (hosts_used == 0);
}
static struct parisc_device_id zalon_tbl[] = {
{ HPHW_A_DMA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00089 },
{ 0, }
};
MODULE_DEVICE_TABLE(parisc, zalon_tbl);
static struct parisc_driver zalon_driver = {
.name = "GSC SCSI (Zalon)",
.id_table = zalon_tbl,
.probe = zalon_scsi_callback,
};
int zalon7xx_detect(Scsi_Host_Template *tpnt)
{
/* "pass" the parameter to the callback functions */
hosts_tptr = tpnt;
hosts_used = 0;
/* claim all zalon cards. */
register_parisc_driver(&zalon_driver);
/* Check if any callbacks actually found/claimed anything. */
return (hosts_used != 0);
}
#ifdef MODULE
extern int ncr53c8xx_release(struct Scsi_Host *host);
int zalon7xx_release(struct Scsi_Host *host)
{
ncr53c8xx_release(host);
unregister_parisc_driver(&zalon_driver);
return 1;
}
#endif
#ifndef ZALON7XX_H
#define ZALON7XX_H
#include <linux/types.h>
#include "sym53c8xx_defs.h"
extern int zalon7xx_detect(Scsi_Host_Template *);
#include <scsi/scsicam.h>
extern struct proc_dir_entry proc_scsi_zalon7xx;
/* borrowed from drivers/scsi/ncr53c8xx.h */
int zalon7xx_detect(Scsi_Host_Template *tpnt);
const char *ncr53c8xx_info(struct Scsi_Host *host);
int ncr53c8xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
#ifdef MODULE
int zalon7xx_release(struct Scsi_Host *);
#else
#define zalon7xx_release NULL
#endif
#define GSC_SCSI_ZALON_OFFSET 0x800
#define IO_MODULE_EIM (1*4)
#define IO_MODULE_DC_ADATA (2*4)
#define IO_MODULE_II_CDATA (3*4)
#define IO_MODULE_IO_COMMAND (12*4)
#define IO_MODULE_IO_STATUS (13*4)
#define IOSTATUS_RY 0x40
#define IOSTATUS_FE 0x80
#define IOIIDATA_SMINT5L 0x40000000
#define IOIIDATA_MINT5EN 0x20000000
#define IOIIDATA_PACKEN 0x10000000
#define IOIIDATA_PREFETCHEN 0x08000000
#define IOIIDATA_IOII 0x00000020
#define CMD_RESET 5
#endif /* ZALON7XX_H */
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