The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/i386/isa/ncr5380.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * FreeBSD generic NCR-5380/NCR-53C400 SCSI driver
    3  *
    4  * Copyright (C) 1994 Serge Vakulenko (vak@cronyx.ru)
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE DEVELOPERS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  */
   27 
   28 /*
   29  * Tested on the following hardware:
   30  *  Adapter: Trantor T130
   31  * Streamer: Archive Viper 150,
   32  *   CD-ROM: NEC CDR-25
   33  */
   34 #undef DEBUG
   35 
   36 #include "nca.h"
   37 #if NNCA > 0
   38 
   39 #include <sys/types.h>
   40 #include <sys/param.h>
   41 #include <sys/systm.h>
   42 #include <sys/kernel.h>
   43 #include <sys/errno.h>
   44 #include <sys/ioctl.h>
   45 #include <sys/malloc.h>
   46 #include <sys/buf.h>
   47 #include <sys/proc.h>
   48 
   49 #include <machine/clock.h>
   50 
   51 #include <i386/isa/isa_device.h>
   52 #include <i386/isa/ic/ncr5380.h>
   53 #include <i386/isa/ic/ncr53400.h>
   54 
   55 #include <scsi/scsi_all.h>
   56 #include <scsi/scsiconf.h>
   57 
   58 #ifdef DEBUG
   59 #   define PRINT(s)     printf s
   60 #else
   61 #   define PRINT(s)     /*void*/
   62 #endif
   63 
   64 #define SCB_TABLE_SIZE  8       /* start with 8 scb entries in table */
   65 #define BLOCK_SIZE      512     /* size of READ/WRITE areas on SCSI card */
   66 #define HOST_SCSI_ADDR  7       /* address of the adapter on the SCSI bus */
   67 
   68 /*
   69  * Defice config flags
   70  */
   71 #define FLAG_NOPARITY   0x01    /* disable SCSI bus parity check */
   72 
   73 /*
   74  * ProAudioSpectrum registers
   75  */
   76 #define PAS16_DATA              8       /* Data Register */
   77 #define PAS16_STAT              9       /* Status Register */
   78 #define PAS16_STAT_DREQ         0x80    /* Pseudo-DMA ready bit */
   79 #define PAS16_REG(r)            (((r) & 0xc) << 11 | ((r) & 3))
   80 
   81 static u_char pas16_irq_magic[] =
   82     { 0,  0,  1,  2,  3,  4,  5,  6, 0,  0,  7,  8,  9,  0, 10, 11 };
   83 
   84 /*
   85  * SCSI bus phases
   86  */
   87 #define PHASE_MASK              (CSBR_MSG | CSBR_CD | CSBR_IO)
   88 #define PHASE_DATAOUT           0
   89 #define PHASE_DATAIN            CSBR_IO
   90 #define PHASE_CMDOUT            CSBR_CD
   91 #define PHASE_STATIN            (CSBR_CD | CSBR_IO)
   92 #define PHASE_MSGOUT            (CSBR_MSG | CSBR_CD)
   93 #define PHASE_MSGIN             (CSBR_MSG | CSBR_CD | CSBR_IO)
   94 #define PHASE_NAME(ph)          phase_name[(ph)>>2]
   95 #define PHASE_TO_TCR(ph)        ((ph) >> 2)
   96 
   97 static char *phase_name[] = {
   98         "DATAOUT", "DATAIN",  "CMDOUT", "STATIN",
   99         "Phase4?", "Phase5?", "MSGOUT", "MSGIN",
  100 };
  101 
  102 /*
  103  * SCSI message codes
  104  */
  105 #define MSG_COMMAND_COMPLETE    0x00
  106 #define MSG_SAVE_POINTERS       0x02
  107 #define MSG_RESTORE_POINTERS    0x03
  108 #define MSG_DISCONNECT          0x04
  109 #define MSG_ABORT               0x06
  110 #define MSG_MESSAGE_REJECT      0x07
  111 #define MSG_NOP                 0x08
  112 #define MSG_BUS_DEV_RESET       0x0c
  113 #define MSG_IDENTIFY(lun)       (0xc0 | ((lun) & 0x7))
  114 #define MSG_ISIDENT(m)          ((m) & 0x80)
  115 
  116 /*
  117  * SCSI control block used to keep info about a scsi command
  118  */
  119 typedef struct scb {
  120         int flags;                      /* status of the instruction */
  121 #define SCB_FREE        0x00
  122 #define SCB_ACTIVE      0x01
  123 #define SCB_ABORTED     0x02
  124 #define SCB_TIMEOUT     0x04
  125 #define SCB_ERROR       0x08
  126 #define SCB_TIMECHK     0x10            /* we have set a timeout on this one */
  127 #define SCB_SENSE       0x20            /* sensed data available */
  128 #define SCB_TBUSY       0x40            /* target busy */
  129         struct scb *next;               /* in free list */
  130         struct scsi_xfer *xfer;         /* the scsi_xfer for this cmd */
  131         u_char *data;                   /* position in data buffer so far */
  132         int32_t datalen;                        /* bytes remaining to transfer */;
  133 } scb_t;
  134 
  135 typedef enum {
  136         CTLR_NONE,
  137         CTLR_NCR_5380,
  138         CTLR_NCR_53C400,
  139         CTLR_PAS_16,
  140 } ctlr_t;
  141 
  142 /*
  143  * Data structure describing the target state.
  144  */
  145 typedef struct {
  146         u_char  busy;                   /* mask of busy luns at device target */
  147         u_long  perrcnt;                /* counter of target parity errors */
  148 } target_t;
  149 
  150 /*
  151  * Data structure describing current status of the scsi bus. One for each
  152  * controller card.
  153  */
  154 typedef struct {
  155         ctlr_t  type;                   /* Seagate or Future Domain */
  156         char    *name;                  /* adapter name */
  157 
  158         /* NCR-5380 controller registers */
  159         u_short ODR;            /* (wo-0) Output Data Register */
  160         u_short CSDR;           /* (ro-0) Current SCSI Data Register */
  161         u_short ICR;            /* (rw-1) Initiator Command Register */
  162         u_short MR;             /* (rw-2) Mode Register */
  163         u_short TCR;            /* (rw-3) Target Command Register */
  164         u_short SER;            /* (wo-4) Select Enable Register */
  165         u_short CSBR;           /* (ro-4) Current SCSI Bus Status Register */
  166         u_short BSR;            /* (ro-5) Bus and Status Register */
  167         u_short SDSR;           /* (wo-5) Start DMA Send Register */
  168         u_short SDIR;           /* (wo-7) Start DMA Initiator Receive Register */
  169         u_short RPIR;           /* (ro-7) Reset Parity/Interrupt Register */
  170 
  171         /* NCR-53C400 controller registers */
  172         u_short CSR;            /* (rw-0) Control and Status Register */
  173         u_short CCR;            /* (rw-1) Clock Counter Register */
  174         u_short HBR;            /* (rw-4) Host Buffer Register */
  175 
  176         /* ProAudioSpectrum controller registers */
  177         u_short PDATA;          /* (rw) Pseudo-DMA Data Register */
  178         u_short PSTAT;          /* (rw) Pseudo-DMA Status Register */
  179 
  180         u_char  scsi_addr;              /* our scsi address, 0..7 */
  181         u_char  scsi_id;                /* our scsi id mask */
  182         u_char  parity;                 /* parity flag: CMD_EN_PARITY or 0 */
  183         u_char  irq;                    /* IRQ number used or 0 if no IRQ */
  184         u_int   timeout_active : 1;     /* timeout() active (requested) */
  185 
  186         struct scsi_link sc_link;       /* struct connecting different data */
  187         scb_t   *queue;                 /* waiting to be issued */
  188         scb_t   *disconnected_queue;    /* waiting to reconnect */
  189 
  190         int     numscb;                 /* number of scsi control blocks */
  191         scb_t   *free_scb;              /* free scb list */
  192         scb_t   scbs[SCB_TABLE_SIZE];
  193 
  194         target_t target[8];             /* target state data */
  195 } adapter_t;
  196 
  197 static adapter_t ncadata[NNCA];
  198 
  199 #define IS_BUSY(a,b)    ((a)->target[(b)->xfer->sc_link->target].busy &\
  200                                 (1 << (b)->xfer->sc_link->lun))
  201 #define SET_BUSY(a,b)   ((a)->target[(b)->xfer->sc_link->target].busy |=\
  202                                 (1 << (b)->xfer->sc_link->lun))
  203 #define CLEAR_BUSY(a,b) ((a)->target[(b)->xfer->sc_link->target].busy &=\
  204                                 ~(1 << (b)->xfer->sc_link->lun))
  205 
  206 /*
  207  * Wait for condition, given as an boolean expression.
  208  * Print the message on timeout.
  209  */
  210 #define WAITFOR(condition,count,message) {\
  211         register u_long cnt = count; char *msg = message;\
  212         while (cnt-- && ! (condition)) continue;\
  213         if (cnt == -1 && msg)\
  214                 printf ("nca: %s timeout\n", msg); }
  215 
  216 static int nca_probe (struct isa_device *dev);
  217 static int nca_attach (struct isa_device *dev);
  218 static int32_t nca_scsi_cmd (struct scsi_xfer *xs);
  219 static u_int32_t nca_adapter_info (int unit);
  220 static void nca_timeout (void *scb);
  221 static void ncaminphys (struct buf *bp);
  222 static void nca_done (adapter_t *z, scb_t *scb);
  223 static void nca_start (adapter_t *z);
  224 static void nca_information_transfer (adapter_t *z, scb_t *scb);
  225 static int nca_poll (adapter_t *z, scb_t *scb);
  226 static int nca_init (adapter_t *z);
  227 static int nca_reselect (adapter_t *z);
  228 static int nca_select (adapter_t *z, scb_t *scb);
  229 static int nca_abort (adapter_t *z, scb_t *scb);
  230 static void nca_send_abort (adapter_t *z);
  231 static u_char nca_msg_input (adapter_t *z);
  232 static void nca_tick (void *arg);
  233 static int nca_sense (adapter_t *z, scb_t *scb);
  234 static void nca_data_output (adapter_t *z, u_char **pdata, u_long *plen);
  235 static void nca_data_input (adapter_t *z, u_char **pdata, u_long *plen);
  236 static void nca_cmd_output (adapter_t *z, u_char *cmd, int cmdlen);
  237 static void nca_53400_dma_xfer (adapter_t *z, int r, u_char **dat, u_long *len);
  238 static void nca_pas_dma_xfer (adapter_t *z, int r, u_char **dat, u_long *len);
  239 
  240 static struct scsi_adapter nca_switch = {
  241         nca_scsi_cmd, ncaminphys, 0, 0, nca_adapter_info, "nca", {0},
  242 };
  243 static struct scsi_device nca_dev = { NULL, NULL, NULL, NULL, "nca", 0, {0} };
  244 struct isa_driver ncadriver = { nca_probe, nca_attach, "nca" };
  245 
  246 /*
  247  * Check if the device can be found at the port given and if so,
  248  * detect the type of board. Set it up ready for further work.
  249  * Takes the isa_dev structure from autoconf as an argument.
  250  * Returns 1 if card recognized, 0 if errors.
  251  */
  252 int nca_probe (struct isa_device *dev)
  253 {
  254         adapter_t *z = &ncadata[dev->id_unit];
  255         int i;
  256 
  257         /* Init fields used by our routines */
  258         z->parity = (dev->id_flags & FLAG_NOPARITY) ? 0 :
  259                 MR_ENABLE_PARITY_CHECKING;
  260         z->scsi_addr = HOST_SCSI_ADDR;
  261         z->scsi_id = 1 << z->scsi_addr;
  262         z->irq = dev->id_irq ? ffs (dev->id_irq) - 1 : 0;
  263         z->queue = 0;
  264         z->disconnected_queue = 0;
  265         for (i=0; i<8; i++)
  266                 z->target[i].busy = 0;
  267 
  268         /* Link up the free list of scbs */
  269         z->numscb = SCB_TABLE_SIZE;
  270         z->free_scb = z->scbs;
  271         for (i=1; i<SCB_TABLE_SIZE; i++)
  272                 z->scbs[i-1].next = z->scbs + i;
  273         z->scbs[SCB_TABLE_SIZE-1].next = 0;
  274 
  275         /* Try NCR 5380. */
  276         z->type  = CTLR_NCR_5380;
  277         z->name  = "NCR-5380";
  278         z->ODR   = dev->id_iobase + C80_ODR;
  279         z->CSDR  = dev->id_iobase + C80_CSDR;
  280         z->ICR   = dev->id_iobase + C80_ICR;
  281         z->MR    = dev->id_iobase + C80_MR;
  282         z->TCR   = dev->id_iobase + C80_TCR;
  283         z->SER   = dev->id_iobase + C80_SER;
  284         z->CSBR  = dev->id_iobase + C80_CSBR;
  285         z->BSR   = dev->id_iobase + C80_BSR;
  286         z->SDSR  = dev->id_iobase + C80_SDSR;
  287         z->SDIR  = dev->id_iobase + C80_SDIR;
  288         z->RPIR  = dev->id_iobase + C80_RPIR;
  289         z->CSR   = 0;
  290         z->CCR   = 0;
  291         z->HBR   = 0;
  292         z->PDATA = 0;
  293         z->PSTAT = 0;
  294         if (nca_init (z) == 0)
  295                 return (8);
  296 
  297         /* Try NCR 53C400. */
  298         z->type  = CTLR_NCR_53C400;
  299         z->name  = "NCR-53C400";
  300         z->ODR   = dev->id_iobase + C400_5380_REG_OFFSET + C80_ODR;
  301         z->CSDR  = dev->id_iobase + C400_5380_REG_OFFSET + C80_CSDR;
  302         z->ICR   = dev->id_iobase + C400_5380_REG_OFFSET + C80_ICR;
  303         z->MR    = dev->id_iobase + C400_5380_REG_OFFSET + C80_MR;
  304         z->TCR   = dev->id_iobase + C400_5380_REG_OFFSET + C80_TCR;
  305         z->SER   = dev->id_iobase + C400_5380_REG_OFFSET + C80_SER;
  306         z->CSBR  = dev->id_iobase + C400_5380_REG_OFFSET + C80_CSBR;
  307         z->BSR   = dev->id_iobase + C400_5380_REG_OFFSET + C80_BSR;
  308         z->SDSR  = dev->id_iobase + C400_5380_REG_OFFSET + C80_SDSR;
  309         z->SDIR  = dev->id_iobase + C400_5380_REG_OFFSET + C80_SDIR;
  310         z->RPIR  = dev->id_iobase + C400_5380_REG_OFFSET + C80_RPIR;
  311         z->CSR   = dev->id_iobase + C400_CSR;
  312         z->CCR   = dev->id_iobase + C400_CCR;
  313         z->HBR   = dev->id_iobase + C400_HBR;
  314         z->PDATA = 0;
  315         z->PSTAT = 0;
  316         if (nca_init (z) == 0)
  317                 return (16);
  318 
  319         /* Try ProAudioSpectrum-16. */
  320         z->type  = CTLR_PAS_16;
  321         z->name  = "ProAudioSpectrum"; /* changed later */
  322         z->ODR   = dev->id_iobase ^ PAS16_REG (C80_ODR);
  323         z->CSDR  = dev->id_iobase ^ PAS16_REG (C80_CSDR);
  324         z->ICR   = dev->id_iobase ^ PAS16_REG (C80_ICR);
  325         z->MR    = dev->id_iobase ^ PAS16_REG (C80_MR);
  326         z->TCR   = dev->id_iobase ^ PAS16_REG (C80_TCR);
  327         z->SER   = dev->id_iobase ^ PAS16_REG (C80_SER);
  328         z->CSBR  = dev->id_iobase ^ PAS16_REG (C80_CSBR);
  329         z->BSR   = dev->id_iobase ^ PAS16_REG (C80_BSR);
  330         z->SDSR  = dev->id_iobase ^ PAS16_REG (C80_SDSR);
  331         z->SDIR  = dev->id_iobase ^ PAS16_REG (C80_SDIR);
  332         z->RPIR  = dev->id_iobase ^ PAS16_REG (C80_RPIR);
  333         z->CSR   = 0;
  334         z->CCR   = 0;
  335         z->HBR   = 0;
  336         z->PDATA = dev->id_iobase ^ PAS16_REG (PAS16_DATA);
  337         z->PSTAT = dev->id_iobase ^ PAS16_REG (PAS16_STAT);
  338         if (nca_init (z) == 0)
  339                 return (4);
  340 
  341         bzero (z, sizeof (*z));
  342         return (0);
  343 }
  344 
  345 /*
  346  * Probe the adapter, and if found, reset the board and the scsi bus.
  347  * Return 0 if the adapter found.
  348  */
  349 int nca_init (adapter_t *z)
  350 {
  351         int i, c;
  352 
  353         if (z->type == CTLR_NCR_53C400) {
  354                 if (inb (z->CSR) == 0xFF)
  355                         return (100);
  356 
  357                 /* Reset 53C400. */
  358                 outb (z->CSR, CSR_5380_ENABLE);
  359 
  360                 /* Enable interrupts. */
  361                 outb (z->CSR, z->irq ? CSR_5380_INTR : 0);
  362         }
  363 
  364         if (z->type == CTLR_PAS_16) {
  365                 u_short base = z->PDATA & 0x3FF;
  366 
  367                 outb (0x9a01, 0xbc + (z-ncadata));      /* unit number */
  368                 outb (0x9a01, base >> 2);
  369 
  370                 if (inb (base^0x803) == 0xFF)
  371                         return (200);
  372 
  373                 if (inb (z->CSDR) == 0xFF && inb (z->CSDR^0x2000) == 0xFF &&
  374                     inb (z->CSDR) == 0xFF && inb (z->CSDR^0x2000) == 0xFF &&
  375                     inb (z->CSDR) == 0xFF && inb (z->CSDR^0x2000) == 0xFF &&
  376                     inb (z->CSDR) == 0xFF && inb (z->CSDR^0x2000) == 0xFF)
  377                         return (201);
  378 
  379                 i = inb (base^0x803);
  380                 outb (base^0x803, i ^ 0xE0);
  381                 c = inb (base^0x803);
  382                 outb (base^0x803, 1);
  383                 if (i != c)
  384                         return (202);
  385 
  386                 /* Various magic. */
  387                 outb (base^0x4000, 0x30);  /* Timeout counter */
  388                 outb (base^0x4001, 0x01);  /* Reset TC */
  389                 outb (base^0xbc00, 0x01);  /* 1 Wait state */
  390                 outb (base^0x8003, 0x4d);  /* sysconfig_4 */
  391                 i = pas16_irq_magic[z->irq];
  392                 if (!i) {
  393                     z->irq = 0;
  394                 } else {
  395                     outb (base^0xf002, i << 4);
  396                     outb (base^0x8003, 0x6d);  /* sysconfig_4 */
  397                 }
  398 
  399                 switch (inb (base^0xEC03) & 0xF) {
  400                 case 6:  z->name = "ProAudioSpectrum-Plus"; break;
  401                 case 12: z->name = "ProAudioSpectrum-16D";  break;
  402                 case 14: z->name = "ProAudioSpectrum-CDPC"; break;
  403                 case 15: z->name = "ProAudioSpectrum-16";   break;
  404                 default: return (203);
  405                 }
  406         }
  407 
  408         /* Read RPI port, resetting parity/interrupt state. */
  409         inb (z->RPIR);
  410 
  411         /* Test BSR: parity error, interrupt request and busy loss state
  412          * should be cleared. */
  413         if (inb (z->BSR) & (BSR_PARITY_ERROR |
  414             BSR_INTERRUPT_REQUEST_ACTIVE | BSR_BUSY_ERROR)) {
  415                 PRINT (("nca: invalid bsr[0x%x]=%b\n", z->BSR,
  416                         inb (z->BSR), BSR_BITS));
  417                 return (1);
  418         }
  419 
  420         /* Reset the SCSI bus. */
  421         outb (z->ICR, ICR_ASSERT_RST);
  422         outb (z->ODR, 0);
  423         /* Hold reset for at least 25 microseconds. */
  424         DELAY (25);
  425         /* Check that status cleared. */
  426         if (inb (z->CSBR) != CSBR_RST) {
  427                 PRINT (("nca: invalid csbr[0x%x]=%b\n", z->CSBR,
  428                         inb (z->CSBR), CSBR_BITS));
  429                 outb (z->ICR, 0);
  430                 return (2);
  431         }
  432         /* Clear reset. */
  433         outb (z->ICR, 0);
  434         /* Wait a Bus Clear Delay (800 ns + bus free delay 800 ns). */
  435         DELAY (2);
  436 
  437         /* Enable data drivers. */
  438         outb (z->ICR, ICR_ASSERT_DATA_BUS);
  439 
  440         /* Check that data register is writable. */
  441         for (i=0; i<256; ++i) {
  442                 outb (z->ODR, i);
  443                 DELAY (1);
  444                 if (inb (z->CSDR) != i) {
  445                         PRINT (("nca: ODR[0x%x] not writable: 0x%x should be 0x%x\n",
  446                                 z->ODR, inb (z->CSDR), i));
  447                         outb (z->ICR, 0);
  448                         return (3);
  449                 }
  450         }
  451 
  452         /* Disable data drivers. */
  453         outb (z->ICR, 0);
  454 
  455         /* Check that data register is NOT writable. */
  456         c = inb (z->CSDR);
  457         for (i=0; i<256; ++i) {
  458                 outb (z->ODR, i);
  459                 DELAY (1);
  460                 if (inb (z->CSDR) != c) {
  461                         PRINT (("nca: ODR[0x%x] writable: 0x%x should be 0x%x\n",
  462                                 z->ODR, inb (z->CSDR), c));
  463                         return (4);
  464                 }
  465         }
  466 
  467         /* Initialize the controller. */
  468         outb (z->MR, z->parity);
  469         outb (z->TCR, 0);
  470         outb (z->SER, z->scsi_id);
  471         return (0);
  472 }
  473 
  474 /*
  475  * Attach all sub-devices we can find.
  476  */
  477 int nca_attach (struct isa_device *dev)
  478 {
  479         int unit = dev->id_unit;
  480         adapter_t *z = &ncadata[unit];
  481         struct scsibus_data *scbus;
  482 
  483         printf ("nca%d: type %s%s\n", unit, z->name,
  484                 (dev->id_flags & FLAG_NOPARITY) ? ", no parity" : "");
  485 
  486         /* fill in the prototype scsi_link */
  487         z->sc_link.adapter_unit = unit;
  488         z->sc_link.adapter_targ = z->scsi_addr;
  489         z->sc_link.adapter_softc = z;
  490         z->sc_link.adapter = &nca_switch;
  491         z->sc_link.device = &nca_dev;
  492 
  493         /*
  494          * Prepare the scsibus_data area for the upperlevel
  495          * scsi code.
  496          */
  497         scbus = scsi_alloc_bus();
  498         if(!scbus)
  499                 return 0;
  500         scbus->adapter_link = &z->sc_link;
  501 
  502         /* ask the adapter what subunits are present */
  503         scsi_attachdevs (scbus);
  504 
  505         return (1);
  506 }
  507 
  508 /*
  509  * Return some information to the caller about
  510  * the adapter and its capabilities.
  511  */
  512 u_int32_t nca_adapter_info (int unit)
  513 {
  514         return (1);
  515 }
  516 
  517 void ncaminphys (struct buf *bp)
  518 {
  519 }
  520 
  521 /*
  522  * Catch an interrupt from the adaptor.
  523  */
  524 void ncaintr (int unit)
  525 {
  526         adapter_t *z = &ncadata[unit];
  527 
  528         PRINT (("nca%d: interrupt bsr=%b csbr=%b\n", unit,
  529                 inb (z->BSR), BSR_BITS, inb (z->CSBR), CSBR_BITS));
  530         nca_start (z);
  531         /* Reset interrupt state. */
  532         inb (z->RPIR);
  533 }
  534 
  535 /*
  536  * This routine is used in the case when we have no IRQ line (z->irq == 0).
  537  * It is called every timer tick and polls for reconnect from target.
  538  */
  539 void nca_tick (void *arg)
  540 {
  541         adapter_t *z = arg;
  542         int x = splbio ();
  543 
  544         z->timeout_active = 0;
  545         nca_start (z);
  546         /* Reset interrupt state. */
  547         inb (z->RPIR);
  548         if (z->disconnected_queue && ! z->timeout_active) {
  549                 timeout (nca_tick, z, 1);
  550                 z->timeout_active = 1;
  551         }
  552         splx (x);
  553 }
  554 
  555 /*
  556  * Start a scsi operation given the command and the data address.
  557  * Also needs the unit, target and lu.  Get a free scb and set it up.
  558  * Call send_scb.  Either start timer or wait until done.
  559  */
  560 int32_t nca_scsi_cmd (struct scsi_xfer *xs)
  561 {
  562         int unit = xs->sc_link->adapter_unit, flags = xs->flags, x = 0;
  563         adapter_t *z = (adapter_t *)xs->sc_link->adapter_softc;
  564         scb_t *scb;
  565 
  566         /* PRINT (("nca%d/%d/%d command 0x%x\n", unit, xs->sc_link->target,
  567                 xs->sc_link->lun, xs->cmd->opcode)); */
  568         if (xs->bp)
  569                 flags |= SCSI_NOSLEEP;
  570         if (flags & ITSDONE) {
  571                 printf ("nca%d: already done?", unit);
  572                 xs->flags &= ~ITSDONE;
  573         }
  574         if (! (flags & INUSE)) {
  575                 printf ("nca%d: not in use?", unit);
  576                 xs->flags |= INUSE;
  577         }
  578         if (flags & SCSI_RESET)
  579                 printf ("nca%d: SCSI_RESET not implemented\n", unit);
  580 
  581         if (! (flags & SCSI_NOMASK))
  582                 x = splbio ();
  583 
  584         /* Get a free scb.
  585          * If we can and have to, sleep waiting for one to come free. */
  586         while (! (scb = z->free_scb)) {
  587                 if (flags & SCSI_NOSLEEP) {
  588                         xs->error = XS_DRIVER_STUFFUP;
  589                         if (! (flags & SCSI_NOMASK))
  590                                 splx (x);
  591                         return (TRY_AGAIN_LATER);
  592                 }
  593                 tsleep ((caddr_t)&z->free_scb, PRIBIO, "ncascb", 0);
  594         }
  595         /* Get scb from free list. */
  596         z->free_scb = scb->next;
  597         scb->next = 0;
  598         scb->flags = SCB_ACTIVE;
  599 
  600         /* Put all the arguments for the xfer in the scb */
  601         scb->xfer = xs;
  602         scb->datalen = xs->datalen;
  603         scb->data = xs->data;
  604 
  605         /* Setup the scb to contain necessary values.
  606          * The interesting values can be read from the xs that is saved.
  607          * I therefore think that the structure can be kept very small.
  608          * The driver doesn't use DMA so the scatter/gather is not needed? */
  609         if (! z->queue) {
  610                 scb->next = z->queue;
  611                 z->queue = scb;
  612         } else {
  613                 scb_t *q;
  614 
  615                 for (q=z->queue; q->next; q=q->next)
  616                         continue;
  617                 q->next = scb;
  618                 scb->next = 0;  /* placed at the end of the queue */
  619         }
  620 
  621         /* Try to send this command to the board. */
  622         nca_start (z);
  623 
  624         /* Usually return SUCCESSFULLY QUEUED. */
  625         if (! (flags & SCSI_NOMASK)) {
  626                 splx (x);
  627                 if (xs->flags & ITSDONE)
  628                         /* Timeout timer not started, already finished.
  629                          * Tried to return COMPLETE but the machine hanged
  630                          * with this. */
  631                         return (SUCCESSFULLY_QUEUED);
  632                 timeout (nca_timeout, (caddr_t) scb, (xs->timeout * hz) / 1000);
  633                 scb->flags |= SCB_TIMECHK;
  634                 PRINT (("nca%d/%d/%d command queued\n", unit,
  635                         xs->sc_link->target, xs->sc_link->lun));
  636                 return (SUCCESSFULLY_QUEUED);
  637         }
  638 
  639         /* If we can't use interrupts, poll on completion. */
  640         if (! nca_poll (z, scb)) {
  641                 /* We timed out, so call the timeout handler manually,
  642                  * accounting for the fact that the clock is not running yet
  643                  * by taking out the clock queue entry it makes. */
  644                 nca_timeout ((void*) scb);
  645 
  646                 /* Because we are polling, take out the timeout entry
  647                  * nca_timeout made. */
  648                 untimeout (nca_timeout, (void*) scb);
  649 
  650                 if (! nca_poll (z, scb))
  651                         /* We timed out again... This is bad. Notice that
  652                          * this time there is no clock queue entry to remove. */
  653                         nca_timeout ((void*) scb);
  654         }
  655         /* PRINT (("nca%d/%d/%d command %s\n", unit,
  656                 xs->sc_link->target, xs->sc_link->lun,
  657                 xs->error ? "failed" : "done")); */
  658         return (xs->error ? HAD_ERROR : COMPLETE);
  659 }
  660 
  661 /*
  662  * Coroutine that runs as long as more work can be done.
  663  * Both scsi_cmd() and intr() will try to start it in
  664  * case it is not running.
  665  * Always called with interrupts disabled.
  666  */
  667 void nca_start (adapter_t *z)
  668 {
  669         scb_t *q, *prev;
  670 again:
  671         /* First check that if any device has tried
  672          * a reconnect while we have done other things
  673          * with interrupts disabled. */
  674         if (nca_reselect (z))
  675                 goto again;
  676 
  677         /* Search through the queue for a command
  678          * destined for a target that's not busy. */
  679         for (q=z->queue, prev=0; q; prev=q, q=q->next) {
  680                 /* Attempt to establish an I_T_L nexus here. */
  681                 if (IS_BUSY (z, q) || ! nca_select (z, q))
  682                         continue;
  683 
  684                 /* Remove the command from the issue queue. */
  685                 if (prev)
  686                         prev->next = q->next;
  687                 else
  688                         z->queue = q->next;
  689                 q->next = 0;
  690 
  691                 /* We are connected. Do the task. */
  692                 nca_information_transfer (z, q);
  693                 goto again;
  694         }
  695 }
  696 
  697 void nca_timeout (void *arg)
  698 {
  699         scb_t *scb = (scb_t*) arg;
  700         int unit = scb->xfer->sc_link->adapter_unit;
  701         adapter_t *z = (adapter_t *)scb->xfer->sc_link->adapter_softc;
  702         int x = splbio ();
  703 
  704         if (! (scb->xfer->flags & SCSI_NOMASK))
  705                 printf ("nca%d/%d/%d (%s%d) timed out\n", unit,
  706                         scb->xfer->sc_link->target,
  707                         scb->xfer->sc_link->lun,
  708                         scb->xfer->sc_link->device->name,
  709                         scb->xfer->sc_link->dev_unit);
  710 
  711         /* If it has been through before, then a previous abort has failed,
  712          * don't try abort again. */
  713         if (! (scb->flags & SCB_ABORTED)) {
  714                 nca_abort (z, scb);
  715                 /* 2 seconds for the abort */
  716                 timeout (nca_timeout, (caddr_t)scb, 2*hz);
  717                 scb->flags |= (SCB_ABORTED | SCB_TIMECHK);
  718         } else {
  719                 /* abort timed out */
  720                 scb->flags |= SCB_ABORTED;
  721                 scb->xfer->retries = 0;
  722                 nca_done (z, scb);
  723         }
  724         splx (x);
  725 }
  726 
  727 static inline void nca_sendbyte (adapter_t *z, u_char data)
  728 {
  729         outb (z->ODR, data);
  730         outb (z->ICR, ICR_ASSERT_DATA_BUS | ICR_ASSERT_ACK);
  731         WAITFOR (! (inb (z->CSBR) & CSBR_REQ), 10000, "sendbyte");
  732         outb (z->ICR, ICR_ASSERT_DATA_BUS);
  733 }
  734 
  735 static inline u_char nca_recvbyte (adapter_t *z)
  736 {
  737         u_char data;
  738 
  739         data = inb (z->CSDR);
  740         outb (z->ICR, ICR_ASSERT_ACK);
  741         WAITFOR (! (inb (z->CSBR) & CSBR_REQ), 10000, "recvbyte");
  742         outb (z->ICR, 0);
  743         return (data);
  744 }
  745 
  746 /*
  747  * Establish I_T_L or I_T_L_Q nexus for new or existing command
  748  * including ARBITRATION, SELECTION, and initial message out
  749  * for IDENTIFY and queue messages.
  750  * Return 1 if selection succeded.
  751  */
  752 int nca_select (adapter_t *z, scb_t *scb)
  753 {
  754         /* Set the phase bits to 0, otherwise the NCR5380 won't drive the
  755          * data bus during SELECTION. */
  756         outb (z->TCR, 0);
  757 
  758         /* Start arbitration. */
  759         outb (z->ODR, z->scsi_id);
  760         outb (z->MR, MR_ARBITRATE);
  761 
  762         /* Wait for arbitration logic to complete (20 usec) */
  763         WAITFOR (inb (z->ICR) & ICR_ARBITRATION_IN_PROGRESS, 200, 0);
  764         if (! (inb (z->ICR) & ICR_ARBITRATION_IN_PROGRESS)) {
  765                 PRINT (("nca%d/%d/%d no arbitration progress, bsr=%b csbr=%b\n",
  766                         z->sc_link.adapter_unit, scb->xfer->sc_link->target,
  767                         scb->xfer->sc_link->lun, inb (z->BSR), BSR_BITS,
  768                         inb (z->CSBR), CSBR_BITS));
  769                 outb (z->MR, z->parity);
  770                 return (0);
  771         }
  772         DELAY (3);
  773 
  774         /* Check for lost arbitration. */
  775         if ((inb (z->ICR) & ICR_LOST_ARBITRATION) ||
  776             (inb (z->CSDR) >> 1 >> z->scsi_addr) ||
  777             (inb (z->ICR) & ICR_LOST_ARBITRATION)) {
  778                 PRINT (("nca%d/%d/%d arbitration lost\n",
  779                         z->sc_link.adapter_unit, scb->xfer->sc_link->target,
  780                         scb->xfer->sc_link->lun));
  781                 outb (z->MR, z->parity);
  782                 return (0);
  783         }
  784 
  785         outb (z->ICR, ICR_ASSERT_SEL);
  786         if (inb (z->ICR) & ICR_LOST_ARBITRATION) {
  787                 PRINT (("nca%d/%d/%d arbitration lost after SEL\n",
  788                         z->sc_link.adapter_unit, scb->xfer->sc_link->target,
  789                         scb->xfer->sc_link->lun));
  790                 outb (z->ICR, 0);
  791                 outb (z->MR, z->parity);
  792                 return (0);
  793         }
  794         DELAY (2);
  795 
  796         /* Start selection, asserting the host and target ID's on the bus. */
  797         outb (z->SER, 0);
  798         outb (z->ODR, z->scsi_id | (1 << scb->xfer->sc_link->target));
  799         outb (z->ICR, ICR_ASSERT_DATA_BUS | ICR_ASSERT_BSY |
  800                 ICR_ASSERT_SEL);
  801 
  802         /* Finish arbitration, drop BSY. */
  803         outb (z->MR, 0);
  804         outb (z->ICR, ICR_ASSERT_DATA_BUS | ICR_ASSERT_SEL |
  805                 ICR_ASSERT_ATN);
  806         DELAY (1);
  807 
  808         /* The SCSI specification calls for a 250 ms timeout for the actual
  809          * selection. */
  810         WAITFOR (inb (z->CSBR) & CSBR_BSY, 100000, 0);
  811         if (! (inb (z->CSBR) & CSBR_BSY)) {
  812                 /* The target does not respond.  Not an error, though. */
  813                 PRINT (("nca%d/%d/%d target does not respond\n",
  814                         z->sc_link.adapter_unit, scb->xfer->sc_link->target,
  815                         scb->xfer->sc_link->lun));
  816                 outb (z->ICR, 0);
  817                 outb (z->SER, z->scsi_id);
  818                 outb (z->MR, z->parity);
  819                 scb->flags |= SCB_TIMEOUT;
  820                 return (0);
  821         }
  822 
  823         /* Clear SEL and SCSI id.
  824          * Wait for start of REQ/ACK handshake. */
  825         outb (z->ICR, ICR_ASSERT_DATA_BUS | ICR_ASSERT_ATN);
  826         WAITFOR (inb (z->CSBR) & CSBR_REQ, 100000, 0);
  827         if (! (inb (z->CSBR) & CSBR_REQ)) {
  828                 PRINT (("nca%d/%d/%d timeout waiting for REQ\n",
  829                         z->sc_link.adapter_unit, scb->xfer->sc_link->target,
  830                         scb->xfer->sc_link->lun));
  831                 outb (z->ICR, 0);
  832                 outb (z->SER, z->scsi_id);
  833                 outb (z->MR, z->parity);
  834                 scb->flags |= SCB_ERROR;
  835                 return (0);
  836         }
  837 
  838         /* Check for phase mismatch. */
  839         if ((inb (z->CSBR) & PHASE_MASK) != PHASE_MSGOUT) {
  840                 /* This should not be taken as an error, but more like
  841                  * an unsupported feature!
  842                  * Should set a flag indicating that the target don't support
  843                  * messages, and continue without failure.
  844                  * (THIS IS NOT AN ERROR!) */
  845                 PRINT (("nca%d/%d/%d waiting for MSGOUT: invalid phase %s\n",
  846                         z->sc_link.adapter_unit, scb->xfer->sc_link->target,
  847                         scb->xfer->sc_link->lun,
  848                         PHASE_NAME (inb (z->CSBR) & PHASE_MASK)));
  849                 outb (z->ICR, 0);
  850                 outb (z->SER, z->scsi_id);
  851                 outb (z->MR, z->parity);
  852                 scb->flags |= SCB_ERROR;
  853                 return (0);
  854         }
  855 
  856         /* Allow disconnects. */
  857         outb (z->TCR, PHASE_TO_TCR (PHASE_MSGOUT));
  858         outb (z->ICR, ICR_ASSERT_DATA_BUS);
  859         nca_sendbyte (z, MSG_IDENTIFY (scb->xfer->sc_link->lun));
  860         outb (z->ICR, 0);
  861         outb (z->SER, z->scsi_id);
  862         outb (z->MR, z->parity);
  863 
  864         SET_BUSY (z, scb);
  865         return (1);
  866 }
  867 
  868 int nca_reselect (adapter_t *z)
  869 {
  870         scb_t *q = 0, *prev = 0;
  871         u_char msg, target_mask, lun;
  872 again:
  873         /* Wait for a device to win the reselection phase. */
  874         /* Signals this by asserting the I/O signal. */
  875         if ((inb (z->CSBR) & (CSBR_SEL | CSBR_IO | CSBR_BSY)) !=
  876             (CSBR_SEL | CSBR_IO))
  877                 return (0);
  878 
  879         /* The data bus contains original initiator id ORed with target id. */
  880         /* See that we really are the initiator. */
  881         target_mask = inb (z->CSDR);
  882         if (! (target_mask & z->scsi_id)) {
  883                 PRINT (("nca%d reselect not for me: mask=0x%x, csbr=%b\n",
  884                         z->sc_link.adapter_unit, target_mask,
  885                         inb (z->CSBR), CSBR_BITS));
  886                 goto again;
  887         }
  888 
  889         /* Find target who won. */
  890         /* Host responds by asserting the BSY signal. */
  891         /* Target should respond by deasserting the SEL signal. */
  892         target_mask &= ~z->scsi_id;
  893         outb (z->ICR, ICR_ASSERT_BSY);
  894         WAITFOR (! (inb (z->CSBR) & CSBR_SEL), 10000, "SEL deassert");
  895 
  896         /* Remove the busy status. */
  897         /* Target should set the MSGIN phase. */
  898         outb (z->ICR, 0);
  899         WAITFOR (inb (z->CSBR) & CSBR_REQ, 10000, "MSGIN");
  900 
  901         /* Hope we get an IDENTIFY message. */
  902         msg = nca_msg_input (z);
  903         if (MSG_ISIDENT (msg)) {
  904                 /* Find the command corresponding to the I_T_L or I_T_L_Q
  905                  * nexus we just restablished, and remove it from
  906                  * the disconnected queue. */
  907                 lun = (msg & 7);
  908                 for (q=z->disconnected_queue; q; prev=q, q=q->next) {
  909                         if (target_mask != (1 << q->xfer->sc_link->target))
  910                                 continue;
  911                         if (lun != q->xfer->sc_link->lun)
  912                                 continue;
  913                         if (prev)
  914                                 prev->next = q->next;
  915                         else
  916                                 z->disconnected_queue = q->next;
  917                         q->next = 0;
  918                         PRINT (("nca%d/%d/%d reselect done\n",
  919                                 z->sc_link.adapter_unit,
  920                                 ffs (target_mask) - 1, lun));
  921                         nca_information_transfer (z, q);
  922                         WAITFOR (! (inb (z->CSBR) & CSBR_BSY), 100000, "reselect !busy");
  923                         return (1);
  924                 }
  925         } else
  926                 printf ("nca%d reselect: expecting IDENTIFY, got 0x%x\n",
  927                         z->sc_link.adapter_unit, msg);
  928 
  929         /* Since we have an established nexus that we can't
  930          * do anything with, we must abort it. */
  931         nca_send_abort (z);
  932         PRINT (("nca%d reselect aborted\n", z->sc_link.adapter_unit));
  933         WAITFOR (! (inb (z->CSBR) & CSBR_BSY), 100000, "reselect abort !busy");
  934         goto again;
  935 }
  936 
  937 /*
  938  * Send an abort to the target.
  939  * Return 1 success, 0 on failure.
  940  * Called on splbio level.
  941  */
  942 int nca_abort (adapter_t *z, scb_t *scb)
  943 {
  944         scb_t *q, **prev;
  945 
  946         /* If the command hasn't been issued yet, we simply remove it
  947          * from the issue queue. */
  948         prev = &z->queue;
  949         for (q=z->queue; q; q=q->next) {
  950                 if (scb == q) {
  951                         (*prev) = q->next;
  952                         q->next = 0;
  953                         return (1);
  954                 }
  955                 prev = &q->next;
  956         }
  957 
  958         /* If the command is currently disconnected from the bus,
  959          * we reconnect the I_T_L or I_T_L_Q nexus associated with it,
  960          * go into message out, and send an abort message. */
  961         for (q=z->disconnected_queue; q; q=q->next) {
  962                 if (scb != q)
  963                         continue;
  964 
  965                 if (! nca_select (z, scb))
  966                         return (0);
  967                 nca_send_abort (z);
  968 
  969                 prev = &z->disconnected_queue;
  970                 for (q=z->disconnected_queue; q; q=q->next) {
  971                         if (scb == q) {
  972                                 *prev = q->next;
  973                                 q->next = 0;
  974                                 /* Set some type of error result
  975                                  * for the operation. */
  976                                 return (1);
  977                         }
  978                         prev = &q->next;
  979                 }
  980         }
  981 
  982         /* Command not found in any queue. */
  983         return (0);
  984 }
  985 
  986 /*
  987  * The task accomplished, mark the i/o control block as done.
  988  * Always called with interrupts disabled.
  989  */
  990 void nca_done (adapter_t *z, scb_t *scb)
  991 {
  992         struct scsi_xfer *xs = scb->xfer;
  993 
  994         if (scb->flags & SCB_TIMECHK)
  995                 untimeout (nca_timeout, (caddr_t) scb);
  996 
  997         /* How much of the buffer was not touched. */
  998         xs->resid = scb->datalen;
  999 
 1000         if (scb->flags != SCB_ACTIVE && ! (xs->flags & SCSI_ERR_OK))
 1001                 if (scb->flags & (SCB_TIMEOUT | SCB_ABORTED))
 1002                         xs->error = XS_TIMEOUT;
 1003                 else if (scb->flags & SCB_ERROR)
 1004                         xs->error = XS_DRIVER_STUFFUP;
 1005                 else if (scb->flags & SCB_TBUSY)
 1006                         xs->error = XS_BUSY;
 1007                 else if (scb->flags & SCB_SENSE)
 1008                         xs->error = XS_SENSE;
 1009 
 1010         xs->flags |= ITSDONE;
 1011 
 1012         /* Free the control block. */
 1013         scb->next = z->free_scb;
 1014         z->free_scb = scb;
 1015         scb->flags = SCB_FREE;
 1016 
 1017         /* If there were none, wake anybody waiting for one to come free,
 1018          * starting with queued entries. */
 1019         if (! scb->next)
 1020                 wakeup ((caddr_t) &z->free_scb);
 1021 
 1022         scsi_done (xs);
 1023 }
 1024 
 1025 /*
 1026  * Wait for completion of command in polled mode.
 1027  * Always called with interrupts masked out.
 1028  */
 1029 int nca_poll (adapter_t *z, scb_t *scb)
 1030 {
 1031         int count;
 1032 
 1033         for (count=0; count<30; ++count) {
 1034                 DELAY (1000);                   /* delay for a while */
 1035                 nca_start (z);                  /* retry operation */
 1036                 if (scb->xfer->flags & ITSDONE)
 1037                         return (1);             /* all is done */
 1038                 if (scb->flags & SCB_TIMEOUT)
 1039                         return (0);             /* no target present */
 1040         }
 1041         return (0);
 1042 }
 1043 
 1044 /*
 1045  * Perform NCR-53C400 pseudo-dma data transfer.
 1046  */
 1047 void nca_53400_dma_xfer (adapter_t *z, int read, u_char **pdata, u_long *plen)
 1048 {
 1049         /* Set dma direction. */
 1050         outb (z->CSR, read ? CSR_TRANSFER_DIRECTION : 0);
 1051 
 1052         /* Enable dma mode. */
 1053         outb (z->MR, MR_DMA_MODE | (read ? z->parity : 0));
 1054 
 1055         /* Start dma transfer. */
 1056         outb (read ? z->SDIR : z->SDSR, 0);
 1057 
 1058         /* Set up clock counter. */
 1059         outb (z->CCR, *plen/128);
 1060 
 1061         for (; *plen>=128; *plen-=128, *pdata+=128) {
 1062                 /* Wait for 53C400 host buffer ready. */
 1063                 WAITFOR (! (inb (z->CSR) & CSR_HOST_BUF_NOT_READY), 100000, 0);
 1064                 if (inb (z->CSR) & CSR_HOST_BUF_NOT_READY)
 1065                         break;
 1066 
 1067                 /* Transfer 128 bytes of data. */
 1068                 if (read)
 1069                         insw (z->HBR, *pdata, 64);
 1070                 else
 1071                         outsw (z->HBR, *pdata, 64);
 1072         }
 1073 
 1074         /* Wait for 5380 registers ready. */
 1075         WAITFOR (inb (z->CSR) & CSR_5380_ENABLE, 10000, 0);
 1076         if (! (inb (z->CSR) & CSR_5380_ENABLE)) {
 1077                 /* Reset 53C400. */
 1078                 PRINT (("nca%d: reset: pseudo-dma incomplete, csr=%b\n",
 1079                         z->sc_link.adapter_unit, inb (z->CSR), CSR_BITS));
 1080                 outb (z->CSR, CSR_5380_ENABLE);
 1081                 outb (z->CSR, 0);
 1082         }
 1083 
 1084         /* Wait for FIFO flush on write. */
 1085         if (! read)
 1086                 WAITFOR (inb (z->TCR) & TCR_LAST_BYTE_SENT, 10000, "last byte");
 1087 
 1088         /* Clear dma mode. */
 1089         outb (z->MR, z->parity);
 1090 
 1091         /* Re-enable interrupts. */
 1092         outb (z->CSR, z->irq ? CSR_5380_INTR : 0);
 1093 }
 1094 
 1095 /*
 1096  * Perform PAS-16 pseudo-dma data transfer.
 1097  */
 1098 void nca_pas_dma_xfer (adapter_t *z, int read, u_char **pdata, u_long *plen)
 1099 {
 1100         /* Enable dma mode. */
 1101         outb (z->MR, MR_DMA_MODE | (read ? z->parity : 0));
 1102 
 1103         /* Start dma transfer. */
 1104         outb (read ? z->SDIR : z->SDSR, 0);
 1105 
 1106         for (; *plen>=512; *plen-=512, *pdata+=512) {
 1107                 /* Wait for pseudo-DMA request. */
 1108                 WAITFOR (inb (z->PSTAT) & PAS16_STAT_DREQ, 10000, "pseudo-dma");
 1109                 if (! (inb (z->PSTAT) & PAS16_STAT_DREQ))
 1110                         break;
 1111 
 1112                 /* Transfer 512 bytes of data. */
 1113                 if (read)
 1114                         insb (z->PDATA, *pdata, 512);
 1115                 else
 1116                         outsb (z->PDATA, *pdata, 512);
 1117         }
 1118 
 1119         /* Clear dma mode. */
 1120         outb (z->MR, z->parity);
 1121 }
 1122 
 1123 /*
 1124  * Send data to the target.
 1125  */
 1126 void nca_data_output (adapter_t *z, u_char **pdata, u_long *plen)
 1127 {
 1128         u_char *data = *pdata;
 1129         u_long len = *plen;
 1130 
 1131         outb (z->ICR, ICR_ASSERT_DATA_BUS);
 1132         if (z->type == CTLR_NCR_53C400 && len%128 == 0)
 1133                 /* Use NCR-53C400 pseudo-dma for data transfer. */
 1134                 nca_53400_dma_xfer (z, 0, &data, &len);
 1135         else if (z->type == CTLR_PAS_16 && len%512 == 0)
 1136                 /* Use PAS-16 pseudo-dma for data transfer. */
 1137                 nca_pas_dma_xfer (z, 0, &data, &len);
 1138         else
 1139                 for (;;) {
 1140                         /* Check SCSI bus phase. */
 1141                         u_char s = inb (z->CSBR) ^ (CSBR_BSY | PHASE_DATAOUT);
 1142                         if (s & (CSBR_BSY | PHASE_MASK))
 1143                                 break;
 1144 
 1145                         /* Wait for REQ. */
 1146                         if (! (s & CSBR_REQ))
 1147                                 continue;
 1148 
 1149                         /* Output data. */
 1150                         outb (z->ODR, *data++);
 1151 
 1152                         /* Assert ACK and wait for REQ deassert,
 1153                          * with irqs disabled. */
 1154                         disable_intr ();
 1155                         outb (z->ICR, ICR_ASSERT_ACK | ICR_ASSERT_DATA_BUS);
 1156                         WAITFOR (! (inb (z->CSBR) & CSBR_REQ), 1000, 0);
 1157                         enable_intr ();
 1158 
 1159                         /* Deassert ACK. */
 1160                         outb (z->ICR, ICR_ASSERT_DATA_BUS);
 1161                         --len;
 1162                 }
 1163         outb (z->ICR, 0);
 1164         PRINT (("nca (DATAOUT) send %ld bytes\n", *plen - len));
 1165         *plen = len;
 1166         *pdata = data;
 1167 }
 1168 
 1169 /*
 1170  * Receive data from the target.
 1171  */
 1172 void nca_data_input (adapter_t *z, u_char **pdata, u_long *plen)
 1173 {
 1174         u_char *data = *pdata;
 1175         u_long len = *plen;
 1176 
 1177         if (z->type == CTLR_NCR_53C400 && len%128 == 0)
 1178                 /* Use NCR-53C400 pseudo-dma for data transfer. */
 1179                 nca_53400_dma_xfer (z, 1, &data, &len);
 1180         else if (z->type == CTLR_PAS_16 && len%512 == 0)
 1181                 /* Use PAS-16 pseudo-dma for data transfer. */
 1182                 nca_pas_dma_xfer (z, 1, &data, &len);
 1183         else
 1184                 for (;;) {
 1185                         /* Check SCSI bus phase. */
 1186                         u_char s = inb (z->CSBR) ^ (CSBR_BSY | PHASE_DATAIN);
 1187                         if (s & (CSBR_BSY | PHASE_MASK))
 1188                                 break;
 1189 
 1190                         /* Wait for REQ. */
 1191                         if (! (s & CSBR_REQ))
 1192                                 continue;
 1193 
 1194                         /* Input data. */
 1195                         *data++ = inb (z->CSDR);
 1196 
 1197                         /* Assert ACK and wait for REQ deassert,
 1198                          * with irqs disabled. */
 1199                         disable_intr ();
 1200                         outb (z->ICR, ICR_ASSERT_ACK);
 1201                         WAITFOR (! (inb (z->CSBR) & CSBR_REQ), 1000, 0);
 1202                         enable_intr ();
 1203 
 1204                         /* Deassert ACK. */
 1205                         outb (z->ICR, 0);
 1206                         --len;
 1207                 }
 1208         PRINT (("nca (DATAIN) got %ld bytes\n", *plen - len));
 1209         *plen = len;
 1210         *pdata = data;
 1211 }
 1212 
 1213 /*
 1214  * Send the command to the target.
 1215  */
 1216 void nca_cmd_output (adapter_t *z, u_char *cmd, int cmdlen)
 1217 {
 1218         PRINT (("nca%d send command (%d bytes) ", z->sc_link.adapter_unit,
 1219                 cmdlen));
 1220 
 1221         outb (z->ICR, ICR_ASSERT_DATA_BUS);
 1222         while (cmdlen) {
 1223                 /* Check for target disconnect. */
 1224                 u_char sts = inb (z->CSBR);
 1225                 if (! (sts & CSBR_BSY))
 1226                         break;
 1227 
 1228                 /* Check for phase mismatch. */
 1229                 if ((sts & PHASE_MASK) != PHASE_CMDOUT) {
 1230                         printf ("nca: sending command: invalid phase %s\n",
 1231                                 PHASE_NAME (sts & PHASE_MASK));
 1232                         break;
 1233                 }
 1234 
 1235                 /* Wait for REQ. */
 1236                 if (! (sts & CSBR_REQ))
 1237                         continue;
 1238 
 1239                 PRINT (("-%x", *cmd));
 1240                 nca_sendbyte (z, *cmd++);
 1241                 --cmdlen;
 1242         }
 1243         outb (z->ICR, 0);
 1244         PRINT (("\n"));
 1245 }
 1246 
 1247 /*
 1248  * Send the message to the target.
 1249  */
 1250 void nca_send_abort (adapter_t *z)
 1251 {
 1252         u_char sts;
 1253 
 1254         outb (z->ICR, ICR_ASSERT_ATN);
 1255 
 1256         /* Wait for REQ, after which the phase bits will be valid. */
 1257         WAITFOR (inb (z->CSBR) & CSBR_REQ, 1000000, "abort message");
 1258         sts = inb (z->CSBR);
 1259         if (! (sts & CSBR_REQ))
 1260                 goto ret;
 1261 
 1262         /* Check for phase mismatch. */
 1263         if ((sts & PHASE_MASK) != PHASE_MSGOUT) {
 1264                 printf ("nca: sending MSG_ABORT: invalid phase %s\n",
 1265                         PHASE_NAME (sts & PHASE_MASK));
 1266                 goto ret;
 1267         }
 1268 
 1269         outb (z->ICR, ICR_ASSERT_DATA_BUS);
 1270         outb (z->TCR, PHASE_TO_TCR (PHASE_MSGOUT));
 1271         nca_sendbyte (z, MSG_ABORT);
 1272 
 1273         PRINT (("nca%d send MSG_ABORT\n", z->sc_link.adapter_unit));
 1274 ret:    outb (z->ICR, 0);
 1275 }
 1276 
 1277 /*
 1278  * Get the message from the target.
 1279  * Return the length of the received message.
 1280  */
 1281 u_char nca_msg_input (adapter_t *z)
 1282 {
 1283         u_char sts, msg;
 1284 
 1285         /* Wait for REQ, after which the phase bits will be valid. */
 1286         WAITFOR (inb (z->CSBR) & CSBR_REQ, 1000000, "message input");
 1287         sts = inb (z->CSBR);
 1288         if (! (sts & CSBR_REQ))
 1289                 return (MSG_ABORT);
 1290 
 1291         /* Check for phase mismatch.
 1292          * Reached if the target decides that it has finished the transfer. */
 1293         if ((sts & PHASE_MASK) != PHASE_MSGIN) {
 1294                 printf ("nca: sending message: invalid phase %s\n",
 1295                         PHASE_NAME (sts & PHASE_MASK));
 1296                 return (MSG_ABORT);
 1297         }
 1298 
 1299         /* Do actual transfer from SCSI bus to memory. */
 1300         outb (z->TCR, PHASE_TO_TCR (PHASE_MSGIN));
 1301         msg = nca_recvbyte (z);
 1302         PRINT (("nca%d (MSG_INPUT) got 0x%x\n", z->sc_link.adapter_unit, msg));
 1303         return (msg);
 1304 }
 1305 
 1306 /*
 1307  * Send request-sense op to the target.
 1308  * Return 1 success, 0 on failure.
 1309  * Called on splbio level.
 1310  */
 1311 int nca_sense (adapter_t *z, scb_t *scb)
 1312 {
 1313         u_char cmd[6], status, msg, *data;
 1314         u_long len;
 1315 
 1316         /* Wait for target to disconnect. */
 1317         WAITFOR (! (inb (z->CSBR) & CSBR_BSY), 100000, "sense bus free");
 1318         if (inb (z->CSBR) & CSBR_BSY)
 1319                 return (0);
 1320 
 1321         /* Select the target again. */
 1322         if (! nca_select (z, scb))
 1323                 return (0);
 1324 
 1325         /* Wait for CMDOUT phase. */
 1326         WAITFOR (inb (z->CSBR) & CSBR_REQ, 100000, "sense CMDOUT");
 1327         if (! (inb (z->CSBR) & CSBR_REQ) ||
 1328             (inb (z->CSBR) & PHASE_MASK) != PHASE_CMDOUT)
 1329                 return (0);
 1330         outb (z->TCR, PHASE_TO_TCR (PHASE_CMDOUT));
 1331 
 1332         /* Send command. */
 1333         len = sizeof (scb->xfer->sense);
 1334         cmd[0] = REQUEST_SENSE;
 1335         cmd[1] = scb->xfer->sc_link->lun << 5;
 1336         cmd[2] = 0;
 1337         cmd[3] = 0;
 1338         cmd[4] = len;
 1339         cmd[5] = 0;
 1340         nca_cmd_output (z, cmd, sizeof (cmd));
 1341 
 1342         /* Wait for DATAIN phase. */
 1343         WAITFOR (inb (z->CSBR) & CSBR_REQ, 100000, "sense DATAIN");
 1344         if (! (inb (z->CSBR) & CSBR_REQ) ||
 1345             (inb (z->CSBR) & PHASE_MASK) != PHASE_DATAIN)
 1346                 return (0);
 1347         outb (z->TCR, PHASE_TO_TCR (PHASE_DATAIN));
 1348 
 1349         data = (u_char*) &scb->xfer->sense;
 1350         nca_data_input (z, &data, &len);
 1351         PRINT (("nca%d sense %x-%x-%x-%x-%x-%x-%x-%x\n",
 1352                 z->sc_link.adapter_unit, scb->xfer->sense.error_code,
 1353                 scb->xfer->sense.ext.extended.segment,
 1354                 scb->xfer->sense.ext.extended.flags,
 1355                 scb->xfer->sense.ext.extended.info[0],
 1356                 scb->xfer->sense.ext.extended.info[1],
 1357                 scb->xfer->sense.ext.extended.info[2],
 1358                 scb->xfer->sense.ext.extended.info[3],
 1359                 scb->xfer->sense.ext.extended.extra_len));
 1360 
 1361         /* Wait for STATIN phase. */
 1362         WAITFOR (inb (z->CSBR) & CSBR_REQ, 100000, "sense STATIN");
 1363         if (! (inb (z->CSBR) & CSBR_REQ) ||
 1364             (inb (z->CSBR) & PHASE_MASK) != PHASE_STATIN)
 1365                 return (0);
 1366         outb (z->TCR, PHASE_TO_TCR (PHASE_STATIN));
 1367 
 1368         status = nca_recvbyte (z);
 1369 
 1370         /* Wait for MSGIN phase. */
 1371         WAITFOR (inb (z->CSBR) & CSBR_REQ, 100000, "sense MSGIN");
 1372         if (! (inb (z->CSBR) & CSBR_REQ) ||
 1373             (inb (z->CSBR) & PHASE_MASK) != PHASE_MSGIN)
 1374                 return (0);
 1375         outb (z->TCR, PHASE_TO_TCR (PHASE_MSGIN));
 1376 
 1377         msg = nca_recvbyte (z);
 1378 
 1379         if (status != 0 || msg != 0)
 1380                 printf ("nca%d: bad sense status=0x%x, msg=0x%x\n",
 1381                         z->sc_link.adapter_unit, status, msg);
 1382         return (1);
 1383 }
 1384 
 1385 /*
 1386  * Do the transfer. We know we are connected. Update the flags,
 1387  * call nca_done when task accomplished. Dialog controlled by the target.
 1388  * Always called with interrupts disabled.
 1389  */
 1390 void nca_information_transfer (adapter_t *z, scb_t *scb)
 1391 {
 1392         u_char *data = scb->data;               /* current data buffer */
 1393         u_long datalen = scb->datalen;          /* current data transfer size */
 1394         register u_char sts;
 1395         u_char msg;
 1396 
 1397         while ((sts = inb (z->CSBR)) & CSBR_BSY) {
 1398                 /* We only have a valid SCSI phase when REQ is asserted. */
 1399                 if (! (sts & CSBR_REQ))
 1400                         continue;
 1401                 if (inb (z->BSR) & BSR_PARITY_ERROR) {
 1402                         int target = scb->xfer->sc_link->target;
 1403                         if (++z->target[target].perrcnt <= 8)
 1404                                 printf ("nca%d/%d/%d parity error\n",
 1405                                         z->sc_link.adapter_unit, target,
 1406                                         scb->xfer->sc_link->lun);
 1407                         if (z->target[target].perrcnt == 8)
 1408                                 printf ("nca%d/%d/%d too many parity errors, not logging any more\n",
 1409                                         z->sc_link.adapter_unit, target,
 1410                                         scb->xfer->sc_link->lun);
 1411                         /* Clear parity error. */
 1412                         inb (z->RPIR);
 1413                 }
 1414                 outb (z->TCR, PHASE_TO_TCR (sts & PHASE_MASK));
 1415                 switch (sts & PHASE_MASK) {
 1416                 case PHASE_DATAOUT:
 1417                         if (datalen <= 0) {
 1418                                 printf ("nca%d/%d/%d data length underflow\n",
 1419                                         z->sc_link.adapter_unit,
 1420                                         scb->xfer->sc_link->target,
 1421                                         scb->xfer->sc_link->lun);
 1422                                 /* send zero byte */
 1423                                 outb (z->ICR, ICR_ASSERT_DATA_BUS);
 1424                                 nca_sendbyte (z, 0);
 1425                                 outb (z->ICR, 0);
 1426                                 break;
 1427                         }
 1428                         nca_data_output (z, &data, &datalen);
 1429                         break;
 1430                 case PHASE_DATAIN:
 1431                         if (datalen <= 0) {
 1432                                 /* Get extra data.  Some devices (e.g. CDROMs)
 1433                                  * use fixed-length blocks (e.g. 2k),
 1434                                  * even if we need less. */
 1435                                 PRINT (("@"));
 1436                                 nca_recvbyte (z);
 1437                                 break;
 1438                         }
 1439                         nca_data_input (z, &data, &datalen);
 1440                         break;
 1441                 case PHASE_CMDOUT:
 1442                         nca_cmd_output (z, (u_char*) scb->xfer->cmd,
 1443                                 scb->xfer->cmdlen);
 1444                         break;
 1445                 case PHASE_STATIN:
 1446                         scb->xfer->status = nca_recvbyte (z);
 1447                         PRINT (("nca%d/%d/%d (STATIN) got 0x%x\n",
 1448                                 z->sc_link.adapter_unit,
 1449                                 scb->xfer->sc_link->target,
 1450                                 scb->xfer->sc_link->lun,
 1451                                 (u_char) scb->xfer->status));
 1452                         break;
 1453                 case PHASE_MSGOUT:
 1454                         /* Send no-op message. */
 1455                         outb (z->ICR, ICR_ASSERT_DATA_BUS);
 1456                         nca_sendbyte (z, MSG_NOP);
 1457                         outb (z->ICR, 0);
 1458                         PRINT (("nca%d/%d/%d (MSGOUT) send NOP\n",
 1459                                 z->sc_link.adapter_unit,
 1460                                 scb->xfer->sc_link->target,
 1461                                 scb->xfer->sc_link->lun));
 1462                         break;
 1463                 case PHASE_MSGIN:
 1464                         /* Don't handle multi-byte messages here, because they
 1465                          * should not be present here. */
 1466                         msg = nca_recvbyte (z);
 1467                         PRINT (("nca%d/%d/%d (MSGIN) got 0x%x\n",
 1468                                 z->sc_link.adapter_unit,
 1469                                 scb->xfer->sc_link->target,
 1470                                 scb->xfer->sc_link->lun, msg));
 1471                         switch (msg) {
 1472                         case MSG_COMMAND_COMPLETE:
 1473                                 scb->data = data;
 1474                                 scb->datalen = datalen;
 1475                                 /* In the case of check-condition status,
 1476                                  * perform the request-sense op. */
 1477                                 switch (scb->xfer->status & 0x1e) {
 1478                                 case SCSI_CHECK:
 1479                                         if (nca_sense (z, scb))
 1480                                                 scb->flags = SCB_SENSE;
 1481                                         break;
 1482                                 case SCSI_BUSY:
 1483                                         scb->flags = SCB_TBUSY;
 1484                                         break;
 1485                                 }
 1486                                 goto done;
 1487                         case MSG_ABORT:
 1488                                 printf ("nca: command aborted by target\n");
 1489                                 scb->flags = SCB_ABORTED;
 1490                                 goto done;
 1491                         case MSG_MESSAGE_REJECT:
 1492                                 printf ("nca: message rejected\n");
 1493                                 scb->flags = SCB_ABORTED;
 1494                                 goto done;
 1495                         case MSG_DISCONNECT:
 1496                                 scb->next = z->disconnected_queue;
 1497                                 z->disconnected_queue = scb;
 1498                                 if (! z->irq && ! z->timeout_active) {
 1499                                         timeout (nca_tick, z, 1);
 1500                                         z->timeout_active = 1;
 1501                                 }
 1502                                 PRINT (("nca%d/%d/%d disconnected\n",
 1503                                         z->sc_link.adapter_unit,
 1504                                         scb->xfer->sc_link->target,
 1505                                         scb->xfer->sc_link->lun));
 1506                                 goto ret;
 1507                         case MSG_SAVE_POINTERS:
 1508                                 scb->data = data;
 1509                                 scb->datalen = datalen;
 1510                                 break;
 1511                         case MSG_RESTORE_POINTERS:
 1512                                 data = scb->data;
 1513                                 datalen = scb->datalen;
 1514                                 break;
 1515                         default:
 1516                                 printf ("nca%d/%d/%d unknown message: 0x%x\n",
 1517                                         z->sc_link.adapter_unit,
 1518                                         scb->xfer->sc_link->target,
 1519                                         scb->xfer->sc_link->lun, msg);
 1520                                 break;
 1521                         }
 1522                         break;
 1523                 default:
 1524                         printf ("nca: unknown phase: %b\n", sts, CSBR_BITS);
 1525                         break;
 1526                 }
 1527         }
 1528         printf ("nca%d/%d/%d unexpected target disconnect\n",
 1529                 z->sc_link.adapter_unit, scb->xfer->sc_link->target,
 1530                 scb->xfer->sc_link->lun);
 1531         scb->flags = SCB_ERROR;
 1532 done:
 1533         CLEAR_BUSY (z, scb);
 1534         nca_done (z, scb);
 1535 ret:
 1536         outb (z->ICR, 0);
 1537         outb (z->TCR, 0);
 1538         outb (z->SER, z->scsi_id);
 1539         WAITFOR (! (inb (z->CSBR) & CSBR_BSY), 100000, "xfer bus free");
 1540 }
 1541 #endif /* NNCA */

Cache object: 2d8d8673aea77996a19bea8191cb1a34


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.