Commit f1bf8612 authored by Linus Torvalds's avatar Linus Torvalds

Import 1.2.6

parent 3793c9b9
...@@ -683,6 +683,10 @@ E: ken@halcyon.com ...@@ -683,6 +683,10 @@ E: ken@halcyon.com
D: CDROM driver "sonycd535" (Sony CDU-535/531) D: CDROM driver "sonycd535" (Sony CDU-535/531)
S: S:
N: Frederic Potter
E: Frederic.Potter@masi.ibp.fr
D: Some PCI kernel support
N: Stefan Probst N: Stefan Probst
E: snprobst@immd4.informatik.uni-erlangen.de E: snprobst@immd4.informatik.uni-erlangen.de
D: The Linux Support Team Erlangen D: The Linux Support Team Erlangen
......
VERSION = 1 VERSION = 1
PATCHLEVEL = 2 PATCHLEVEL = 2
SUBLEVEL = 5 SUBLEVEL = 6
ARCH = i386 ARCH = i386
......
...@@ -74,6 +74,10 @@ bool 'Scsi tape support' CONFIG_CHR_DEV_ST n ...@@ -74,6 +74,10 @@ bool 'Scsi tape support' CONFIG_CHR_DEV_ST n
bool 'Scsi CDROM support' CONFIG_BLK_DEV_SR n bool 'Scsi CDROM support' CONFIG_BLK_DEV_SR n
bool 'Scsi generic support' CONFIG_CHR_DEV_SG n bool 'Scsi generic support' CONFIG_CHR_DEV_SG n
comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs'
bool 'Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN n
comment 'SCSI low-level drivers' comment 'SCSI low-level drivers'
bool 'Adaptec AHA152X support' CONFIG_SCSI_AHA152X n bool 'Adaptec AHA152X support' CONFIG_SCSI_AHA152X n
......
...@@ -4,7 +4,7 @@ Wed Apr 12 08:06:16 1995 Theodore Y. Ts'o <tytso@localhost> ...@@ -4,7 +4,7 @@ Wed Apr 12 08:06:16 1995 Theodore Y. Ts'o <tytso@localhost>
rs_init): Hangups are now scheduled via a separate tqueue rs_init): Hangups are now scheduled via a separate tqueue
structure in the async_struct structure, tqueue_hangup. structure in the async_struct structure, tqueue_hangup.
This task is pushed on to the tq_schedule queue, so that This task is pushed on to the tq_schedule queue, so that
it is processed syncronously by the scheduler. it is processed synchronously by the scheduler.
Sat Feb 18 12:13:51 1995 Theodore Y. Ts'o (tytso@rt-11) Sat Feb 18 12:13:51 1995 Theodore Y. Ts'o (tytso@rt-11)
......
...@@ -733,7 +733,7 @@ static void do_softint(void *private_) ...@@ -733,7 +733,7 @@ static void do_softint(void *private_)
/* /*
* This routine is called from the scheduler tqueue when the interrupt * This routine is called from the scheduler tqueue when the interrupt
* routine has signalled that a hangup has occured. The path of * routine has signalled that a hangup has occurred. The path of
* hangup processing is: * hangup processing is:
* *
* serial interrupt routine -> (scheduler tqueue) -> * serial interrupt routine -> (scheduler tqueue) ->
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771 Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
*/ */
static char *version = "lance.c:v1.07 1/18/95 becker@cesdis.gsfc.nasa.gov\n"; static char *version = "lance.c:v1.08 4/10/95 dplatt@3do.com\n";
#include <linux/config.h> #include <linux/config.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -203,12 +203,18 @@ struct lance_private { ...@@ -203,12 +203,18 @@ struct lance_private {
int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */ int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */
int dma; int dma;
struct enet_statistics stats; struct enet_statistics stats;
char chip_version; /* See lance_chip_type. */ unsigned char chip_version; /* See lance_chip_type. */
char tx_full; char tx_full;
char lock; char lock;
int pad0, pad1; /* Used for 8-byte alignment */ int pad0, pad1; /* Used for 8-byte alignment */
}; };
#define LANCE_MUST_PAD 0x00000001
#define LANCE_ENABLE_AUTOSELECT 0x00000002
#define LANCE_MUST_REINIT_RING 0x00000004
#define LANCE_MUST_UNRESET 0x00000008
#define LANCE_HAS_MISSED_FRAME 0x00000010
/* A mapping from the chip ID number to the part number and features. /* A mapping from the chip ID number to the part number and features.
These are from the datasheets -- in real life the '970 version These are from the datasheets -- in real life the '970 version
reportedly has the same ID as the '965. */ reportedly has the same ID as the '965. */
...@@ -217,14 +223,25 @@ static struct lance_chip_type { ...@@ -217,14 +223,25 @@ static struct lance_chip_type {
char *name; char *name;
int flags; int flags;
} chip_table[] = { } chip_table[] = {
{0x0000, "LANCE 7990", 0}, /* Ancient lance chip. */ {0x0000, "LANCE 7990", /* Ancient lance chip. */
{0x0003, "PCnet/ISA 79C960", 0}, /* 79C960 PCnet/ISA. */ LANCE_MUST_PAD + LANCE_MUST_UNRESET},
{0x2260, "PCnet/ISA+ 79C961", 0}, /* 79C961 PCnet/ISA+, Plug-n-Play. */ {0x0003, "PCnet/ISA 79C960", /* 79C960 PCnet/ISA. */
{0x2420, "PCnet/PCI 79C970", 0}, /* 79C970 or 79C974 PCnet-SCSI, PCI. */ LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
LANCE_HAS_MISSED_FRAME},
{0x2260, "PCnet/ISA+ 79C961", /* 79C961 PCnet/ISA+, Plug-n-Play. */
LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
LANCE_HAS_MISSED_FRAME},
{0x2420, "PCnet/PCI 79C970", /* 79C970 or 79C974 PCnet-SCSI, PCI. */
LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
LANCE_HAS_MISSED_FRAME},
/* Bug: the PCnet/PCI actually uses the PCnet/VLB ID number, so just call /* Bug: the PCnet/PCI actually uses the PCnet/VLB ID number, so just call
it the PCnet32. */ it the PCnet32. */
{0x2430, "PCnet32", 0}, /* 79C965 PCnet for VL bus. */ {0x2430, "PCnet32", /* 79C965 PCnet for VL bus. */
{0x0, "PCnet (unknown)", 0}, LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
LANCE_HAS_MISSED_FRAME},
{0x0, "PCnet (unknown)",
LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
LANCE_HAS_MISSED_FRAME},
}; };
enum {OLD_LANCE = 0, PCNET_ISA=1, PCNET_ISAP=2, PCNET_PCI=3, PCNET_VLB=4, LANCE_UNKNOWN=5}; enum {OLD_LANCE = 0, PCNET_ISA=1, PCNET_ISAP=2, PCNET_PCI=3, PCNET_VLB=4, LANCE_UNKNOWN=5};
...@@ -256,8 +273,6 @@ unsigned long lance_init(unsigned long mem_start, unsigned long mem_end) ...@@ -256,8 +273,6 @@ unsigned long lance_init(unsigned long mem_start, unsigned long mem_end)
int *port; int *port;
#if defined(CONFIG_PCI) #if defined(CONFIG_PCI)
#define AMD_VENDOR_ID 0x1022
#define AMD_DEVICE_ID 0x2000
if (pcibios_present()) { if (pcibios_present()) {
int pci_index; int pci_index;
printk("lance.c: PCI bios is present, checking for devices...\n"); printk("lance.c: PCI bios is present, checking for devices...\n");
...@@ -266,7 +281,8 @@ unsigned long lance_init(unsigned long mem_start, unsigned long mem_end) ...@@ -266,7 +281,8 @@ unsigned long lance_init(unsigned long mem_start, unsigned long mem_end)
unsigned long pci_ioaddr; unsigned long pci_ioaddr;
unsigned short pci_command; unsigned short pci_command;
if (pcibios_find_device (AMD_VENDOR_ID, AMD_DEVICE_ID, pci_index, if (pcibios_find_device (PCI_VENDOR_ID_AMD,
PCI_DEVICE_ID_AMD_LANCE, pci_index,
&pci_bus, &pci_device_fn) != 0) &pci_bus, &pci_device_fn) != 0)
break; break;
pcibios_read_config_byte(pci_bus, pci_device_fn, pcibios_read_config_byte(pci_bus, pci_device_fn,
...@@ -522,7 +538,7 @@ unsigned long lance_probe1(int ioaddr, unsigned long mem_start) ...@@ -522,7 +538,7 @@ unsigned long lance_probe1(int ioaddr, unsigned long mem_start)
} }
} }
if (lp->chip_version != OLD_LANCE) { if (chip_table[lp->chip_version].flags & LANCE_ENABLE_AUTOSELECT) {
/* Turn on auto-select of media (10baseT or BNC) so that the user /* Turn on auto-select of media (10baseT or BNC) so that the user
can watch the LEDs even if the board isn't opened. */ can watch the LEDs even if the board isn't opened. */
outw(0x0002, ioaddr+LANCE_ADDR); outw(0x0002, ioaddr+LANCE_ADDR);
...@@ -570,10 +586,10 @@ lance_open(struct device *dev) ...@@ -570,10 +586,10 @@ lance_open(struct device *dev)
} }
/* Un-Reset the LANCE, needed only for the NE2100. */ /* Un-Reset the LANCE, needed only for the NE2100. */
if (lp->chip_version == OLD_LANCE) if (chip_table[lp->chip_version].flags & LANCE_MUST_UNRESET)
outw(0, ioaddr+LANCE_RESET); outw(0, ioaddr+LANCE_RESET);
if (lp->chip_version != OLD_LANCE) { if (chip_table[lp->chip_version].flags & LANCE_ENABLE_AUTOSELECT) {
/* This is 79C960-specific: Turn on auto-select of media (AUI, BNC). */ /* This is 79C960-specific: Turn on auto-select of media (AUI, BNC). */
outw(0x0002, ioaddr+LANCE_ADDR); outw(0x0002, ioaddr+LANCE_ADDR);
outw(0x0002, ioaddr+LANCE_BUS_IF); outw(0x0002, ioaddr+LANCE_BUS_IF);
...@@ -617,6 +633,33 @@ lance_open(struct device *dev) ...@@ -617,6 +633,33 @@ lance_open(struct device *dev)
return 0; /* Always succeed */ return 0; /* Always succeed */
} }
/* The LANCE has been halted for one reason or another (busmaster memory
arbitration error, Tx FIFO underflow, driver stopped it to reconfigure,
etc.). Modern LANCE variants always reload their ring-buffer
configuration when restarted, so we must reinitialize our ring
context before restarting. As part of this reinitialization,
find all packets still on the Tx ring and pretend that they had been
sent (in effect, drop the packets on the floor) - the higher-level
protocols will time out and retransmit. It'd be better to shuffle
these skbs to a temp list and then actually re-Tx them after
restarting the chip, but I'm too lazy to do so right now. dplatt@3do.com
*/
static void
lance_purge_tx_ring(struct device *dev)
{
struct lance_private *lp = (struct lance_private *)dev->priv;
int i;
for (i = 0; i < TX_RING_SIZE; i++) {
if (lp->tx_skbuff[i]) {
dev_kfree_skb(lp->tx_skbuff[i],FREE_WRITE);
lp->tx_skbuff[i] = NULL;
}
}
}
/* Initialize the LANCE Rx and Tx rings. */ /* Initialize the LANCE Rx and Tx rings. */
static void static void
lance_init_ring(struct device *dev) lance_init_ring(struct device *dev)
...@@ -647,12 +690,27 @@ lance_init_ring(struct device *dev) ...@@ -647,12 +690,27 @@ lance_init_ring(struct device *dev)
lp->init_block.tx_ring = (int)lp->tx_ring | TX_RING_LEN_BITS; lp->init_block.tx_ring = (int)lp->tx_ring | TX_RING_LEN_BITS;
} }
static void
lance_restart(struct device *dev, unsigned int csr0_bits, int must_reinit)
{
struct lance_private *lp = (struct lance_private *)dev->priv;
if (must_reinit ||
(chip_table[lp->chip_version].flags & LANCE_MUST_REINIT_RING)) {
lance_purge_tx_ring(dev);
lance_init_ring(dev);
}
outw(0x0000, dev->base_addr + LANCE_ADDR);
outw(csr0_bits, dev->base_addr + LANCE_DATA);
}
static int static int
lance_start_xmit(struct sk_buff *skb, struct device *dev) lance_start_xmit(struct sk_buff *skb, struct device *dev)
{ {
struct lance_private *lp = (struct lance_private *)dev->priv; struct lance_private *lp = (struct lance_private *)dev->priv;
int ioaddr = dev->base_addr; int ioaddr = dev->base_addr;
int entry; int entry;
unsigned long flags;
/* Transmitter timeout, serious problems. */ /* Transmitter timeout, serious problems. */
if (dev->tbusy) { if (dev->tbusy) {
...@@ -681,8 +739,7 @@ lance_start_xmit(struct sk_buff *skb, struct device *dev) ...@@ -681,8 +739,7 @@ lance_start_xmit(struct sk_buff *skb, struct device *dev)
printk("\n"); printk("\n");
} }
#endif #endif
lance_init_ring(dev); lance_restart(dev, 0x0043, 1);
outw(0x0043, ioaddr+LANCE_DATA);
dev->tbusy=0; dev->tbusy=0;
dev->trans_start = jiffies; dev->trans_start = jiffies;
...@@ -728,7 +785,7 @@ lance_start_xmit(struct sk_buff *skb, struct device *dev) ...@@ -728,7 +785,7 @@ lance_start_xmit(struct sk_buff *skb, struct device *dev)
with the "ownership" bits last. */ with the "ownership" bits last. */
/* The old LANCE chips doesn't automatically pad buffers to min. size. */ /* The old LANCE chips doesn't automatically pad buffers to min. size. */
if (lp->chip_version == OLD_LANCE) { if (chip_table[lp->chip_version].flags & LANCE_MUST_PAD) {
lp->tx_ring[entry].length = lp->tx_ring[entry].length =
-(ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN); -(ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN);
} else } else
...@@ -758,13 +815,14 @@ lance_start_xmit(struct sk_buff *skb, struct device *dev) ...@@ -758,13 +815,14 @@ lance_start_xmit(struct sk_buff *skb, struct device *dev)
dev->trans_start = jiffies; dev->trans_start = jiffies;
save_flags(flags);
cli(); cli();
lp->lock = 0; lp->lock = 0;
if (lp->tx_ring[(entry+1) & TX_RING_MOD_MASK].base == 0) if (lp->tx_ring[(entry+1) & TX_RING_MOD_MASK].base == 0)
dev->tbusy=0; dev->tbusy=0;
else else
lp->tx_full = 1; lp->tx_full = 1;
sti(); restore_flags(flags);
return 0; return 0;
} }
...@@ -776,6 +834,7 @@ lance_interrupt(int irq, struct pt_regs * regs) ...@@ -776,6 +834,7 @@ lance_interrupt(int irq, struct pt_regs * regs)
struct device *dev = (struct device *)(irq2dev_map[irq]); struct device *dev = (struct device *)(irq2dev_map[irq]);
struct lance_private *lp; struct lance_private *lp;
int csr0, ioaddr, boguscnt=10; int csr0, ioaddr, boguscnt=10;
int must_restart;
if (dev == NULL) { if (dev == NULL) {
printk ("lance_interrupt(): irq %d for unknown device.\n", irq); printk ("lance_interrupt(): irq %d for unknown device.\n", irq);
...@@ -795,6 +854,8 @@ lance_interrupt(int irq, struct pt_regs * regs) ...@@ -795,6 +854,8 @@ lance_interrupt(int irq, struct pt_regs * regs)
/* Acknowledge all of the current interrupt sources ASAP. */ /* Acknowledge all of the current interrupt sources ASAP. */
outw(csr0 & ~0x004f, dev->base_addr + LANCE_DATA); outw(csr0 & ~0x004f, dev->base_addr + LANCE_DATA);
must_restart = 0;
if (lance_debug > 5) if (lance_debug > 5)
printk("%s: interrupt csr0=%#2.2x new csr=%#2.2x.\n", printk("%s: interrupt csr0=%#2.2x new csr=%#2.2x.\n",
dev->name, csr0, inw(dev->base_addr + LANCE_DATA)); dev->name, csr0, inw(dev->base_addr + LANCE_DATA));
...@@ -828,7 +889,7 @@ lance_interrupt(int irq, struct pt_regs * regs) ...@@ -828,7 +889,7 @@ lance_interrupt(int irq, struct pt_regs * regs)
printk("%s: Tx FIFO error! Status %4.4x.\n", printk("%s: Tx FIFO error! Status %4.4x.\n",
dev->name, csr0); dev->name, csr0);
/* Restart the chip. */ /* Restart the chip. */
outw(0x0002, dev->base_addr + LANCE_DATA); must_restart = 1;
} }
} else { } else {
if (status & 0x18000000) if (status & 0x18000000)
...@@ -871,7 +932,14 @@ lance_interrupt(int irq, struct pt_regs * regs) ...@@ -871,7 +932,14 @@ lance_interrupt(int irq, struct pt_regs * regs)
printk("%s: Bus master arbitration failure, status %4.4x.\n", printk("%s: Bus master arbitration failure, status %4.4x.\n",
dev->name, csr0); dev->name, csr0);
/* Restart the chip. */ /* Restart the chip. */
outw(0x0002, dev->base_addr + LANCE_DATA); must_restart = 1;
}
if (must_restart) {
/* stop the chip to clear the error condition, then restart */
outw(0x0000, dev->base_addr + LANCE_ADDR);
outw(0x0004, dev->base_addr + LANCE_DATA);
lance_restart(dev, 0x0002, 0);
} }
} }
...@@ -961,7 +1029,7 @@ lance_close(struct device *dev) ...@@ -961,7 +1029,7 @@ lance_close(struct device *dev)
dev->start = 0; dev->start = 0;
dev->tbusy = 1; dev->tbusy = 1;
if (lp->chip_version != OLD_LANCE) { if (chip_table[lp->chip_version].flags & LANCE_HAS_MISSED_FRAME) {
outw(112, ioaddr+LANCE_ADDR); outw(112, ioaddr+LANCE_ADDR);
lp->stats.rx_missed_errors = inw(ioaddr+LANCE_DATA); lp->stats.rx_missed_errors = inw(ioaddr+LANCE_DATA);
} }
...@@ -991,14 +1059,16 @@ lance_get_stats(struct device *dev) ...@@ -991,14 +1059,16 @@ lance_get_stats(struct device *dev)
struct lance_private *lp = (struct lance_private *)dev->priv; struct lance_private *lp = (struct lance_private *)dev->priv;
short ioaddr = dev->base_addr; short ioaddr = dev->base_addr;
short saved_addr; short saved_addr;
unsigned long flags;
if (lp->chip_version != OLD_LANCE) { if (chip_table[lp->chip_version].flags & LANCE_HAS_MISSED_FRAME) {
save_flags(flags);
cli(); cli();
saved_addr = inw(ioaddr+LANCE_ADDR); saved_addr = inw(ioaddr+LANCE_ADDR);
outw(112, ioaddr+LANCE_ADDR); outw(112, ioaddr+LANCE_ADDR);
lp->stats.rx_missed_errors = inw(ioaddr+LANCE_DATA); lp->stats.rx_missed_errors = inw(ioaddr+LANCE_DATA);
outw(saved_addr, ioaddr+LANCE_ADDR); outw(saved_addr, ioaddr+LANCE_ADDR);
sti(); restore_flags(flags);
} }
return &lp->stats; return &lp->stats;
...@@ -1015,11 +1085,9 @@ set_multicast_list(struct device *dev, int num_addrs, void *addrs) ...@@ -1015,11 +1085,9 @@ set_multicast_list(struct device *dev, int num_addrs, void *addrs)
{ {
short ioaddr = dev->base_addr; short ioaddr = dev->base_addr;
/* We take the simple way out and always enable promiscuous mode. */
outw(0, ioaddr+LANCE_ADDR); outw(0, ioaddr+LANCE_ADDR);
outw(0x0004, ioaddr+LANCE_DATA); /* Temporarily stop the lance. */ outw(0x0004, ioaddr+LANCE_DATA); /* Temporarily stop the lance. */
outw(15, ioaddr+LANCE_ADDR);
if (num_addrs >= 0) { if (num_addrs >= 0) {
short multicast_table[4]; short multicast_table[4];
int i; int i;
...@@ -1029,15 +1097,17 @@ set_multicast_list(struct device *dev, int num_addrs, void *addrs) ...@@ -1029,15 +1097,17 @@ set_multicast_list(struct device *dev, int num_addrs, void *addrs)
outw(8 + i, ioaddr+LANCE_ADDR); outw(8 + i, ioaddr+LANCE_ADDR);
outw(multicast_table[i], ioaddr+LANCE_DATA); outw(multicast_table[i], ioaddr+LANCE_DATA);
} }
outw(15, ioaddr+LANCE_ADDR);
outw(0x0000, ioaddr+LANCE_DATA); /* Unset promiscuous mode */ outw(0x0000, ioaddr+LANCE_DATA); /* Unset promiscuous mode */
} else { } else {
/* Log any net taps. */ /* Log any net taps. */
printk("%s: Promiscuous mode enabled.\n", dev->name); printk("%s: Promiscuous mode enabled.\n", dev->name);
outw(15, ioaddr+LANCE_ADDR);
outw(0x8000, ioaddr+LANCE_DATA); /* Set promiscuous mode */ outw(0x8000, ioaddr+LANCE_DATA); /* Set promiscuous mode */
} }
outw(0, ioaddr+LANCE_ADDR); lance_restart(dev, 0x0142, 0); /* Resume normal operation */
outw(0x0142, ioaddr+LANCE_DATA); /* Resume normal operation. */
} }
......
...@@ -376,7 +376,6 @@ ne_block_output(struct device *dev, int count, ...@@ -376,7 +376,6 @@ ne_block_output(struct device *dev, int count,
{ {
int retries = 0; int retries = 0;
int nic_base = NE_BASE; int nic_base = NE_BASE;
unsigned long flags;
/* Round the count up for word writes. Do we need to do this? /* Round the count up for word writes. Do we need to do this?
What effect will an odd byte count have on the 8390? What effect will an odd byte count have on the 8390?
...@@ -412,19 +411,7 @@ ne_block_output(struct device *dev, int count, ...@@ -412,19 +411,7 @@ ne_block_output(struct device *dev, int count,
SLOW_DOWN_IO; SLOW_DOWN_IO;
#endif /* rw_bugfix */ #endif /* rw_bugfix */
/* /* Now the normal output. */
Now the normal output. I believe that if we don't lock this, a
race condition will munge the remote byte count values, and then
the ne2k will hang the machine by holding I/O CH RDY because it
expects more data. Hopefully fixes the lockups. -- Paul Gortmaker.
Use save_flags/cli/restore_flags rather than cli/sti to avoid risk
of accidentally enabling interrupts which were disabled when we
were entered. Dave Platt <dplatt@3do.com>
*/
save_flags(flags);
cli();
outb_p(count & 0xff, nic_base + EN0_RCNTLO); outb_p(count & 0xff, nic_base + EN0_RCNTLO);
outb_p(count >> 8, nic_base + EN0_RCNTHI); outb_p(count >> 8, nic_base + EN0_RCNTHI);
outb_p(0x00, nic_base + EN0_RSARLO); outb_p(0x00, nic_base + EN0_RSARLO);
...@@ -436,7 +423,6 @@ ne_block_output(struct device *dev, int count, ...@@ -436,7 +423,6 @@ ne_block_output(struct device *dev, int count,
} else { } else {
outsb(NE_BASE + NE_DATAPORT, buf, count); outsb(NE_BASE + NE_DATAPORT, buf, count);
} }
restore_flags(flags);
#ifdef CONFIG_NE_SANITY #ifdef CONFIG_NE_SANITY
/* This was for the ALPHA version only, but enough people have /* This was for the ALPHA version only, but enough people have
......
...@@ -98,6 +98,7 @@ static char *version = "NET3 PLIP version 2.0 gniibe@mri.co.jp\n"; ...@@ -98,6 +98,7 @@ static char *version = "NET3 PLIP version 2.0 gniibe@mri.co.jp\n";
#include <linux/ioport.h> #include <linux/ioport.h>
#include <asm/bitops.h> #include <asm/bitops.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/byteorder.h>
/* Use 0 for production, 1 for verification, >2 for debug */ /* Use 0 for production, 1 for verification, >2 for debug */
#ifndef NET_DEBUG #ifndef NET_DEBUG
...@@ -165,26 +166,14 @@ struct plip_local { ...@@ -165,26 +166,14 @@ struct plip_local {
enum plip_nibble_state nibble; enum plip_nibble_state nibble;
union { union {
struct { struct {
#if defined(__i386__) #if defined(LITTLE_ENDIAN)
unsigned char lsb; unsigned char lsb;
unsigned char msb; unsigned char msb;
#elif defined(__mc68000__) #elif defined(BIG_ENDIAN)
unsigned char msb; unsigned char msb;
unsigned char lsb; unsigned char lsb;
#elif defined(__sparc__)
unsigned char msb;
unsigned char lsb;
#elif defined(__MIPSEL__)
unsigned char lsb;
unsigned char msb;
#elif defined(__MIPSEB__)
unsigned char msb;
unsigned char lsb;
#elif defined(__alpha__)
unsigned char lsb;
unsigned char msb;
#else #else
#error "Adjust this structure to match your CPU" #error "Please fix the endianness defines in <asm/byteorder.h>"
#endif #endif
} b; } b;
unsigned short h; unsigned short h;
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
* weed out brain damaged main boards. * weed out brain damaged main boards.
*/ */
#define PERM_OPTIONS (OPTION_IO_MAPPED|OPTION_DEBUG_TEST1)
#define PERM_OPTIONS (OPTION_IO_MAPPED|OPTION_DEBUG_TEST1)
/* /*
* Define SCSI_MALLOC to use scsi_malloc instead of kmalloc. Other than * Define SCSI_MALLOC to use scsi_malloc instead of kmalloc. Other than
* preventing deadlock, I'm not sure why we'd want to do this. * preventing deadlock, I'm not sure why we'd want to do this.
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
* Hannover, Germany * Hannover, Germany
* hm@ix.de * hm@ix.de
* *
* Copyright 1993, 1994 Drew Eckhardt * Copyright 1993, 1994, 1995 Drew Eckhardt
* Visionary Computing * Visionary Computing
* (Unix and Linux consulting and custom programming) * (Unix and Linux consulting and custom programming)
* drew@Colorado.EDU * drew@Colorado.EDU
...@@ -28,8 +28,6 @@ ...@@ -28,8 +28,6 @@
* *
* TolerANT and SCSI SCRIPTS are registered trademarks of NCR Corporation. * TolerANT and SCSI SCRIPTS are registered trademarks of NCR Corporation.
* *
* PRE-ALPHA
*
* For more information, please consult * For more information, please consult
* *
* *
...@@ -156,6 +154,11 @@ ...@@ -156,6 +154,11 @@
* *
*/ */
#ifdef MODULE
#include <linux/module.h>
#endif
#include <asm/dma.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/system.h> #include <asm/system.h>
#include <linux/delay.h> #include <linux/delay.h>
...@@ -176,7 +179,9 @@ ...@@ -176,7 +179,9 @@
static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int result); static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int result);
static int NCR53c8xx_run_tests (struct Scsi_Host *host); static int NCR53c8xx_run_tests (struct Scsi_Host *host);
static int NCR53c8xx_script_len; static int NCR53c8xx_script_len;
static int NCR53c8xx_dsa_len;
static void NCR53c7x0_intr(int irq, struct pt_regs * regs); static void NCR53c7x0_intr(int irq, struct pt_regs * regs);
static int halt (struct Scsi_Host *host);
static void intr_phase_mismatch (struct Scsi_Host *host, struct NCR53c7x0_cmd static void intr_phase_mismatch (struct Scsi_Host *host, struct NCR53c7x0_cmd
*cmd); *cmd);
static void intr_dma (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd); static void intr_dma (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd);
...@@ -190,40 +195,11 @@ static int NCR53c8x0_dstat_sir_intr (struct Scsi_Host *host, struct ...@@ -190,40 +195,11 @@ static int NCR53c8x0_dstat_sir_intr (struct Scsi_Host *host, struct
NCR53c7x0_cmd *cmd); NCR53c7x0_cmd *cmd);
static void NCR53c8x0_soft_reset (struct Scsi_Host *host); static void NCR53c8x0_soft_reset (struct Scsi_Host *host);
static int perm_options = PERM_OPTIONS;
static struct Scsi_Host *first_host = NULL; /* Head of list of NCR boards */ static struct Scsi_Host *first_host = NULL; /* Head of list of NCR boards */
static Scsi_Host_Template *the_template = NULL; static Scsi_Host_Template *the_template = NULL;
/* Allocate storage space for constant messages, etc. */
static long NCR53c7xx_zero = 0;
static long NCR53c7xx_sink;
static char NCR53c7xx_msg_reject = MESSAGE_REJECT;
static char NCR53c7xx_msg_abort = ABORT;
static char NCR53c7xx_msg_nop = NOP;
/* Buffer for commands run before *malloc() works */
/*
* XXX - if need be, replace this with normal wait.
*/
static int scan_scsis_buf_busy = 0;
static char scan_scsis_buf[512];
/*
* Spl-levels are evil. We shouldn't emulate braindamage.
* Linus
*/
static int splx (int new_level)
{
register int old_level, tmp;
save_flags(tmp);
old_level = (tmp & 0x200) ? 7 : 0;
if (new_level)
sti();
else
cli();
return old_level;
}
/* /*
* TODO : * TODO :
...@@ -285,8 +261,7 @@ static int splx (int new_level) ...@@ -285,8 +261,7 @@ static int splx (int new_level)
* *
* For the very similar chips, we should probably hack the fixup code * For the very similar chips, we should probably hack the fixup code
* and interrupt code so that it works everywhere, but I suspect the * and interrupt code so that it works everywhere, but I suspect the
* NCR53c700 is going * NCR53c700 is going to need it's own fixup routine.
* to need it's own fixup routine.
*/ */
/* /*
...@@ -420,7 +395,8 @@ setup_wrapper(825) ...@@ -420,7 +395,8 @@ setup_wrapper(825)
* field of the hostdata structure MUST have been set. * field of the hostdata structure MUST have been set.
*/ */
static int NCR53c7x0_init (struct Scsi_Host *host) { static int
NCR53c7x0_init (struct Scsi_Host *host) {
NCR53c7x0_local_declare(); NCR53c7x0_local_declare();
/* unsigned char tmp; */ /* unsigned char tmp; */
int i, j, ccf; int i, j, ccf;
...@@ -450,13 +426,19 @@ static int NCR53c7x0_init (struct Scsi_Host *host) { ...@@ -450,13 +426,19 @@ static int NCR53c7x0_init (struct Scsi_Host *host) {
return -1; return -1;
} }
/* Assign constants accessed by NCR */
hostdata->NCR53c7xx_zero = 0;
hostdata->NCR53c7xx_msg_reject = MESSAGE_REJECT;
hostdata->NCR53c7xx_msg_abort = ABORT;
hostdata->NCR53c7xx_msg_nop = NOP;
/* /*
* Set up an interrupt handler if we aren't already sharing an IRQ * Set up an interrupt handler if we aren't already sharing an IRQ
* with another board. * with another board.
*/ */
for (search = first_host; search && (search->hostt == the_template) && for (search = first_host; search && ((search->hostt != the_template) ||
(search->irq != host->irq); search=search->next); (search->irq != host->irq)); search=search->next);
if (!search) { if (!search) {
if (request_irq(host->irq, NCR53c7x0_intr, SA_INTERRUPT, "53c7,8xx")) { if (request_irq(host->irq, NCR53c7x0_intr, SA_INTERRUPT, "53c7,8xx")) {
...@@ -479,6 +461,10 @@ static int NCR53c7x0_init (struct Scsi_Host *host) { ...@@ -479,6 +461,10 @@ static int NCR53c7x0_init (struct Scsi_Host *host) {
hostdata->istat = ((hostdata->chip / 100) == 8) ? hostdata->istat = ((hostdata->chip / 100) == 8) ?
ISTAT_REG_800 : ISTAT_REG_700; ISTAT_REG_800 : ISTAT_REG_700;
/* Only the ISTAT register is readable when the NCR is running, so make
sure it's halted. */
halt(host);
/* /*
* XXX - the NCR53c700 uses bitfielded registers for SCID, SDID, etc, * XXX - the NCR53c700 uses bitfielded registers for SCID, SDID, etc,
* as does the 710 with one bit per SCSI ID. Conversely, the NCR * as does the 710 with one bit per SCSI ID. Conversely, the NCR
...@@ -523,9 +509,9 @@ static int NCR53c7x0_init (struct Scsi_Host *host) { ...@@ -523,9 +509,9 @@ static int NCR53c7x0_init (struct Scsi_Host *host) {
hostdata->saved_dcntl = NCR53c7x0_read8(DCNTL_REG); hostdata->saved_dcntl = NCR53c7x0_read8(DCNTL_REG);
if ((hostdata->chip / 100) == 8) if ((hostdata->chip / 100) == 8)
printk ("scsi%d : using %s interrupts.\n", host->host_no, printk ("scsi%d : using %s interrupts\n", host->host_no,
(hostdata->saved_dcntl & DCNTL_800_IRQM) ? "level active" : (hostdata->saved_dcntl & DCNTL_800_IRQM) ? "edge triggered" :
"edge triggered"); "level active");
/* /*
* DMODE controls DMA burst length, and on 700 series chips, * DMODE controls DMA burst length, and on 700 series chips,
...@@ -547,8 +533,9 @@ static int NCR53c7x0_init (struct Scsi_Host *host) { ...@@ -547,8 +533,9 @@ static int NCR53c7x0_init (struct Scsi_Host *host) {
case DMODE_BL_4: i = 4; break; case DMODE_BL_4: i = 4; break;
case DMODE_BL_8: i = 8; break; case DMODE_BL_8: i = 8; break;
case DMODE_BL_16: i = 16; break; case DMODE_BL_16: i = 16; break;
default: i = 0;
} }
printk ("scsi%d ; burst length %d\n", host->host_no, i); printk ("scsi%d : burst length %d\n", host->host_no, i);
} }
} }
...@@ -592,6 +579,7 @@ static int NCR53c7x0_init (struct Scsi_Host *host) { ...@@ -592,6 +579,7 @@ static int NCR53c7x0_init (struct Scsi_Host *host) {
*/ */
for (i = 0; i < 8; ++i) { for (i = 0; i < 8; ++i) {
hostdata->cmd_allocated[i] = 0;
for (j = 0; j < 8; ++j) for (j = 0; j < 8; ++j)
hostdata->busy[i][j] = 0; hostdata->busy[i][j] = 0;
/* /*
...@@ -620,8 +608,8 @@ static int NCR53c7x0_init (struct Scsi_Host *host) { ...@@ -620,8 +608,8 @@ static int NCR53c7x0_init (struct Scsi_Host *host) {
hostdata->issue_queue = hostdata->running_list = hostdata->issue_queue = hostdata->running_list =
hostdata->finished_queue = NULL; hostdata->finished_queue = NULL;
hostdata->issue_dsa_head = hostdata->issue_dsa_head = NULL;
hostdata->issue_dsa_tail = NULL; hostdata->issue_dsa_tail = NULL;
if (hostdata->init_save_regs) if (hostdata->init_save_regs)
hostdata->init_save_regs (host); hostdata->init_save_regs (host);
...@@ -688,11 +676,11 @@ static int normal_init (Scsi_Host_Template *tpnt, int board, int chip, ...@@ -688,11 +676,11 @@ static int normal_init (Scsi_Host_Template *tpnt, int board, int chip,
struct Scsi_Host *instance; struct Scsi_Host *instance;
struct NCR53c7x0_hostdata *hostdata; struct NCR53c7x0_hostdata *hostdata;
char chip_str[80]; char chip_str[80];
int script_len = 0, size = 0; int script_len = 0, dsa_len = 0, size = 0, max_cmd_size = 0;
int ok = 0; int ok = 0;
options |= PERM_OPTIONS; options |= perm_options;
switch (chip) { switch (chip) {
case 825: case 825:
...@@ -700,6 +688,7 @@ static int normal_init (Scsi_Host_Template *tpnt, int board, int chip, ...@@ -700,6 +688,7 @@ static int normal_init (Scsi_Host_Template *tpnt, int board, int chip,
case 815: case 815:
case 810: case 810:
script_len = NCR53c8xx_script_len; script_len = NCR53c8xx_script_len;
dsa_len = NCR53c8xx_dsa_len;
options |= OPTION_INTFLY; options |= OPTION_INTFLY;
sprintf (chip_str, "NCR53c%d", chip); sprintf (chip_str, "NCR53c%d", chip);
break; break;
...@@ -718,7 +707,7 @@ static int normal_init (Scsi_Host_Template *tpnt, int board, int chip, ...@@ -718,7 +707,7 @@ static int normal_init (Scsi_Host_Template *tpnt, int board, int chip,
if ((chip / 100 == 8) && !pci_valid) if ((chip / 100 == 8) && !pci_valid)
printk ("scsi-ncr53c7,8xx : for better reliability and performance, please use the\n" printk ("scsi-ncr53c7,8xx : for better reliability and performance, please use the\n"
" PCI override instead.\n" " PCI override instead.\n"
" Syntax : ncr53c8{10,20,25}=pci,<bus>,<device>,<function>\n" " Syntax : ncr53c8{10,15,20,25}=pci,<bus>,<device>,<function>\n"
" <bus> and <device> are usually 0.\n"); " <bus> and <device> are usually 0.\n");
if (options & OPTION_DEBUG_PROBE_ONLY) { if (options & OPTION_DEBUG_PROBE_ONLY) {
...@@ -726,9 +715,50 @@ static int normal_init (Scsi_Host_Template *tpnt, int board, int chip, ...@@ -726,9 +715,50 @@ static int normal_init (Scsi_Host_Template *tpnt, int board, int chip,
return -1; return -1;
} }
size = sizeof(struct NCR53c7x0_hostdata) + script_len; max_cmd_size = sizeof(struct NCR53c7x0_cmd) + dsa_len +
/* Size of dynamic part of command structure : */
2 * /* Worst case : we don't know if we need DATA IN or DATA out */
( 2 * /* Current instructions per scatter/gather segment */
tpnt->sg_tablesize +
3 /* Current startup / termination required per phase */
) *
8 /* Each instruction is eight bytes */;
/* Note that alignment will be guaranteed, since we put the command
allocated at probe time after the fixed-up SCSI script, which
consists of 32 bit words, aligned on a 32 bit boundary. */
/* Allocate fixed part of hostdata, dynamic part to hold appropriate
SCSI SCRIPT(tm) plus a single, maximum-sized NCR53c7x0_cmd structure.
We need a NCR53c7x0_cmd structure for scan_scsis() when we are
not loaded as a module, and when we're loaded as a module, we
can't use a non-dynamically allocated structure because modules
are vmalloc()'d, which can allow structures to cross page
boundaries and breaks our physical/virtual address assumptions
for DMA.
So, we stick it past the end of our hostdata structure.
ASSUMPTION :
Irregardless of how many simultaenous SCSI commands we allow,
the probe code only executes a _single_ instruction at a time,
so we only need one here, and don't need to allocate NCR53c7x0_cmd
structures for each target until we are no longer in scan_scsis
and kmalloc() has become functional (memory_init() happens
after all device driver initialization).
*/
size = sizeof(struct NCR53c7x0_hostdata) + script_len + max_cmd_size;
instance = scsi_register (tpnt, size); instance = scsi_register (tpnt, size);
if (!instance)
return -1;
/* FIXME : if we ever support an ISA NCR53c7xx based board, we
need to check if the chip is running in a 16 bit mode, and if so
unregister it if it is past the 16M (0x1000000) mark */
hostdata = (struct NCR53c7x0_hostdata *) hostdata = (struct NCR53c7x0_hostdata *)
instance->hostdata; instance->hostdata;
hostdata->size = size; hostdata->size = size;
...@@ -784,7 +814,18 @@ static int normal_init (Scsi_Host_Template *tpnt, int board, int chip, ...@@ -784,7 +814,18 @@ static int normal_init (Scsi_Host_Template *tpnt, int board, int chip,
instance->dma_channel = dma; instance->dma_channel = dma;
hostdata->options = options; hostdata->options = options;
hostdata->dsa_size = dsa_len;
hostdata->max_cmd_size = max_cmd_size;
hostdata->num_cmds = 1;
/* Initialize single command */
hostdata->free = (struct NCR53c7x0_cmd *)
(hostdata->script + hostdata->script_count);
hostdata->free->real = (void *) hostdata->free;
hostdata->free->size = max_cmd_size;
hostdata->free->free = NULL;
hostdata->free->next = NULL;
return NCR53c7x0_init(instance); return NCR53c7x0_init(instance);
} }
...@@ -796,7 +837,7 @@ static int normal_init (Scsi_Host_Template *tpnt, int board, int chip, ...@@ -796,7 +837,7 @@ static int normal_init (Scsi_Host_Template *tpnt, int board, int chip,
* Purpose : initializes a NCR53c800 family based on the PCI * Purpose : initializes a NCR53c800 family based on the PCI
* bus, device, and function location of it. Allows * bus, device, and function location of it. Allows
* reprogramming of latency timer and determining addresses * reprogramming of latency timer and determining addresses
* and weather bus mastering, etc. are OK. * and whether bus mastering, etc. are OK.
* *
* Useful where a new NCR chip is backwards compatible with * Useful where a new NCR chip is backwards compatible with
* a supported chip, but the DEVICE ID has changed so it * a supported chip, but the DEVICE ID has changed so it
...@@ -815,7 +856,8 @@ static int pci_init (Scsi_Host_Template *tpnt, int board, int chip, ...@@ -815,7 +856,8 @@ static int pci_init (Scsi_Host_Template *tpnt, int board, int chip,
unsigned short vendor_id, device_id, command; unsigned short vendor_id, device_id, command;
unsigned long base, io_port; unsigned long base, io_port;
unsigned char irq, revision; unsigned char irq, revision;
int error, expected_chip, expected_id, max_revision, min_revision; int error, expected_chip;
int expected_id = -1, max_revision = -1, min_revision = -1;
int i; int i;
printk("scsi-ncr53c7,8xx : at PCI bus %d, device %d, function %d\n", printk("scsi-ncr53c7,8xx : at PCI bus %d, device %d, function %d\n",
...@@ -870,6 +912,8 @@ static int pci_init (Scsi_Host_Template *tpnt, int board, int chip, ...@@ -870,6 +912,8 @@ static int pci_init (Scsi_Host_Template *tpnt, int board, int chip,
io_port = 0; io_port = 0;
} else } else
io_port &= PCI_BASE_ADDRESS_IO_MASK; io_port &= PCI_BASE_ADDRESS_IO_MASK;
} else {
io_port = 0;
} }
if (command & PCI_COMMAND_MEMORY) { if (command & PCI_COMMAND_MEMORY) {
...@@ -879,6 +923,8 @@ static int pci_init (Scsi_Host_Template *tpnt, int board, int chip, ...@@ -879,6 +923,8 @@ static int pci_init (Scsi_Host_Template *tpnt, int board, int chip,
base = 0; base = 0;
} else } else
base &= PCI_BASE_ADDRESS_MEM_MASK; base &= PCI_BASE_ADDRESS_MEM_MASK;
} else {
base = 0;
} }
if (!io_port && !base) { if (!io_port && !base) {
...@@ -932,7 +978,6 @@ static int pci_init (Scsi_Host_Template *tpnt, int board, int chip, ...@@ -932,7 +978,6 @@ static int pci_init (Scsi_Host_Template *tpnt, int board, int chip,
*/ */
int NCR53c7xx_detect(Scsi_Host_Template *tpnt) { int NCR53c7xx_detect(Scsi_Host_Template *tpnt) {
short current_chip;
int i; int i;
int current_override; int current_override;
int count; /* Number of boards detected */ int count; /* Number of boards detected */
...@@ -979,6 +1024,7 @@ int NCR53c7xx_detect(Scsi_Host_Template *tpnt) { ...@@ -979,6 +1024,7 @@ int NCR53c7xx_detect(Scsi_Host_Template *tpnt) {
#include "53c8xx_d.h" #include "53c8xx_d.h"
static int NCR53c8xx_script_len = sizeof (SCRIPT); static int NCR53c8xx_script_len = sizeof (SCRIPT);
static int NCR53c8xx_dsa_len = A_dsa_end + Ent_dsa_zero - Ent_dsa_code_template;
/* /*
* Function : static void NCR53c8x0_init_fixup (struct Scsi_Host *host) * Function : static void NCR53c8x0_init_fixup (struct Scsi_Host *host)
...@@ -989,7 +1035,8 @@ static int NCR53c8xx_script_len = sizeof (SCRIPT); ...@@ -989,7 +1035,8 @@ static int NCR53c8xx_script_len = sizeof (SCRIPT);
* *
*/ */
static void NCR53c8x0_init_fixup (struct Scsi_Host *host) { static void
NCR53c8x0_init_fixup (struct Scsi_Host *host) {
NCR53c7x0_local_declare(); NCR53c7x0_local_declare();
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
host->hostdata; host->hostdata;
...@@ -1008,6 +1055,16 @@ static void NCR53c8x0_init_fixup (struct Scsi_Host *host) { ...@@ -1008,6 +1055,16 @@ static void NCR53c8x0_init_fixup (struct Scsi_Host *host) {
for (i = 0; i < PATCHES; ++i) for (i = 0; i < PATCHES; ++i)
hostdata->script[LABELPATCHES[i]] += hostdata->script[LABELPATCHES[i]] +=
(unsigned long) hostdata->script; (unsigned long) hostdata->script;
/* Fixup addresses of constants that used to be EXTERNAL */
patch_abs_32 (hostdata->script, 0, NCR53c7xx_msg_abort,
(long) &(hostdata->NCR53c7xx_msg_abort));
patch_abs_32 (hostdata->script, 0, NCR53c7xx_msg_reject,
(long) &(hostdata->NCR53c7xx_msg_reject));
patch_abs_32 (hostdata->script, 0, NCR53c7xx_zero,
(long) &(hostdata->NCR53c7xx_zero));
patch_abs_32 (hostdata->script, 0, NCR53c7xx_sink,
(long) &(hostdata->NCR53c7xx_sink));
/* /*
* Fixup absolutes set at boot-time. * Fixup absolutes set at boot-time.
...@@ -1037,10 +1094,6 @@ static void NCR53c8x0_init_fixup (struct Scsi_Host *host) { ...@@ -1037,10 +1094,6 @@ static void NCR53c8x0_init_fixup (struct Scsi_Host *host) {
ncr_to_ncr = memory_to_ncr = ncr_to_memory = tmp; ncr_to_ncr = memory_to_ncr = ncr_to_memory = tmp;
} }
printk ("scsi%d : m_to_n = 0x%x, n_to_m = 0x%x, n_to_n = 0x%x\n",
(int) host->host_no, (int) memory_to_ncr, (int)
ncr_to_memory, ncr_to_ncr);
patch_abs_32 (hostdata->script, 0, addr_scratch, base + SCRATCHA_REG_800); patch_abs_32 (hostdata->script, 0, addr_scratch, base + SCRATCHA_REG_800);
patch_abs_32 (hostdata->script, 0, addr_sfbr, base + SFBR_REG); patch_abs_32 (hostdata->script, 0, addr_sfbr, base + SFBR_REG);
patch_abs_32 (hostdata->script, 0, addr_temp, base + TEMP_REG); patch_abs_32 (hostdata->script, 0, addr_temp, base + TEMP_REG);
...@@ -1059,11 +1112,15 @@ static void NCR53c8x0_init_fixup (struct Scsi_Host *host) { ...@@ -1059,11 +1112,15 @@ static void NCR53c8x0_init_fixup (struct Scsi_Host *host) {
patch_abs_rwri_data (hostdata->script, 0, dmode_ncr_to_memory, ncr_to_memory); patch_abs_rwri_data (hostdata->script, 0, dmode_ncr_to_memory, ncr_to_memory);
patch_abs_rwri_data (hostdata->script, 0, dmode_ncr_to_ncr, ncr_to_ncr); patch_abs_rwri_data (hostdata->script, 0, dmode_ncr_to_ncr, ncr_to_ncr);
patch_abs_32 (hostdata->script, 0, issue_dsa_head, (long) &(hostdata->issue_dsa_head)); patch_abs_32 (hostdata->script, 0, issue_dsa_head,
(long) &(hostdata->issue_dsa_head));
patch_abs_32 (hostdata->script, 0, msg_buf, (long) &(hostdata->msg_buf)); patch_abs_32 (hostdata->script, 0, msg_buf, (long) &(hostdata->msg_buf));
patch_abs_32 (hostdata->script, 0, reconnect_dsa_head, (long) &(hostdata->reconnect_dsa_head)); patch_abs_32 (hostdata->script, 0, reconnect_dsa_head,
patch_abs_32 (hostdata->script, 0, reselected_identify, (long) &(hostdata->reselected_identify)); (long) &(hostdata->reconnect_dsa_head));
patch_abs_32 (hostdata->script, 0, reselected_tag, (long) &(hostdata->reselected_tag)); patch_abs_32 (hostdata->script, 0, reselected_identify,
(long) &(hostdata->reselected_identify));
patch_abs_32 (hostdata->script, 0, reselected_tag,
(long) &(hostdata->reselected_tag));
patch_abs_32 (hostdata->script, 0, test_dest, (long) &(hostdata->test_dest)); patch_abs_32 (hostdata->script, 0, test_dest, (long) &(hostdata->test_dest));
patch_abs_32 (hostdata->script, 0, test_src, (long) &(hostdata->test_source)); patch_abs_32 (hostdata->script, 0, test_src, (long) &(hostdata->test_source));
...@@ -1145,17 +1202,18 @@ static int NCR53c8xx_run_tests (struct Scsi_Host *host) { ...@@ -1145,17 +1202,18 @@ static int NCR53c8xx_run_tests (struct Scsi_Host *host) {
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
host->hostdata; host->hostdata;
unsigned long timeout, start; unsigned long timeout, start;
int old_level, failed, i; int failed, i;
unsigned long flags;
NCR53c7x0_local_setup(host); NCR53c7x0_local_setup(host);
printk("scsi%d : testing\n", host->host_no);
/* The NCR chip _must_ be idle to run the test scripts */ /* The NCR chip _must_ be idle to run the test scripts */
old_level = splx(0); save_flags(flags);
cli();
if (!hostdata->idle) { if (!hostdata->idle) {
printk ("scsi%d : chip not idle, aborting tests\n", host->host_no); printk ("scsi%d : chip not idle, aborting tests\n", host->host_no);
splx(old_level); restore_flags(flags);
return -1; return -1;
} }
...@@ -1181,7 +1239,7 @@ static int NCR53c8xx_run_tests (struct Scsi_Host *host) { ...@@ -1181,7 +1239,7 @@ static int NCR53c8xx_run_tests (struct Scsi_Host *host) {
printk ("scsi%d : test 1", host->host_no); printk ("scsi%d : test 1", host->host_no);
NCR53c7x0_write32 (DSP_REG, start); NCR53c7x0_write32 (DSP_REG, start);
printk (" started\n"); printk (" started\n");
splx(7); sti();
timeout = jiffies + 50; /* arbitrary */ timeout = jiffies + 50; /* arbitrary */
while ((hostdata->test_completed == -1) && jiffies < timeout); while ((hostdata->test_completed == -1) && jiffies < timeout);
...@@ -1217,7 +1275,7 @@ static int NCR53c8xx_run_tests (struct Scsi_Host *host) { ...@@ -1217,7 +1275,7 @@ static int NCR53c8xx_run_tests (struct Scsi_Host *host) {
(unsigned long) hostdata->script, start); (unsigned long) hostdata->script, start);
printk ("scsi%d : DSPS = 0x%lx\n", host->host_no, printk ("scsi%d : DSPS = 0x%lx\n", host->host_no,
(unsigned long) NCR53c7x0_read32(DSPS_REG)); (unsigned long) NCR53c7x0_read32(DSPS_REG));
splx(old_level); restore_flags(flags);
return -1; return -1;
} }
hostdata->test_running = 0; hostdata->test_running = 0;
...@@ -1253,10 +1311,10 @@ static int NCR53c8xx_run_tests (struct Scsi_Host *host) { ...@@ -1253,10 +1311,10 @@ static int NCR53c8xx_run_tests (struct Scsi_Host *host) {
dsa[11] = (unsigned long) &msg; dsa[11] = (unsigned long) &msg;
for (i = 0; i < 3; ++i) { for (i = 0; i < 3; ++i) {
splx(0); cli();
if (!hostdata->idle) { if (!hostdata->idle) {
printk ("scsi%d : chip not idle, aborting tests\n", host->host_no); printk ("scsi%d : chip not idle, aborting tests\n", host->host_no);
splx(old_level); restore_flags(flags);
return -1; return -1;
} }
...@@ -1269,7 +1327,7 @@ static int NCR53c8xx_run_tests (struct Scsi_Host *host) { ...@@ -1269,7 +1327,7 @@ static int NCR53c8xx_run_tests (struct Scsi_Host *host) {
hostdata->state = STATE_RUNNING; hostdata->state = STATE_RUNNING;
NCR53c7x0_write32 (DSA_REG, (unsigned long) dsa); NCR53c7x0_write32 (DSA_REG, (unsigned long) dsa);
NCR53c7x0_write32 (DSP_REG, start); NCR53c7x0_write32 (DSP_REG, start);
splx(7); sti();
timeout = jiffies + 500; /* arbitrary */ timeout = jiffies + 500; /* arbitrary */
while ((hostdata->test_completed == -1) && jiffies < timeout); while ((hostdata->test_completed == -1) && jiffies < timeout);
...@@ -1289,12 +1347,12 @@ static int NCR53c8xx_run_tests (struct Scsi_Host *host) { ...@@ -1289,12 +1347,12 @@ static int NCR53c8xx_run_tests (struct Scsi_Host *host) {
host->host_no, i); host->host_no, i);
if (!hostdata->idle) { if (!hostdata->idle) {
printk("scsi%d : not idle\n", host->host_no); printk("scsi%d : not idle\n", host->host_no);
splx(old_level); restore_flags(flags);
return -1; return -1;
} }
} else if (hostdata->test_completed == -1) { } else if (hostdata->test_completed == -1) {
printk ("scsi%d : test 2 timed out\n", host->host_no); printk ("scsi%d : test 2 timed out\n", host->host_no);
splx(old_level); restore_flags(flags);
return -1; return -1;
} }
hostdata->test_running = 0; hostdata->test_running = 0;
...@@ -1305,9 +1363,8 @@ static int NCR53c8xx_run_tests (struct Scsi_Host *host) { ...@@ -1305,9 +1363,8 @@ static int NCR53c8xx_run_tests (struct Scsi_Host *host) {
} }
} }
} }
printk ("scsi%d : tests complete.\n", host->host_no);
splx(old_level); restore_flags(flags);
return 0; return 0;
} }
...@@ -1364,11 +1421,12 @@ static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int result) { ...@@ -1364,11 +1421,12 @@ static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int result) {
struct Scsi_Host *host = c->host; struct Scsi_Host *host = c->host;
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
host->hostdata; host->hostdata;
int old_level; unsigned long flags;
char **prev, *search; char **prev, *search;
int i; int i;
old_level = splx(0); save_flags(flags);
cli();
for (i = 0; i < 2; ++i) { for (i = 0; i < 2; ++i) {
for (search = (char *) (i ? hostdata->issue_dsa_head : for (search = (char *) (i ? hostdata->issue_dsa_head :
hostdata->reconnect_dsa_head), prev = (char **) (i ? hostdata->reconnect_dsa_head), prev = (char **) (i ?
...@@ -1390,21 +1448,14 @@ static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int result) { ...@@ -1390,21 +1448,14 @@ static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int result) {
if (hostdata->running_list == cmd) if (hostdata->running_list == cmd)
hostdata->running_list = cmd->next; hostdata->running_list = cmd->next;
if (!scan_scsis_buf_busy) { cmd->next = hostdata->free;
#ifdef SCSI_MALLOC hostdata->free = cmd;
scsi_free ((void *) cmd->real, cmd->size);
#else
kfree_s (cmd->real, cmd->size);
#endif
} else {
scan_scsis_buf_busy = 0;
}
c->host_scribble = NULL; c->host_scribble = NULL;
c->result = result; c->result = result;
c->scsi_done(c); c->scsi_done(c);
splx(old_level); restore_flags(flags);
} }
/* /*
...@@ -1429,7 +1480,7 @@ static void intr_break (struct Scsi_Host *host, struct ...@@ -1429,7 +1480,7 @@ static void intr_break (struct Scsi_Host *host, struct
unsigned long *dsp; unsigned long *dsp;
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
host->hostdata; host->hostdata;
int old_level; unsigned long flags;
NCR53c7x0_local_setup(host); NCR53c7x0_local_setup(host);
/* /*
...@@ -1437,8 +1488,8 @@ static void intr_break (struct Scsi_Host *host, struct ...@@ -1437,8 +1488,8 @@ static void intr_break (struct Scsi_Host *host, struct
* dump the appropriate debugging information to standard * dump the appropriate debugging information to standard
* output. * output.
*/ */
save_flags(flags);
old_level = splx(0); cli();
dsp = (unsigned long *) NCR53c7x0_read32(DSP_REG); dsp = (unsigned long *) NCR53c7x0_read32(DSP_REG);
for (bp = hostdata->breakpoints; bp && bp->address != dsp; for (bp = hostdata->breakpoints; bp && bp->address != dsp;
bp = bp->next); bp = bp->next);
...@@ -1460,7 +1511,7 @@ static void intr_break (struct Scsi_Host *host, struct ...@@ -1460,7 +1511,7 @@ static void intr_break (struct Scsi_Host *host, struct
* instruction in bytes. * instruction in bytes.
*/ */
splx(old_level); restore_flags(flags);
} }
/* /*
...@@ -1575,7 +1626,7 @@ static void synchronous (struct Scsi_Host *host, int target, char *msg) { ...@@ -1575,7 +1626,7 @@ static void synchronous (struct Scsi_Host *host, int target, char *msg) {
hostdata->sync[target].select_indirect = (scntl3 << 24) | (target << 16) | hostdata->sync[target].select_indirect = (scntl3 << 24) | (target << 16) |
(sxfer << 8); (sxfer << 8);
script = hostdata->sync[target].script; script = (long *) hostdata->sync[target].script;
/* XXX - add NCR53c7x0 code to reprogram SCF bits if we want to */ /* XXX - add NCR53c7x0 code to reprogram SCF bits if we want to */
if ((hostdata->chip / 100) == 8) { if ((hostdata->chip / 100) == 8) {
...@@ -1630,7 +1681,7 @@ static int NCR53c8x0_dstat_sir_intr (struct Scsi_Host *host, struct ...@@ -1630,7 +1681,7 @@ static int NCR53c8x0_dstat_sir_intr (struct Scsi_Host *host, struct
printk ("scsi%d : message", host->host_no); printk ("scsi%d : message", host->host_no);
if (cmd) if (cmd)
printk (" from target %d lun %d", c->target, c->lun); printk (" from target %d lun %d", c->target, c->lun);
print_msg (hostdata->msg_buf); print_msg ((unsigned char *) hostdata->msg_buf);
printk("\n"); printk("\n");
switch (hostdata->msg_buf[0]) { switch (hostdata->msg_buf[0]) {
/* /*
...@@ -1665,7 +1716,8 @@ static int NCR53c8x0_dstat_sir_intr (struct Scsi_Host *host, struct ...@@ -1665,7 +1716,8 @@ static int NCR53c8x0_dstat_sir_intr (struct Scsi_Host *host, struct
*/ */
if (cmd->flags & CMD_FLAG_SDTR) { if (cmd->flags & CMD_FLAG_SDTR) {
cmd->flags &= ~CMD_FLAG_SDTR; cmd->flags &= ~CMD_FLAG_SDTR;
synchronous (host, c->target, hostdata->msg_buf); synchronous (host, c->target, (unsigned char *)
hostdata->msg_buf);
hostdata->dsp = hostdata->script + hostdata->E_accept_message / hostdata->dsp = hostdata->script + hostdata->E_accept_message /
sizeof(long); sizeof(long);
hostdata->dsp_changed = 1; hostdata->dsp_changed = 1;
...@@ -1673,7 +1725,8 @@ static int NCR53c8x0_dstat_sir_intr (struct Scsi_Host *host, struct ...@@ -1673,7 +1725,8 @@ static int NCR53c8x0_dstat_sir_intr (struct Scsi_Host *host, struct
} else { } else {
if (hostdata->options & OPTION_SYNCHRONOUS) { if (hostdata->options & OPTION_SYNCHRONOUS) {
cmd->flags |= CMD_FLAG_DID_SDTR; cmd->flags |= CMD_FLAG_DID_SDTR;
synchronous (host, c->target, hostdata->msg_buf); synchronous (host, c->target, (unsigned char *)
hostdata->msg_buf);
} else { } else {
hostdata->msg_buf[4] = 0; /* 0 offset = async */ hostdata->msg_buf[4] = 0; /* 0 offset = async */
} }
...@@ -1948,15 +2001,16 @@ static int debugger_fn_bc (struct Scsi_Host *host, struct debugger_token *token, ...@@ -1948,15 +2001,16 @@ static int debugger_fn_bc (struct Scsi_Host *host, struct debugger_token *token,
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
instance->hostdata; instance->hostdata;
struct NCR53c7x0_break *bp, **prev; struct NCR53c7x0_break *bp, **prev;
int old_level; unsigned long flags;
old_level = splx(0); save_flags(flags);
cli();
for (bp = (struct NCR53c7x0_break *) instance->breakpoints, for (bp = (struct NCR53c7x0_break *) instance->breakpoints,
prev = (struct NCR53c7x0_break **) &instance->breakpoints; prev = (struct NCR53c7x0_break **) &instance->breakpoints;
bp; prev = (struct NCR53c7x0_break **) &(bp->next), bp; prev = (struct NCR53c7x0_break **) &(bp->next),
bp = (struct NCR53c7x0_break *) bp->next); bp = (struct NCR53c7x0_break *) bp->next);
if (!bp) { if (!bp) {
splx(old_level); restore_flags(flags);
return -EIO; return -EIO;
} }
...@@ -1969,7 +2023,7 @@ static int debugger_fn_bc (struct Scsi_Host *host, struct debugger_token *token, ...@@ -1969,7 +2023,7 @@ static int debugger_fn_bc (struct Scsi_Host *host, struct debugger_token *token,
if (prev) if (prev)
*prev = bp->next; *prev = bp->next;
splx(old_level); restore_flags(flags);
return 0; return 0;
} }
...@@ -1981,7 +2035,7 @@ static int debugger_fn_bl (struct Scsi_Host *host, struct debugger_token *token, ...@@ -1981,7 +2035,7 @@ static int debugger_fn_bl (struct Scsi_Host *host, struct debugger_token *token,
struct NCR53c7x0_break *bp; struct NCR53c7x0_break *bp;
char buf[80]; char buf[80];
size_t len; size_t len;
int old_level; unsigned long flags;
/* /*
* XXX - we need to insure that the processor is halted * XXX - we need to insure that the processor is halted
* here in order to prevent a race condition. So, if the * here in order to prevent a race condition. So, if the
...@@ -1992,7 +2046,8 @@ static int debugger_fn_bl (struct Scsi_Host *host, struct debugger_token *token, ...@@ -1992,7 +2046,8 @@ static int debugger_fn_bl (struct Scsi_Host *host, struct debugger_token *token,
host->host_no); host->host_no);
debugger_kernel_write (host, buf, strlen(buf)); debugger_kernel_write (host, buf, strlen(buf));
old_level=splx(0); save_flags(flags);
cli();
for (bp = (struct NCR53c7x0_break *) host->breakpoints; for (bp = (struct NCR53c7x0_break *) host->breakpoints;
bp; bp = (struct NCR53c7x0_break *) bp->next); { bp; bp = (struct NCR53c7x0_break *) bp->next); {
sprintf (buf, "scsi%d : bp : success : at %08x, replaces %08x %08x", sprintf (buf, "scsi%d : bp : success : at %08x, replaces %08x %08x",
...@@ -2007,7 +2062,7 @@ static int debugger_fn_bl (struct Scsi_Host *host, struct debugger_token *token, ...@@ -2007,7 +2062,7 @@ static int debugger_fn_bl (struct Scsi_Host *host, struct debugger_token *token,
len = strlen(buf); len = strlen(buf);
debugger_kernel_write (host, buf, len); debugger_kernel_write (host, buf, len);
} }
splx(old_level); restore_flags(flags);
return 0; return 0;
} }
...@@ -2018,20 +2073,21 @@ static int debugger_fn_bs (struct Scsi_Host *host, struct debugger_token *token, ...@@ -2018,20 +2073,21 @@ static int debugger_fn_bs (struct Scsi_Host *host, struct debugger_token *token,
struct NCR53c7x0_break *bp; struct NCR53c7x0_break *bp;
char buf[80]; char buf[80];
size_t len; size_t len;
int old_level; unsigned long flags;
old_level=splx(0); save_flags(flags);
cli();
if (hostdata->state != STATE_HALTED) { if (hostdata->state != STATE_HALTED) {
sprintf (buf, "scsi%d : bs : failure : NCR not halted\n", host->host_no); sprintf (buf, "scsi%d : bs : failure : NCR not halted\n", host->host_no);
debugger_kernel_write (host, buf, strlen(buf)); debugger_kernel_write (host, buf, strlen(buf));
splx(old_level); restore_flags(flags);
return -1; return -1;
} }
if (!(bp = kmalloc (sizeof (struct NCR53c7x0_break)))) { if (!(bp = kmalloc (sizeof (struct NCR53c7x0_break)))) {
printk ("scsi%d : kmalloc(%d) of breakpoint structure failed, try again\n", printk ("scsi%d : kmalloc(%d) of breakpoint structure failed, try again\n",
host->host_no, sizeof(struct NCR53c7x0_break)); host->host_no, sizeof(struct NCR53c7x0_break));
splx(old_level); restore_flags(flags);
return -1; return -1;
} }
...@@ -2043,7 +2099,7 @@ static int debugger_fn_bs (struct Scsi_Host *host, struct debugger_token *token, ...@@ -2043,7 +2099,7 @@ static int debugger_fn_bs (struct Scsi_Host *host, struct debugger_token *token,
hostdata->breakpoints = bp->next; hostdata->breakpoints = bp->next;
memcpy ((void *) bp->address, (void *) hostdata->E_debug_break, 8); memcpy ((void *) bp->address, (void *) hostdata->E_debug_break, 8);
splx(old_level); restore_flags(flags);
return 0; return 0;
} }
...@@ -2132,9 +2188,10 @@ static debugger_kernel_write (struct Scsi_Host *host, char *buf, size_t ...@@ -2132,9 +2188,10 @@ static debugger_kernel_write (struct Scsi_Host *host, char *buf, size_t
buflen) { buflen) {
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
host->hostdata; host->hostdata;
int copy, left, old_level; int copy, left;
unsigned long flags;
old_level = splx(0); save_flags(flags);
cli();
while (buflen) { while (buflen) {
left = (hostdata->debug_buf + hostdata->debug_size - 1) - left = (hostdata->debug_buf + hostdata->debug_size - 1) -
hostdata->debug_write; hostdata->debug_write;
...@@ -2147,7 +2204,7 @@ static debugger_kernel_write (struct Scsi_Host *host, char *buf, size_t ...@@ -2147,7 +2204,7 @@ static debugger_kernel_write (struct Scsi_Host *host, char *buf, size_t
(hostdata->debug_buf + hostdata->debug_size)) (hostdata->debug_buf + hostdata->debug_size))
hosdata->debug_write = hostdata->debug_buf; hosdata->debug_write = hostdata->debug_buf;
} }
(void) splx(old_level); restore_flags(flags);
} }
#endif /* def NCRDEBUG */ #endif /* def NCRDEBUG */
...@@ -2164,7 +2221,8 @@ static debugger_kernel_write (struct Scsi_Host *host, char *buf, size_t ...@@ -2164,7 +2221,8 @@ static debugger_kernel_write (struct Scsi_Host *host, char *buf, size_t
* *
*/ */
static void NCR53c8x0_soft_reset (struct Scsi_Host *host) { static void
NCR53c8x0_soft_reset (struct Scsi_Host *host) {
NCR53c7x0_local_declare(); NCR53c7x0_local_declare();
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
host->hostdata; host->hostdata;
...@@ -2187,14 +2245,18 @@ static void NCR53c8x0_soft_reset (struct Scsi_Host *host) { ...@@ -2187,14 +2245,18 @@ static void NCR53c8x0_soft_reset (struct Scsi_Host *host) {
/* /*
* Respond to selection and reselection by targets and * Respond to reselection by targets and use our _initiator_ SCSI ID
* use our _initiator_ SCSI ID for arbitration. * for arbitration. If notyet, also respond to SCSI selection.
* *
* XXX - Note : we must reprogram this when reselecting as * XXX - Note : we must reprogram this when reselecting as
* a target. * a target.
*/ */
#ifdef notyet
NCR53c7x0_write8(SCID_REG, (host->this_id & 7)|SCID_800_RRE|SCID_800_SRE); NCR53c7x0_write8(SCID_REG, (host->this_id & 7)|SCID_800_RRE|SCID_800_SRE);
#else
NCR53c7x0_write8(SCID_REG, (host->this_id & 7)|SCID_800_RRE);
#endif
NCR53c7x0_write8(RESPID_REG_800, hostdata->this_id_mask); NCR53c7x0_write8(RESPID_REG_800, hostdata->this_id_mask);
/* /*
...@@ -2222,8 +2284,7 @@ static void NCR53c8x0_soft_reset (struct Scsi_Host *host) { ...@@ -2222,8 +2284,7 @@ static void NCR53c8x0_soft_reset (struct Scsi_Host *host) {
NCR53c7x0_write8(SIEN0_REG_800, ((hostdata->options & OPTION_PARITY) ? NCR53c7x0_write8(SIEN0_REG_800, ((hostdata->options & OPTION_PARITY) ?
SIEN_PAR : 0) | SIEN_RST | SIEN_UDC | SIEN_SGE | SIEN_800_SEL | SIEN_PAR : 0) | SIEN_RST | SIEN_UDC | SIEN_SGE | SIEN_MA);
SIEN_800_RESEL | SIEN_MA);
NCR53c7x0_write8(SIEN1_REG_800, SIEN1_800_STO | SIEN1_800_HTH); NCR53c7x0_write8(SIEN1_REG_800, SIEN1_800_STO | SIEN1_800_HTH);
/* /*
...@@ -2243,11 +2304,13 @@ static void NCR53c8x0_soft_reset (struct Scsi_Host *host) { ...@@ -2243,11 +2304,13 @@ static void NCR53c8x0_soft_reset (struct Scsi_Host *host) {
/* /*
* Function static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) * Function static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd)
* *
* Purpose : Using scsi_malloc() if the system is initialized, * Purpose : If we have not allready allocated enough NCR53c7x0_cmd
* scan_scsis_buf if not, allocate space to store the variable * structures to satisfy any allowable number of simultaenous
* length NCR53c7x0_cmd structure. Initialize it based on * commands for this host; do so (using either scsi_malloc()
* the Scsi_Cmnd structure passed in, including dsa and * or kmalloc() depending on configuration), and add them to the
* Linux field initialization, and dsa code relocation. * hostdata free list. Take the first structure off the free list,
* initialize it based on the Scsi_Cmnd structure passed in,
* including dsa and Linux field initialization, and dsa code relocation.
* *
* Inputs : cmd - SCSI command * Inputs : cmd - SCSI command
* *
...@@ -2255,26 +2318,86 @@ static void NCR53c8x0_soft_reset (struct Scsi_Host *host) { ...@@ -2255,26 +2318,86 @@ static void NCR53c8x0_soft_reset (struct Scsi_Host *host) {
* NULL on failure. * NULL on failure.
*/ */
static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) { static struct NCR53c7x0_cmd *
create_cmd (Scsi_Cmnd *cmd) {
NCR53c7x0_local_declare(); NCR53c7x0_local_declare();
struct Scsi_Host *host = cmd->host; struct Scsi_Host *host = cmd->host;
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
host->hostdata; host->hostdata;
int size; /* Size of *tmp */ struct NCR53c7x0_cmd *tmp = NULL; /* NCR53c7x0_cmd structure for this command */
struct NCR53c7x0_cmd *tmp; /* NCR53c7x0_cmd structure for this command */
int datain, /* Number of instructions per phase */ int datain, /* Number of instructions per phase */
dataout; dataout;
int data_transfer_instructions, /* Count of dynamic instructions */ int data_transfer_instructions, /* Count of dynamic instructions */
i, /* Counter */ i; /* Counter */
alignment; /* Alignment adjustment (0 - 4) */
unsigned long *cmd_datain, /* Address of datain/dataout code */ unsigned long *cmd_datain, /* Address of datain/dataout code */
*cmd_dataout; /* Incremented as we assemble */ *cmd_dataout; /* Incremented as we assemble */
#ifdef notyet
void *real; /* Real address */ void *real; /* Real address */
int size; /* Size of *tmp */
int alignment; /* Alignment adjustment (0 - 4) */
#endif
unsigned long flags;
NCR53c7x0_local_setup(cmd->host); NCR53c7x0_local_setup(cmd->host);
/* FIXME : when we start doing multiple simultaenous commands per LUN,
we will need to either
- Do an attach_slave() and detach_slave() the right way (alocate
memory in attach_slave() as we do in scsi_register).
- Make sure this code works
with the former being cleaner. At the same time, we can also go with
a per-device host_scribble, and introduce a NCR53c7x0_device structure
to replace the messy fixed length arrays we're starting to use. */
#ifdef notyet
if (hostdata->num_commands < host->can_queue &&
!in_scan_scsis &&
!(hostdata->cmd_allocated[cmd->target] & (1 << cmd->lun))) {
for (i = host->hostt->cmd_per_lun - 1; i >= 0 --i) {
#ifdef SCSI_MALLOC
/* scsi_malloc must allocate with a 512 byte granularity, but allways
returns buffers which are aligned on a 512 boundary */
size = (hostdata->max_cmd_size + 511) / 512 * 512;
tmp = (struct NCR53c7x0_cmd *) scsi_malloc (size);
if (!tmp)
break;
tmp->real = (void *) tmp;
#else
/* kmalloc() can allocate any size, but historically has returned
unaligned addresses, so we need to allow for alignment */
size = hostdata->max_cmd_size + 4;
real = kmalloc (size, GFP_ATOMIC);
alignment = 4 - (((unsigned) real) & 3);
tmp = (struct NCR53c7x0_cmd *) (((char *) real) + alignment);
if (!tmp)
break;
tmp->real = real;
#endif /* def SCSI_MALLOC */
tmp->size = size;
/* Insert all but last into list */
if (i > 0) {
tmp->next = hostdata->free;
hostdata->free = tmp;
}
}
}
#endif /* def notyet */
if (!tmp) {
save_flags(flags);
cli();
tmp = (struct NCR53c7x0_cmd *) hostdata->free;
if (tmp) {
hostdata->free = tmp->next;
restore_flags(flags);
} else {
restore_flags(flags);
return NULL;
}
}
/* /*
* Decide weather we need to generate commands for DATA IN, * Decide whether we need to generate commands for DATA IN,
* DATA OUT, neither, or both based on the SCSI command * DATA OUT, neither, or both based on the SCSI command
*/ */
...@@ -2323,10 +2446,6 @@ static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) { ...@@ -2323,10 +2446,6 @@ static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) {
datain = dataout = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3; datain = dataout = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3;
} }
/*
* Allocate memory for the NCR53c7x0_cmd structure.
*/
/* /*
* For each data phase implemented, we need a JUMP instruction * For each data phase implemented, we need a JUMP instruction
* to return control to other_transfer. We also need a MOVE * to return control to other_transfer. We also need a MOVE
...@@ -2344,63 +2463,11 @@ static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) { ...@@ -2344,63 +2463,11 @@ static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) {
if (data_transfer_instructions < 2) if (data_transfer_instructions < 2)
data_transfer_instructions = 2; data_transfer_instructions = 2;
/*
* We need enough space to store the base NCR53c7x0 structure,
* DSA, and data transfer instructions at 2 long words each,
* as well as padding out to the next 512 bytes for scsi_malloc.
*
* We also need to guarantee alignment of _4_ bytes.
*/
#ifdef SCSI_MALLOC
size = ((sizeof (struct NCR53c7x0_cmd) + (hostdata->dsa_end -
hostdata->dsa_start) + 2 * sizeof(long) *
data_transfer_instructions + 4 + 511) / 512) * 512;
#else
size = sizeof (struct NCR53c7x0_cmd) + (hostdata->dsa_end -
hostdata->dsa_start) + 2 * sizeof(long) *
data_transfer_instructions + 4;
#endif
#if 0
if (size > 512) {
printk("scsi%d : size = %d\n", host->host_no, size);
}
#endif
#ifdef SCSI_MALLOC
real = in_scan_scsis ? NULL : scsi_malloc (size);
#else
real = kmalloc (size, GFP_ATOMIC);
#endif
if (!real) {
if (!scan_scsis_buf_busy && size <= sizeof(scan_scsis_buf)) {
scan_scsis_buf_busy = 1;
real = scan_scsis_buf;
} else {
panic ("scsi%d : scan_scsis_buf too small (need %d bytes)\n",
host->host_no, size);
}
}
alignment = 4 - (((unsigned) real) & 3);
tmp = (struct NCR53c7x0_cmd *) (((char *) real) + alignment);
tmp->real = real;
if (((unsigned long) tmp->dsa) & 0x3)
panic ("scsi%d : pid %d dsa structure not dword aligned!\n",
host->host_no, cmd->pid);
/* /*
* Initialize Linux specific fields. * Initialize Linux specific fields.
*/ */
tmp->size = size;
tmp->cmd = cmd; tmp->cmd = cmd;
tmp->next = NULL; tmp->next = NULL;
tmp->prev = NULL; tmp->prev = NULL;
...@@ -2434,7 +2501,7 @@ static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) { ...@@ -2434,7 +2501,7 @@ static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) {
patch_dsa_32(tmp->dsa, dsa_select, 0, hostdata->sync[cmd->target]. patch_dsa_32(tmp->dsa, dsa_select, 0, hostdata->sync[cmd->target].
select_indirect); select_indirect);
/* /*
* XXX - we need to figure this size based on weather * XXX - we need to figure this size based on whether
* or not we'll be using any additional messages. * or not we'll be using any additional messages.
*/ */
patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1); patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1);
...@@ -2462,7 +2529,7 @@ static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) { ...@@ -2462,7 +2529,7 @@ static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) {
patch_dsa_32(tmp->dsa, dsa_status, 1, &cmd->result); patch_dsa_32(tmp->dsa, dsa_status, 1, &cmd->result);
patch_dsa_32(tmp->dsa, dsa_msgout_other, 0, 1); patch_dsa_32(tmp->dsa, dsa_msgout_other, 0, 1);
patch_dsa_32(tmp->dsa, dsa_msgout_other, 1, patch_dsa_32(tmp->dsa, dsa_msgout_other, 1,
&NCR53c7xx_msg_nop); &(hostdata->NCR53c7xx_msg_nop));
/* /*
...@@ -2486,8 +2553,8 @@ static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) { ...@@ -2486,8 +2553,8 @@ static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) {
#endif #endif
/* /*
* XXX - I'm undecided weather all of this nonsense is faster * XXX - I'm undecided whether all of this nonsense is faster
* in the long run, or weather I should just go and implement a loop * in the long run, or whether I should just go and implement a loop
* on the NCR chip using table indirect mode? * on the NCR chip using table indirect mode?
* *
* In any case, this is how it _must_ be done for 53c700/700-66 chips, * In any case, this is how it _must_ be done for 53c700/700-66 chips,
...@@ -2516,8 +2583,8 @@ static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) { ...@@ -2516,8 +2583,8 @@ static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) {
cmd_datain[2] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL | cmd_datain[2] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL |
DCMD_TCI_CD | DCMD_TCI_IO | DCMD_TCI_MSG) << 24) | DCMD_TCI_CD | DCMD_TCI_IO | DCMD_TCI_MSG) << 24) |
DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE | DBC_TCI_TRUE; DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE | DBC_TCI_TRUE;
cmd_datain[3] = hostdata->script + hostdata->E_msg_in / cmd_datain[3] = (unsigned long) hostdata->script +
sizeof(long); hostdata->E_msg_in;
#if 0 #if 0
print_insn (host, cmd_datain, "dynamic ", 1); print_insn (host, cmd_datain, "dynamic ", 1);
print_insn (host, cmd_datain + 2, "dynamic ", 1); print_insn (host, cmd_datain + 2, "dynamic ", 1);
...@@ -2530,8 +2597,8 @@ static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) { ...@@ -2530,8 +2597,8 @@ static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) {
cmd_dataout[2] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL | cmd_dataout[2] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL |
DCMD_TCI_CD | DCMD_TCI_IO | DCMD_TCI_MSG) << 24) | DCMD_TCI_CD | DCMD_TCI_IO | DCMD_TCI_MSG) << 24) |
DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE | DBC_TCI_TRUE; DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE | DBC_TCI_TRUE;
cmd_dataout[3] = hostdata->script + hostdata->E_msg_in / cmd_dataout[3] = (unsigned long) hostdata->script +
sizeof(long); hostdata->E_msg_in;
#if 0 #if 0
print_insn (host, cmd_dataout, "dynamic ", 1); print_insn (host, cmd_dataout, "dynamic ", 1);
print_insn (host, cmd_dataout + 2, "dynamic ", 1); print_insn (host, cmd_dataout + 2, "dynamic ", 1);
...@@ -2548,8 +2615,8 @@ static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) { ...@@ -2548,8 +2615,8 @@ static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) {
if (datain) { if (datain) {
cmd_datain[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP) << 24) | cmd_datain[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP) << 24) |
DBC_TCI_TRUE; DBC_TCI_TRUE;
cmd_datain[1] = hostdata->script + hostdata->E_other_transfer cmd_datain[1] = (unsigned long) hostdata->script +
/ sizeof(long); hostdata->E_other_transfer;
#if 0 #if 0
print_insn (host, cmd_datain, "dynamic jump ", 1); print_insn (host, cmd_datain, "dynamic jump ", 1);
#endif #endif
...@@ -2567,8 +2634,8 @@ static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) { ...@@ -2567,8 +2634,8 @@ static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) {
if (dataout) { if (dataout) {
cmd_dataout[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP) << 24) | cmd_dataout[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP) << 24) |
DBC_TCI_TRUE; DBC_TCI_TRUE;
cmd_dataout[1] = hostdata->script + hostdata->E_other_transfer cmd_dataout[1] = (unsigned long) hostdata->script +
/ sizeof(long); hostdata->E_other_transfer;
#if 0 #if 0
print_insn (host, cmd_dataout, "dynamic jump ", 1); print_insn (host, cmd_dataout, "dynamic jump ", 1);
#endif #endif
...@@ -2603,7 +2670,7 @@ int NCR53c7xx_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) { ...@@ -2603,7 +2670,7 @@ int NCR53c7xx_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) {
struct Scsi_Host *host = cmd->host; struct Scsi_Host *host = cmd->host;
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
host->hostdata; host->hostdata;
int old_level; unsigned long flags;
unsigned char target_was_busy; unsigned char target_was_busy;
NCR53c7x0_local_setup(host); NCR53c7x0_local_setup(host);
...@@ -2671,7 +2738,8 @@ int NCR53c7xx_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) { ...@@ -2671,7 +2738,8 @@ int NCR53c7xx_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) {
* valid while the condition exists. * valid while the condition exists.
*/ */
old_level = splx(0); save_flags(flags);
cli();
/* /*
* Consider a target busy if there are _any_ commands running * Consider a target busy if there are _any_ commands running
...@@ -2764,7 +2832,7 @@ int NCR53c7xx_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) { ...@@ -2764,7 +2832,7 @@ int NCR53c7xx_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) {
tmp->next; tmp = (struct NCR53c7x0_cmd *) tmp->next); tmp->next; tmp = (struct NCR53c7x0_cmd *) tmp->next);
tmp->next = tmp; tmp->next = tmp;
} }
splx(old_level); restore_flags(flags);
return 0; return 0;
} }
...@@ -2848,9 +2916,9 @@ static void intr_scsi (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) { ...@@ -2848,9 +2916,9 @@ static void intr_scsi (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
if (sstat0_sist0 & SSTAT0_UDC) { if (sstat0_sist0 & SSTAT0_UDC) {
fatal = 1; fatal = 1;
printk("scsi%d : target %d lun %d unexpected disconnect\n",
host->host_no, cmd->cmd->target, cmd->cmd->lun);
if (cmd) { if (cmd) {
printk("scsi%d : target %d lun %d unexpected disconnect\n",
host->host_no, cmd->cmd->target, cmd->cmd->lun);
abnormal_finished(cmd, DID_ERROR << 16); abnormal_finished(cmd, DID_ERROR << 16);
} }
hostdata->dsp = hostdata->script + hostdata->E_schedule / hostdata->dsp = hostdata->script + hostdata->E_schedule /
...@@ -2950,7 +3018,7 @@ static void NCR53c7x0_intr (int irq, struct pt_regs * regs) { ...@@ -2950,7 +3018,7 @@ static void NCR53c7x0_intr (int irq, struct pt_regs * regs) {
should terminate */ should terminate */
int interrupted = 0; /* This HA generated int interrupted = 0; /* This HA generated
an interrupt */ an interrupt */
int old_level; unsigned long flags;
#ifdef NCR_DEBUG #ifdef NCR_DEBUG
char buf[80]; /* Debugging sprintf buffer */ char buf[80]; /* Debugging sprintf buffer */
...@@ -3011,12 +3079,14 @@ static void NCR53c7x0_intr (int irq, struct pt_regs * regs) { ...@@ -3011,12 +3079,14 @@ static void NCR53c7x0_intr (int irq, struct pt_regs * regs) {
*/ */
old_level = splx(0); save_flags(flags);
cli();
restart: restart:
for (cmd_prev_ptr = (struct NCR53c7x0_cmd **) for (cmd_prev_ptr = (struct NCR53c7x0_cmd **)
&(hostdata->running_list), cmd = (struct NCR53c7x0_cmd *) &(hostdata->running_list), cmd =
hostdata->running_list; cmd ; cmd_prev_ptr = (struct NCR53c7x0_cmd *) hostdata->running_list; cmd ;
&(cmd->next), cmd = (struct NCR53c7x0_cmd *) cmd->next) { cmd_prev_ptr = (struct NCR53c7x0_cmd **) &(cmd->next),
cmd = (struct NCR53c7x0_cmd *) cmd->next) {
Scsi_Cmnd *tmp; Scsi_Cmnd *tmp;
if (!cmd) { if (!cmd) {
...@@ -3045,7 +3115,7 @@ static void NCR53c7x0_intr (int irq, struct pt_regs * regs) { ...@@ -3045,7 +3115,7 @@ static void NCR53c7x0_intr (int irq, struct pt_regs * regs) {
if (cmd->prev) if (cmd->prev)
cmd->prev->next = cmd->next; cmd->prev->next = cmd->next;
if (cmd_prev_ptr) if (cmd_prev_ptr)
*cmd_prev_ptr = cmd->next; *cmd_prev_ptr = (struct NCR53c7x0_cmd *) cmd->next;
#ifdef LUN_BUSY #ifdef LUN_BUSY
/* Check for next command for target, add to issue queue */ /* Check for next command for target, add to issue queue */
...@@ -3054,16 +3124,8 @@ static void NCR53c7x0_intr (int irq, struct pt_regs * regs) { ...@@ -3054,16 +3124,8 @@ static void NCR53c7x0_intr (int irq, struct pt_regs * regs) {
#endif #endif
if (!scan_scsis_buf_busy) { cmd->next = hostdata->free;
#ifdef SCSI_MALLOC hostdata->free = cmd;
scsi_free ((void *) cmd->real, cmd->size);
#else
kfree_s ((void *) cmd->real, cmd->size);
#endif
} else {
scan_scsis_buf_busy = 0;
}
tmp->host_scribble = NULL; tmp->host_scribble = NULL;
...@@ -3081,7 +3143,7 @@ static void NCR53c7x0_intr (int irq, struct pt_regs * regs) { ...@@ -3081,7 +3143,7 @@ static void NCR53c7x0_intr (int irq, struct pt_regs * regs) {
goto restart; goto restart;
} }
splx(old_level); restore_flags(flags);
if (!search_found) { if (!search_found) {
printk ("scsi%d : WARNING : INTFLY with no completed commands.\n", printk ("scsi%d : WARNING : INTFLY with no completed commands.\n",
...@@ -3204,7 +3266,8 @@ static void NCR53c7x0_intr (int irq, struct pt_regs * regs) { ...@@ -3204,7 +3266,8 @@ static void NCR53c7x0_intr (int irq, struct pt_regs * regs) {
* *
*/ */
static int abort_connected (struct Scsi_Host *host) { static int
abort_connected (struct Scsi_Host *host) {
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
host->hostdata; host->hostdata;
...@@ -3398,15 +3461,13 @@ static void intr_dma (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) { ...@@ -3398,15 +3461,13 @@ static void intr_dma (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
NCR53c7x0_local_declare(); NCR53c7x0_local_declare();
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
host->hostdata; host->hostdata;
unsigned char dstat, /* DSTAT */ unsigned char dstat; /* DSTAT */
dbc_dcmd; /* DCMD (high eight bits) + DBC */
unsigned long *dsp, unsigned long *dsp,
*next_dsp, /* Current dsp */ *next_dsp, /* Current dsp */
*dsa; *dsa,
dbc_dcmd; /* DCMD (high eight bits) + DBC */
int tmp;
int ipl, /* Old ipl from splx(0) */ unsigned long flags;
tmp;
NCR53c7x0_local_setup(host); NCR53c7x0_local_setup(host);
if (!hostdata->dstat_valid) { if (!hostdata->dstat_valid) {
...@@ -3460,12 +3521,13 @@ static void intr_dma (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) { ...@@ -3460,12 +3521,13 @@ static void intr_dma (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
if (hostdata->options & OPTION_DEBUG_TRACE) { if (hostdata->options & OPTION_DEBUG_TRACE) {
} else if (hostdata->options & OPTION_DEBUG_SINGLE) { } else if (hostdata->options & OPTION_DEBUG_SINGLE) {
print_insn (host, dsp, "s ", 0); print_insn (host, dsp, "s ", 0);
ipl = splx(0); save_flags(flags);
cli();
/* XXX - should we do this, or can we get away with writing dsp? */ /* XXX - should we do this, or can we get away with writing dsp? */
NCR53c7x0_write8 (DCNTL_REG, (NCR53c7x0_read8(DCNTL_REG) & NCR53c7x0_write8 (DCNTL_REG, (NCR53c7x0_read8(DCNTL_REG) &
~DCNTL_SSM) | DCNTL_STD); ~DCNTL_SSM) | DCNTL_STD);
splx(ipl); restore_flags(flags);
} else { } else {
printk("scsi%d : unexpected single step interrupt at\n" printk("scsi%d : unexpected single step interrupt at\n"
" ", host->host_no); " ", host->host_no);
...@@ -3654,9 +3716,10 @@ int NCR53c7xx_abort (Scsi_Cmnd *cmd) { ...@@ -3654,9 +3716,10 @@ int NCR53c7xx_abort (Scsi_Cmnd *cmd) {
struct Scsi_Host *host = cmd->host; struct Scsi_Host *host = cmd->host;
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
host->hostdata; host->hostdata;
int old_level; unsigned long flags;
struct NCR53c7x0_cmd *curr, **prev; struct NCR53c7x0_cmd *curr, **prev;
old_level = splx(0); save_flags(flags);
cli();
/* /*
* The command could be hiding in the issue_queue. This would be very * The command could be hiding in the issue_queue. This would be very
...@@ -3668,28 +3731,23 @@ int NCR53c7xx_abort (Scsi_Cmnd *cmd) { ...@@ -3668,28 +3731,23 @@ int NCR53c7xx_abort (Scsi_Cmnd *cmd) {
* pull the command out of the old queue, and call it aborted. * pull the command out of the old queue, and call it aborted.
*/ */
for (curr = hostdata->issue_queue, prev = &(hostdata->issue_queue); for (curr = (struct NCR53c7x0_cmd *) hostdata->issue_queue,
curr && curr->cmd != cmd; prev = &(curr->next), curr = curr->next); prev = (struct NCR53c7x0_cmd **) &(hostdata->issue_queue);
curr && curr->cmd != cmd; prev = (struct NCR53c7x0_cmd **)
&(curr->next), curr = (struct NCR53c7x0_cmd *) curr->next);
if (curr) { if (curr) {
*prev = curr->next; *prev = (struct NCR53c7x0_cmd *) curr->next;
/* XXX - get rid of DLL ? */ /* XXX - get rid of DLL ? */
if (curr->prev) if (curr->prev)
curr->prev->next = curr->next; curr->prev->next = curr->next;
if (!scan_scsis_buf_busy) { curr->next = hostdata->free;
#ifdef SCSI_MALLOC hostdata->free = curr;
scsi_free ((void *) curr->real, curr->size);
#else
kfree_s ((void *) curr->real, curr->size);
#endif
} else {
scan_scsis_buf_busy = 0;
}
cmd->result = 0; cmd->result = 0;
cmd->scsi_done(cmd); cmd->scsi_done(cmd);
splx(old_level); restore_flags(flags);
return SCSI_ABORT_SUCCESS; return SCSI_ABORT_SUCCESS;
} }
...@@ -3698,11 +3756,13 @@ int NCR53c7xx_abort (Scsi_Cmnd *cmd) { ...@@ -3698,11 +3756,13 @@ int NCR53c7xx_abort (Scsi_Cmnd *cmd) {
* commands. If this is the case, drastic measures are called for. * commands. If this is the case, drastic measures are called for.
*/ */
for (curr = hostdata->running_list, prev = &(hostdata->running_list); for (curr = (struct NCR53c7x0_cmd *) hostdata->running_list,
curr && curr->cmd != cmd; prev = &(curr->next), curr = curr->next); prev = (struct NCR53c7x0_cmd **) &(hostdata->running_list);
curr && curr->cmd != cmd; prev = (struct NCR53c7x0_cmd **)
&(curr->next), curr = (struct NCR53c7x0_cmd *) curr->next);
if (curr) { if (curr) {
splx(old_level); restore_flags(flags);
printk ("scsi%d : DANGER : command in running list, can not abort.\n", printk ("scsi%d : DANGER : command in running list, can not abort.\n",
cmd->host->host_no); cmd->host->host_no);
return SCSI_ABORT_SNOOZE; return SCSI_ABORT_SNOOZE;
...@@ -3715,16 +3775,8 @@ int NCR53c7xx_abort (Scsi_Cmnd *cmd) { ...@@ -3715,16 +3775,8 @@ int NCR53c7xx_abort (Scsi_Cmnd *cmd) {
*/ */
curr = (struct NCR53c7x0_cmd *) cmd->host_scribble; curr = (struct NCR53c7x0_cmd *) cmd->host_scribble;
curr->next = hostdata->free;
if (!scan_scsis_buf_busy) { hostdata->free = curr;
#ifdef SCSI_MALLOC
scsi_free ((void *) curr->real, curr->size);
#else
kfree_s ((void *) curr->real, curr->size);
#endif
} else {
scan_scsis_buf_busy = 0;
}
if (((cmd->result & 0xff00) == 0xff00) || if (((cmd->result & 0xff00) == 0xff00) ||
((cmd->result & 0xff) == 0xff)) { ((cmd->result & 0xff) == 0xff)) {
...@@ -3734,7 +3786,7 @@ int NCR53c7xx_abort (Scsi_Cmnd *cmd) { ...@@ -3734,7 +3786,7 @@ int NCR53c7xx_abort (Scsi_Cmnd *cmd) {
host->host_no); host->host_no);
} }
cmd->scsi_done(cmd); cmd->scsi_done(cmd);
splx(old_level); restore_flags(flags);
return SCSI_ABORT_SNOOZE; return SCSI_ABORT_SNOOZE;
} }
...@@ -3749,17 +3801,47 @@ int NCR53c7xx_abort (Scsi_Cmnd *cmd) { ...@@ -3749,17 +3801,47 @@ int NCR53c7xx_abort (Scsi_Cmnd *cmd) {
* Returns : 0 on success. * Returns : 0 on success.
*/ */
int NCR53c7xx_reset (Scsi_Cmnd *cmd) { int
NCR53c7xx_reset (Scsi_Cmnd *cmd) {
NCR53c7x0_local_declare(); NCR53c7x0_local_declare();
struct Scsi_Host *host = cmd ? cmd->host : NULL; unsigned long flags;
int found;
struct NCR53c7x0_cmd * c;
Scsi_Cmnd *tmp;
struct Scsi_Host *host = cmd->host;
struct NCR53c7x0_hostdata *hostdata = host ? struct NCR53c7x0_hostdata *hostdata = host ?
(struct NCR53c7x0_hostdata *) host->hostdata : NULL; (struct NCR53c7x0_hostdata *) host->hostdata : NULL;
if (host) NCR53c7x0_local_setup(host); NCR53c7x0_local_setup(host);
save_flags(flags);
halt (host);
NCR53c7x0_write8(SCNTL1_REG, SCNTL1_RST);
udelay(25); /* Minimum ammount of time to assert RST */
NCR53c7x0_write8(SCNTL1_REG, SCNTL1_RST);
for (c = (struct NCR53c7x0_cmd *) hostdata->running_list, found = 0; c;
c = (struct NCR53c7x0_cmd *) c->next) {
tmp = c->cmd;
c->next = hostdata->free;
hostdata->free = c;
if (tmp == cmd)
found = 1;
tmp->result = DID_RESET << 16;
tmp->scsi_done(tmp);
}
if (!found) {
c = (struct NCR53c7x0_cmd *) cmd->host_scribble;
if (c) {
c->next = hostdata->free;
hostdata->free = c;
}
cmd->result = DID_RESET << 16;
cmd->scsi_done(cmd);
}
restore_flags(flags);
printk ("scsi%d : DANGER : NCR53c7xx_reset is NOP\n", printk ("scsi%d : DANGER : NCR53c7xx_reset is NOP\n",
cmd->host->host_no); cmd->host->host_no);
return SCSI_RESET_SNOOZE; return SCSI_RESET_SUCCESS;
} }
/* /*
...@@ -3770,13 +3852,11 @@ int NCR53c7xx_reset (Scsi_Cmnd *cmd) { ...@@ -3770,13 +3852,11 @@ int NCR53c7xx_reset (Scsi_Cmnd *cmd) {
static void print_dsa (struct Scsi_Host *host, unsigned long *dsa) { static void print_dsa (struct Scsi_Host *host, unsigned long *dsa) {
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
host->hostdata; host->hostdata;
Scsi_Cmnd * cmd;
struct NCR53c7x0_cmd * c;
int i, len; int i, len;
char *ptr; char *ptr;
printk("scsi%d : dsa at 0x%x\n" printk("scsi%d : dsa at 0x%x\n"
" + %d : dsa_msgout length = %d, data = 0x%x\n" , " + %ld : dsa_msgout length = %lu, data = 0x%lx\n" ,
host->host_no, (unsigned) dsa, hostdata->dsa_msgout, host->host_no, (unsigned) dsa, hostdata->dsa_msgout,
dsa[hostdata->dsa_msgout / sizeof(long)], dsa[hostdata->dsa_msgout / sizeof(long)],
dsa[hostdata->dsa_msgout / sizeof(long) + 1]); dsa[hostdata->dsa_msgout / sizeof(long) + 1]);
...@@ -3790,3 +3870,108 @@ static void print_dsa (struct Scsi_Host *host, unsigned long *dsa) { ...@@ -3790,3 +3870,108 @@ static void print_dsa (struct Scsi_Host *host, unsigned long *dsa) {
} }
} }
/*
* Function : static int shutdown (struct Scsi_Host *host)
*
* Purpose : does a clean (we hope) shutdown of the NCR SCSI
* chip. Use prior to dumping core, unloading the NCR driver,
* etc.
*
* Returns : 0 on success
*/
#ifdef MODULE
static int
shutdown (struct Scsi_Host *host) {
NCR53c7x0_local_declare();
unsigned long flags;
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
host->hostdata;
NCR53c7x0_local_setup(host);
save_flags (flags);
cli();
halt (host);
hostdata->soft_reset(host);
/*
* For now, we take the simplest solution : reset the SCSI bus. Eventually,
* - If a command is connected, kill it with an ABORT message
* - If commands are disconnected, connect to each target/LUN and
* do a ABORT, followed by a SOFT reset, followed by a hard
* reset.
*/
NCR53c7x0_write8(SCNTL1_REG, SCNTL1_RST);
udelay(25); /* Minimum ammount of time to assert RST */
NCR53c7x0_write8(SCNTL1_REG, SCNTL1_RST);
restore_flags (flags);
return 0;
}
#endif
/*
* Function : static int halt (struct Scsi_Host *host)
*
* Purpose : halts the SCSI SCRIPTS(tm) processor on the NCR chip
*
* Inputs : host - SCSI chip to halt
*
* Returns : 0 on success
*/
static int
halt (struct Scsi_Host *host) {
NCR53c7x0_local_declare();
unsigned long flags;
unsigned char istat, tmp;
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
host->hostdata;
NCR53c7x0_local_setup(host);
save_flags(flags);
cli();
NCR53c7x0_write8(hostdata->istat, ISTAT_ABRT);
/* Eat interrupts until we find what we're looking for */
for (;;) {
istat = NCR53c7x0_read8 (hostdata->istat);
if (istat & ISTAT_SIP) {
if ((hostdata->chip / 100) == 8) {
tmp = NCR53c7x0_read8(SIST0_REG_800);
udelay(1);
tmp = NCR53c7x0_read8(SIST1_REG_800);
} else {
tmp = NCR53c7x0_read8(SSTAT0_REG);
}
} else if (istat & ISTAT_DIP) {
NCR53c7x0_write8(hostdata->istat, 0);
tmp = NCR53c7x0_read8(DSTAT_REG);
if (tmp & DSTAT_ABRT)
break;
else
panic("scsi%d: could not halt NCR chip\n", host->host_no);
}
}
hostdata->state = STATE_HALTED;
restore_flags(flags);
return 0;
}
#ifdef MODULE
int NCR53c7x0_release(struct Scsi_Host *host) {
shutdown (host);
/* FIXME : need to recursively free tpnt structure */
if (host->irq != IRQ_NONE)
{
int irq_count;
struct Scsi_Host *tmp;
for (irq_count = 0, tmp = first_host; tmp; tmp = tmp->next)
if (tmp->hostt == the_template && tmp->irq == host->irq)
++irq_count;
if (irq_count == 1)
free_irq(host->irq);
}
if (host->dma_channel != DMA_NONE)
free_dma(host->dma_channel);
return 1;
}
Scsi_Host_Template driver_template = NCR53c7xx;
#include "scsi_module.c"
#endif /* def MODULE */
...@@ -46,20 +46,27 @@ ...@@ -46,20 +46,27 @@
* array. * array.
*/ */
#ifdef HOSTS_C #if defined(HOSTS_C) || defined(MODULE)
#include <linux/scsicam.h> #include <linux/scsicam.h>
extern int NCR53c7xx_abort(Scsi_Cmnd *); extern int NCR53c7xx_abort(Scsi_Cmnd *);
extern int NCR53c7xx_detect(Scsi_Host_Template *tpnt); extern int NCR53c7xx_detect(Scsi_Host_Template *tpnt);
extern int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); extern int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
extern int NCR53c7xx_reset(Scsi_Cmnd *); extern int NCR53c7xx_reset(Scsi_Cmnd *);
#ifdef MODULE
#define NCR53c7xx {NULL, NULL, "NCR53c{7,8}xx (rel 3)", NCR53c7xx_detect, \ extern int NCR53c7xx_release(struct Scsi_Host *);
NULL, NULL, \
NULL, NCR53c7xx_queue_command, NCR53c7xx_abort, NCR53c7xx_reset,\
NULL, scsicam_bios_param, \
/* can queue */ 1, /* id */ 7, 127 /* old SG_ALL */, \
/* cmd per lun */ 1 , 0, 0, DISABLE_CLUSTERING}
#else #else
#define NCR53c7xx_release NULL
#endif
#define NCR53c7xx {NULL, NULL, "NCR53c{7,8}xx (rel 4)", NCR53c7xx_detect, \
NULL, /* info */ NULL, /* command, depricated */ NULL, \
NCR53c7xx_queue_command, NCR53c7xx_abort, NCR53c7xx_reset, \
NULL /* slave attach */, scsicam_bios_param, /* can queue */ 1, \
/* id */ 7, 127 /* old SG_ALL */, /* cmd per lun */ 1 , \
/* present */ 0, /* unchecked isa dma */ 0, DISABLE_CLUSTERING}
#endif /* defined(HOSTS_C) || defined(MODULE) */
#ifndef HOSTS_C
/* Register addresses, ordered numerically */ /* Register addresses, ordered numerically */
...@@ -932,6 +939,9 @@ struct NCR53c7x0_table_indirect { ...@@ -932,6 +939,9 @@ struct NCR53c7x0_table_indirect {
struct NCR53c7x0_cmd { struct NCR53c7x0_cmd {
void *real; /* Real, unaligned address */ void *real; /* Real, unaligned address */
void (* free)(void *); /* Command to deallocate; NULL
for structures allocated with
scsi_register, etc. */
Scsi_Cmnd *cmd; /* Associated Scsi_Cmnd Scsi_Cmnd *cmd; /* Associated Scsi_Cmnd
structure, Scsi_Cmnd points structure, Scsi_Cmnd points
at NCR53c7x0_cmd using at NCR53c7x0_cmd using
...@@ -949,7 +959,11 @@ struct NCR53c7x0_cmd { ...@@ -949,7 +959,11 @@ struct NCR53c7x0_cmd {
*/ */
struct NCR53c7x0_cmd *next, *prev; /* Linux maintained lists */ volatile struct NCR53c7x0_cmd *next, *prev;
/* Linux maintained lists. Note that
hostdata->free is a singly linked
list; the rest are doubly linked */
unsigned long *data_transfer_start; /* Start of data transfer routines */ unsigned long *data_transfer_start; /* Start of data transfer routines */
...@@ -986,10 +1000,12 @@ struct NCR53c7x0_break { ...@@ -986,10 +1000,12 @@ struct NCR53c7x0_break {
/* Indicates that the NCR is executing other code. */ /* Indicates that the NCR is executing other code. */
#define STATE_RUNNING 2 #define STATE_RUNNING 2
/* /*
* Indicates that the NCR was being aborted. Only used when running * Indicates that the NCR was being aborted.
* NCR53c700 compatible scripts.
*/ */
#define STATE_ABORTING 3 #define STATE_ABORTING 3
/*
* Indicates that the NCR was successfully aborted. */
#define STATE_ABORTED 4
/* /*
...@@ -1072,6 +1088,7 @@ struct NCR53c7x0_hostdata { ...@@ -1072,6 +1088,7 @@ struct NCR53c7x0_hostdata {
int (* dstat_sir_intr)(struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd); int (* dstat_sir_intr)(struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd);
long dsa_size; /* Size of DSA structure */
/* /*
* Location of DSA fields for the SCSI SCRIPT corresponding to this * Location of DSA fields for the SCSI SCRIPT corresponding to this
...@@ -1160,11 +1177,13 @@ struct NCR53c7x0_hostdata { ...@@ -1160,11 +1177,13 @@ struct NCR53c7x0_hostdata {
*breakpoint_current; /* Current breakpoint being stepped *breakpoint_current; /* Current breakpoint being stepped
through, NULL if we are running through, NULL if we are running
normally. */ normally. */
#ifdef NCR_DEBUG
int debug_size; /* Size of debug buffer */ int debug_size; /* Size of debug buffer */
volatile int debug_count; /* Current data count */ volatile int debug_count; /* Current data count */
volatile char *debug_buf; /* Output ring buffer */ volatile char *debug_buf; /* Output ring buffer */
volatile char *debug_write; /* Current write pointer */ volatile char *debug_write; /* Current write pointer */
volatile char *debug_read; /* Current read pointer */ volatile char *debug_read; /* Current read pointer */
#endif /* def NCR_DEBUG */
/* XXX - primitive debugging junk, remove when working ? */ /* XXX - primitive debugging junk, remove when working ? */
int debug_print_limit; /* Number of commands to print int debug_print_limit; /* Number of commands to print
...@@ -1203,6 +1222,21 @@ struct NCR53c7x0_hostdata { ...@@ -1203,6 +1222,21 @@ struct NCR53c7x0_hostdata {
nexus, ONLY valid for nexus, ONLY valid for
NCR53c700/NCR53c700-66 NCR53c700/NCR53c700-66
*/ */
volatile struct NCR53c7x0_cmd *spare; /* pointer to spare,
allocated at probe time,
which we can use for
initialization */
volatile struct NCR53c7x0_cmd *free;
int max_cmd_size; /* Maximum size of NCR53c7x0_cmd
based on number of
scatter/gather segments, etc.
*/
volatile int num_cmds; /* Number of commands
allocated */
volatile unsigned char cmd_allocated[8]; /* Have we allocated commands
for this target yet? If not,
do so ASAP */
volatile unsigned char busy[8][8]; /* number of commands volatile unsigned char busy[8][8]; /* number of commands
executing on each target executing on each target
*/ */
...@@ -1226,13 +1260,21 @@ struct NCR53c7x0_hostdata { ...@@ -1226,13 +1260,21 @@ struct NCR53c7x0_hostdata {
volatile unsigned char msg_buf[16]; /* buffer for messages volatile unsigned char msg_buf[16]; /* buffer for messages
other than the command other than the command
complete message */ complete message */
volatile struct NCR53c7x0_cmd *reconnect_dsa_head; volatile unsigned char *reconnect_dsa_head;
/* disconnected commands, /* disconnected commands,
maintained by NCR */ maintained by NCR */
/* Data identifying nexus we are trying to match during reselection */ /* Data identifying nexus we are trying to match during reselection */
volatile unsigned char reselected_identify; /* IDENTIFY message */ volatile unsigned char reselected_identify; /* IDENTIFY message */
volatile unsigned char reselected_tag; /* second byte of queue tag volatile unsigned char reselected_tag; /* second byte of queue tag
message or 0 */ message or 0 */
/* These were static variables before we moved them */
long NCR53c7xx_zero;
long NCR53c7xx_sink;
char NCR53c7xx_msg_reject;
char NCR53c7xx_msg_abort;
char NCR53c7xx_msg_nop;
int script_count; /* Size of script in longs */ int script_count; /* Size of script in longs */
unsigned long script[0]; /* Relocated SCSI script */ unsigned long script[0]; /* Relocated SCSI script */
......
...@@ -221,10 +221,10 @@ ABSOLUTE int_test_1 = 0x04000000 ; Test 1 complete ...@@ -221,10 +221,10 @@ ABSOLUTE int_test_1 = 0x04000000 ; Test 1 complete
ABSOLUTE int_test_2 = 0x04010000 ; Test 2 complete ABSOLUTE int_test_2 = 0x04010000 ; Test 2 complete
ABSOLUTE int_test_3 = 0x04020000 ; Test 3 complete ABSOLUTE int_test_3 = 0x04020000 ; Test 3 complete
EXTERNAL NCR53c7xx_msg_abort ; Pointer to abort message ABSOLUTE NCR53c7xx_msg_abort = 0 ; Pointer to abort message
EXTERNAL NCR53c7xx_msg_reject ; Pointer to reject message ABSOLUTE NCR53c7xx_msg_reject = 0 ; Pointer to reject message
EXTERNAL NCR53c7xx_zero ; long with zero in it, use for source ABSOLUTE NCR53c7xx_zero = 0 ; long with zero in it, use for source
EXTERNAL NCR53c7xx_sink ; long to dump worthless data in ABSOLUTE NCR53c7xx_sink = 0 ; long to dump worthless data in
; Pointer to final bytes of multi-byte messages ; Pointer to final bytes of multi-byte messages
ABSOLUTE msg_buf = 0 ABSOLUTE msg_buf = 0
...@@ -881,13 +881,23 @@ selected: ...@@ -881,13 +881,23 @@ selected:
wait_reselect_failed: wait_reselect_failed:
; Reading CTEST2 clears the SIG_P bit in the ISTAT register. ; Reading CTEST2 clears the SIG_P bit in the ISTAT register.
MOVE CTEST2 & 0x40 TO SFBR MOVE CTEST2 & 0x40 TO SFBR
JUMP selected, IF NOT 0x40 JUMP schedule, IF 0x40
MOVE SIST0 & 0x20 TO SFBR
JUMP selected, IF 0x20
; FIXME : Something bogus happened, and we shouldn't fail silently.
JUMP schedule JUMP schedule
select_failed: select_failed:
MOVE ISTAT & 0x20 TO SFBR ; If SIGP is set, the user just gave us another command, and
JUMP reselected, IF NOT 0x20 ; we should restart or return to the scheduler.
MOVE ISTAT & 0xdf TO ISTAT ; Reading CTEST2 clears the SIG_P bit in the ISTAT register.
MOVE CTEST2 & 0x40 TO SFBR
JUMP select, IF 0x40
; Otherwise, mask the selected and reselected bits off SIST0
MOVE SIST0 & 0x30 TO SFBR
JUMP selected, IF 0x20
JUMP reselected, IF 0x10
; FIXME : Something bogus happened, and we shouldn't fail silently.
JUMP schedule JUMP schedule
; ;
...@@ -980,7 +990,10 @@ no_source_data: ...@@ -980,7 +990,10 @@ no_source_data:
; If DSP points here, and a phase mismatch is encountered, we need to ; If DSP points here, and a phase mismatch is encountered, we need to
; do a bus reset. ; do a bus reset.
; ;
MOVE SCNTL2 & 0x7f TO SCNTL2
MOVE 1, NCR53c7xx_msg_abort, WHEN MSG_OUT MOVE 1, NCR53c7xx_msg_abort, WHEN MSG_OUT
WAIT DISCONNECT
INT int_norm_aborted INT int_norm_aborted
; ;
......
...@@ -127,7 +127,7 @@ at 0x00000008 : */ 0x78380000,0x00000000, ...@@ -127,7 +127,7 @@ at 0x00000008 : */ 0x78380000,0x00000000,
/* /*
CALL scratch_to_dsa CALL scratch_to_dsa
at 0x0000000a : */ 0x88080000,0x00000800, at 0x0000000a : */ 0x88080000,0x00000830,
/* /*
JUMP reselected_check_next JUMP reselected_check_next
...@@ -283,10 +283,10 @@ ABSOLUTE int_test_1 = 0x04000000 ; Test 1 complete ...@@ -283,10 +283,10 @@ ABSOLUTE int_test_1 = 0x04000000 ; Test 1 complete
ABSOLUTE int_test_2 = 0x04010000 ; Test 2 complete ABSOLUTE int_test_2 = 0x04010000 ; Test 2 complete
ABSOLUTE int_test_3 = 0x04020000 ; Test 3 complete ABSOLUTE int_test_3 = 0x04020000 ; Test 3 complete
EXTERNAL NCR53c7xx_msg_abort ; Pointer to abort message ABSOLUTE NCR53c7xx_msg_abort = 0 ; Pointer to abort message
EXTERNAL NCR53c7xx_msg_reject ; Pointer to reject message ABSOLUTE NCR53c7xx_msg_reject = 0 ; Pointer to reject message
EXTERNAL NCR53c7xx_zero ; long with zero in it, use for source ABSOLUTE NCR53c7xx_zero = 0 ; long with zero in it, use for source
EXTERNAL NCR53c7xx_sink ; long to dump worthless data in ABSOLUTE NCR53c7xx_sink = 0 ; long to dump worthless data in
; Pointer to final bytes of multi-byte messages ; Pointer to final bytes of multi-byte messages
ABSOLUTE msg_buf = 0 ABSOLUTE msg_buf = 0
...@@ -325,7 +325,7 @@ ENTRY dsa_schedule ...@@ -325,7 +325,7 @@ ENTRY dsa_schedule
; ;
CALL dsa_to_scratch CALL dsa_to_scratch
at 0x0000002d : */ 0x88080000,0x000007b8, at 0x0000002d : */ 0x88080000,0x000007e8,
/* /*
; XXX - we need to deal with the NCR53c710, which lacks an add with ; XXX - we need to deal with the NCR53c710, which lacks an add with
; carry instruction, by moving around the DSA alignment to avoid ; carry instruction, by moving around the DSA alignment to avoid
...@@ -370,7 +370,7 @@ at 0x0000003e : */ 0xc0000004,0x00000000,0x00000000, ...@@ -370,7 +370,7 @@ at 0x0000003e : */ 0xc0000004,0x00000000,0x00000000,
; And update the head pointer. ; And update the head pointer.
CALL dsa_to_scratch CALL dsa_to_scratch
at 0x00000041 : */ 0x88080000,0x000007b8, at 0x00000041 : */ 0x88080000,0x000007e8,
/* /*
MOVE dmode_ncr_to_memory TO DMODE MOVE dmode_ncr_to_memory TO DMODE
...@@ -422,7 +422,7 @@ at 0x00000051 : */ 0x78380000,0x00000000, ...@@ -422,7 +422,7 @@ at 0x00000051 : */ 0x78380000,0x00000000,
CALL scratch_to_dsa CALL scratch_to_dsa
at 0x00000053 : */ 0x88080000,0x00000800, at 0x00000053 : */ 0x88080000,0x00000830,
/* /*
...@@ -514,7 +514,7 @@ at 0x00000065 : */ 0x60000200,0x00000000, ...@@ -514,7 +514,7 @@ at 0x00000065 : */ 0x60000200,0x00000000,
SELECT ATN FROM dsa_select, select_failed SELECT ATN FROM dsa_select, select_failed
at 0x00000067 : */ 0x4300003c,0x00000694, at 0x00000067 : */ 0x4300003c,0x000006a4,
/* /*
JUMP select_msgout, WHEN MSG_OUT JUMP select_msgout, WHEN MSG_OUT
...@@ -539,7 +539,7 @@ at 0x0000006b : */ 0x1e000000,0x00000040, ...@@ -539,7 +539,7 @@ at 0x0000006b : */ 0x1e000000,0x00000040,
CALL dsa_to_scratch CALL dsa_to_scratch
at 0x0000006d : */ 0x88080000,0x000007b8, at 0x0000006d : */ 0x88080000,0x000007e8,
/* /*
MOVE SCRATCH0 + dsa_next TO SCRATCH0 MOVE SCRATCH0 + dsa_next TO SCRATCH0
...@@ -711,7 +711,7 @@ at 0x00000099 : */ 0x80080000,0x00000234, ...@@ -711,7 +711,7 @@ at 0x00000099 : */ 0x80080000,0x00000234,
do_dataout: do_dataout:
CALL dsa_to_scratch CALL dsa_to_scratch
at 0x0000009b : */ 0x88080000,0x000007b8, at 0x0000009b : */ 0x88080000,0x000007e8,
/* /*
MOVE SCRATCH0 + dsa_dataout TO SCRATCH0 MOVE SCRATCH0 + dsa_dataout TO SCRATCH0
...@@ -756,7 +756,7 @@ at 0x000000af : */ 0x80080000,0x00000000, ...@@ -756,7 +756,7 @@ at 0x000000af : */ 0x80080000,0x00000000,
do_datain: do_datain:
CALL dsa_to_scratch CALL dsa_to_scratch
at 0x000000b1 : */ 0x88080000,0x000007b8, at 0x000000b1 : */ 0x88080000,0x000007e8,
/* /*
MOVE SCRATCH0 + dsa_datain TO SCRATCH0 MOVE SCRATCH0 + dsa_datain TO SCRATCH0
...@@ -1100,7 +1100,7 @@ at 0x00000130 : */ 0x60000040,0x00000000, ...@@ -1100,7 +1100,7 @@ at 0x00000130 : */ 0x60000040,0x00000000,
/* /*
MOVE 1, NCR53c7xx_msg_reject, WHEN MSG_OUT MOVE 1, NCR53c7xx_msg_reject, WHEN MSG_OUT
at 0x00000132 : */ 0x0e000001,((unsigned long)&NCR53c7xx_msg_reject), at 0x00000132 : */ 0x0e000001,0x00000000,
/* /*
RETURN RETURN
...@@ -1295,7 +1295,7 @@ at 0x0000015a : */ 0x0f000001,0x00000000, ...@@ -1295,7 +1295,7 @@ at 0x0000015a : */ 0x0f000001,0x00000000,
reselected_notag: reselected_notag:
MOVE MEMORY 1, NCR53c7xx_zero, reselected_tag MOVE MEMORY 1, NCR53c7xx_zero, reselected_tag
at 0x0000015c : */ 0xc0000001,((unsigned long)&NCR53c7xx_zero),0x00000000, at 0x0000015c : */ 0xc0000001,0x00000000,0x00000000,
/* /*
...@@ -1317,7 +1317,7 @@ at 0x00000164 : */ 0x78380000,0x00000000, ...@@ -1317,7 +1317,7 @@ at 0x00000164 : */ 0x78380000,0x00000000,
/* /*
CALL scratch_to_dsa CALL scratch_to_dsa
at 0x00000166 : */ 0x88080000,0x00000800, at 0x00000166 : */ 0x88080000,0x00000830,
/* /*
; Fix the update-next pointer so that the reconnect_dsa_head ; Fix the update-next pointer so that the reconnect_dsa_head
...@@ -1477,31 +1477,53 @@ at 0x0000019d : */ 0x98080000,0x00010000, ...@@ -1477,31 +1477,53 @@ at 0x0000019d : */ 0x98080000,0x00010000,
at 0x0000019f : */ 0x741a4000,0x00000000, at 0x0000019f : */ 0x741a4000,0x00000000,
/* /*
JUMP selected, IF NOT 0x40 JUMP schedule, IF 0x40
at 0x000001a1 : */ 0x80040040,0x00000674, at 0x000001a1 : */ 0x800c0040,0x00000130,
/* /*
MOVE SIST0 & 0x20 TO SFBR
at 0x000001a3 : */ 0x74422000,0x00000000,
/*
JUMP selected, IF 0x20
at 0x000001a5 : */ 0x800c0020,0x00000674,
/*
; FIXME : Something bogus happened, and we shouldn't fail silently.
JUMP schedule JUMP schedule
at 0x000001a3 : */ 0x80080000,0x00000130, at 0x000001a7 : */ 0x80080000,0x00000130,
/* /*
select_failed: select_failed:
MOVE ISTAT & 0x20 TO SFBR ; If SIGP is set, the user just gave us another command, and
; we should restart or return to the scheduler.
; Reading CTEST2 clears the SIG_P bit in the ISTAT register.
MOVE CTEST2 & 0x40 TO SFBR
at 0x000001a9 : */ 0x741a4000,0x00000000,
/*
JUMP select, IF 0x40
at 0x000001a5 : */ 0x74142000,0x00000000, at 0x000001ab : */ 0x800c0040,0x00000194,
/* /*
JUMP reselected, IF NOT 0x20 ; Otherwise, mask the selected and reselected bits off SIST0
MOVE SIST0 & 0x30 TO SFBR
at 0x000001a7 : */ 0x80040020,0x00000568, at 0x000001ad : */ 0x74423000,0x00000000,
/* /*
MOVE ISTAT & 0xdf TO ISTAT JUMP selected, IF 0x20
at 0x000001a9 : */ 0x7c14df00,0x00000000, at 0x000001af : */ 0x800c0020,0x00000674,
/* /*
JUMP reselected, IF 0x10
at 0x000001b1 : */ 0x800c0010,0x00000568,
/*
; FIXME : Something bogus happened, and we shouldn't fail silently.
JUMP schedule JUMP schedule
at 0x000001ab : */ 0x80080000,0x00000130, at 0x000001b3 : */ 0x80080000,0x00000130,
/* /*
; ;
...@@ -1525,11 +1547,11 @@ ENTRY test_1 ...@@ -1525,11 +1547,11 @@ ENTRY test_1
test_1: test_1:
MOVE MEMORY 4, test_src, test_dest MOVE MEMORY 4, test_src, test_dest
at 0x000001ad : */ 0xc0000004,0x00000000,0x00000000, at 0x000001b5 : */ 0xc0000004,0x00000000,0x00000000,
/* /*
INT int_test_1 INT int_test_1
at 0x000001b0 : */ 0x98080000,0x04000000, at 0x000001b8 : */ 0x98080000,0x04000000,
/* /*
; ;
...@@ -1540,61 +1562,61 @@ ENTRY test_2 ...@@ -1540,61 +1562,61 @@ ENTRY test_2
test_2: test_2:
CLEAR TARGET CLEAR TARGET
at 0x000001b2 : */ 0x60000200,0x00000000, at 0x000001ba : */ 0x60000200,0x00000000,
/* /*
SELECT ATN FROM 0, test_2_fail SELECT ATN FROM 0, test_2_fail
at 0x000001b4 : */ 0x43000000,0x00000720, at 0x000001bc : */ 0x43000000,0x00000740,
/* /*
JUMP test_2_msgout, WHEN MSG_OUT JUMP test_2_msgout, WHEN MSG_OUT
at 0x000001b6 : */ 0x860b0000,0x000006e0, at 0x000001be : */ 0x860b0000,0x00000700,
/* /*
ENTRY test_2_msgout ENTRY test_2_msgout
test_2_msgout: test_2_msgout:
MOVE FROM 8, WHEN MSG_OUT MOVE FROM 8, WHEN MSG_OUT
at 0x000001b8 : */ 0x1e000000,0x00000008, at 0x000001c0 : */ 0x1e000000,0x00000008,
/* /*
MOVE FROM 16, WHEN CMD MOVE FROM 16, WHEN CMD
at 0x000001ba : */ 0x1a000000,0x00000010, at 0x000001c2 : */ 0x1a000000,0x00000010,
/* /*
MOVE FROM 24, WHEN DATA_IN MOVE FROM 24, WHEN DATA_IN
at 0x000001bc : */ 0x19000000,0x00000018, at 0x000001c4 : */ 0x19000000,0x00000018,
/* /*
MOVE FROM 32, WHEN STATUS MOVE FROM 32, WHEN STATUS
at 0x000001be : */ 0x1b000000,0x00000020, at 0x000001c6 : */ 0x1b000000,0x00000020,
/* /*
MOVE FROM 40, WHEN MSG_IN MOVE FROM 40, WHEN MSG_IN
at 0x000001c0 : */ 0x1f000000,0x00000028, at 0x000001c8 : */ 0x1f000000,0x00000028,
/* /*
MOVE SCNTL2 & 0x7f TO SCNTL2 MOVE SCNTL2 & 0x7f TO SCNTL2
at 0x000001c2 : */ 0x7c027f00,0x00000000, at 0x000001ca : */ 0x7c027f00,0x00000000,
/* /*
CLEAR ACK CLEAR ACK
at 0x000001c4 : */ 0x60000040,0x00000000, at 0x000001cc : */ 0x60000040,0x00000000,
/* /*
WAIT DISCONNECT WAIT DISCONNECT
at 0x000001c6 : */ 0x48000000,0x00000000, at 0x000001ce : */ 0x48000000,0x00000000,
/* /*
test_2_fail: test_2_fail:
INT int_test_2 INT int_test_2
at 0x000001c8 : */ 0x98080000,0x04010000, at 0x000001d0 : */ 0x98080000,0x04010000,
/* /*
ENTRY debug_break ENTRY debug_break
debug_break: debug_break:
INT int_debug_break INT int_debug_break
at 0x000001ca : */ 0x98080000,0x03000000, at 0x000001d2 : */ 0x98080000,0x03000000,
/* /*
; ;
...@@ -1610,26 +1632,26 @@ ENTRY target_abort ...@@ -1610,26 +1632,26 @@ ENTRY target_abort
target_abort: target_abort:
SET TARGET SET TARGET
at 0x000001cc : */ 0x58000200,0x00000000, at 0x000001d4 : */ 0x58000200,0x00000000,
/* /*
DISCONNECT DISCONNECT
at 0x000001ce : */ 0x48000000,0x00000000, at 0x000001d6 : */ 0x48000000,0x00000000,
/* /*
CLEAR TARGET CLEAR TARGET
at 0x000001d0 : */ 0x60000200,0x00000000, at 0x000001d8 : */ 0x60000200,0x00000000,
/* /*
JUMP schedule JUMP schedule
at 0x000001d2 : */ 0x80080000,0x00000130, at 0x000001da : */ 0x80080000,0x00000130,
/* /*
ENTRY initiator_abort ENTRY initiator_abort
initiator_abort: initiator_abort:
SET ATN SET ATN
at 0x000001d4 : */ 0x58000008,0x00000000, at 0x000001dc : */ 0x58000008,0x00000000,
/* /*
; In order to abort the currently established nexus, we ; In order to abort the currently established nexus, we
; need to source/sink up to one byte of data in any SCSI phase, ; need to source/sink up to one byte of data in any SCSI phase,
...@@ -1637,60 +1659,69 @@ at 0x000001d4 : */ 0x58000008,0x00000000, ...@@ -1637,60 +1659,69 @@ at 0x000001d4 : */ 0x58000008,0x00000000,
; false->true ; false->true
JUMP no_eat_cmd, WHEN NOT CMD JUMP no_eat_cmd, WHEN NOT CMD
at 0x000001d6 : */ 0x82030000,0x00000768, at 0x000001de : */ 0x82030000,0x00000788,
/* /*
MOVE 1, NCR53c7xx_zero, WHEN CMD MOVE 1, NCR53c7xx_zero, WHEN CMD
at 0x000001d8 : */ 0x0a000001,((unsigned long)&NCR53c7xx_zero), at 0x000001e0 : */ 0x0a000001,0x00000000,
/* /*
no_eat_cmd: no_eat_cmd:
JUMP no_eat_msg, WHEN NOT MSG_IN JUMP no_eat_msg, WHEN NOT MSG_IN
at 0x000001da : */ 0x87030000,0x00000778, at 0x000001e2 : */ 0x87030000,0x00000798,
/* /*
MOVE 1, NCR53c7xx_sink, WHEN MSG_IN MOVE 1, NCR53c7xx_sink, WHEN MSG_IN
at 0x000001dc : */ 0x0f000001,((unsigned long)&NCR53c7xx_sink), at 0x000001e4 : */ 0x0f000001,0x00000000,
/* /*
no_eat_msg: no_eat_msg:
JUMP no_eat_data, WHEN NOT DATA_IN JUMP no_eat_data, WHEN NOT DATA_IN
at 0x000001de : */ 0x81030000,0x00000788, at 0x000001e6 : */ 0x81030000,0x000007a8,
/* /*
MOVE 1, NCR53c7xx_sink, WHEN DATA_IN MOVE 1, NCR53c7xx_sink, WHEN DATA_IN
at 0x000001e0 : */ 0x09000001,((unsigned long)&NCR53c7xx_sink), at 0x000001e8 : */ 0x09000001,0x00000000,
/* /*
no_eat_data: no_eat_data:
JUMP no_eat_status, WHEN NOT STATUS JUMP no_eat_status, WHEN NOT STATUS
at 0x000001e2 : */ 0x83030000,0x00000798, at 0x000001ea : */ 0x83030000,0x000007b8,
/* /*
MOVE 1, NCR53c7xx_sink, WHEN STATUS MOVE 1, NCR53c7xx_sink, WHEN STATUS
at 0x000001e4 : */ 0x0b000001,((unsigned long)&NCR53c7xx_sink), at 0x000001ec : */ 0x0b000001,0x00000000,
/* /*
no_eat_status: no_eat_status:
JUMP no_source_data, WHEN NOT DATA_OUT JUMP no_source_data, WHEN NOT DATA_OUT
at 0x000001e6 : */ 0x80030000,0x000007a8, at 0x000001ee : */ 0x80030000,0x000007c8,
/* /*
MOVE 1, NCR53c7xx_zero, WHEN DATA_OUT MOVE 1, NCR53c7xx_zero, WHEN DATA_OUT
at 0x000001e8 : */ 0x08000001,((unsigned long)&NCR53c7xx_zero), at 0x000001f0 : */ 0x08000001,0x00000000,
/* /*
no_source_data: no_source_data:
; ;
; If DSP points here, and a phase mismatch is encountered, we need to ; If DSP points here, and a phase mismatch is encountered, we need to
; do a bus reset. ; do a bus reset.
; ;
MOVE SCNTL2 & 0x7f TO SCNTL2
at 0x000001f2 : */ 0x7c027f00,0x00000000,
/*
MOVE 1, NCR53c7xx_msg_abort, WHEN MSG_OUT MOVE 1, NCR53c7xx_msg_abort, WHEN MSG_OUT
at 0x000001ea : */ 0x0e000001,((unsigned long)&NCR53c7xx_msg_abort), at 0x000001f4 : */ 0x0e000001,0x00000000,
/*
WAIT DISCONNECT
at 0x000001f6 : */ 0x48000000,0x00000000,
/* /*
INT int_norm_aborted INT int_norm_aborted
at 0x000001ec : */ 0x98080000,0x02040000, at 0x000001f8 : */ 0x98080000,0x02040000,
/* /*
; ;
...@@ -1711,77 +1742,101 @@ at 0x000001ec : */ 0x98080000,0x02040000, ...@@ -1711,77 +1742,101 @@ at 0x000001ec : */ 0x98080000,0x02040000,
dsa_to_scratch: dsa_to_scratch:
MOVE DSA0 TO SFBR MOVE DSA0 TO SFBR
at 0x000001ee : */ 0x72100000,0x00000000, at 0x000001fa : */ 0x72100000,0x00000000,
/* /*
MOVE SFBR TO SCRATCH0 MOVE SFBR TO SCRATCH0
at 0x000001f0 : */ 0x6a340000,0x00000000, at 0x000001fc : */ 0x6a340000,0x00000000,
/* /*
MOVE DSA1 TO SFBR MOVE DSA1 TO SFBR
at 0x000001f2 : */ 0x72110000,0x00000000, at 0x000001fe : */ 0x72110000,0x00000000,
/* /*
MOVE SFBR TO SCRATCH1 MOVE SFBR TO SCRATCH1
at 0x000001f4 : */ 0x6a350000,0x00000000, at 0x00000200 : */ 0x6a350000,0x00000000,
/* /*
MOVE DSA2 TO SFBR MOVE DSA2 TO SFBR
at 0x000001f6 : */ 0x72120000,0x00000000, at 0x00000202 : */ 0x72120000,0x00000000,
/* /*
MOVE SFBR TO SCRATCH2 MOVE SFBR TO SCRATCH2
at 0x000001f8 : */ 0x6a360000,0x00000000, at 0x00000204 : */ 0x6a360000,0x00000000,
/* /*
MOVE DSA3 TO SFBR MOVE DSA3 TO SFBR
at 0x000001fa : */ 0x72130000,0x00000000, at 0x00000206 : */ 0x72130000,0x00000000,
/* /*
MOVE SFBR TO SCRATCH3 MOVE SFBR TO SCRATCH3
at 0x000001fc : */ 0x6a370000,0x00000000, at 0x00000208 : */ 0x6a370000,0x00000000,
/* /*
RETURN RETURN
at 0x000001fe : */ 0x90080000,0x00000000, at 0x0000020a : */ 0x90080000,0x00000000,
/* /*
scratch_to_dsa: scratch_to_dsa:
MOVE SCRATCH0 TO SFBR MOVE SCRATCH0 TO SFBR
at 0x00000200 : */ 0x72340000,0x00000000, at 0x0000020c : */ 0x72340000,0x00000000,
/* /*
MOVE SFBR TO DSA0 MOVE SFBR TO DSA0
at 0x00000202 : */ 0x6a100000,0x00000000, at 0x0000020e : */ 0x6a100000,0x00000000,
/* /*
MOVE SCRATCH1 TO SFBR MOVE SCRATCH1 TO SFBR
at 0x00000204 : */ 0x72350000,0x00000000, at 0x00000210 : */ 0x72350000,0x00000000,
/* /*
MOVE SFBR TO DSA1 MOVE SFBR TO DSA1
at 0x00000206 : */ 0x6a110000,0x00000000, at 0x00000212 : */ 0x6a110000,0x00000000,
/* /*
MOVE SCRATCH2 TO SFBR MOVE SCRATCH2 TO SFBR
at 0x00000208 : */ 0x72360000,0x00000000, at 0x00000214 : */ 0x72360000,0x00000000,
/* /*
MOVE SFBR TO DSA2 MOVE SFBR TO DSA2
at 0x0000020a : */ 0x6a120000,0x00000000, at 0x00000216 : */ 0x6a120000,0x00000000,
/* /*
MOVE SCRATCH3 TO SFBR MOVE SCRATCH3 TO SFBR
at 0x0000020c : */ 0x72370000,0x00000000, at 0x00000218 : */ 0x72370000,0x00000000,
/* /*
MOVE SFBR TO DSA3 MOVE SFBR TO DSA3
at 0x0000020e : */ 0x6a130000,0x00000000, at 0x0000021a : */ 0x6a130000,0x00000000,
/* /*
RETURN RETURN
at 0x00000210 : */ 0x90080000,0x00000000, at 0x0000021c : */ 0x90080000,0x00000000,
};
#define A_NCR53c7xx_msg_abort 0x00000000
unsigned long A_NCR53c7xx_msg_abort_used[] = {
0x000001f5,
};
#define A_NCR53c7xx_msg_reject 0x00000000
unsigned long A_NCR53c7xx_msg_reject_used[] = {
0x00000133,
};
#define A_NCR53c7xx_sink 0x00000000
unsigned long A_NCR53c7xx_sink_used[] = {
0x000001e5,
0x000001e9,
0x000001ed,
};
#define A_NCR53c7xx_zero 0x00000000
unsigned long A_NCR53c7xx_zero_used[] = {
0x0000015d,
0x000001e1,
0x000001f1,
}; };
#define A_addr_scratch 0x00000000 #define A_addr_scratch 0x00000000
...@@ -1940,7 +1995,7 @@ unsigned long A_dsa_temp_target_used[] = { ...@@ -1940,7 +1995,7 @@ unsigned long A_dsa_temp_target_used[] = {
#define A_int_debug_break 0x03000000 #define A_int_debug_break 0x03000000
unsigned long A_int_debug_break_used[] = { unsigned long A_int_debug_break_used[] = {
0x000001cb, 0x000001d3,
}; };
#define A_int_debug_dsa_loaded 0x03030000 #define A_int_debug_dsa_loaded 0x03030000
...@@ -2013,7 +2068,7 @@ unsigned long A_int_msg_wdtr_used[] = { ...@@ -2013,7 +2068,7 @@ unsigned long A_int_msg_wdtr_used[] = {
#define A_int_norm_aborted 0x02040000 #define A_int_norm_aborted 0x02040000
unsigned long A_int_norm_aborted_used[] = { unsigned long A_int_norm_aborted_used[] = {
0x000001ed, 0x000001f9,
}; };
#define A_int_norm_command_complete 0x02020000 #define A_int_norm_command_complete 0x02020000
...@@ -2038,12 +2093,12 @@ unsigned long A_int_norm_select_complete_used[] = { ...@@ -2038,12 +2093,12 @@ unsigned long A_int_norm_select_complete_used[] = {
#define A_int_test_1 0x04000000 #define A_int_test_1 0x04000000
unsigned long A_int_test_1_used[] = { unsigned long A_int_test_1_used[] = {
0x000001b1, 0x000001b9,
}; };
#define A_int_test_2 0x04010000 #define A_int_test_2 0x04010000
unsigned long A_int_test_2_used[] = { unsigned long A_int_test_2_used[] = {
0x000001c9, 0x000001d1,
}; };
#define A_int_test_3 0x04020000 #define A_int_test_3 0x04020000
...@@ -2087,26 +2142,26 @@ unsigned long A_reselected_tag_used[] = { ...@@ -2087,26 +2142,26 @@ unsigned long A_reselected_tag_used[] = {
#define A_test_dest 0x00000000 #define A_test_dest 0x00000000
unsigned long A_test_dest_used[] = { unsigned long A_test_dest_used[] = {
0x000001af, 0x000001b7,
}; };
#define A_test_src 0x00000000 #define A_test_src 0x00000000
unsigned long A_test_src_used[] = { unsigned long A_test_src_used[] = {
0x000001ae, 0x000001b6,
}; };
#define Ent_accept_message 0x000004d8 #define Ent_accept_message 0x000004d8
#define Ent_cmdout_cmdout 0x0000022c #define Ent_cmdout_cmdout 0x0000022c
#define Ent_command_complete 0x00000508 #define Ent_command_complete 0x00000508
#define Ent_command_complete_msgin 0x00000518 #define Ent_command_complete_msgin 0x00000518
#define Ent_debug_break 0x00000728 #define Ent_debug_break 0x00000748
#define Ent_dsa_code_check_reselect 0x00000038 #define Ent_dsa_code_check_reselect 0x00000038
#define Ent_dsa_code_template 0x00000000 #define Ent_dsa_code_template 0x00000000
#define Ent_dsa_code_template_end 0x000000b4 #define Ent_dsa_code_template_end 0x000000b4
#define Ent_dsa_jump_resume 0x00000088 #define Ent_dsa_jump_resume 0x00000088
#define Ent_dsa_schedule 0x000000b4 #define Ent_dsa_schedule 0x000000b4
#define Ent_dsa_zero 0x00000090 #define Ent_dsa_zero 0x00000090
#define Ent_initiator_abort 0x00000750 #define Ent_initiator_abort 0x00000770
#define Ent_msg_in 0x00000354 #define Ent_msg_in 0x00000354
#define Ent_other_transfer 0x0000031c #define Ent_other_transfer 0x0000031c
#define Ent_reject_message 0x000004b8 #define Ent_reject_message 0x000004b8
...@@ -2115,10 +2170,10 @@ unsigned long A_test_src_used[] = { ...@@ -2115,10 +2170,10 @@ unsigned long A_test_src_used[] = {
#define Ent_schedule 0x00000130 #define Ent_schedule 0x00000130
#define Ent_select 0x00000194 #define Ent_select 0x00000194
#define Ent_select_msgout 0x000001ac #define Ent_select_msgout 0x000001ac
#define Ent_target_abort 0x00000730 #define Ent_target_abort 0x00000750
#define Ent_test_1 0x000006b4 #define Ent_test_1 0x000006d4
#define Ent_test_2 0x000006c8 #define Ent_test_2 0x000006e8
#define Ent_test_2_msgout 0x000006e0 #define Ent_test_2_msgout 0x00000700
unsigned long LABELPATCHES[] = { unsigned long LABELPATCHES[] = {
0x00000002, 0x00000002,
0x0000000b, 0x0000000b,
...@@ -2178,18 +2233,21 @@ unsigned long LABELPATCHES[] = { ...@@ -2178,18 +2233,21 @@ unsigned long LABELPATCHES[] = {
0x0000017a, 0x0000017a,
0x00000191, 0x00000191,
0x000001a2, 0x000001a2,
0x000001a4, 0x000001a6,
0x000001a8, 0x000001a8,
0x000001ac, 0x000001ac,
0x000001b5, 0x000001b0,
0x000001b7, 0x000001b2,
0x000001d3, 0x000001b4,
0x000001d7, 0x000001bd,
0x000001bf,
0x000001db, 0x000001db,
0x000001df, 0x000001df,
0x000001e3, 0x000001e3,
0x000001e7, 0x000001e7,
0x000001eb,
0x000001ef,
}; };
unsigned long INSTRUCTIONS = 0x000000fe; unsigned long INSTRUCTIONS = 0x00000104;
unsigned long PATCHES = 0x00000045; unsigned long PATCHES = 0x00000048;
#undef A_NCR53c7xx_msg_abort
#undef A_NCR53c7xx_msg_reject
#undef A_NCR53c7xx_sink
#undef A_NCR53c7xx_zero
#undef A_addr_scratch #undef A_addr_scratch
#undef A_addr_sfbr #undef A_addr_sfbr
#undef A_addr_temp #undef A_addr_temp
......
Wed Apr 12 15:25:52 1995 Eric Youngdale (eric@andante)
* Linux 1.2.5 released.
* buslogic.c: Update to version 1.15 (From Dave G, I expect).
Fixed interrupt routine to avoid races when handling multiple
complete commands per interrupt. Seems to come up with faster
cards.
* eata_dma.c: Modularize. Update to 2.3.5r.
* scsi.c: If we get a FMK, EOM, or ILI when attempting to scan
the bus, assume that it was just noise on the bus, and ignore
the device.
* scsi.h: Update and add a bunch of missing commands which we
were never using.
* sd.c: Use restore_flags in do_sd_request - this may result in
latency conditions, but it gets rid of races and crashes.
Do not save flags again when searching for a second command to
queue.
* st.c: Use bytes, not STP->buffer->buffer_size when reading
from tape.
Tue Apr 4 09:42:08 1995 Eric Youngdale (eric@andante)
* Linux 1.2.4 released.
* st.c: Fix typo - restoring wrong flags.
Wed Mar 29 06:55:12 1995 Eric Youngdale (eric@andante)
* Linux 1.2.3 released.
* st.c: Perform some waiting operations with interrupts off.
Is this correct???
Wed Mar 22 10:34:26 1995 Eric Youngdale (eric@andante)
* Linux 1.2.2 released.
* aha152x.c: Modularize. Add support for PCMCIA.
* eata.c: Update to version 2.0. Fixed bug preventing media
detection. If scsi_register_host returns NULL, fail gracefully.
* scsi.c: Detect as NEC (for photo-cd purposes) for the 84
and 25 models as "NEC_OLDCDR".
* scsi.h: Add define for NEC_OLDCDR
* sr.c: Add handling for NEC_OLDCDR. Treat as unknown.
* u14-34f.c: Update to version 2.0. Fixed same bug as in
eata.c.
Mon Mar 6 11:11:20 1995 Eric Youngdale (eric@andante)
* Linux 1.2.0 released. Yeah!!!
* Minor spelling/punctuation changes throughout. Nothing
substantive.
Mon Feb 20 21:33:03 1995 Eric Youngdale (eric@andante)
* Linux 1.1.95 released.
* qlogic.c: Update to version 0.41.
* seagate.c: Change some message to be more descriptive about what
we detected.
* sr.c: spelling/whitespace changes.
Mon Feb 20 21:33:03 1995 Eric Youngdale (eric@andante)
* Linux 1.1.94 released.
Mon Feb 20 08:57:17 1995 Eric Youngdale (eric@andante)
* Linux 1.1.93 released.
* hosts.h: Change io_port to long int from short.
* 53c7,8xx.c: crash on AEN fixed, SCSI reset is no longer a NOP,
NULL pointer panic on odd UDCs fixed, two bugs in diagnostic output
fixed, should initialize correctly if left running, now loadable,
new memory allocation, extraneous diagnostic output supressed,
splx() replaced with save/restore flags. [ Drew ]
* hosts.c, hosts.h, scsi_ioctl.c, sd.c, sd_ioctl.c, sg.c, sr.c,
sr_ioctl.c: Add special junk at end that Emacs will use for
formatting the file.
* qlogic.c: Update to v0.40a. Improve parity handling.
* scsi.c: Add Hitachi DK312C to blacklist. Change "};" to "}" in
many places. Use scsi_init_malloc to get command block - may
need this to be dma compatible for some host adapters.
Restore interrupts after unregistering a host.
* sd.c: Use sti instead of restore flags - causes latency problems.
* seagate.c: Use controller_type to determine string used when
registering irq.
* sr.c: More photo-cd hacks to make sure we get the xa stuff right.
* sr.h, sr.c: Change is_xa to xa_flags field.
* st.c: Diable retries for write operations.
Wed Feb 15 10:52:56 1995 Eric Youngdale (eric@andante)
* Linux 1.1.92 released.
* eata.c: Update to 1.17.
* eata_dma.c: Add more support for /proc/scsi, add HBA_interpret flag.
* hosts.c: If we remove last host registered, reuse host number.
When freeing memory from host being deregistered, free extra_bytes
too.
* scsi.c (scan_scsis): memset(SDpnt, 0) and set SCmd.device to SDpnt.
Change memory allocation to work around bugs in __get_dma_pages.
Do not free host if usage count is not zero (for modules).
* sr_ioctl.c: Increase IOCTL_TIMEOUT to 3000.
* st.c: Allow for ST_EXTRA_DEVS in st data structures.
* u14-34f.c: Update to 1.17.
Thu Feb 9 10:11:16 1995 Eric Youngdale (eric@andante)
* Linux 1.1.91 released.
* eata.c: Update to 1.16. Use wish_block instead of host->block.
* hosts.c: Initialize wish_block to 0.
* hosts.h: Add wish_block.
* scsi.c: Use wish_block as indicator that the host should be added
to block list.
* sg.c: Add SG_EXTRA_DEVS to number of slots.
* u14-34f.c: Use wish_block.
Tue Feb 7 11:46:04 1995 Eric Youngdale (eric@andante)
* Linux 1.1.90 released.
* eata.c: Change naming from eata_* to eata2x_*. Now at vers 1.15.
Update interrupt handler to take pt_regs as arg. Allow blocking
even if loaded as module. Initialize target_time_out array.
Do not put sti(); in timing loop.
* hosts.c: Do not reuse host numbers.
Use scsi_make_blocked_list to generate blocking list.
* script_asm.pl: Beats me. Don't know perl. Something to do with
phase index.
* scsi.c (scsi_make_blocked_list): New function - code copied from
hosts.c.
* scsi.c: Update code to disable photo CD for Toshiba cdroms.
Use just manufacturer name, not model number.
* sr.c: Fix setting density for Toshiba drives.
* u14-34f.c: Clear target_time_out array during reset.
Wed Feb 1 09:20:45 1995 Eric Youngdale (eric@andante)
* Linux 1.1.89 released.
* Makefile, u14-34f.c: Modulariz.e
* Makefile, eata.c: Modularize. Now version 1.14
* NCR5380.c: Update interrupt handler with new arglist. Minor
cleanups.
* eata_dma.c: Modularize. Add hooks for /proc/scsi.
New version 2.3.0a.
* hosts.c: Initialize ->dma_channel and ->io_port when registering
a new host.
* qlogic.c: Modularize and add PCMCIA support.
* scsi.c: Add Hitachi to blacklist.
* scsi.c: Change default to no lun scan (too many problem devices).
* scsi.h: Define QUEUE_FULL condition.
* sd.c: Do not check for non-existant partition until after
new media check.
* sg.c: Undo previous change which was wrong.
* sr_ioctl.c: Increase IOCTL_TIMEOUT to 2000.
* st.c: Patches from Kai - improve filemark handling.
Tue Jan 31 17:32:12 1995 Eric Youngdale (eric@andante)
* Linux 1.1.88 released.
* Throughout - spelling/grammar fixups.
* scsi.c: Make sure that all buffers are 16 byte aligned - some
drivers (buslogic) need this.
* scsi.c (scan_scsis): Remove message printed.
* scsi.c (scsi_init): Move message here.
Mon Jan 30 06:40:25 1995 Eric Youngdale (eric@andante)
* Linux 1.1.87 released.
* sr.c: Photo-cd related changes. (Gerd Knorr??).
* st.c: Changes from Kai related to EOM detection.
Mon Jan 23 23:53:10 1995 Eric Youngdale (eric@andante)
* Linux 1.1.86 released.
* 53c7,8xx.h: Change SG size to 127.
* eata_dma: Update to version 0i.
* scsi.c: Test for Toshiba XM-3401TA and exclude from detection
as toshiba drive - photo cd does not work with this drive.
* sr.c: Update photocd code.
Mon Jan 23 23:53:10 1995 Eric Youngdale (eric@andante)
* Linux 1.1.85 released.
* st.c, st_ioctl.c, sg.c, sd_ioctl.c, scsi_ioctl.c, hosts.c:
include linux/mm.h
* qlogic.c, buslogic.c, aha1542.c: Include linux/module.h.
Sun Jan 22 22:08:46 1995 Eric Youngdale (eric@andante)
* Linux 1.1.84 released.
* Makefile: Support for loadable QLOGIC boards.
* aha152x.c: Update to version 1.8 from Juergen.
* eata_dma.c: Update from Michael Neuffer
* in2000.c: Fix biosparam to support large disks.
* qlogic.c: Minor changes (change sti -> restore_flags).
Wed Jan 18 23:33:09 1995 Eric Youngdale (eric@andante)
* Linux 1.1.83 released.
* aha1542.c(aha1542_intr_handle): Use arguments handed down to find
which irq.
* buslogic.c: Likewise.
* eata_dma.c: Use min of 2 cmd_per_lun for OCS_enabled boards.
* scsi.c: Make RECOVERED_ERROR a SUGGEST_IS_OK.
* sd.c: Fail if we are opening a non-existant partition.
* sr.c: Bump SR_TIMEOUT to 15000.
Do not probe for media size at boot time(hard on changers).
Flag device as needing sector size instead.
* sr_ioctl.c: Remove CDROMMULTISESSION_SYS ioctl.
* ultrastor.c: Fix bug in call to ultrastor_interrupt (wrong #args).
Mon Jan 16 07:18:23 1995 Eric Youngdale (eric@andante) Mon Jan 16 07:18:23 1995 Eric Youngdale (eric@andante)
* Linux 1.1.82 released. * Linux 1.1.82 released.
......
...@@ -127,6 +127,8 @@ endif ...@@ -127,6 +127,8 @@ endif
ifdef CONFIG_SCSI_NCR53C7xx ifdef CONFIG_SCSI_NCR53C7xx
SCSI_OBJS := $(SCSI_OBJS) 53c7,8xx.o SCSI_OBJS := $(SCSI_OBJS) 53c7,8xx.o
SCSI_SRCS := $(SCSI_SRCS) 53c7,8xx.c SCSI_SRCS := $(SCSI_SRCS) 53c7,8xx.c
else
SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) 53c7,8xx.o
endif endif
ifdef CONFIG_SCSI_PAS16 ifdef CONFIG_SCSI_PAS16
...@@ -190,7 +192,7 @@ seagate.o: seagate.c ...@@ -190,7 +192,7 @@ seagate.o: seagate.c
53c8xx_d.h 53c8xx_u.h : 53c7,8xx.scr script_asm.pl 53c8xx_d.h 53c8xx_u.h : 53c7,8xx.scr script_asm.pl
ln 53c7,8xx.scr fake.c ln 53c7,8xx.scr fake.c
$(CPP) -DCHIP=810 fake.c | grep -v ^# | perl script_asm.pl $(CPP) -traditional -DCHIP=810 fake.c | grep -v '^#' | perl script_asm.pl
mv script.h 53c8xx_d.h mv script.h 53c8xx_d.h
mv scriptu.h 53c8xx_u.h mv scriptu.h 53c8xx_u.h
rm fake.c rm fake.c
......
...@@ -469,10 +469,7 @@ static void buslogic_interrupt(int irq, struct pt_regs * regs) ...@@ -469,10 +469,7 @@ static void buslogic_interrupt(int irq, struct pt_regs * regs)
interrupt_flags = inb(INTERRUPT(base)); interrupt_flags = inb(INTERRUPT(base));
if (!(interrupt_flags & INTV)) if (!(interrupt_flags & INTV))
{ buslogic_printk("interrupt received, but INTV not set\n");
buslogic_printk("interrupt received, but INTV not set\n");
return;
}
/* /*
Reset the Host Adapter Interrupt Register. It appears to be Reset the Host Adapter Interrupt Register. It appears to be
...@@ -504,16 +501,27 @@ static void buslogic_interrupt(int irq, struct pt_regs * regs) ...@@ -504,16 +501,27 @@ static void buslogic_interrupt(int irq, struct pt_regs * regs)
while (mb[mbi].status != MBX_NOT_IN_USE && found < BUSLOGIC_MAILBOXES) while (mb[mbi].status != MBX_NOT_IN_USE && found < BUSLOGIC_MAILBOXES)
{ {
int mbo = (struct ccb *)mb[mbi].ccbptr - ccb; int mbo = (struct ccb *)mb[mbi].ccbptr - ccb;
int result = 0;
saved_mbo[found++] = mbo; sctmp = HOSTDATA(shpnt)->sc[mbo];
/*
If sctmp has become NULL, higher level code must have aborted
this operation and called the necessary completion routine.
*/
if (sctmp != NULL && mb[mbi].status != MBX_COMPLETION_NOT_FOUND)
{
int result = 0;
saved_mbo[found++] = mbo;
if (mb[mbi].status != MBX_COMPLETION_OK) if (mb[mbi].status != MBX_COMPLETION_OK)
result = makecode(ccb[mbo].hastat, ccb[mbo].tarstat); result = makecode(ccb[mbo].hastat, ccb[mbo].tarstat);
HOSTDATA(shpnt)->sc[mbo]->result = result; sctmp->result = result;
mb[mbi].status = MBX_NOT_IN_USE; mb[mbi].status = MBX_NOT_IN_USE;
}
HOSTDATA(shpnt)->last_mbi_used = mbi; HOSTDATA(shpnt)->last_mbi_used = mbi;
...@@ -535,6 +543,7 @@ static void buslogic_interrupt(int irq, struct pt_regs * regs) ...@@ -535,6 +543,7 @@ static void buslogic_interrupt(int irq, struct pt_regs * regs)
{ {
int mbo = saved_mbo[i]; int mbo = saved_mbo[i];
sctmp = HOSTDATA(shpnt)->sc[mbo]; sctmp = HOSTDATA(shpnt)->sc[mbo];
if (sctmp == NULL) continue;
/* /*
First, free any storage allocated for a scatter/gather First, free any storage allocated for a scatter/gather
data segment list. data segment list.
...@@ -542,14 +551,15 @@ static void buslogic_interrupt(int irq, struct pt_regs * regs) ...@@ -542,14 +551,15 @@ static void buslogic_interrupt(int irq, struct pt_regs * regs)
if (sctmp->host_scribble) if (sctmp->host_scribble)
scsi_free(sctmp->host_scribble, BUSLOGIC_SG_MALLOC); scsi_free(sctmp->host_scribble, BUSLOGIC_SG_MALLOC);
/* /*
Next, call the SCSI command completion handler. Next, mark the SCSI Command as completed so it may be reused
for another command by buslogic_queuecommand. This also signals
to buslogic_reset that the command is no longer active.
*/ */
sctmp->scsi_done(sctmp); HOSTDATA(shpnt)->sc[mbo] = NULL;
/* /*
Finally, mark the SCSI Command as completed so it may be reused Finally, call the SCSI command completion handler.
for another command by buslogic_queuecommand.
*/ */
HOSTDATA(shpnt)->sc[mbo] = NULL; sctmp->scsi_done(sctmp);
} }
} }
...@@ -1344,7 +1354,7 @@ int buslogic_abort(Scsi_Cmnd *scpnt) ...@@ -1344,7 +1354,7 @@ int buslogic_abort(Scsi_Cmnd *scpnt)
#if 1 #if 1
static const unsigned char buscmd[] = { CMD_START_SCSI }; static const unsigned char buscmd[] = { CMD_START_SCSI };
struct mailbox *mb; struct mailbox *mb;
size_t mbi, mbo; int mbi, mbo, last_mbi;
unsigned long flags; unsigned long flags;
unsigned int i; unsigned int i;
...@@ -1355,28 +1365,30 @@ int buslogic_abort(Scsi_Cmnd *scpnt) ...@@ -1355,28 +1365,30 @@ int buslogic_abort(Scsi_Cmnd *scpnt)
save_flags(flags); save_flags(flags);
cli(); cli();
mb = HOSTDATA(scpnt->host)->mb; mb = HOSTDATA(scpnt->host)->mb;
mbi = HOSTDATA(scpnt->host)->last_mbi_used + 1; last_mbi = HOSTDATA(scpnt->host)->last_mbi_used;
mbi = last_mbi + 1;
if (mbi >= 2 * BUSLOGIC_MAILBOXES) if (mbi >= 2 * BUSLOGIC_MAILBOXES)
mbi = BUSLOGIC_MAILBOXES; mbi = BUSLOGIC_MAILBOXES;
do { do {
if (mb[mbi].status != MBX_NOT_IN_USE) if (mb[mbi].status != MBX_NOT_IN_USE)
break; break;
last_mbi = mbi;
mbi++; mbi++;
if (mbi >= 2 * BUSLOGIC_MAILBOXES) if (mbi >= 2 * BUSLOGIC_MAILBOXES)
mbi = BUSLOGIC_MAILBOXES; mbi = BUSLOGIC_MAILBOXES;
} while (mbi != HOSTDATA(scpnt->host)->last_mbi_used); } while (mbi != HOSTDATA(scpnt->host)->last_mbi_used);
restore_flags(flags);
if (mb[mbi].status != MBX_NOT_IN_USE) { if (mb[mbi].status != MBX_NOT_IN_USE) {
buslogic_printk("lost interrupt discovered on irq %d" buslogic_printk("lost interrupt discovered on irq %d, "
" - attempting to recover...\n", " - attempting to recover...\n",
scpnt->host->irq); scpnt->host->irq);
{ HOSTDATA(scpnt->host)->last_mbi_used = last_mbi;
buslogic_interrupt(scpnt->host->irq, NULL); buslogic_interrupt(scpnt->host->irq, NULL);
return SCSI_ABORT_SUCCESS; restore_flags(flags);
} return SCSI_ABORT_SUCCESS;
} }
restore_flags(flags);
/* OK, no lost interrupt. Try looking to see how many pending commands we /* OK, no lost interrupt. Try looking to see how many pending commands we
think we have. */ think we have. */
......
...@@ -710,7 +710,7 @@ int get_conf_PIO(struct eata_register *base, struct get_conf *buf) ...@@ -710,7 +710,7 @@ int get_conf_PIO(struct eata_register *base, struct get_conf *buf)
while (inb((uint) base + HA_RSTATUS) & HA_SDRQ) while (inb((uint) base + HA_RSTATUS) & HA_SDRQ)
inw((uint) base + HA_RDATA); inw((uint) base + HA_RDATA);
if (warning == TRUE) if (warning == TRUE)
printk("Warning: HBA with IO on 0x%p dectected,\n" printk("Warning: HBA with IO on 0x%p detected,\n"
" this IO space is already allocated, probably by the IDE driver.\n" " this IO space is already allocated, probably by the IDE driver.\n"
" This might lead to problems.", base); " This might lead to problems.", base);
return (TRUE); return (TRUE);
......
...@@ -123,7 +123,7 @@ static int nfs_file_read(struct inode *inode, struct file *file, char *buf, ...@@ -123,7 +123,7 @@ static int nfs_file_read(struct inode *inode, struct file *file, char *buf,
if ((cache[i].inode_num == inode->i_ino) if ((cache[i].inode_num == inode->i_ino)
&& (cache[i].file_pos <= pos) && (cache[i].file_pos <= pos)
&& (cache[i].file_pos + cache[i].len >= pos + count) && (cache[i].file_pos + cache[i].len >= pos + count)
&& (abs(jiffies - cache[i].time) <= EXPIRE_CACHE)) && (abs(jiffies - cache[i].time) < EXPIRE_CACHE))
break; break;
if (i < READ_CACHE_SIZE) { if (i < READ_CACHE_SIZE) {
++cache[i].in_use; ++cache[i].in_use;
......
...@@ -237,11 +237,10 @@ asmlinkage int sys_select( unsigned long *buffer ) ...@@ -237,11 +237,10 @@ asmlinkage int sys_select( unsigned long *buffer )
} }
current->timeout = timeout; current->timeout = timeout;
i = do_select(n, &in, &out, &ex, &res_in, &res_out, &res_ex); i = do_select(n, &in, &out, &ex, &res_in, &res_out, &res_ex);
if (current->timeout > jiffies) timeout = current->timeout - jiffies - 1;
timeout = current->timeout - jiffies;
else
timeout = 0;
current->timeout = 0; current->timeout = 0;
if ((long) timeout < 0)
timeout = 0;
if (tvp && !(current->personality & STICKY_TIMEOUTS)) { if (tvp && !(current->personality & STICKY_TIMEOUTS)) {
put_fs_long(timeout/HZ, (unsigned long *) &tvp->tv_sec); put_fs_long(timeout/HZ, (unsigned long *) &tvp->tv_sec);
timeout %= HZ; timeout %= HZ;
......
...@@ -6,6 +6,9 @@ ...@@ -6,6 +6,9 @@
#undef htonl #undef htonl
#undef htons #undef htons
#define LITTLE_ENDIAN
#define LITTLE_ENDIAN_BITFIELD
extern unsigned long int ntohl(unsigned long int); extern unsigned long int ntohl(unsigned long int);
extern unsigned short int ntohs(unsigned short int); extern unsigned short int ntohs(unsigned short int);
extern unsigned long int htonl(unsigned long int); extern unsigned long int htonl(unsigned long int);
......
...@@ -6,6 +6,9 @@ ...@@ -6,6 +6,9 @@
#undef htonl #undef htonl
#undef htons #undef htons
#define LITTLE_ENDIAN 1234
#define LITTLE_ENDIAN_BITFIELD
extern unsigned long int ntohl(unsigned long int); extern unsigned long int ntohl(unsigned long int);
extern unsigned short int ntohs(unsigned short int); extern unsigned short int ntohs(unsigned short int);
extern unsigned long int htonl(unsigned long int); extern unsigned long int htonl(unsigned long int);
......
...@@ -6,6 +6,16 @@ ...@@ -6,6 +6,16 @@
#undef htonl #undef htonl
#undef htons #undef htons
#ifdef MIPSEL
#define LITTLE_ENDIAN
#define LITTLE_ENDIAN_BITFIELD
#elif MIPSEB
#define BIG_ENDIAN
#define BIG_ENDIAN_BITFIELD
#else
#error "MIPS but neither MIPSEL nor MIPSEB?"
#endif
extern unsigned long int ntohl(unsigned long int); extern unsigned long int ntohl(unsigned long int);
extern unsigned short int ntohs(unsigned short int); extern unsigned short int ntohs(unsigned short int);
extern unsigned long int htonl(unsigned long int); extern unsigned long int htonl(unsigned long int);
......
...@@ -6,6 +6,9 @@ ...@@ -6,6 +6,9 @@
#undef htonl #undef htonl
#undef htons #undef htons
#define BIG_ENDIAN
#define BIG_ENDIAN_BITFIELD
extern unsigned long int ntohl(unsigned long int); extern unsigned long int ntohl(unsigned long int);
extern unsigned short int ntohs(unsigned short int); extern unsigned short int ntohs(unsigned short int);
extern unsigned long int htonl(unsigned long int); extern unsigned long int htonl(unsigned long int);
......
...@@ -48,5 +48,5 @@ extern int pcibios_write_config_word (unsigned char bus, ...@@ -48,5 +48,5 @@ extern int pcibios_write_config_word (unsigned char bus,
unsigned char device_fn, unsigned char where, unsigned short value); unsigned char device_fn, unsigned char where, unsigned short value);
extern pcibios_write_config_dword (unsigned char bus, extern pcibios_write_config_dword (unsigned char bus,
unsigned char device_fn, unsigned char where, unsigned long value); unsigned char device_fn, unsigned char where, unsigned long value);
extern char *pcibios_strerror (int error);
#endif /* ndef BIOS32_H */ #endif /* ndef BIOS32_H */
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
*/ */
#ifndef _LINUX_IP_H #ifndef _LINUX_IP_H
#define _LINUX_IP_H #define _LINUX_IP_H
#include <asm/byteorder.h>
#define IPOPT_END 0 #define IPOPT_END 0
#define IPOPT_NOOP 1 #define IPOPT_NOOP 1
...@@ -34,26 +34,14 @@ struct timestamp { ...@@ -34,26 +34,14 @@ struct timestamp {
__u8 len; __u8 len;
__u8 ptr; __u8 ptr;
union { union {
#if defined(__i386__) #if defined(LITTLE_ENDIAN_BITFIELD)
__u8 flags:4,
overflow:4;
#elif defined(__mc68000__)
__u8 overflow:4,
flags:4;
#elif defined(__MIPSEL__)
__u8 flags:4,
overflow:4;
#elif defined(__MIPSEB__)
__u8 overflow:4,
flags:4;
#elif defined(__alpha__)
__u8 flags:4, __u8 flags:4,
overflow:4; overflow:4;
#elif defined(__sparc__) #elif defined(BIG_ENDIAN_BITFIELD)
__u8 overflow:4, __u8 overflow:4,
flags:4; flags:4;
#else #else
#error "Adjust this structure to match your CPU" #error "Please fix <asm/byteorder.h>"
#endif #endif
__u8 full_char; __u8 full_char;
} x; } x;
...@@ -84,26 +72,14 @@ struct options { ...@@ -84,26 +72,14 @@ struct options {
struct iphdr { struct iphdr {
#if defined(__i386__) #if defined(LITTLE_ENDIAN_BITFIELD)
__u8 ihl:4,
version:4;
#elif defined (__mc68000__)
__u8 version:4,
ihl:4;
#elif defined(__MIPSEL__)
__u8 ihl:4,
version:4;
#elif defined(__MIPSEB__)
__u8 version:4,
ihl:4;
#elif defined(__alpha__)
__u8 ihl:4, __u8 ihl:4,
version:4; version:4;
#elif defined (__sparc__) #elif defined (BIG_ENDIAN_BITFIELD)
__u8 version:4, __u8 version:4,
ihl:4; ihl:4;
#else #else
#error "Adjust this structure to match your CPU" #error "Please fix <asm/byteorder.h>"
#endif #endif
__u8 tos; __u8 tos;
__u16 tot_len; __u16 tot_len;
......
...@@ -26,7 +26,7 @@ struct tcphdr { ...@@ -26,7 +26,7 @@ struct tcphdr {
__u16 dest; __u16 dest;
__u32 seq; __u32 seq;
__u32 ack_seq; __u32 ack_seq;
#if defined(__i386__) #if defined(LITTLE_ENDIAN_BITFIELD)
__u16 res1:4, __u16 res1:4,
doff:4, doff:4,
fin:1, fin:1,
...@@ -36,47 +36,7 @@ struct tcphdr { ...@@ -36,47 +36,7 @@ struct tcphdr {
ack:1, ack:1,
urg:1, urg:1,
res2:2; res2:2;
#elif defined(__mc68000__) #elif defined(BIG_ENDIAN_BITFIELD)
__u16 res2:2,
urg:1,
ack:1,
psh:1,
rst:1,
syn:1,
fin:1,
doff:4,
res1:4;
#elif defined(__MIPSEL__)
__u16 res1:4,
doff:4,
fin:1,
syn:1,
rst:1,
psh:1,
ack:1,
urg:1,
res2:2;
#elif defined(__MIPSEB__)
__u16 res2:2,
urg:1,
ack:1,
psh:1,
rst:1,
syn:1,
fin:1,
doff:4,
res1:4;
#elif defined(__alpha__)
__u16 res1:4,
doff:4,
fin:1,
syn:1,
rst:1,
psh:1,
ack:1,
urg:1,
res2:2;
#elif defined(__sparc__)
__u16 res2:2, __u16 res2:2,
urg:1, urg:1,
ack:1, ack:1,
...@@ -87,7 +47,7 @@ struct tcphdr { ...@@ -87,7 +47,7 @@ struct tcphdr {
doff:4, doff:4,
res1:4; res1:4;
#else #else
#error "Adjust this structure for your cpu alignment rules" #error "Adjust your <asm/byteorder.h> defines"
#endif #endif
__u16 window; __u16 window;
__u16 check; __u16 check;
......
...@@ -34,9 +34,10 @@ ...@@ -34,9 +34,10 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/config.h> #include <linux/config.h>
#ifdef CONFIG_INET #ifdef CONFIG_NET
#include <linux/net.h> #include <linux/net.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#ifdef CONFIG_INET
#include <linux/ip.h> #include <linux/ip.h>
#include <linux/tcp.h> #include <linux/tcp.h>
#include "../net/inet/protocol.h" #include "../net/inet/protocol.h"
...@@ -45,6 +46,7 @@ ...@@ -45,6 +46,7 @@
#include "../drivers/net/slhc.h" #include "../drivers/net/slhc.h"
#endif #endif
#endif #endif
#endif
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
#include <linux/pci.h> #include <linux/pci.h>
#endif #endif
...@@ -105,6 +107,7 @@ struct symbol_table symbol_table = { ...@@ -105,6 +107,7 @@ struct symbol_table symbol_table = {
X(pcibios_read_config_byte), X(pcibios_read_config_byte),
X(pcibios_read_config_word), X(pcibios_read_config_word),
X(pcibios_read_config_dword), X(pcibios_read_config_dword),
X(pcibios_strerror),
X(pcibios_write_config_byte), X(pcibios_write_config_byte),
X(pcibios_write_config_word), X(pcibios_write_config_word),
X(pcibios_write_config_dword), X(pcibios_write_config_dword),
...@@ -277,6 +280,7 @@ struct symbol_table symbol_table = { ...@@ -277,6 +280,7 @@ struct symbol_table symbol_table = {
X(inet_add_protocol), X(inet_add_protocol),
X(inet_del_protocol), X(inet_del_protocol),
#if defined(CONFIG_PPP) || defined(CONFIG_SLIP) #if defined(CONFIG_PPP) || defined(CONFIG_SLIP)
/* VJ header compression */
X(slhc_init), X(slhc_init),
X(slhc_free), X(slhc_free),
X(slhc_remember), X(slhc_remember),
...@@ -321,6 +325,11 @@ struct symbol_table symbol_table = { ...@@ -321,6 +325,11 @@ struct symbol_table symbol_table = {
#endif #endif
#ifdef CONFIG_SCSI #ifdef CONFIG_SCSI
/* Supports loadable scsi drivers */ /* Supports loadable scsi drivers */
/*
* in_scan_scsis is a hack, and should go away once the new
* memory allocation code is in the NCR driver
*/
X(in_scan_scsis),
X(scsi_register_module), X(scsi_register_module),
X(scsi_unregister_module), X(scsi_unregister_module),
X(scsi_free), X(scsi_free),
...@@ -331,6 +340,8 @@ struct symbol_table symbol_table = { ...@@ -331,6 +340,8 @@ struct symbol_table symbol_table = {
X(scsi_init_malloc), X(scsi_init_malloc),
X(scsi_init_free), X(scsi_init_free),
X(print_command), X(print_command),
X(print_msg),
X(print_status),
#endif #endif
/* Added to make file system as module */ /* Added to make file system as module */
X(set_writetime), X(set_writetime),
......
...@@ -523,7 +523,7 @@ static int swap_out(unsigned int priority) ...@@ -523,7 +523,7 @@ static int swap_out(unsigned int priority)
int loop, counter; int loop, counter;
struct task_struct *p; struct task_struct *p;
counter = 2*nr_tasks >> priority; counter = 6*nr_tasks >> priority;
for(; counter >= 0; counter--) { for(; counter >= 0; counter--) {
/* /*
* Check that swap_task is suitable for swapping. If not, look for * Check that swap_task is suitable for swapping. If not, look for
...@@ -605,7 +605,7 @@ static int try_to_free_page(int priority) ...@@ -605,7 +605,7 @@ static int try_to_free_page(int priority)
if (swap_out(i)) if (swap_out(i))
return 1; return 1;
state = 0; state = 0;
} while(--i); } while(i--);
} }
return 0; return 0;
} }
......
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