diff -u --recursive --new-file v1.2.5/linux/CREDITS linux/CREDITS --- v1.2.5/linux/CREDITS Wed Mar 29 06:52:56 1995 +++ linux/CREDITS Sun Apr 16 08:12:01 1995 @@ -683,6 +683,10 @@ D: CDROM driver "sonycd535" (Sony CDU-535/531) S: +N: Frederic Potter +E: Frederic.Potter@masi.ibp.fr +D: Some PCI kernel support + N: Stefan Probst E: snprobst@immd4.informatik.uni-erlangen.de D: The Linux Support Team Erlangen diff -u --recursive --new-file v1.2.5/linux/Makefile linux/Makefile --- v1.2.5/linux/Makefile Fri Apr 14 12:02:41 1995 +++ linux/Makefile Fri Apr 14 12:05:10 1995 @@ -1,6 +1,6 @@ VERSION = 1 PATCHLEVEL = 2 -SUBLEVEL = 5 +SUBLEVEL = 6 ARCH = i386 diff -u --recursive --new-file v1.2.5/linux/arch/i386/config.in linux/arch/i386/config.in --- v1.2.5/linux/arch/i386/config.in Wed Feb 15 10:50:55 1995 +++ linux/arch/i386/config.in Mon Apr 17 13:47:56 1995 @@ -74,6 +74,10 @@ bool 'Scsi CDROM support' CONFIG_BLK_DEV_SR 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' bool 'Adaptec AHA152X support' CONFIG_SCSI_AHA152X n diff -u --recursive --new-file v1.2.5/linux/drivers/char/ChangeLog linux/drivers/char/ChangeLog --- v1.2.5/linux/drivers/char/ChangeLog Fri Apr 14 12:02:41 1995 +++ linux/drivers/char/ChangeLog Fri Apr 14 12:01:41 1995 @@ -4,7 +4,7 @@ rs_init): Hangups are now scheduled via a separate tqueue structure in the async_struct structure, tqueue_hangup. 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) diff -u --recursive --new-file v1.2.5/linux/drivers/char/serial.c linux/drivers/char/serial.c --- v1.2.5/linux/drivers/char/serial.c Fri Apr 14 12:02:41 1995 +++ linux/drivers/char/serial.c Fri Apr 14 12:01:40 1995 @@ -733,7 +733,7 @@ /* * 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: * * serial interrupt routine -> (scheduler tqueue) -> diff -u --recursive --new-file v1.2.5/linux/drivers/net/lance.c linux/drivers/net/lance.c --- v1.2.5/linux/drivers/net/lance.c Fri Apr 14 12:02:41 1995 +++ linux/drivers/net/lance.c Fri Apr 14 12:01:40 1995 @@ -15,7 +15,7 @@ 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 #include @@ -203,12 +203,18 @@ int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */ int dma; struct enet_statistics stats; - char chip_version; /* See lance_chip_type. */ + unsigned char chip_version; /* See lance_chip_type. */ char tx_full; char lock; 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. These are from the datasheets -- in real life the '970 version reportedly has the same ID as the '965. */ @@ -217,14 +223,25 @@ char *name; int flags; } chip_table[] = { - {0x0000, "LANCE 7990", 0}, /* Ancient lance chip. */ - {0x0003, "PCnet/ISA 79C960", 0}, /* 79C960 PCnet/ISA. */ - {0x2260, "PCnet/ISA+ 79C961", 0}, /* 79C961 PCnet/ISA+, Plug-n-Play. */ - {0x2420, "PCnet/PCI 79C970", 0}, /* 79C970 or 79C974 PCnet-SCSI, PCI. */ + {0x0000, "LANCE 7990", /* Ancient lance chip. */ + LANCE_MUST_PAD + LANCE_MUST_UNRESET}, + {0x0003, "PCnet/ISA 79C960", /* 79C960 PCnet/ISA. */ + 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 it the PCnet32. */ - {0x2430, "PCnet32", 0}, /* 79C965 PCnet for VL bus. */ - {0x0, "PCnet (unknown)", 0}, + {0x2430, "PCnet32", /* 79C965 PCnet for VL bus. */ + 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}; @@ -256,8 +273,6 @@ int *port; #if defined(CONFIG_PCI) -#define AMD_VENDOR_ID 0x1022 -#define AMD_DEVICE_ID 0x2000 if (pcibios_present()) { int pci_index; printk("lance.c: PCI bios is present, checking for devices...\n"); @@ -266,7 +281,8 @@ unsigned long pci_ioaddr; 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) break; pcibios_read_config_byte(pci_bus, pci_device_fn, @@ -522,7 +538,7 @@ } } - 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 can watch the LEDs even if the board isn't opened. */ outw(0x0002, ioaddr+LANCE_ADDR); @@ -570,10 +586,10 @@ } /* 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); - 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). */ outw(0x0002, ioaddr+LANCE_ADDR); outw(0x0002, ioaddr+LANCE_BUS_IF); @@ -617,6 +633,33 @@ 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. */ static void lance_init_ring(struct device *dev) @@ -647,12 +690,27 @@ 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 lance_start_xmit(struct sk_buff *skb, struct device *dev) { struct lance_private *lp = (struct lance_private *)dev->priv; int ioaddr = dev->base_addr; int entry; + unsigned long flags; /* Transmitter timeout, serious problems. */ if (dev->tbusy) { @@ -681,8 +739,7 @@ printk("\n"); } #endif - lance_init_ring(dev); - outw(0x0043, ioaddr+LANCE_DATA); + lance_restart(dev, 0x0043, 1); dev->tbusy=0; dev->trans_start = jiffies; @@ -728,7 +785,7 @@ with the "ownership" bits last. */ /* 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 = -(ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN); } else @@ -758,13 +815,14 @@ dev->trans_start = jiffies; + save_flags(flags); cli(); lp->lock = 0; if (lp->tx_ring[(entry+1) & TX_RING_MOD_MASK].base == 0) dev->tbusy=0; else lp->tx_full = 1; - sti(); + restore_flags(flags); return 0; } @@ -776,6 +834,7 @@ struct device *dev = (struct device *)(irq2dev_map[irq]); struct lance_private *lp; int csr0, ioaddr, boguscnt=10; + int must_restart; if (dev == NULL) { printk ("lance_interrupt(): irq %d for unknown device.\n", irq); @@ -795,6 +854,8 @@ /* Acknowledge all of the current interrupt sources ASAP. */ outw(csr0 & ~0x004f, dev->base_addr + LANCE_DATA); + must_restart = 0; + if (lance_debug > 5) printk("%s: interrupt csr0=%#2.2x new csr=%#2.2x.\n", dev->name, csr0, inw(dev->base_addr + LANCE_DATA)); @@ -828,7 +889,7 @@ printk("%s: Tx FIFO error! Status %4.4x.\n", dev->name, csr0); /* Restart the chip. */ - outw(0x0002, dev->base_addr + LANCE_DATA); + must_restart = 1; } } else { if (status & 0x18000000) @@ -871,7 +932,14 @@ printk("%s: Bus master arbitration failure, status %4.4x.\n", dev->name, csr0); /* 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 @@ dev->start = 0; 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); lp->stats.rx_missed_errors = inw(ioaddr+LANCE_DATA); } @@ -991,14 +1059,16 @@ struct lance_private *lp = (struct lance_private *)dev->priv; short ioaddr = dev->base_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(); saved_addr = inw(ioaddr+LANCE_ADDR); outw(112, ioaddr+LANCE_ADDR); lp->stats.rx_missed_errors = inw(ioaddr+LANCE_DATA); outw(saved_addr, ioaddr+LANCE_ADDR); - sti(); + restore_flags(flags); } return &lp->stats; @@ -1015,11 +1085,9 @@ { short ioaddr = dev->base_addr; - /* We take the simple way out and always enable promiscuous mode. */ outw(0, ioaddr+LANCE_ADDR); outw(0x0004, ioaddr+LANCE_DATA); /* Temporarily stop the lance. */ - outw(15, ioaddr+LANCE_ADDR); if (num_addrs >= 0) { short multicast_table[4]; int i; @@ -1029,15 +1097,17 @@ outw(8 + i, ioaddr+LANCE_ADDR); outw(multicast_table[i], ioaddr+LANCE_DATA); } + outw(15, ioaddr+LANCE_ADDR); outw(0x0000, ioaddr+LANCE_DATA); /* Unset promiscuous mode */ } else { /* Log any net taps. */ printk("%s: Promiscuous mode enabled.\n", dev->name); + outw(15, ioaddr+LANCE_ADDR); outw(0x8000, ioaddr+LANCE_DATA); /* Set promiscuous mode */ } - outw(0, ioaddr+LANCE_ADDR); - outw(0x0142, ioaddr+LANCE_DATA); /* Resume normal operation. */ + lance_restart(dev, 0x0142, 0); /* Resume normal operation */ + } diff -u --recursive --new-file v1.2.5/linux/drivers/net/ne.c linux/drivers/net/ne.c --- v1.2.5/linux/drivers/net/ne.c Fri Apr 14 12:02:41 1995 +++ linux/drivers/net/ne.c Thu Apr 20 11:24:55 1995 @@ -376,7 +376,6 @@ { int retries = 0; int nic_base = NE_BASE; - unsigned long flags; /* Round the count up for word writes. Do we need to do this? What effect will an odd byte count have on the 8390? @@ -412,19 +411,7 @@ SLOW_DOWN_IO; #endif /* rw_bugfix */ - /* - 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 - */ - - save_flags(flags); - cli(); + /* Now the normal output. */ outb_p(count & 0xff, nic_base + EN0_RCNTLO); outb_p(count >> 8, nic_base + EN0_RCNTHI); outb_p(0x00, nic_base + EN0_RSARLO); @@ -436,7 +423,6 @@ } else { outsb(NE_BASE + NE_DATAPORT, buf, count); } - restore_flags(flags); #ifdef CONFIG_NE_SANITY /* This was for the ALPHA version only, but enough people have diff -u --recursive --new-file v1.2.5/linux/drivers/net/plip.c linux/drivers/net/plip.c --- v1.2.5/linux/drivers/net/plip.c Mon Feb 20 08:59:52 1995 +++ linux/drivers/net/plip.c Mon Apr 17 13:47:56 1995 @@ -98,6 +98,7 @@ #include #include #include +#include /* Use 0 for production, 1 for verification, >2 for debug */ #ifndef NET_DEBUG @@ -165,26 +166,14 @@ enum plip_nibble_state nibble; union { struct { -#if defined(__i386__) +#if defined(LITTLE_ENDIAN) unsigned char lsb; unsigned char msb; -#elif defined(__mc68000__) +#elif defined(BIG_ENDIAN) unsigned char msb; 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 -#error "Adjust this structure to match your CPU" +#error "Please fix the endianness defines in " #endif } b; unsigned short h; diff -u --recursive --new-file v1.2.5/linux/drivers/scsi/53c7,8xx.c linux/drivers/scsi/53c7,8xx.c --- v1.2.5/linux/drivers/scsi/53c7,8xx.c Sun Feb 19 11:22:43 1995 +++ linux/drivers/scsi/53c7,8xx.c Mon Apr 17 13:47:57 1995 @@ -5,8 +5,8 @@ * 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 * preventing deadlock, I'm not sure why we'd want to do this. @@ -20,7 +20,7 @@ * Hannover, Germany * hm@ix.de * - * Copyright 1993, 1994 Drew Eckhardt + * Copyright 1993, 1994, 1995 Drew Eckhardt * Visionary Computing * (Unix and Linux consulting and custom programming) * drew@Colorado.EDU @@ -28,8 +28,6 @@ * * TolerANT and SCSI SCRIPTS are registered trademarks of NCR Corporation. * - * PRE-ALPHA - * * For more information, please consult * * @@ -156,6 +154,11 @@ * */ +#ifdef MODULE +#include +#endif + +#include #include #include #include @@ -176,7 +179,9 @@ static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int result); static int NCR53c8xx_run_tests (struct Scsi_Host *host); static int NCR53c8xx_script_len; +static int NCR53c8xx_dsa_len; 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 *cmd); static void intr_dma (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd); @@ -190,40 +195,11 @@ NCR53c7x0_cmd *cmd); 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 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 : @@ -285,8 +261,7 @@ * * For the very similar chips, we should probably hack the fixup code * and interrupt code so that it works everywhere, but I suspect the - * NCR53c700 is going - * to need it's own fixup routine. + * NCR53c700 is going to need it's own fixup routine. */ /* @@ -420,7 +395,8 @@ * 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(); /* unsigned char tmp; */ int i, j, ccf; @@ -450,13 +426,19 @@ 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 * with another board. */ - for (search = first_host; search && (search->hostt == the_template) && - (search->irq != host->irq); search=search->next); + for (search = first_host; search && ((search->hostt != the_template) || + (search->irq != host->irq)); search=search->next); if (!search) { if (request_irq(host->irq, NCR53c7x0_intr, SA_INTERRUPT, "53c7,8xx")) { @@ -479,6 +461,10 @@ hostdata->istat = ((hostdata->chip / 100) == 8) ? 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, * as does the 710 with one bit per SCSI ID. Conversely, the NCR @@ -523,9 +509,9 @@ hostdata->saved_dcntl = NCR53c7x0_read8(DCNTL_REG); if ((hostdata->chip / 100) == 8) - printk ("scsi%d : using %s interrupts.\n", host->host_no, - (hostdata->saved_dcntl & DCNTL_800_IRQM) ? "level active" : - "edge triggered"); + printk ("scsi%d : using %s interrupts\n", host->host_no, + (hostdata->saved_dcntl & DCNTL_800_IRQM) ? "edge triggered" : + "level active"); /* * DMODE controls DMA burst length, and on 700 series chips, @@ -547,8 +533,9 @@ case DMODE_BL_4: i = 4; break; case DMODE_BL_8: i = 8; 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 @@ */ for (i = 0; i < 8; ++i) { + hostdata->cmd_allocated[i] = 0; for (j = 0; j < 8; ++j) hostdata->busy[i][j] = 0; /* @@ -620,8 +608,8 @@ hostdata->issue_queue = hostdata->running_list = hostdata->finished_queue = NULL; - hostdata->issue_dsa_head = - hostdata->issue_dsa_tail = NULL; + hostdata->issue_dsa_head = NULL; + hostdata->issue_dsa_tail = NULL; if (hostdata->init_save_regs) hostdata->init_save_regs (host); @@ -688,11 +676,11 @@ struct Scsi_Host *instance; struct NCR53c7x0_hostdata *hostdata; 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; - options |= PERM_OPTIONS; + options |= perm_options; switch (chip) { case 825: @@ -700,6 +688,7 @@ case 815: case 810: script_len = NCR53c8xx_script_len; + dsa_len = NCR53c8xx_dsa_len; options |= OPTION_INTFLY; sprintf (chip_str, "NCR53c%d", chip); break; @@ -718,7 +707,7 @@ if ((chip / 100 == 8) && !pci_valid) printk ("scsi-ncr53c7,8xx : for better reliability and performance, please use the\n" " PCI override instead.\n" - " Syntax : ncr53c8{10,20,25}=pci,,,\n" + " Syntax : ncr53c8{10,15,20,25}=pci,,,\n" " and are usually 0.\n"); if (options & OPTION_DEBUG_PROBE_ONLY) { @@ -726,9 +715,50 @@ 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); + 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 *) instance->hostdata; hostdata->size = size; @@ -784,7 +814,18 @@ instance->dma_channel = dma; 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); } @@ -796,7 +837,7 @@ * Purpose : initializes a NCR53c800 family based on the PCI * bus, device, and function location of it. Allows * 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 * a supported chip, but the DEVICE ID has changed so it @@ -815,7 +856,8 @@ unsigned short vendor_id, device_id, command; unsigned long base, io_port; 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; printk("scsi-ncr53c7,8xx : at PCI bus %d, device %d, function %d\n", @@ -870,6 +912,8 @@ io_port = 0; } else io_port &= PCI_BASE_ADDRESS_IO_MASK; + } else { + io_port = 0; } if (command & PCI_COMMAND_MEMORY) { @@ -879,6 +923,8 @@ base = 0; } else base &= PCI_BASE_ADDRESS_MEM_MASK; + } else { + base = 0; } if (!io_port && !base) { @@ -932,7 +978,6 @@ */ int NCR53c7xx_detect(Scsi_Host_Template *tpnt) { - short current_chip; int i; int current_override; int count; /* Number of boards detected */ @@ -979,6 +1024,7 @@ #include "53c8xx_d.h" 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) @@ -989,7 +1035,8 @@ * */ -static void NCR53c8x0_init_fixup (struct Scsi_Host *host) { +static void +NCR53c8x0_init_fixup (struct Scsi_Host *host) { NCR53c7x0_local_declare(); struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) host->hostdata; @@ -1008,6 +1055,16 @@ for (i = 0; i < PATCHES; ++i) hostdata->script[LABELPATCHES[i]] += (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. @@ -1037,10 +1094,6 @@ 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_sfbr, base + SFBR_REG); patch_abs_32 (hostdata->script, 0, addr_temp, base + TEMP_REG); @@ -1059,11 +1112,15 @@ 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_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, reconnect_dsa_head, (long) &(hostdata->reconnect_dsa_head)); - 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, reconnect_dsa_head, + (long) &(hostdata->reconnect_dsa_head)); + 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_src, (long) &(hostdata->test_source)); @@ -1145,17 +1202,18 @@ struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) host->hostdata; unsigned long timeout, start; - int old_level, failed, i; + int failed, i; + unsigned long flags; + NCR53c7x0_local_setup(host); - printk("scsi%d : testing\n", host->host_no); - /* The NCR chip _must_ be idle to run the test scripts */ - old_level = splx(0); + save_flags(flags); + cli(); if (!hostdata->idle) { printk ("scsi%d : chip not idle, aborting tests\n", host->host_no); - splx(old_level); + restore_flags(flags); return -1; } @@ -1181,7 +1239,7 @@ printk ("scsi%d : test 1", host->host_no); NCR53c7x0_write32 (DSP_REG, start); printk (" started\n"); - splx(7); + sti(); timeout = jiffies + 50; /* arbitrary */ while ((hostdata->test_completed == -1) && jiffies < timeout); @@ -1217,7 +1275,7 @@ (unsigned long) hostdata->script, start); printk ("scsi%d : DSPS = 0x%lx\n", host->host_no, (unsigned long) NCR53c7x0_read32(DSPS_REG)); - splx(old_level); + restore_flags(flags); return -1; } hostdata->test_running = 0; @@ -1253,10 +1311,10 @@ dsa[11] = (unsigned long) &msg; for (i = 0; i < 3; ++i) { - splx(0); + cli(); if (!hostdata->idle) { printk ("scsi%d : chip not idle, aborting tests\n", host->host_no); - splx(old_level); + restore_flags(flags); return -1; } @@ -1269,7 +1327,7 @@ hostdata->state = STATE_RUNNING; NCR53c7x0_write32 (DSA_REG, (unsigned long) dsa); NCR53c7x0_write32 (DSP_REG, start); - splx(7); + sti(); timeout = jiffies + 500; /* arbitrary */ while ((hostdata->test_completed == -1) && jiffies < timeout); @@ -1289,12 +1347,12 @@ host->host_no, i); if (!hostdata->idle) { printk("scsi%d : not idle\n", host->host_no); - splx(old_level); + restore_flags(flags); return -1; } } else if (hostdata->test_completed == -1) { printk ("scsi%d : test 2 timed out\n", host->host_no); - splx(old_level); + restore_flags(flags); return -1; } hostdata->test_running = 0; @@ -1305,9 +1363,8 @@ } } } - printk ("scsi%d : tests complete.\n", host->host_no); - splx(old_level); + restore_flags(flags); return 0; } @@ -1364,11 +1421,12 @@ struct Scsi_Host *host = c->host; struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) host->hostdata; - int old_level; + unsigned long flags; char **prev, *search; int i; - old_level = splx(0); + save_flags(flags); + cli(); for (i = 0; i < 2; ++i) { for (search = (char *) (i ? hostdata->issue_dsa_head : hostdata->reconnect_dsa_head), prev = (char **) (i ? @@ -1390,21 +1448,14 @@ if (hostdata->running_list == cmd) hostdata->running_list = cmd->next; - if (!scan_scsis_buf_busy) { -#ifdef SCSI_MALLOC - scsi_free ((void *) cmd->real, cmd->size); -#else - kfree_s (cmd->real, cmd->size); -#endif - } else { - scan_scsis_buf_busy = 0; - } + cmd->next = hostdata->free; + hostdata->free = cmd; c->host_scribble = NULL; c->result = result; c->scsi_done(c); - splx(old_level); + restore_flags(flags); } /* @@ -1429,7 +1480,7 @@ unsigned long *dsp; struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) host->hostdata; - int old_level; + unsigned long flags; NCR53c7x0_local_setup(host); /* @@ -1437,8 +1488,8 @@ * dump the appropriate debugging information to standard * output. */ - - old_level = splx(0); + save_flags(flags); + cli(); dsp = (unsigned long *) NCR53c7x0_read32(DSP_REG); for (bp = hostdata->breakpoints; bp && bp->address != dsp; bp = bp->next); @@ -1460,7 +1511,7 @@ * instruction in bytes. */ - splx(old_level); + restore_flags(flags); } /* @@ -1575,7 +1626,7 @@ hostdata->sync[target].select_indirect = (scntl3 << 24) | (target << 16) | (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 */ if ((hostdata->chip / 100) == 8) { @@ -1630,7 +1681,7 @@ printk ("scsi%d : message", host->host_no); if (cmd) printk (" from target %d lun %d", c->target, c->lun); - print_msg (hostdata->msg_buf); + print_msg ((unsigned char *) hostdata->msg_buf); printk("\n"); switch (hostdata->msg_buf[0]) { /* @@ -1665,7 +1716,8 @@ */ if (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 / sizeof(long); hostdata->dsp_changed = 1; @@ -1673,7 +1725,8 @@ } else { if (hostdata->options & OPTION_SYNCHRONOUS) { cmd->flags |= CMD_FLAG_DID_SDTR; - synchronous (host, c->target, hostdata->msg_buf); + synchronous (host, c->target, (unsigned char *) + hostdata->msg_buf); } else { hostdata->msg_buf[4] = 0; /* 0 offset = async */ } @@ -1948,15 +2001,16 @@ struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) instance->hostdata; struct NCR53c7x0_break *bp, **prev; - int old_level; - old_level = splx(0); + unsigned long flags; + save_flags(flags); + cli(); for (bp = (struct NCR53c7x0_break *) instance->breakpoints, prev = (struct NCR53c7x0_break **) &instance->breakpoints; bp; prev = (struct NCR53c7x0_break **) &(bp->next), bp = (struct NCR53c7x0_break *) bp->next); if (!bp) { - splx(old_level); + restore_flags(flags); return -EIO; } @@ -1969,7 +2023,7 @@ if (prev) *prev = bp->next; - splx(old_level); + restore_flags(flags); return 0; } @@ -1981,7 +2035,7 @@ struct NCR53c7x0_break *bp; char buf[80]; size_t len; - int old_level; + unsigned long flags; /* * XXX - we need to insure that the processor is halted * here in order to prevent a race condition. So, if the @@ -1992,7 +2046,8 @@ host->host_no); debugger_kernel_write (host, buf, strlen(buf)); - old_level=splx(0); + save_flags(flags); + cli(); for (bp = (struct NCR53c7x0_break *) host->breakpoints; bp; bp = (struct NCR53c7x0_break *) bp->next); { sprintf (buf, "scsi%d : bp : success : at %08x, replaces %08x %08x", @@ -2007,7 +2062,7 @@ len = strlen(buf); debugger_kernel_write (host, buf, len); } - splx(old_level); + restore_flags(flags); return 0; } @@ -2018,20 +2073,21 @@ struct NCR53c7x0_break *bp; char buf[80]; size_t len; - int old_level; - old_level=splx(0); + unsigned long flags; + save_flags(flags); + cli(); if (hostdata->state != STATE_HALTED) { sprintf (buf, "scsi%d : bs : failure : NCR not halted\n", host->host_no); debugger_kernel_write (host, buf, strlen(buf)); - splx(old_level); + restore_flags(flags); return -1; } if (!(bp = kmalloc (sizeof (struct NCR53c7x0_break)))) { printk ("scsi%d : kmalloc(%d) of breakpoint structure failed, try again\n", host->host_no, sizeof(struct NCR53c7x0_break)); - splx(old_level); + restore_flags(flags); return -1; } @@ -2043,7 +2099,7 @@ hostdata->breakpoints = bp->next; memcpy ((void *) bp->address, (void *) hostdata->E_debug_break, 8); - splx(old_level); + restore_flags(flags); return 0; } @@ -2132,9 +2188,10 @@ buflen) { struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) host->hostdata; - int copy, left, old_level; - - old_level = splx(0); + int copy, left; + unsigned long flags; + save_flags(flags); + cli(); while (buflen) { left = (hostdata->debug_buf + hostdata->debug_size - 1) - hostdata->debug_write; @@ -2147,7 +2204,7 @@ (hostdata->debug_buf + hostdata->debug_size)) hosdata->debug_write = hostdata->debug_buf; } - (void) splx(old_level); + restore_flags(flags); } #endif /* def NCRDEBUG */ @@ -2164,7 +2221,8 @@ * */ -static void NCR53c8x0_soft_reset (struct Scsi_Host *host) { +static void +NCR53c8x0_soft_reset (struct Scsi_Host *host) { NCR53c7x0_local_declare(); struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) host->hostdata; @@ -2187,14 +2245,18 @@ /* - * Respond to selection and reselection by targets and - * use our _initiator_ SCSI ID for arbitration. + * Respond to reselection by targets and use our _initiator_ SCSI ID + * for arbitration. If notyet, also respond to SCSI selection. * * XXX - Note : we must reprogram this when reselecting as * a target. */ +#ifdef notyet 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); /* @@ -2222,8 +2284,7 @@ NCR53c7x0_write8(SIEN0_REG_800, ((hostdata->options & OPTION_PARITY) ? - SIEN_PAR : 0) | SIEN_RST | SIEN_UDC | SIEN_SGE | SIEN_800_SEL | - SIEN_800_RESEL | SIEN_MA); + SIEN_PAR : 0) | SIEN_RST | SIEN_UDC | SIEN_SGE | SIEN_MA); NCR53c7x0_write8(SIEN1_REG_800, SIEN1_800_STO | SIEN1_800_HTH); /* @@ -2243,11 +2304,13 @@ /* * Function static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) * - * Purpose : Using scsi_malloc() if the system is initialized, - * scan_scsis_buf if not, allocate space to store the variable - * length NCR53c7x0_cmd structure. Initialize it based on - * the Scsi_Cmnd structure passed in, including dsa and - * Linux field initialization, and dsa code relocation. + * Purpose : If we have not allready allocated enough NCR53c7x0_cmd + * structures to satisfy any allowable number of simultaenous + * commands for this host; do so (using either scsi_malloc() + * or kmalloc() depending on configuration), and add them to the + * 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 * @@ -2255,26 +2318,86 @@ * NULL on failure. */ -static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) { +static struct NCR53c7x0_cmd * +create_cmd (Scsi_Cmnd *cmd) { NCR53c7x0_local_declare(); struct Scsi_Host *host = cmd->host; struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) host->hostdata; - int size; /* Size of *tmp */ - struct NCR53c7x0_cmd *tmp; /* NCR53c7x0_cmd structure for this command */ + struct NCR53c7x0_cmd *tmp = NULL; /* NCR53c7x0_cmd structure for this command */ int datain, /* Number of instructions per phase */ dataout; int data_transfer_instructions, /* Count of dynamic instructions */ - i, /* Counter */ - alignment; /* Alignment adjustment (0 - 4) */ + i; /* Counter */ unsigned long *cmd_datain, /* Address of datain/dataout code */ *cmd_dataout; /* Incremented as we assemble */ +#ifdef notyet void *real; /* Real address */ + int size; /* Size of *tmp */ + int alignment; /* Alignment adjustment (0 - 4) */ +#endif + unsigned long flags; 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 */ @@ -2323,10 +2446,6 @@ 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 * to return control to other_transfer. We also need a MOVE @@ -2344,63 +2463,11 @@ if (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. */ - tmp->size = size; tmp->cmd = cmd; tmp->next = NULL; tmp->prev = NULL; @@ -2434,7 +2501,7 @@ patch_dsa_32(tmp->dsa, dsa_select, 0, hostdata->sync[cmd->target]. 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. */ patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1); @@ -2462,7 +2529,7 @@ 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, 1, - &NCR53c7xx_msg_nop); + &(hostdata->NCR53c7xx_msg_nop)); /* @@ -2486,8 +2553,8 @@ #endif /* - * XXX - I'm undecided weather all of this nonsense is faster - * in the long run, or weather I should just go and implement a loop + * XXX - I'm undecided whether all of this nonsense is faster + * in the long run, or whether I should just go and implement a loop * on the NCR chip using table indirect mode? * * In any case, this is how it _must_ be done for 53c700/700-66 chips, @@ -2516,8 +2583,8 @@ cmd_datain[2] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL | DCMD_TCI_CD | DCMD_TCI_IO | DCMD_TCI_MSG) << 24) | DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE | DBC_TCI_TRUE; - cmd_datain[3] = hostdata->script + hostdata->E_msg_in / - sizeof(long); + cmd_datain[3] = (unsigned long) hostdata->script + + hostdata->E_msg_in; #if 0 print_insn (host, cmd_datain, "dynamic ", 1); print_insn (host, cmd_datain + 2, "dynamic ", 1); @@ -2530,8 +2597,8 @@ cmd_dataout[2] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL | DCMD_TCI_CD | DCMD_TCI_IO | DCMD_TCI_MSG) << 24) | DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE | DBC_TCI_TRUE; - cmd_dataout[3] = hostdata->script + hostdata->E_msg_in / - sizeof(long); + cmd_dataout[3] = (unsigned long) hostdata->script + + hostdata->E_msg_in; #if 0 print_insn (host, cmd_dataout, "dynamic ", 1); print_insn (host, cmd_dataout + 2, "dynamic ", 1); @@ -2548,8 +2615,8 @@ if (datain) { cmd_datain[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP) << 24) | DBC_TCI_TRUE; - cmd_datain[1] = hostdata->script + hostdata->E_other_transfer - / sizeof(long); + cmd_datain[1] = (unsigned long) hostdata->script + + hostdata->E_other_transfer; #if 0 print_insn (host, cmd_datain, "dynamic jump ", 1); #endif @@ -2567,8 +2634,8 @@ if (dataout) { cmd_dataout[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP) << 24) | DBC_TCI_TRUE; - cmd_dataout[1] = hostdata->script + hostdata->E_other_transfer - / sizeof(long); + cmd_dataout[1] = (unsigned long) hostdata->script + + hostdata->E_other_transfer; #if 0 print_insn (host, cmd_dataout, "dynamic jump ", 1); #endif @@ -2603,7 +2670,7 @@ struct Scsi_Host *host = cmd->host; struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) host->hostdata; - int old_level; + unsigned long flags; unsigned char target_was_busy; NCR53c7x0_local_setup(host); @@ -2671,7 +2738,8 @@ * valid while the condition exists. */ - old_level = splx(0); + save_flags(flags); + cli(); /* * Consider a target busy if there are _any_ commands running @@ -2764,7 +2832,7 @@ tmp->next; tmp = (struct NCR53c7x0_cmd *) tmp->next); tmp->next = tmp; } - splx(old_level); + restore_flags(flags); return 0; } @@ -2848,9 +2916,9 @@ if (sstat0_sist0 & SSTAT0_UDC) { fatal = 1; - printk("scsi%d : target %d lun %d unexpected disconnect\n", - host->host_no, cmd->cmd->target, cmd->cmd->lun); 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); } hostdata->dsp = hostdata->script + hostdata->E_schedule / @@ -2950,7 +3018,7 @@ should terminate */ int interrupted = 0; /* This HA generated an interrupt */ - int old_level; + unsigned long flags; #ifdef NCR_DEBUG char buf[80]; /* Debugging sprintf buffer */ @@ -3011,12 +3079,14 @@ */ - old_level = splx(0); + save_flags(flags); + cli(); restart: for (cmd_prev_ptr = (struct NCR53c7x0_cmd **) - &(hostdata->running_list), cmd = (struct NCR53c7x0_cmd *) - hostdata->running_list; cmd ; cmd_prev_ptr = - &(cmd->next), cmd = (struct NCR53c7x0_cmd *) cmd->next) { + &(hostdata->running_list), cmd = + (struct NCR53c7x0_cmd *) hostdata->running_list; cmd ; + cmd_prev_ptr = (struct NCR53c7x0_cmd **) &(cmd->next), + cmd = (struct NCR53c7x0_cmd *) cmd->next) { Scsi_Cmnd *tmp; if (!cmd) { @@ -3045,7 +3115,7 @@ if (cmd->prev) cmd->prev->next = cmd->next; if (cmd_prev_ptr) - *cmd_prev_ptr = cmd->next; + *cmd_prev_ptr = (struct NCR53c7x0_cmd *) cmd->next; #ifdef LUN_BUSY /* Check for next command for target, add to issue queue */ @@ -3054,16 +3124,8 @@ #endif - if (!scan_scsis_buf_busy) { -#ifdef SCSI_MALLOC - scsi_free ((void *) cmd->real, cmd->size); -#else - kfree_s ((void *) cmd->real, cmd->size); -#endif - } else { - scan_scsis_buf_busy = 0; - } - + cmd->next = hostdata->free; + hostdata->free = cmd; tmp->host_scribble = NULL; @@ -3081,7 +3143,7 @@ goto restart; } - splx(old_level); + restore_flags(flags); if (!search_found) { printk ("scsi%d : WARNING : INTFLY with no completed commands.\n", @@ -3204,7 +3266,8 @@ * */ -static int abort_connected (struct Scsi_Host *host) { +static int +abort_connected (struct Scsi_Host *host) { struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) host->hostdata; @@ -3398,15 +3461,13 @@ NCR53c7x0_local_declare(); struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) host->hostdata; - unsigned char dstat, /* DSTAT */ - dbc_dcmd; /* DCMD (high eight bits) + DBC */ + unsigned char dstat; /* DSTAT */ unsigned long *dsp, *next_dsp, /* Current dsp */ - *dsa; - - - int ipl, /* Old ipl from splx(0) */ - tmp; + *dsa, + dbc_dcmd; /* DCMD (high eight bits) + DBC */ + int tmp; + unsigned long flags; NCR53c7x0_local_setup(host); if (!hostdata->dstat_valid) { @@ -3460,12 +3521,13 @@ if (hostdata->options & OPTION_DEBUG_TRACE) { } else if (hostdata->options & OPTION_DEBUG_SINGLE) { 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? */ NCR53c7x0_write8 (DCNTL_REG, (NCR53c7x0_read8(DCNTL_REG) & ~DCNTL_SSM) | DCNTL_STD); - splx(ipl); + restore_flags(flags); } else { printk("scsi%d : unexpected single step interrupt at\n" " ", host->host_no); @@ -3654,9 +3716,10 @@ struct Scsi_Host *host = cmd->host; struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) host->hostdata; - int old_level; + unsigned long flags; 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 @@ -3668,28 +3731,23 @@ * pull the command out of the old queue, and call it aborted. */ - for (curr = hostdata->issue_queue, prev = &(hostdata->issue_queue); - curr && curr->cmd != cmd; prev = &(curr->next), curr = curr->next); + for (curr = (struct NCR53c7x0_cmd *) hostdata->issue_queue, + 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) { - *prev = curr->next; + *prev = (struct NCR53c7x0_cmd *) curr->next; /* XXX - get rid of DLL ? */ if (curr->prev) curr->prev->next = curr->next; - if (!scan_scsis_buf_busy) { -#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; - } + curr->next = hostdata->free; + hostdata->free = curr; cmd->result = 0; cmd->scsi_done(cmd); - splx(old_level); + restore_flags(flags); return SCSI_ABORT_SUCCESS; } @@ -3698,11 +3756,13 @@ * commands. If this is the case, drastic measures are called for. */ - for (curr = hostdata->running_list, prev = &(hostdata->running_list); - curr && curr->cmd != cmd; prev = &(curr->next), curr = curr->next); + for (curr = (struct NCR53c7x0_cmd *) hostdata->running_list, + 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) { - splx(old_level); + restore_flags(flags); printk ("scsi%d : DANGER : command in running list, can not abort.\n", cmd->host->host_no); return SCSI_ABORT_SNOOZE; @@ -3715,16 +3775,8 @@ */ curr = (struct NCR53c7x0_cmd *) cmd->host_scribble; - - if (!scan_scsis_buf_busy) { -#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; - } + curr->next = hostdata->free; + hostdata->free = curr; if (((cmd->result & 0xff00) == 0xff00) || ((cmd->result & 0xff) == 0xff)) { @@ -3734,7 +3786,7 @@ host->host_no); } cmd->scsi_done(cmd); - splx(old_level); + restore_flags(flags); return SCSI_ABORT_SNOOZE; } @@ -3749,17 +3801,47 @@ * Returns : 0 on success. */ -int NCR53c7xx_reset (Scsi_Cmnd *cmd) { +int +NCR53c7xx_reset (Scsi_Cmnd *cmd) { 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 *) host->hostdata : NULL; - if (host) NCR53c7x0_local_setup(host); - + (struct NCR53c7x0_hostdata *) host->hostdata : NULL; + 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", cmd->host->host_no); - return SCSI_RESET_SNOOZE; + return SCSI_RESET_SUCCESS; } /* @@ -3770,13 +3852,11 @@ static void print_dsa (struct Scsi_Host *host, unsigned long *dsa) { struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) host->hostdata; - Scsi_Cmnd * cmd; - struct NCR53c7x0_cmd * c; int i, len; char *ptr; 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, dsa[hostdata->dsa_msgout / sizeof(long)], dsa[hostdata->dsa_msgout / sizeof(long) + 1]); @@ -3790,3 +3870,108 @@ } } +/* + * 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 */ diff -u --recursive --new-file v1.2.5/linux/drivers/scsi/53c7,8xx.h linux/drivers/scsi/53c7,8xx.h --- v1.2.5/linux/drivers/scsi/53c7,8xx.h Wed Jan 25 09:06:17 1995 +++ linux/drivers/scsi/53c7,8xx.h Mon Apr 17 13:47:57 1995 @@ -46,20 +46,27 @@ * array. */ -#ifdef HOSTS_C +#if defined(HOSTS_C) || defined(MODULE) #include extern int NCR53c7xx_abort(Scsi_Cmnd *); extern int NCR53c7xx_detect(Scsi_Host_Template *tpnt); extern int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); extern int NCR53c7xx_reset(Scsi_Cmnd *); - -#define NCR53c7xx {NULL, NULL, "NCR53c{7,8}xx (rel 3)", NCR53c7xx_detect, \ - 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} +#ifdef MODULE +extern int NCR53c7xx_release(struct Scsi_Host *); #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 */ @@ -932,6 +939,9 @@ struct NCR53c7x0_cmd { 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 structure, Scsi_Cmnd points at NCR53c7x0_cmd using @@ -949,7 +959,11 @@ */ - 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 */ @@ -986,10 +1000,12 @@ /* Indicates that the NCR is executing other code. */ #define STATE_RUNNING 2 /* - * Indicates that the NCR was being aborted. Only used when running - * NCR53c700 compatible scripts. + * Indicates that the NCR was being aborted. */ #define STATE_ABORTING 3 +/* + * Indicates that the NCR was successfully aborted. */ +#define STATE_ABORTED 4 /* @@ -1072,6 +1088,7 @@ 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 @@ -1160,11 +1177,13 @@ *breakpoint_current; /* Current breakpoint being stepped through, NULL if we are running normally. */ +#ifdef NCR_DEBUG int debug_size; /* Size of debug buffer */ volatile int debug_count; /* Current data count */ volatile char *debug_buf; /* Output ring buffer */ volatile char *debug_write; /* Current write pointer */ volatile char *debug_read; /* Current read pointer */ +#endif /* def NCR_DEBUG */ /* XXX - primitive debugging junk, remove when working ? */ int debug_print_limit; /* Number of commands to print @@ -1203,6 +1222,21 @@ nexus, ONLY valid for 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 executing on each target */ @@ -1226,13 +1260,21 @@ volatile unsigned char msg_buf[16]; /* buffer for messages other than the command complete message */ - volatile struct NCR53c7x0_cmd *reconnect_dsa_head; + volatile unsigned char *reconnect_dsa_head; /* disconnected commands, maintained by NCR */ /* Data identifying nexus we are trying to match during reselection */ volatile unsigned char reselected_identify; /* IDENTIFY message */ volatile unsigned char reselected_tag; /* second byte of queue tag 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 */ unsigned long script[0]; /* Relocated SCSI script */ diff -u --recursive --new-file v1.2.5/linux/drivers/scsi/53c7,8xx.scr linux/drivers/scsi/53c7,8xx.scr --- v1.2.5/linux/drivers/scsi/53c7,8xx.scr Thu Mar 9 20:37:34 1995 +++ linux/drivers/scsi/53c7,8xx.scr Mon Apr 17 13:52:38 1995 @@ -221,10 +221,10 @@ ABSOLUTE int_test_2 = 0x04010000 ; Test 2 complete ABSOLUTE int_test_3 = 0x04020000 ; Test 3 complete -EXTERNAL NCR53c7xx_msg_abort ; Pointer to abort message -EXTERNAL NCR53c7xx_msg_reject ; Pointer to reject message -EXTERNAL NCR53c7xx_zero ; long with zero in it, use for source -EXTERNAL NCR53c7xx_sink ; long to dump worthless data in +ABSOLUTE NCR53c7xx_msg_abort = 0 ; Pointer to abort message +ABSOLUTE NCR53c7xx_msg_reject = 0 ; Pointer to reject message +ABSOLUTE NCR53c7xx_zero = 0 ; long with zero in it, use for source +ABSOLUTE NCR53c7xx_sink = 0 ; long to dump worthless data in ; Pointer to final bytes of multi-byte messages ABSOLUTE msg_buf = 0 @@ -881,13 +881,23 @@ wait_reselect_failed: ; Reading CTEST2 clears the SIG_P bit in the ISTAT register. 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 select_failed: - MOVE ISTAT & 0x20 TO SFBR - JUMP reselected, IF NOT 0x20 - MOVE ISTAT & 0xdf TO ISTAT +; 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 + 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 ; @@ -980,7 +990,10 @@ ; If DSP points here, and a phase mismatch is encountered, we need to ; do a bus reset. ; + + MOVE SCNTL2 & 0x7f TO SCNTL2 MOVE 1, NCR53c7xx_msg_abort, WHEN MSG_OUT + WAIT DISCONNECT INT int_norm_aborted ; diff -u --recursive --new-file v1.2.5/linux/drivers/scsi/53c8xx_d.h linux/drivers/scsi/53c8xx_d.h --- v1.2.5/linux/drivers/scsi/53c8xx_d.h Thu Mar 9 20:37:34 1995 +++ linux/drivers/scsi/53c8xx_d.h Mon Apr 17 13:52:55 1995 @@ -127,7 +127,7 @@ /* CALL scratch_to_dsa -at 0x0000000a : */ 0x88080000,0x00000800, +at 0x0000000a : */ 0x88080000,0x00000830, /* JUMP reselected_check_next @@ -283,10 +283,10 @@ ABSOLUTE int_test_2 = 0x04010000 ; Test 2 complete ABSOLUTE int_test_3 = 0x04020000 ; Test 3 complete -EXTERNAL NCR53c7xx_msg_abort ; Pointer to abort message -EXTERNAL NCR53c7xx_msg_reject ; Pointer to reject message -EXTERNAL NCR53c7xx_zero ; long with zero in it, use for source -EXTERNAL NCR53c7xx_sink ; long to dump worthless data in +ABSOLUTE NCR53c7xx_msg_abort = 0 ; Pointer to abort message +ABSOLUTE NCR53c7xx_msg_reject = 0 ; Pointer to reject message +ABSOLUTE NCR53c7xx_zero = 0 ; long with zero in it, use for source +ABSOLUTE NCR53c7xx_sink = 0 ; long to dump worthless data in ; Pointer to final bytes of multi-byte messages ABSOLUTE msg_buf = 0 @@ -325,7 +325,7 @@ ; 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 ; carry instruction, by moving around the DSA alignment to avoid @@ -370,7 +370,7 @@ ; And update the head pointer. CALL dsa_to_scratch -at 0x00000041 : */ 0x88080000,0x000007b8, +at 0x00000041 : */ 0x88080000,0x000007e8, /* MOVE dmode_ncr_to_memory TO DMODE @@ -422,7 +422,7 @@ CALL scratch_to_dsa -at 0x00000053 : */ 0x88080000,0x00000800, +at 0x00000053 : */ 0x88080000,0x00000830, /* @@ -514,7 +514,7 @@ SELECT ATN FROM dsa_select, select_failed -at 0x00000067 : */ 0x4300003c,0x00000694, +at 0x00000067 : */ 0x4300003c,0x000006a4, /* JUMP select_msgout, WHEN MSG_OUT @@ -539,7 +539,7 @@ CALL dsa_to_scratch -at 0x0000006d : */ 0x88080000,0x000007b8, +at 0x0000006d : */ 0x88080000,0x000007e8, /* MOVE SCRATCH0 + dsa_next TO SCRATCH0 @@ -711,7 +711,7 @@ do_dataout: CALL dsa_to_scratch -at 0x0000009b : */ 0x88080000,0x000007b8, +at 0x0000009b : */ 0x88080000,0x000007e8, /* MOVE SCRATCH0 + dsa_dataout TO SCRATCH0 @@ -756,7 +756,7 @@ do_datain: CALL dsa_to_scratch -at 0x000000b1 : */ 0x88080000,0x000007b8, +at 0x000000b1 : */ 0x88080000,0x000007e8, /* MOVE SCRATCH0 + dsa_datain TO SCRATCH0 @@ -1100,7 +1100,7 @@ /* MOVE 1, NCR53c7xx_msg_reject, WHEN MSG_OUT -at 0x00000132 : */ 0x0e000001,((unsigned long)&NCR53c7xx_msg_reject), +at 0x00000132 : */ 0x0e000001,0x00000000, /* RETURN @@ -1295,7 +1295,7 @@ reselected_notag: MOVE MEMORY 1, NCR53c7xx_zero, reselected_tag -at 0x0000015c : */ 0xc0000001,((unsigned long)&NCR53c7xx_zero),0x00000000, +at 0x0000015c : */ 0xc0000001,0x00000000,0x00000000, /* @@ -1317,7 +1317,7 @@ /* CALL scratch_to_dsa -at 0x00000166 : */ 0x88080000,0x00000800, +at 0x00000166 : */ 0x88080000,0x00000830, /* ; Fix the update-next pointer so that the reconnect_dsa_head @@ -1477,31 +1477,53 @@ 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 -at 0x000001a3 : */ 0x80080000,0x00000130, +at 0x000001a7 : */ 0x80080000,0x00000130, /* 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 -at 0x000001ab : */ 0x80080000,0x00000130, +at 0x000001b3 : */ 0x80080000,0x00000130, /* ; @@ -1525,11 +1547,11 @@ test_1: MOVE MEMORY 4, test_src, test_dest -at 0x000001ad : */ 0xc0000004,0x00000000,0x00000000, +at 0x000001b5 : */ 0xc0000004,0x00000000,0x00000000, /* INT int_test_1 -at 0x000001b0 : */ 0x98080000,0x04000000, +at 0x000001b8 : */ 0x98080000,0x04000000, /* ; @@ -1540,61 +1562,61 @@ test_2: CLEAR TARGET -at 0x000001b2 : */ 0x60000200,0x00000000, +at 0x000001ba : */ 0x60000200,0x00000000, /* SELECT ATN FROM 0, test_2_fail -at 0x000001b4 : */ 0x43000000,0x00000720, +at 0x000001bc : */ 0x43000000,0x00000740, /* JUMP test_2_msgout, WHEN MSG_OUT -at 0x000001b6 : */ 0x860b0000,0x000006e0, +at 0x000001be : */ 0x860b0000,0x00000700, /* ENTRY test_2_msgout test_2_msgout: MOVE FROM 8, WHEN MSG_OUT -at 0x000001b8 : */ 0x1e000000,0x00000008, +at 0x000001c0 : */ 0x1e000000,0x00000008, /* MOVE FROM 16, WHEN CMD -at 0x000001ba : */ 0x1a000000,0x00000010, +at 0x000001c2 : */ 0x1a000000,0x00000010, /* MOVE FROM 24, WHEN DATA_IN -at 0x000001bc : */ 0x19000000,0x00000018, +at 0x000001c4 : */ 0x19000000,0x00000018, /* MOVE FROM 32, WHEN STATUS -at 0x000001be : */ 0x1b000000,0x00000020, +at 0x000001c6 : */ 0x1b000000,0x00000020, /* MOVE FROM 40, WHEN MSG_IN -at 0x000001c0 : */ 0x1f000000,0x00000028, +at 0x000001c8 : */ 0x1f000000,0x00000028, /* MOVE SCNTL2 & 0x7f TO SCNTL2 -at 0x000001c2 : */ 0x7c027f00,0x00000000, +at 0x000001ca : */ 0x7c027f00,0x00000000, /* CLEAR ACK -at 0x000001c4 : */ 0x60000040,0x00000000, +at 0x000001cc : */ 0x60000040,0x00000000, /* WAIT DISCONNECT -at 0x000001c6 : */ 0x48000000,0x00000000, +at 0x000001ce : */ 0x48000000,0x00000000, /* test_2_fail: INT int_test_2 -at 0x000001c8 : */ 0x98080000,0x04010000, +at 0x000001d0 : */ 0x98080000,0x04010000, /* ENTRY debug_break debug_break: INT int_debug_break -at 0x000001ca : */ 0x98080000,0x03000000, +at 0x000001d2 : */ 0x98080000,0x03000000, /* ; @@ -1610,26 +1632,26 @@ target_abort: SET TARGET -at 0x000001cc : */ 0x58000200,0x00000000, +at 0x000001d4 : */ 0x58000200,0x00000000, /* DISCONNECT -at 0x000001ce : */ 0x48000000,0x00000000, +at 0x000001d6 : */ 0x48000000,0x00000000, /* CLEAR TARGET -at 0x000001d0 : */ 0x60000200,0x00000000, +at 0x000001d8 : */ 0x60000200,0x00000000, /* JUMP schedule -at 0x000001d2 : */ 0x80080000,0x00000130, +at 0x000001da : */ 0x80080000,0x00000130, /* ENTRY initiator_abort initiator_abort: SET ATN -at 0x000001d4 : */ 0x58000008,0x00000000, +at 0x000001dc : */ 0x58000008,0x00000000, /* ; In order to abort the currently established nexus, we ; need to source/sink up to one byte of data in any SCSI phase, @@ -1637,60 +1659,69 @@ ; false->true JUMP no_eat_cmd, WHEN NOT CMD -at 0x000001d6 : */ 0x82030000,0x00000768, +at 0x000001de : */ 0x82030000,0x00000788, /* MOVE 1, NCR53c7xx_zero, WHEN CMD -at 0x000001d8 : */ 0x0a000001,((unsigned long)&NCR53c7xx_zero), +at 0x000001e0 : */ 0x0a000001,0x00000000, /* no_eat_cmd: JUMP no_eat_msg, WHEN NOT MSG_IN -at 0x000001da : */ 0x87030000,0x00000778, +at 0x000001e2 : */ 0x87030000,0x00000798, /* MOVE 1, NCR53c7xx_sink, WHEN MSG_IN -at 0x000001dc : */ 0x0f000001,((unsigned long)&NCR53c7xx_sink), +at 0x000001e4 : */ 0x0f000001,0x00000000, /* no_eat_msg: JUMP no_eat_data, WHEN NOT DATA_IN -at 0x000001de : */ 0x81030000,0x00000788, +at 0x000001e6 : */ 0x81030000,0x000007a8, /* MOVE 1, NCR53c7xx_sink, WHEN DATA_IN -at 0x000001e0 : */ 0x09000001,((unsigned long)&NCR53c7xx_sink), +at 0x000001e8 : */ 0x09000001,0x00000000, /* no_eat_data: JUMP no_eat_status, WHEN NOT STATUS -at 0x000001e2 : */ 0x83030000,0x00000798, +at 0x000001ea : */ 0x83030000,0x000007b8, /* MOVE 1, NCR53c7xx_sink, WHEN STATUS -at 0x000001e4 : */ 0x0b000001,((unsigned long)&NCR53c7xx_sink), +at 0x000001ec : */ 0x0b000001,0x00000000, /* no_eat_status: JUMP no_source_data, WHEN NOT DATA_OUT -at 0x000001e6 : */ 0x80030000,0x000007a8, +at 0x000001ee : */ 0x80030000,0x000007c8, /* MOVE 1, NCR53c7xx_zero, WHEN DATA_OUT -at 0x000001e8 : */ 0x08000001,((unsigned long)&NCR53c7xx_zero), +at 0x000001f0 : */ 0x08000001,0x00000000, /* no_source_data: ; ; If DSP points here, and a phase mismatch is encountered, we need to ; do a bus reset. ; + + MOVE SCNTL2 & 0x7f TO SCNTL2 + +at 0x000001f2 : */ 0x7c027f00,0x00000000, +/* 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 -at 0x000001ec : */ 0x98080000,0x02040000, +at 0x000001f8 : */ 0x98080000,0x02040000, /* ; @@ -1711,77 +1742,101 @@ dsa_to_scratch: MOVE DSA0 TO SFBR -at 0x000001ee : */ 0x72100000,0x00000000, +at 0x000001fa : */ 0x72100000,0x00000000, /* MOVE SFBR TO SCRATCH0 -at 0x000001f0 : */ 0x6a340000,0x00000000, +at 0x000001fc : */ 0x6a340000,0x00000000, /* MOVE DSA1 TO SFBR -at 0x000001f2 : */ 0x72110000,0x00000000, +at 0x000001fe : */ 0x72110000,0x00000000, /* MOVE SFBR TO SCRATCH1 -at 0x000001f4 : */ 0x6a350000,0x00000000, +at 0x00000200 : */ 0x6a350000,0x00000000, /* MOVE DSA2 TO SFBR -at 0x000001f6 : */ 0x72120000,0x00000000, +at 0x00000202 : */ 0x72120000,0x00000000, /* MOVE SFBR TO SCRATCH2 -at 0x000001f8 : */ 0x6a360000,0x00000000, +at 0x00000204 : */ 0x6a360000,0x00000000, /* MOVE DSA3 TO SFBR -at 0x000001fa : */ 0x72130000,0x00000000, +at 0x00000206 : */ 0x72130000,0x00000000, /* MOVE SFBR TO SCRATCH3 -at 0x000001fc : */ 0x6a370000,0x00000000, +at 0x00000208 : */ 0x6a370000,0x00000000, /* RETURN -at 0x000001fe : */ 0x90080000,0x00000000, +at 0x0000020a : */ 0x90080000,0x00000000, /* scratch_to_dsa: MOVE SCRATCH0 TO SFBR -at 0x00000200 : */ 0x72340000,0x00000000, +at 0x0000020c : */ 0x72340000,0x00000000, /* MOVE SFBR TO DSA0 -at 0x00000202 : */ 0x6a100000,0x00000000, +at 0x0000020e : */ 0x6a100000,0x00000000, /* MOVE SCRATCH1 TO SFBR -at 0x00000204 : */ 0x72350000,0x00000000, +at 0x00000210 : */ 0x72350000,0x00000000, /* MOVE SFBR TO DSA1 -at 0x00000206 : */ 0x6a110000,0x00000000, +at 0x00000212 : */ 0x6a110000,0x00000000, /* MOVE SCRATCH2 TO SFBR -at 0x00000208 : */ 0x72360000,0x00000000, +at 0x00000214 : */ 0x72360000,0x00000000, /* MOVE SFBR TO DSA2 -at 0x0000020a : */ 0x6a120000,0x00000000, +at 0x00000216 : */ 0x6a120000,0x00000000, /* MOVE SCRATCH3 TO SFBR -at 0x0000020c : */ 0x72370000,0x00000000, +at 0x00000218 : */ 0x72370000,0x00000000, /* MOVE SFBR TO DSA3 -at 0x0000020e : */ 0x6a130000,0x00000000, +at 0x0000021a : */ 0x6a130000,0x00000000, /* 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 @@ -1940,7 +1995,7 @@ #define A_int_debug_break 0x03000000 unsigned long A_int_debug_break_used[] = { - 0x000001cb, + 0x000001d3, }; #define A_int_debug_dsa_loaded 0x03030000 @@ -2013,7 +2068,7 @@ #define A_int_norm_aborted 0x02040000 unsigned long A_int_norm_aborted_used[] = { - 0x000001ed, + 0x000001f9, }; #define A_int_norm_command_complete 0x02020000 @@ -2038,12 +2093,12 @@ #define A_int_test_1 0x04000000 unsigned long A_int_test_1_used[] = { - 0x000001b1, + 0x000001b9, }; #define A_int_test_2 0x04010000 unsigned long A_int_test_2_used[] = { - 0x000001c9, + 0x000001d1, }; #define A_int_test_3 0x04020000 @@ -2087,26 +2142,26 @@ #define A_test_dest 0x00000000 unsigned long A_test_dest_used[] = { - 0x000001af, + 0x000001b7, }; #define A_test_src 0x00000000 unsigned long A_test_src_used[] = { - 0x000001ae, + 0x000001b6, }; #define Ent_accept_message 0x000004d8 #define Ent_cmdout_cmdout 0x0000022c #define Ent_command_complete 0x00000508 #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_template 0x00000000 #define Ent_dsa_code_template_end 0x000000b4 #define Ent_dsa_jump_resume 0x00000088 #define Ent_dsa_schedule 0x000000b4 #define Ent_dsa_zero 0x00000090 -#define Ent_initiator_abort 0x00000750 +#define Ent_initiator_abort 0x00000770 #define Ent_msg_in 0x00000354 #define Ent_other_transfer 0x0000031c #define Ent_reject_message 0x000004b8 @@ -2115,10 +2170,10 @@ #define Ent_schedule 0x00000130 #define Ent_select 0x00000194 #define Ent_select_msgout 0x000001ac -#define Ent_target_abort 0x00000730 -#define Ent_test_1 0x000006b4 -#define Ent_test_2 0x000006c8 -#define Ent_test_2_msgout 0x000006e0 +#define Ent_target_abort 0x00000750 +#define Ent_test_1 0x000006d4 +#define Ent_test_2 0x000006e8 +#define Ent_test_2_msgout 0x00000700 unsigned long LABELPATCHES[] = { 0x00000002, 0x0000000b, @@ -2178,18 +2233,21 @@ 0x0000017a, 0x00000191, 0x000001a2, - 0x000001a4, + 0x000001a6, 0x000001a8, 0x000001ac, - 0x000001b5, - 0x000001b7, - 0x000001d3, - 0x000001d7, + 0x000001b0, + 0x000001b2, + 0x000001b4, + 0x000001bd, + 0x000001bf, 0x000001db, 0x000001df, 0x000001e3, 0x000001e7, + 0x000001eb, + 0x000001ef, }; -unsigned long INSTRUCTIONS = 0x000000fe; -unsigned long PATCHES = 0x00000045; +unsigned long INSTRUCTIONS = 0x00000104; +unsigned long PATCHES = 0x00000048; diff -u --recursive --new-file v1.2.5/linux/drivers/scsi/53c8xx_u.h linux/drivers/scsi/53c8xx_u.h --- v1.2.5/linux/drivers/scsi/53c8xx_u.h Tue Aug 2 11:29:17 1994 +++ linux/drivers/scsi/53c8xx_u.h Mon Apr 17 13:48:24 1995 @@ -1,3 +1,7 @@ +#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_sfbr #undef A_addr_temp diff -u --recursive --new-file v1.2.5/linux/drivers/scsi/ChangeLog linux/drivers/scsi/ChangeLog --- v1.2.5/linux/drivers/scsi/ChangeLog Tue Jan 31 09:39:01 1995 +++ linux/drivers/scsi/ChangeLog Fri Apr 21 08:51:27 1995 @@ -1,3 +1,296 @@ +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) * Linux 1.1.82 released. diff -u --recursive --new-file v1.2.5/linux/drivers/scsi/Makefile linux/drivers/scsi/Makefile --- v1.2.5/linux/drivers/scsi/Makefile Fri Apr 14 12:02:42 1995 +++ linux/drivers/scsi/Makefile Mon Apr 17 13:53:22 1995 @@ -127,6 +127,8 @@ ifdef CONFIG_SCSI_NCR53C7xx SCSI_OBJS := $(SCSI_OBJS) 53c7,8xx.o SCSI_SRCS := $(SCSI_SRCS) 53c7,8xx.c +else +SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) 53c7,8xx.o endif ifdef CONFIG_SCSI_PAS16 @@ -190,7 +192,7 @@ 53c8xx_d.h 53c8xx_u.h : 53c7,8xx.scr script_asm.pl 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 scriptu.h 53c8xx_u.h rm fake.c diff -u --recursive --new-file v1.2.5/linux/drivers/scsi/buslogic.c linux/drivers/scsi/buslogic.c --- v1.2.5/linux/drivers/scsi/buslogic.c Fri Apr 14 12:02:42 1995 +++ linux/drivers/scsi/buslogic.c Sun Apr 23 19:18:13 1995 @@ -469,10 +469,7 @@ interrupt_flags = inb(INTERRUPT(base)); if (!(interrupt_flags & INTV)) - { - buslogic_printk("interrupt received, but INTV not set\n"); - return; - } + buslogic_printk("interrupt received, but INTV not set\n"); /* Reset the Host Adapter Interrupt Register. It appears to be @@ -504,16 +501,27 @@ while (mb[mbi].status != MBX_NOT_IN_USE && found < BUSLOGIC_MAILBOXES) { 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) - result = makecode(ccb[mbo].hastat, ccb[mbo].tarstat); + if (mb[mbi].status != MBX_COMPLETION_OK) + 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; @@ -535,6 +543,7 @@ { int mbo = saved_mbo[i]; sctmp = HOSTDATA(shpnt)->sc[mbo]; + if (sctmp == NULL) continue; /* First, free any storage allocated for a scatter/gather data segment list. @@ -542,14 +551,15 @@ if (sctmp->host_scribble) 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 - for another command by buslogic_queuecommand. + Finally, call the SCSI command completion handler. */ - HOSTDATA(shpnt)->sc[mbo] = NULL; + sctmp->scsi_done(sctmp); } } @@ -1344,7 +1354,7 @@ #if 1 static const unsigned char buscmd[] = { CMD_START_SCSI }; struct mailbox *mb; - size_t mbi, mbo; + int mbi, mbo, last_mbi; unsigned long flags; unsigned int i; @@ -1355,28 +1365,30 @@ save_flags(flags); cli(); 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) mbi = BUSLOGIC_MAILBOXES; do { if (mb[mbi].status != MBX_NOT_IN_USE) break; + last_mbi = mbi; mbi++; if (mbi >= 2 * BUSLOGIC_MAILBOXES) mbi = BUSLOGIC_MAILBOXES; } while (mbi != HOSTDATA(scpnt->host)->last_mbi_used); - restore_flags(flags); 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", scpnt->host->irq); - { - buslogic_interrupt(scpnt->host->irq, NULL); - return SCSI_ABORT_SUCCESS; - } + HOSTDATA(scpnt->host)->last_mbi_used = last_mbi; + buslogic_interrupt(scpnt->host->irq, NULL); + restore_flags(flags); + return SCSI_ABORT_SUCCESS; } + restore_flags(flags); /* OK, no lost interrupt. Try looking to see how many pending commands we think we have. */ diff -u --recursive --new-file v1.2.5/linux/drivers/scsi/eata_dma.c linux/drivers/scsi/eata_dma.c --- v1.2.5/linux/drivers/scsi/eata_dma.c Fri Apr 14 12:02:42 1995 +++ linux/drivers/scsi/eata_dma.c Fri Apr 14 12:01:41 1995 @@ -710,7 +710,7 @@ while (inb((uint) base + HA_RSTATUS) & HA_SDRQ) inw((uint) base + HA_RDATA); 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 might lead to problems.", base); return (TRUE); diff -u --recursive --new-file v1.2.5/linux/fs/nfs/file.c linux/fs/nfs/file.c --- v1.2.5/linux/fs/nfs/file.c Mon Jan 23 10:38:29 1995 +++ linux/fs/nfs/file.c Mon Apr 17 13:41:26 1995 @@ -123,7 +123,7 @@ if ((cache[i].inode_num == inode->i_ino) && (cache[i].file_pos <= pos) && (cache[i].file_pos + cache[i].len >= pos + count) - && (abs(jiffies - cache[i].time) <= EXPIRE_CACHE)) + && (abs(jiffies - cache[i].time) < EXPIRE_CACHE)) break; if (i < READ_CACHE_SIZE) { ++cache[i].in_use; diff -u --recursive --new-file v1.2.5/linux/fs/select.c linux/fs/select.c --- v1.2.5/linux/fs/select.c Mon Jan 23 23:04:10 1995 +++ linux/fs/select.c Tue Apr 18 08:57:32 1995 @@ -237,11 +237,10 @@ } current->timeout = timeout; i = do_select(n, &in, &out, &ex, &res_in, &res_out, &res_ex); - if (current->timeout > jiffies) - timeout = current->timeout - jiffies; - else - timeout = 0; + timeout = current->timeout - jiffies - 1; current->timeout = 0; + if ((long) timeout < 0) + timeout = 0; if (tvp && !(current->personality & STICKY_TIMEOUTS)) { put_fs_long(timeout/HZ, (unsigned long *) &tvp->tv_sec); timeout %= HZ; diff -u --recursive --new-file v1.2.5/linux/include/asm-alpha/byteorder.h linux/include/asm-alpha/byteorder.h --- v1.2.5/linux/include/asm-alpha/byteorder.h Tue Feb 21 09:05:02 1995 +++ linux/include/asm-alpha/byteorder.h Mon Apr 17 13:47:56 1995 @@ -6,6 +6,9 @@ #undef htonl #undef htons +#define LITTLE_ENDIAN +#define LITTLE_ENDIAN_BITFIELD + extern unsigned long int ntohl(unsigned long int); extern unsigned short int ntohs(unsigned short int); extern unsigned long int htonl(unsigned long int); diff -u --recursive --new-file v1.2.5/linux/include/asm-i386/byteorder.h linux/include/asm-i386/byteorder.h --- v1.2.5/linux/include/asm-i386/byteorder.h Tue Feb 21 09:02:02 1995 +++ linux/include/asm-i386/byteorder.h Mon Apr 17 13:47:56 1995 @@ -6,6 +6,9 @@ #undef htonl #undef htons +#define LITTLE_ENDIAN 1234 +#define LITTLE_ENDIAN_BITFIELD + extern unsigned long int ntohl(unsigned long int); extern unsigned short int ntohs(unsigned short int); extern unsigned long int htonl(unsigned long int); diff -u --recursive --new-file v1.2.5/linux/include/asm-mips/byteorder.h linux/include/asm-mips/byteorder.h --- v1.2.5/linux/include/asm-mips/byteorder.h Sat Jan 14 02:27:06 1995 +++ linux/include/asm-mips/byteorder.h Mon Apr 17 13:47:56 1995 @@ -6,6 +6,16 @@ #undef htonl #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 short int ntohs(unsigned short int); extern unsigned long int htonl(unsigned long int); diff -u --recursive --new-file v1.2.5/linux/include/asm-sparc/byteorder.h linux/include/asm-sparc/byteorder.h --- v1.2.5/linux/include/asm-sparc/byteorder.h Thu Feb 2 08:42:35 1995 +++ linux/include/asm-sparc/byteorder.h Mon Apr 17 13:47:56 1995 @@ -6,6 +6,9 @@ #undef htonl #undef htons +#define BIG_ENDIAN +#define BIG_ENDIAN_BITFIELD + extern unsigned long int ntohl(unsigned long int); extern unsigned short int ntohs(unsigned short int); extern unsigned long int htonl(unsigned long int); diff -u --recursive --new-file v1.2.5/linux/include/linux/bios32.h linux/include/linux/bios32.h --- v1.2.5/linux/include/linux/bios32.h Fri Feb 3 19:28:28 1995 +++ linux/include/linux/bios32.h Mon Apr 17 13:48:18 1995 @@ -48,5 +48,5 @@ unsigned char device_fn, unsigned char where, unsigned short value); extern pcibios_write_config_dword (unsigned char bus, unsigned char device_fn, unsigned char where, unsigned long value); - +extern char *pcibios_strerror (int error); #endif /* ndef BIOS32_H */ diff -u --recursive --new-file v1.2.5/linux/include/linux/ip.h linux/include/linux/ip.h --- v1.2.5/linux/include/linux/ip.h Mon Feb 20 08:59:52 1995 +++ linux/include/linux/ip.h Mon Apr 17 13:47:56 1995 @@ -16,7 +16,7 @@ */ #ifndef _LINUX_IP_H #define _LINUX_IP_H - +#include #define IPOPT_END 0 #define IPOPT_NOOP 1 @@ -34,26 +34,14 @@ __u8 len; __u8 ptr; union { -#if defined(__i386__) - __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__) +#if defined(LITTLE_ENDIAN_BITFIELD) __u8 flags:4, overflow:4; -#elif defined(__sparc__) +#elif defined(BIG_ENDIAN_BITFIELD) __u8 overflow:4, flags:4; #else -#error "Adjust this structure to match your CPU" +#error "Please fix " #endif __u8 full_char; } x; @@ -84,26 +72,14 @@ struct iphdr { -#if defined(__i386__) - __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__) +#if defined(LITTLE_ENDIAN_BITFIELD) __u8 ihl:4, version:4; -#elif defined (__sparc__) +#elif defined (BIG_ENDIAN_BITFIELD) __u8 version:4, ihl:4; #else -#error "Adjust this structure to match your CPU" +#error "Please fix " #endif __u8 tos; __u16 tot_len; diff -u --recursive --new-file v1.2.5/linux/include/linux/tcp.h linux/include/linux/tcp.h --- v1.2.5/linux/include/linux/tcp.h Mon Feb 20 08:59:52 1995 +++ linux/include/linux/tcp.h Mon Apr 17 13:47:56 1995 @@ -26,7 +26,7 @@ __u16 dest; __u32 seq; __u32 ack_seq; -#if defined(__i386__) +#if defined(LITTLE_ENDIAN_BITFIELD) __u16 res1:4, doff:4, fin:1, @@ -36,47 +36,7 @@ ack:1, urg:1, res2:2; -#elif defined(__mc68000__) - __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__) +#elif defined(BIG_ENDIAN_BITFIELD) __u16 res2:2, urg:1, ack:1, @@ -87,7 +47,7 @@ doff:4, res1:4; #else -#error "Adjust this structure for your cpu alignment rules" +#error "Adjust your defines" #endif __u16 window; __u16 check; diff -u --recursive --new-file v1.2.5/linux/kernel/ksyms.c linux/kernel/ksyms.c --- v1.2.5/linux/kernel/ksyms.c Fri Apr 14 12:02:43 1995 +++ linux/kernel/ksyms.c Mon Apr 17 13:48:23 1995 @@ -34,9 +34,10 @@ #include #include -#ifdef CONFIG_INET +#ifdef CONFIG_NET #include #include +#ifdef CONFIG_INET #include #include #include "../net/inet/protocol.h" @@ -45,6 +46,7 @@ #include "../drivers/net/slhc.h" #endif #endif +#endif #ifdef CONFIG_PCI #include #endif @@ -105,6 +107,7 @@ X(pcibios_read_config_byte), X(pcibios_read_config_word), X(pcibios_read_config_dword), + X(pcibios_strerror), X(pcibios_write_config_byte), X(pcibios_write_config_word), X(pcibios_write_config_dword), @@ -277,6 +280,7 @@ X(inet_add_protocol), X(inet_del_protocol), #if defined(CONFIG_PPP) || defined(CONFIG_SLIP) + /* VJ header compression */ X(slhc_init), X(slhc_free), X(slhc_remember), @@ -321,6 +325,11 @@ #endif #ifdef CONFIG_SCSI /* 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_unregister_module), X(scsi_free), @@ -331,6 +340,8 @@ X(scsi_init_malloc), X(scsi_init_free), X(print_command), + X(print_msg), + X(print_status), #endif /* Added to make file system as module */ X(set_writetime), diff -u --recursive --new-file v1.2.5/linux/mm/swap.c linux/mm/swap.c --- v1.2.5/linux/mm/swap.c Sun Apr 9 11:59:57 1995 +++ linux/mm/swap.c Fri Apr 21 13:41:36 1995 @@ -523,7 +523,7 @@ int loop, counter; struct task_struct *p; - counter = 2*nr_tasks >> priority; + counter = 6*nr_tasks >> priority; for(; counter >= 0; counter--) { /* * Check that swap_task is suitable for swapping. If not, look for @@ -605,7 +605,7 @@ if (swap_out(i)) return 1; state = 0; - } while(--i); + } while(i--); } return 0; }