home *** CD-ROM | disk | FTP | other *** search
/ PC-Online 1996 May / PCOnline_05_1996.bin / linux / source / kernel-s / v1.1 / scsi / 274x / aha274x / aic7770.pat < prev    next >
Text File  |  1995-10-10  |  89KB  |  3,203 lines

  1. diff -u --recursive --new-file linux-1.1.49/Makefile linux/Makefile
  2. --- linux-1.1.49/Makefile    Thu Sep  8 22:36:38 1994
  3. +++ linux/Makefile    Thu Sep  8 23:33:06 1994
  4. @@ -181,6 +181,7 @@
  5.      rm -f Image System.map tools/build
  6.      rm -f zBoot/zSystem zBoot/xtract zBoot/piggyback
  7.      rm -f .tmp* drivers/sound/configure
  8. +    rm -f drivers/scsi/aic7770
  9.  
  10.  mrproper: clean
  11.      rm -f include/linux/autoconf.h tools/version.h
  12. @@ -188,6 +189,7 @@
  13.      rm -f .version .config* config.in config.old
  14.      rm -f boot include/asm kernel/entry.S
  15.      rm -f .depend `find . -name .depend -print`
  16. +    rm -f drivers/scsi/aha274x_seq.h
  17.  
  18.  distclean: mrproper
  19.  
  20. diff -u --recursive --new-file linux-1.1.49/arch/i386/config.in linux/arch/i386/config.in
  21. --- linux-1.1.49/arch/i386/config.in    Thu Sep  8 22:34:56 1994
  22. +++ linux/arch/i386/config.in    Thu Sep  8 23:20:58 1994
  23. @@ -51,6 +51,7 @@
  24.  bool 'Adaptec AHA152X support' CONFIG_SCSI_AHA152X n
  25.  bool 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 y
  26.  bool 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 n
  27. +bool 'Adaptec AHA274X/284X support' CONFIG_SCSI_AHA274X y
  28.  bool 'BusLogic SCSI support' CONFIG_SCSI_BUSLOGIC n
  29.  bool 'Future Domain 16xx SCSI support' CONFIG_SCSI_FUTURE_DOMAIN n
  30.  bool 'Generic NCR5380 SCSI support' CONFIG_SCSI_GENERIC_NCR5380 n
  31. diff -u --recursive --new-file linux-1.1.49/drivers/scsi/Makefile linux/drivers/scsi/Makefile
  32. --- linux-1.1.49/drivers/scsi/Makefile    Tue Aug  2 08:02:16 1994
  33. +++ linux/drivers/scsi/Makefile    Fri Sep  9 00:14:34 1994
  34. @@ -21,6 +21,7 @@
  35.  
  36.  SCSI_OBJS =
  37.  SCSI_SRCS =
  38. +SCSI_HDRS =
  39.  
  40.  ifdef CONFIG_SCSI
  41.  
  42. @@ -62,6 +63,12 @@
  43.  SCSI_SRCS := $(SCSI_SRCS) aha1740.c
  44.  endif
  45.  
  46. +ifdef CONFIG_SCSI_AHA274X
  47. +SCSI_OBJS := $(SCSI_OBJS) aha274x.o
  48. +SCSI_SRCS := $(SCSI_SRCS) aha274x.c
  49. +SCSI_HDRS := $(SCSI_HDRS) aha274x_seq.h
  50. +endif
  51. +
  52.  ifdef CONFIG_SCSI_BUSLOGIC
  53.  SCSI_OBJS := $(SCSI_OBJS) buslogic.o
  54.  SCSI_SRCS := $(SCSI_SRCS) buslogic.c
  55. @@ -132,6 +139,11 @@
  56.  aha152x.o: aha152x.c
  57.      $(CC) $(CFLAGS) $(AHA152X) -c aha152x.c 
  58.  
  59. +aic7770: aic7770.c
  60. +    $(CC) $(CFLAGS) -o $@ aic7770.c
  61. +
  62. +aha274x_seq.h: aic7770 aha274x.seq
  63. +    aic7770 -o$@ aha274x.seq
  64.  
  65.  seagate.o: seagate.c
  66.      $(CC) $(CFLAGS) -DARBITRATE -DSLOW_HANDSHAKE -DFAST32 -c seagate.c 
  67. @@ -147,7 +159,7 @@
  68.      mv scriptu.h 53c8xx_u.h
  69.      rm fake.c
  70.  
  71. -dep:
  72. +dep: $(SCSI_HDRS)
  73.      $(CPP) -M $(AHA152X) $(SCSI_SRCS) > .depend
  74.  
  75.  else
  76. diff -u --recursive --new-file linux-1.1.49/drivers/scsi/aha274x.c linux/drivers/scsi/aha274x.c
  77. --- linux-1.1.49/drivers/scsi/aha274x.c    Wed Dec 31 16:00:00 1969
  78. +++ linux/drivers/scsi/aha274x.c    Thu Sep  8 23:20:59 1994
  79. @@ -0,0 +1,1428 @@
  80. +/*
  81. + *  @(#)aha274x.c 1.25 94/09/06 jda
  82. + *
  83. + *  Adaptec 274x device driver for Linux.
  84. + *  Copyright (c) 1994 The University of Calgary Department of Computer Science.
  85. + *  
  86. + *  This program is free software; you can redistribute it and/or modify
  87. + *  it under the terms of the GNU General Public License as published by
  88. + *  the Free Software Foundation; either version 2 of the License, or
  89. + *  (at your option) any later version.
  90. + *  
  91. + *  This program is distributed in the hope that it will be useful,
  92. + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  93. + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  94. + *  GNU General Public License for more details.
  95. + *  
  96. + *  You should have received a copy of the GNU General Public License
  97. + *  along with this program; if not, write to the Free Software
  98. + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  99. + *
  100. + *  Sources include the Adaptec 1740 driver (aha1740.c), the
  101. + *  Ultrastor 24F driver (ultrastor.c), various Linux kernel
  102. + *  source, the Adaptec EISA config file (!adp7771.cfg), the
  103. + *  Adaptec AHA-2740A Series User's Guide, the Linux Kernel
  104. + *  Hacker's Guide, Writing a SCSI Device Driver for Linux,
  105. + *  the Adaptec 1542 driver (aha1542.c), the Adaptec EISA
  106. + *  overlay file (adp7770.ovl), the Adaptec AHA-2740 Series
  107. + *  Technical Reference Manual, the Adaptec AIC-7770 Data
  108. + *  Book, the ANSI SCSI specification, the ANSI SCSI-2
  109. + *  specification (draft 10c), ...
  110. + *
  111. + *  On a twin-bus adapter card, channel B is ignored.  Rationale:
  112. + *  it would greatly complicate the sequencer and host driver code,
  113. + *  and both busses are multiplexed on to the EISA bus anyway.  So
  114. + *  I don't really see any technical advantage to supporting both.
  115. + *
  116. + *  As well, multiple adapter card using the same IRQ level are
  117. + *  not supported.  It doesn't make sense to configure the cards
  118. + *  this way from a performance standpoint.  Not to mention that
  119. + *  the kernel would have to support two devices per registered IRQ.
  120. + */
  121. +
  122. +#include <stdarg.h>
  123. +#include <asm/io.h>
  124. +#include <linux/string.h>
  125. +#include <linux/kernel.h>
  126. +#include <linux/ioport.h>
  127. +#include <linux/delay.h>
  128. +
  129. +#include "../block/blk.h"
  130. +#include "sd.h"
  131. +#include "scsi.h"
  132. +#include "hosts.h"
  133. +#include "aha274x.h"
  134. +
  135. +/*
  136. + *  There should be a specific return value for this in scsi.h, but
  137. + *  it seems that most drivers ignore it.
  138. + */
  139. +#define DID_UNDERFLOW    DID_ERROR
  140. +
  141. +/* EISA stuff */
  142. +
  143. +#define MINEISA        1
  144. +#define MAXEISA        15
  145. +#define SLOTBASE(x)    ((x) << 12)
  146. +
  147. +#define MAXIRQ        15
  148. +
  149. +/* AIC-7770 offset definitions */
  150. +
  151. +#define O_MINREG(x)    ((x) + 0xc00)        /* i/o range to reserve */
  152. +#define O_MAXREG(x)    ((x) + 0xcbf)
  153. +
  154. +#define O_SCSISEQ(x)    ((x) + 0xc00)        /* scsi sequence control */
  155. +#define O_SCSISIGI(x)    ((x) + 0xc03)        /* scsi control signal read */
  156. +#define O_SCSISIGO(x)    ((x) + 0xc03)        /* scsi control signal write */
  157. +#define O_SCSIID(x)    ((x) + 0xc05)        /* scsi id */
  158. +#define O_SSTAT0(x)    ((x) + 0xc0b)        /* scsi status register 0 */
  159. +#define O_CLRSINT1(x)    ((x) + 0xc0c)        /* clear scsi interrupt 1 */
  160. +#define O_SSTAT1(x)    ((x) + 0xc0c)        /* scsi status register 1 */
  161. +#define O_SELID(x)    ((x) + 0xc19)        /* [re]selection id */
  162. +#define O_SBLKCTL(x)    ((x) + 0xc1f)        /* scsi block control */
  163. +#define O_SEQCTL(x)    ((x) + 0xc60)        /* sequencer control */
  164. +#define O_SEQRAM(x)    ((x) + 0xc61)        /* sequencer ram data */
  165. +#define O_SEQADDR(x)    ((x) + 0xc62)        /* sequencer address (W) */
  166. +#define O_BIDx(x)    ((x) + 0xc80)        /* board id */
  167. +#define O_BCTL(x)    ((x) + 0xc84)        /* board control */
  168. +#define O_HCNTRL(x)    ((x) + 0xc87)        /* host control */
  169. +#define O_SCBPTR(x)    ((x) + 0xc90)        /* scb pointer */
  170. +#define O_INTSTAT(x)    ((x) + 0xc91)        /* interrupt status */
  171. +#define O_ERROR(x)    ((x) + 0xc92)        /* hard error */
  172. +#define O_CLRINT(x)    ((x) + 0xc92)        /* clear interrupt status */
  173. +#define O_SCBCNT(x)    ((x) + 0xc9a)        /* scb auto increment */
  174. +#define O_QINFIFO(x)    ((x) + 0xc9b)        /* queue in fifo */
  175. +#define O_QINCNT(x)    ((x) + 0xc9c)        /* queue in count */
  176. +#define O_QOUTFIFO(x)    ((x) + 0xc9d)        /* queue out fifo */
  177. +#define O_QOUTCNT(x)    ((x) + 0xc9e)        /* queue out count */
  178. +#define O_SCBARRAY(x)    ((x) + 0xca0)        /* scb array start */
  179. +
  180. +/* host adapter offset definitions */
  181. +
  182. +#define HA_REJBYTE(x)    ((x) + 0xc31)        /* 1st message in byte */
  183. +#define HA_MSG_FLAGS(x)    ((x) + 0xc35)        /* outgoing message flag */
  184. +#define HA_MSG_LEN(x)    ((x) + 0xc36)        /* outgoing message length */
  185. +#define HA_MSG_START(x)    ((x) + 0xc37)        /* outgoing message body */
  186. +#define HA_ARG_1(x)    ((x) + 0xc4c)        /* sdtr <-> rate parameters */
  187. +#define HA_ARG_2(x)    ((x) + 0xc4d)
  188. +#define HA_RETURN_1(x)    ((x) + 0xc4c)
  189. +#define HA_RETURN_2(x)    ((x) + 0xc4d)
  190. +#define HA_SIGSTATE(x)    ((x) + 0xc4e)        /* value in SCSISIGO */
  191. +#define HA_NEEDSDTR(x)    ((x) + 0xc4f)        /* synchronous negotiation? */
  192. +
  193. +#define HA_SCSICONF(x)    ((x) + 0xc5a)        /* SCSI config register */
  194. +#define HA_INTDEF(x)    ((x) + 0xc5c)        /* interrupt def'n register */
  195. +#define HA_HOSTCONF(x)    ((x) + 0xc5d)        /* host config def'n register */
  196. +
  197. +/* debugging code */
  198. +
  199. +#define AHA274X_DEBUG
  200. +
  201. +/*
  202. + *  If a parity error occurs during a data transfer phase, run the
  203. + *  command to completion - it's easier that way - making a note
  204. + *  of the error condition in this location.  This then will modify
  205. + *  a DID_OK status into a DID_PARITY one for the higher-level SCSI
  206. + *  code.
  207. + */
  208. +#define aha274x_parity(cmd)    ((cmd)->SCp.Status)
  209. +
  210. +/*
  211. + *  Since the sequencer code DMAs the scatter-gather structures
  212. + *  directly from memory, we use this macro to assert that the
  213. + *  kernel structure hasn't changed.
  214. + */
  215. +#define SG_STRUCT_CHECK(sg) \
  216. +    ((char *)&(sg).address - (char *)&(sg) != 0 ||    \
  217. +     (char *)&(sg).length  - (char *)&(sg) != 8 ||    \
  218. +     sizeof((sg).address) != 4 ||            \
  219. +     sizeof((sg).length)  != 4 ||            \
  220. +     sizeof(sg)          != 12)
  221. +
  222. +/*
  223. + *  "Static" structures.  Note that these are NOT initialized
  224. + *  to zero inside the kernel - we have to initialize them all
  225. + *  explicitly.
  226. + *
  227. + *  We support a maximum of one adapter card per IRQ level (see the
  228. + *  rationale for this above).  On an interrupt, use the IRQ as an
  229. + *  index into aha274x_boards[] to locate the card information.
  230. + */
  231. +static struct Scsi_Host *aha274x_boards[MAXIRQ + 1];
  232. +
  233. +struct aha274x_host {
  234. +    int base;                    /* card base address */
  235. +    int unpause;                    /* value for HCNTRL */
  236. +    volatile Scsi_Cmnd *SCB_array[AHA274X_MAXSCB];    /* active commands */
  237. +};
  238. +
  239. +struct aha274x_scb {
  240. +    unsigned char control;
  241. +    unsigned char target_channel_lun;        /* 4/1/3 bits */
  242. +    unsigned char SG_segment_count;
  243. +    unsigned char SG_list_pointer[4];
  244. +    unsigned char SCSI_cmd_pointer[4];
  245. +    unsigned char SCSI_cmd_length;
  246. +    unsigned char RESERVED[2];            /* must be zero */
  247. +    unsigned char target_status;
  248. +    unsigned char residual_data_count[3];
  249. +    unsigned char residual_SG_segment_count;
  250. +    unsigned char data_pointer[4];
  251. +    unsigned char data_count[3];
  252. +#if 0
  253. +    /*
  254. +     *  No real point in transferring this to the
  255. +     *  SCB registers.
  256. +     */
  257. +    unsigned char RESERVED[6];
  258. +#endif
  259. +};
  260. +
  261. +/*
  262. + *  NB.  This table MUST be ordered shortest period first.
  263. + */
  264. +static struct {
  265. +    short period;
  266. +    short rate;
  267. +    char *english;
  268. +} aha274x_synctab[] = {
  269. +    100,    0,    "10.0",
  270. +    125,    1,    "8.0",
  271. +    150,    2,    "6.67",
  272. +    175,    3,    "5.7",
  273. +    200,    4,    "5.0",
  274. +    225,    5,    "4.4",
  275. +    250,    6,    "4.0",
  276. +    275,    7,    "3.6"
  277. +};
  278. +
  279. +static int aha274x_synctab_max =
  280. +    sizeof(aha274x_synctab) / sizeof(aha274x_synctab[0]);
  281. +
  282. +enum aha_type {
  283. +    T_NONE,
  284. +    T_274X,
  285. +    T_284X,
  286. +    T_MAX
  287. +};
  288. +
  289. +#ifdef AHA274X_DEBUG
  290. +
  291. +    extern int vsprintf(char *, const char *, va_list);
  292. +
  293. +    static
  294. +    void debug(const char *fmt, ...)
  295. +    {
  296. +        va_list ap;
  297. +        char buf[256];
  298. +
  299. +        va_start(ap, fmt);
  300. +          vsprintf(buf, fmt, ap);
  301. +          printk(buf);
  302. +        va_end(ap);
  303. +    }
  304. +
  305. +    static
  306. +    void debug_config(enum aha_type type, int base)
  307. +    {
  308. +        int ioport2, ioport3, ioport4;
  309. +
  310. +        static char *BRT[T_MAX][16] = {
  311. +            { },                    /* T_NONE */
  312. +            {
  313. +                "2",   "???", "???", "12",    /* T_274X */
  314. +                "???", "???", "???", "28",
  315. +                "???", "???", "???", "44",
  316. +                "???", "???", "???", "60"
  317. +            },
  318. +            {
  319. +                "2",  "4",  "8",  "12",        /* T_284X */
  320. +                "16", "20", "24", "28",
  321. +                "32", "36", "40", "44",
  322. +                "48", "52", "56", "60"
  323. +            }
  324. +        };
  325. +        static int DFT[4] = {
  326. +            0, 50, 75, 100
  327. +        };
  328. +        static int SST[4] = {
  329. +            256, 128, 64, 32
  330. +        };
  331. +
  332. +        ioport2 = inb(HA_HOSTCONF(base));
  333. +        ioport3 = inb(HA_SCSICONF(base));
  334. +        ioport4 = inb(HA_INTDEF(base));
  335. +
  336. +        if (type == T_284X)
  337. +            printk("AHA284X AT SLOT %d:\n", base >> 12);
  338. +        else
  339. +            printk("AHA274X AT EISA SLOT %d:\n", base >> 12);
  340. +
  341. +        printk("    irq %d\n"
  342. +               "    bus release time %s bclks\n"
  343. +               "    data fifo threshold %d%%\n",
  344. +               ioport4 & 0xf,
  345. +               BRT[type][(ioport2 >> 2) & 0xf],
  346. +               DFT[(ioport2 >> 6) & 0x3]);
  347. +
  348. +        printk("    SCSI CHANNEL A:\n"
  349. +               "        scsi id %d\n"
  350. +               "        scsi bus parity check %sabled\n"
  351. +               "        scsi selection timeout %d ms\n"
  352. +               "        scsi bus reset at power-on %sabled\n",
  353. +               ioport3 & 0x7,
  354. +               (ioport3 & 0x20) ? "en" : "dis",
  355. +               SST[(ioport3 >> 3) & 0x3],
  356. +               (ioport3 & 0x40) ? "en" : "dis");
  357. +
  358. +        if (type == T_274X) {
  359. +            printk("        scsi bus termination %sabled\n",
  360. +                   (ioport3 & 0x80) ? "en" : "dis");
  361. +        }
  362. +    }
  363. +
  364. +    static
  365. +    void debug_rate(int base, int rate)
  366. +    {
  367. +        int target = inb(O_SCSIID(base)) >> 4;
  368. +
  369. +        if (rate) {
  370. +            printk("aha274x: target %d now synchronous at %sMb/s\n",
  371. +                   target,
  372. +                   aha274x_synctab[(rate >> 4) & 0x7].english);
  373. +        } else {
  374. +            printk("aha274x: target %d using asynchronous mode\n",
  375. +                   target);
  376. +        }
  377. +    }
  378. +
  379. +#else
  380. +
  381. +#    define debug(fmt, args...)
  382. +#    define debug_config(x)
  383. +#    define debug_rate(x,y)
  384. +
  385. +#endif AHA274X_DEBUG
  386. +
  387. +static
  388. +void aha274x_getscb(int base, struct aha274x_scb *scb)
  389. +{
  390. +    /*
  391. +     *  This is almost identical to aha274x_putscb().
  392. +     */
  393. +    outb(0x80, O_SCBCNT(base));    /* SCBAUTO */
  394. +
  395. +    asm volatile("cld\n\t"
  396. +             "rep\n\t"
  397. +             "insb"
  398. +             : /* no output */
  399. +             :"D" (scb), "c" (sizeof(*scb)), "d" (O_SCBARRAY(base))
  400. +             :"di", "cx", "dx");
  401. +
  402. +    outb(0, O_SCBCNT(base));
  403. +}
  404. +
  405. +/*
  406. + *  How much data should be transferred for this SCSI command?  Stop
  407. + *  at segment sg_last if it's a scatter-gather command so we can
  408. + *  compute underflow easily.
  409. + */
  410. +static
  411. +unsigned aha274x_length(Scsi_Cmnd *cmd, int sg_last)
  412. +{
  413. +    int i, segments;
  414. +    unsigned length;
  415. +    struct scatterlist *sg;
  416. +
  417. +    segments = cmd->use_sg - sg_last;
  418. +    sg = (struct scatterlist *)cmd->buffer;
  419. +
  420. +    if (cmd->use_sg) {
  421. +        for (i = length = 0;
  422. +             i < cmd->use_sg && i < segments;
  423. +             i++)
  424. +        {
  425. +            length += sg[i].length;
  426. +        }
  427. +    } else
  428. +        length = cmd->request_bufflen;
  429. +
  430. +    return(length);
  431. +}
  432. +
  433. +static
  434. +void aha274x_sg_check(Scsi_Cmnd *cmd)
  435. +{
  436. +    int i;
  437. +    struct scatterlist *sg = (struct scatterlist *)cmd->buffer;
  438. +
  439. +    if (cmd->use_sg) {
  440. +        for (i = 0; i < cmd->use_sg; i++)
  441. +            if ((unsigned)sg[i].length > 0xffff)
  442. +                panic("aha274x_sg_check: s/g segment > 64k\n");
  443. +    }
  444. +}
  445. +
  446. +static
  447. +void aha274x_to_scsirate(unsigned char *rate,
  448. +             unsigned char transfer,
  449. +             unsigned char offset)
  450. +{
  451. +    int i;
  452. +
  453. +    transfer *= 4;
  454. +
  455. +    for (i = 0; i < aha274x_synctab_max-1; i++) {
  456. +
  457. +        if (transfer == aha274x_synctab[i].period) {
  458. +            *rate = (aha274x_synctab[i].rate << 4) | (offset & 0xf);
  459. +            return;
  460. +        }
  461. +
  462. +        if (transfer > aha274x_synctab[i].period &&
  463. +            transfer < aha274x_synctab[i+1].period)
  464. +        {
  465. +            *rate = (aha274x_synctab[i+1].rate << 4) |
  466. +                (offset & 0xf);
  467. +            return;
  468. +        }
  469. +    }
  470. +    *rate = 0;
  471. +}
  472. +
  473. +/*
  474. + *  Pause the sequencer and wait for it to actually stop - this
  475. + *  is important since the sequencer can disable pausing for critical
  476. + *  sections.
  477. + */
  478. +#define PAUSE_SEQUENCER(p)    \
  479. +    do {                                \
  480. +        outb(0xe, O_HCNTRL(p->base));    /* IRQMS|PAUSE|INTEN */    \
  481. +                                    \
  482. +        while ((inb(O_HCNTRL(p->base)) & 0x4) == 0)        \
  483. +            ;                        \
  484. +    } while (0)
  485. +
  486. +/*
  487. + *  Unpause the sequencer.  Unremarkable, yet done often enough to
  488. + *  warrant an easy way to do it.
  489. + */
  490. +#define UNPAUSE_SEQUENCER(p)    \
  491. +    outb(p->unpause, O_HCNTRL(p->base))    /* IRQMS|INTEN */
  492. +
  493. +/*
  494. + *  See comments in aha274x_loadram() wrt this.
  495. + */
  496. +#define RESTART_SEQUENCER(p)    \
  497. +    do {                        \
  498. +        do {                    \
  499. +            outb(0x2, O_SEQCTL(p->base));    \
  500. +        } while (inw(O_SEQADDR(p->base)) != 0);    \
  501. +                            \
  502. +        UNPAUSE_SEQUENCER(p);            \
  503. +    } while (0)
  504. +
  505. +/*
  506. + *  Since we declared this using SA_INTERRUPT, interrupts should
  507. + *  be disabled all through this function unless we say otherwise.
  508. + */
  509. +static
  510. +void aha274x_isr(int irq)
  511. +{
  512. +    int base, intstat;
  513. +    struct aha274x_host *p;
  514. +    
  515. +    p = (struct aha274x_host *)aha274x_boards[irq]->hostdata;
  516. +    base = p->base;
  517. +
  518. +    /*
  519. +     *  Handle all the interrupt sources - especially for SCSI
  520. +     *  interrupts, we won't get a second chance at them.
  521. +     */
  522. +    intstat = inb(O_INTSTAT(base));
  523. +
  524. +    if (intstat & 0x8) {                /* BRKADRINT */
  525. +
  526. +        panic("aha274x_isr: brkadrint, error = 0x%x, seqaddr = 0x%x\n",
  527. +              inb(O_ERROR(base)), inw(O_SEQADDR(base)));
  528. +    }
  529. +
  530. +    if (intstat & 0x4) {                /* SCSIINT */
  531. +
  532. +        int scbptr = inb(O_SCBPTR(base));
  533. +        int status = inb(O_SSTAT1(base));
  534. +        Scsi_Cmnd *cmd;
  535. +
  536. +        cmd = (Scsi_Cmnd *)p->SCB_array[scbptr];
  537. +        if (!cmd) {
  538. +            printk("aha274x_isr: no command for scb (scsiint)\n");
  539. +            /*
  540. +             *  Turn off the interrupt and set status
  541. +             *  to zero, so that it falls through the
  542. +             *  reset of the SCSIINT code.
  543. +             */
  544. +            outb(status, O_CLRSINT1(base));
  545. +            UNPAUSE_SEQUENCER(p);
  546. +            outb(0x4, O_CLRINT(base));    /* undocumented */
  547. +            status = 0;
  548. +        }
  549. +        p->SCB_array[scbptr] = NULL;
  550. +
  551. +        /*
  552. +         *  Only the SCSI Status 1 register has information
  553. +         *  about exceptional conditions that we'd have a
  554. +         *  SCSIINT about; anything in SSTAT0 will be handled
  555. +         *  by the sequencer.  Note that there can be multiple
  556. +         *  bits set.
  557. +         */
  558. +        if (status & 0x80) {            /* SELTO */
  559. +            /*
  560. +             *  Hardware selection timer has expired.  Turn
  561. +             *  off SCSI selection sequence.
  562. +             */
  563. +            outb(0, O_SCSISEQ(base));
  564. +            cmd->result = DID_TIME_OUT << 16;
  565. +
  566. +            /*
  567. +             *  If there's an active message, it belongs to the
  568. +             *  command that is getting punted - remove it.
  569. +             */
  570. +            outb(0, HA_MSG_FLAGS(base));
  571. +
  572. +            /*
  573. +             *  Shut off the offending interrupt sources, reset
  574. +             *  the sequencer address to zero and unpause it,
  575. +             *  then call the high-level SCSI completion routine.
  576. +             *
  577. +             *  WARNING!  This is a magic sequence!  After many
  578. +             *  hours of guesswork, turning off the SCSI interrupts
  579. +             *  in CLRSINT? does NOT clear the SCSIINT bit in
  580. +             *  INTSTAT.  By writing to the (undocumented, unused
  581. +             *  according to the AIC-7770 manual) third bit of
  582. +             *  CLRINT, you can clear INTSTAT.  But, if you do it
  583. +             *  while the sequencer is paused, you get a BRKADRINT
  584. +             *  with an Illegal Host Address status, so the
  585. +             *  sequencer has to be restarted first.
  586. +             */
  587. +            outb(0x80, O_CLRSINT1(base));    /* CLRSELTIMO */
  588. +            RESTART_SEQUENCER(p);
  589. +
  590. +            outb(0x4, O_CLRINT(base));    /* undocumented */
  591. +            cmd->scsi_done(cmd);
  592. +        }
  593. +
  594. +        if (status & 0x4) {            /* SCSIPERR */
  595. +            /*
  596. +             *  A parity error has occurred during a data
  597. +             *  transfer phase.  Flag it and continue.
  598. +             */
  599. +            printk("aha274x: parity error on target %d, lun %d\n",
  600. +                   cmd->target,
  601. +                   cmd->lun);
  602. +            aha274x_parity(cmd) = DID_PARITY;
  603. +
  604. +            /*
  605. +             *  Clear interrupt and resume as above.
  606. +             */
  607. +            outb(0x4, O_CLRSINT1(base));    /* CLRSCSIPERR */
  608. +            UNPAUSE_SEQUENCER(p);
  609. +
  610. +            outb(0x4, O_CLRINT(base));    /* undocumented */
  611. +        }
  612. +
  613. +        if ((status & (0x8|0x4)) == 0 && status) {
  614. +            /*
  615. +             *  We don't know what's going on.  Turn off the
  616. +             *  interrupt source and try to continue.
  617. +             */
  618. +            printk("aha274x_isr: sstat1 = 0x%x\n", status);
  619. +            outb(status, O_CLRSINT1(base));
  620. +            UNPAUSE_SEQUENCER(p);
  621. +            outb(0x4, O_CLRINT(base));    /* undocumented */
  622. +        }
  623. +    }
  624. +
  625. +    if (intstat & 0x2) {                /* CMDCMPLT */
  626. +
  627. +        int complete, old_scbptr;
  628. +        struct aha274x_scb scb;
  629. +        unsigned actual;
  630. +        Scsi_Cmnd *cmd;
  631. +
  632. +        /*
  633. +         *  The sequencer will continue running when it
  634. +         *  issues this interrupt.  There may be >1 commands
  635. +         *  finished, so loop until we've processed them all.
  636. +         */
  637. +        do {
  638. +            complete = inb(O_QOUTFIFO(base));
  639. +
  640. +            cmd = (Scsi_Cmnd *)p->SCB_array[complete];
  641. +            if (!cmd) {
  642. +                printk("aha274x warning: "
  643. +                       "no command for scb (cmdcmplt)\n");
  644. +                continue;
  645. +            }
  646. +            p->SCB_array[complete] = NULL;
  647. +            
  648. +            PAUSE_SEQUENCER(p);
  649. +
  650. +            /*
  651. +             *  After pausing the sequencer (and waiting
  652. +             *  for it to stop), save its SCB pointer, then
  653. +             *  write in our completed one and read the SCB
  654. +             *  registers.  Afterwards, restore the saved
  655. +             *  pointer, unpause the sequencer and call the
  656. +             *  higher-level completion function - unpause
  657. +             *  first since we have no idea how long done()
  658. +             *  will take.
  659. +             */
  660. +            old_scbptr = inb(O_SCBPTR(base));
  661. +            outb(complete, O_SCBPTR(base));
  662. +
  663. +            aha274x_getscb(base, &scb);
  664. +            outb(old_scbptr, O_SCBPTR(base));
  665. +
  666. +            UNPAUSE_SEQUENCER(p);
  667. +
  668. +            cmd->result = scb.target_status |
  669. +                     (aha274x_parity(cmd) << 16);
  670. +
  671. +            /*
  672. +             *  Did we underflow?  At this time, there's only
  673. +             *  one other driver that bothers to check for this,
  674. +             *  and cmd->underflow seems to be set rather half-
  675. +             *  heartedly in the higher-level SCSI code.
  676. +             */
  677. +            actual = aha274x_length(cmd,
  678. +                        scb.residual_SG_segment_count);
  679. +
  680. +            actual -= ((scb.residual_data_count[2] << 16) |
  681. +                   (scb.residual_data_count[1] <<  8) |
  682. +                   (scb.residual_data_count[0]));
  683. +
  684. +            if (actual < cmd->underflow) {
  685. +                printk("aha274x: target %d underflow - "
  686. +                       "wanted (at least) %u, got %u\n",
  687. +                       cmd->target, cmd->underflow, actual);
  688. +
  689. +                cmd->result = scb.target_status |
  690. +                         (DID_UNDERFLOW << 16);
  691. +            }
  692. +
  693. +            cmd->scsi_done(cmd);
  694. +
  695. +            /*
  696. +             *  Clear interrupt status before checking
  697. +             *  the output queue again.  This eliminates
  698. +             *  a race condition whereby a command could
  699. +             *  complete between the queue poll and the
  700. +             *  interrupt clearing, so notification of the
  701. +             *  command being complete never made it back
  702. +             *  up to the kernel.
  703. +             */
  704. +            outb(0x2, O_CLRINT(base));    /* CLRCMDINT */
  705. +
  706. +        } while (inb(O_QOUTCNT(base)));
  707. +    }
  708. +
  709. +    if (intstat & 0x1) {                /* SEQINT */
  710. +
  711. +        unsigned char transfer, offset, rate;
  712. +
  713. +        /*
  714. +         *  Although the sequencer is paused immediately on
  715. +         *  a SEQINT, an interrupt for a SCSIINT or a CMDCMPLT
  716. +         *  condition will have unpaused the sequencer before
  717. +         *  this point.
  718. +         */
  719. +        PAUSE_SEQUENCER(p);
  720. +
  721. +        switch (intstat & 0xf0) {
  722. +            case 0x00:
  723. +            panic("aha274x_isr: unknown scsi bus phase\n");
  724. +            case 0x10:
  725. +            debug("aha274x_isr warning: "
  726. +                  "issuing message reject, 1st byte 0x%x\n",
  727. +                  inb(HA_REJBYTE(base)));
  728. +            break;
  729. +            case 0x20:
  730. +            panic("aha274x_isr: reconnecting target %d "
  731. +                  "didn't issue IDENTIFY message\n",
  732. +                  (inb(O_SELID(base)) >> 4) & 0xf);
  733. +            case 0x30:
  734. +            debug("aha274x_isr: sequencer couldn't find match "
  735. +                  "for reconnecting target %d - issuing ABORT\n",
  736. +                  (inb(O_SELID(base)) >> 4) & 0xf);
  737. +            break;
  738. +            case 0x40:
  739. +            transfer = inb(HA_ARG_1(base));
  740. +            offset = inb(HA_ARG_2(base));
  741. +            aha274x_to_scsirate(&rate, transfer, offset);
  742. +            outb(rate, HA_RETURN_1(base));
  743. +            debug_rate(base, rate);
  744. +            break;
  745. +            default:
  746. +            debug("aha274x_isr: seqint, "
  747. +                  "intstat = 0x%x, scsisigi = 0x%x\n",
  748. +                  intstat, inb(O_SCSISIGI(base)));
  749. +            break;
  750. +        }
  751. +
  752. +        outb(0x1, O_CLRINT(base));        /* CLRSEQINT */
  753. +        UNPAUSE_SEQUENCER(p);
  754. +    }
  755. +}
  756. +
  757. +/*
  758. + *  Probing for EISA boards: it looks like the first two bytes
  759. + *  are a manufacturer code - three characters, five bits each:
  760. + *
  761. + *         BYTE 0   BYTE 1   BYTE 2   BYTE 3
  762. + *        ?1111122 22233333 PPPPPPPP RRRRRRRR
  763. + *
  764. + *  The characters are baselined off ASCII '@', so add that value
  765. + *  to each to get the real ASCII code for it.  The next two bytes
  766. + *  appear to be a product and revision number, probably vendor-
  767. + *  specific.  This is what is being searched for at each port,
  768. + *  and what should probably correspond to the ID= field in the
  769. + *  ECU's .cfg file for the card - if your card is not detected,
  770. + *  make sure your signature is listed in the array.
  771. + *
  772. + *  The fourth byte's lowest bit seems to be an enabled/disabled
  773. + *  flag (rest of the bits are reserved?).
  774. + */
  775. +
  776. +static
  777. +enum aha_type aha274x_probe(int slot, int s_base)
  778. +{
  779. +    int i;
  780. +    unsigned char buf[4];
  781. +
  782. +    static struct {
  783. +        int n;
  784. +        unsigned char signature[sizeof(buf)];
  785. +        enum aha_type type;
  786. +    } S[] = {
  787. +        4, { 0x04, 0x90, 0x77, 0x71 }, T_274X,    /* host adapter 274x */
  788. +        4, { 0x04, 0x90, 0x77, 0x70 }, T_274X,    /* motherboard 274x  */
  789. +        4, { 0x04, 0x90, 0x77, 0x56 }, T_284X,    /* 284x, BIOS enabled */
  790. +    };
  791. +
  792. +    for (i = 0; i < sizeof(buf); i++) {
  793. +        /*
  794. +         *  The VL-bus cards need to be primed by
  795. +         *  writing before a signature check.
  796. +         */
  797. +        outb(0x80 + i, s_base);
  798. +        buf[i] = inb(s_base + i);
  799. +    }
  800. +
  801. +    for (i = 0; i < sizeof(S)/sizeof(S[0]); i++) {
  802. +        if (!memcmp(buf, S[i].signature, S[i].n)) {
  803. +            /*
  804. +             *  Signature match on enabled card?
  805. +             */
  806. +            if (inb(s_base + 4) & 1)
  807. +                return(S[i].type);
  808. +            printk("aha274x disabled at slot %d, ignored\n", slot);
  809. +        }
  810. +    }
  811. +    return(T_NONE);
  812. +}
  813. +
  814. +/*
  815. + *  Return ' ' for plain 274x, 'T' for twin-channel, 'W' for
  816. + *  wide channel, '?' for anything else.
  817. + */
  818. +
  819. +static
  820. +char aha274x_type(int base)
  821. +{
  822. +    /*
  823. +     *  The AIC-7770 can be wired so that, on chip reset,
  824. +     *  the SCSI Block Control register indicates how many
  825. +     *  busses the chip is configured for.
  826. +     */
  827. +    switch (inb(O_SBLKCTL(base))) {
  828. +        case 0:
  829. +        return(' ');
  830. +        case 2:
  831. +        return('W');
  832. +        case 8:
  833. +        return('T');
  834. +        default:
  835. +        printk("aha274x has unknown bus configuration\n");
  836. +        return('?');
  837. +    }
  838. +}
  839. +
  840. +static
  841. +void aha274x_loadram(int base)
  842. +{
  843. +    static unsigned char seqprog[] = {
  844. +        /*
  845. +         *  Each sequencer instruction is 29 bits
  846. +         *  long (fill in the excess with zeroes)
  847. +         *  and has to be loaded from least -> most
  848. +         *  significant byte, so this table has the
  849. +         *  byte ordering reversed.
  850. +         */
  851. +#        include "aha274x_seq.h"
  852. +    };
  853. +
  854. +    /*
  855. +     *  When the AIC-7770 is paused (as on chip reset), the
  856. +     *  sequencer address can be altered and a sequencer
  857. +     *  program can be loaded by writing it, byte by byte, to
  858. +     *  the sequencer RAM port - the Adaptec documentation
  859. +     *  recommends using REP OUTSB to do this, hence the inline
  860. +     *  assembly.  Since the address autoincrements as we load
  861. +     *  the program, reset it back to zero afterward.  Disable
  862. +     *  sequencer RAM parity error detection while loading, and
  863. +     *  make sure the LOADRAM bit is enabled for loading.
  864. +     */
  865. +    outb(0x83, O_SEQCTL(base));    /* PERRORDIS|SEQRESET|LOADRAM */
  866. +
  867. +    asm volatile("cld\n\t"
  868. +             "rep\n\t"
  869. +             "outsb"
  870. +             : /* no output */
  871. +             :"S" (seqprog), "c" (sizeof(seqprog)), "d" (O_SEQRAM(base))
  872. +             :"si", "cx", "dx");
  873. +
  874. +    /*
  875. +     *  WARNING!  This is a magic sequence!  After extensive
  876. +     *  experimentation, it seems that you MUST turn off the
  877. +     *  LOADRAM bit before you play with SEQADDR again, else
  878. +     *  you will end up with parity errors being flagged on
  879. +     *  your sequencer program.  (You would also think that
  880. +     *  turning off LOADRAM and setting SEQRESET to reset the
  881. +     *  address to zero would work, but you need to do it twice
  882. +     *  for it to take effect on the address.  Timing problem?)
  883. +     */
  884. +    outb(0, O_SEQCTL(base));
  885. +    do {
  886. +        /*
  887. +         *  Actually, reset it until
  888. +         *  the address shows up as
  889. +         *  zero just to be safe..
  890. +         */
  891. +        outb(0x2, O_SEQCTL(base));    /* SEQRESET */
  892. +
  893. +    } while (inw(O_SEQADDR(base)) != 0);
  894. +}
  895. +
  896. +static
  897. +int aha274x_register(Scsi_Host_Template *template,
  898. +             enum aha_type type,
  899. +             int base)
  900. +{
  901. +    int i, irq, scsi_id;
  902. +    struct Scsi_Host *host;
  903. +    struct aha274x_host *p;
  904. +
  905. +    /*
  906. +     *  Give the AIC-7770 a reset - reading the 274x's registers
  907. +     *  returns zeroes unless you do.  This forces a pause of the
  908. +     *  Sequencer.
  909. +     */
  910. +    outb(1, O_HCNTRL(base));    /* CHIPRST */
  911. +
  912. +    /*
  913. +     *  The IRQ level in i/o port 4 maps directly onto the real
  914. +     *  IRQ number.  If it's ok, register it with the kernel.
  915. +     *
  916. +     *  NB. the Adaptec documentation says the IRQ number is only
  917. +     *    in the lower four bits; the ECU information shows the
  918. +     *    high bit being used as well.  Which is correct?
  919. +     */
  920. +    irq = inb(HA_INTDEF(base)) & 0xf;
  921. +    if (irq < 9 || irq > 15) {
  922. +        printk("aha274x uses unsupported IRQ level, ignoring\n");
  923. +        return(0);
  924. +    }
  925. +    
  926. +    /*
  927. +     *  Lock out other contenders for our i/o space.
  928. +     */
  929. +    snarf_region(O_MINREG(base), O_MAXREG(base)-O_MINREG(base));
  930. +
  931. +    /*
  932. +     *  Any card-type-specific adjustments before we register
  933. +     *  the scsi host(s).
  934. +     */
  935. +
  936. +    scsi_id = inb(HA_SCSICONF(base)) & 0x7;
  937. +
  938. +    switch (aha274x_type(base)) {
  939. +        case 'T':
  940. +        printk("aha274x warning: ignoring channel B of 274x-twin\n");
  941. +        break;
  942. +        case ' ':
  943. +        break;
  944. +        default:
  945. +        printk("aha274x is an unsupported type, ignoring\n");
  946. +        free_irq(irq);
  947. +        return(0);
  948. +    }
  949. +
  950. +    /*
  951. +     *  Before registry, make sure that the offsets of the
  952. +     *  struct scatterlist are what the sequencer will expect,
  953. +     *  otherwise disable scatter-gather altogether until someone
  954. +     *  can fix it.  This is important since the sequencer will
  955. +     *  DMA elements of the SG array in while executing commands.
  956. +     */
  957. +    if (template->sg_tablesize != SG_NONE) {
  958. +        struct scatterlist sg;
  959. +
  960. +        if (SG_STRUCT_CHECK(sg)) {
  961. +            printk("aha274x warning: kernel scatter-gather "
  962. +                   "structures changed, disabling it\n");
  963. +            template->sg_tablesize = SG_NONE;
  964. +        }
  965. +    }
  966. +    
  967. +    /*
  968. +     *  Register each "host" and fill in the returned Scsi_Host
  969. +     *  structure as best we can.  Some of the parameters aren't
  970. +     *  really relevant for EISA, and none of the high-level SCSI
  971. +     *  code looks at it anyway.. why are the fields there?  Also
  972. +     *  save the pointer so that we can find the information when
  973. +     *  an IRQ is triggered.
  974. +     */
  975. +    host = scsi_register(template, sizeof(struct aha274x_host));
  976. +    host->this_id = scsi_id;
  977. +    host->irq = irq;
  978. +
  979. +    aha274x_boards[irq] = host;
  980. +    
  981. +    p = (struct aha274x_host *)host->hostdata;
  982. +    for (i = 0; i < AHA274X_MAXSCB; i++)
  983. +        p->SCB_array[i] = NULL;
  984. +    p->base = base;
  985. +
  986. +    /*
  987. +     *  The interrupt trigger is different depending
  988. +     *  on whether the card is EISA or VL-bus.
  989. +     */
  990. +    p->unpause = (type != T_274X ? 0x2 : 0xa);
  991. +
  992. +    /*
  993. +     *  Register IRQ with the kernel _after_ the host information
  994. +     *  is set up, in case we take an interrupt right away.
  995. +     *
  996. +     *  XXX - the card is reset and disabled, so why would we be
  997. +     *      getting an interrupt?
  998. +     */
  999. +    if (request_irq(irq, aha274x_isr, SA_INTERRUPT, "AHA274x/284x")) {
  1000. +        printk("aha274x couldn't register irq %d, ignoring\n", irq);
  1001. +        return(0);
  1002. +    }
  1003. +
  1004. +    /*
  1005. +     *  Print out debugging information before re-enabling
  1006. +     *  the card - a lot of registers on it can't be read
  1007. +     *  when the sequencer is active.
  1008. +     */
  1009. +    debug_config(type, base);
  1010. +
  1011. +    /*
  1012. +     *  Load the sequencer program, then re-enable the board -
  1013. +     *  resetting the AIC-7770 disables it, leaving the lights
  1014. +     *  on with nobody home.
  1015. +     */
  1016. +    aha274x_loadram(base);
  1017. +    outb(1, O_BCTL(base));        /* ENABLE */
  1018. +
  1019. +    /*
  1020. +     *  Set the host adapter registers to indicate that synchronous
  1021. +     *  negotiation should be attempted the first time the targets
  1022. +     *  are communicated with.  Also initialize the active message
  1023. +     *  flag to indicate that there is no message.
  1024. +     */
  1025. +    outb(0xff, HA_NEEDSDTR(base));
  1026. +    outb(0, HA_MSG_FLAGS(base));
  1027. +
  1028. +    /*
  1029. +     *  Unpause the sequencer before returning and enable
  1030. +     *  interrupts - we shouldn't get any until the first
  1031. +     *  command is sent to us by the high-level SCSI code.
  1032. +     */
  1033. +    UNPAUSE_SEQUENCER(p);
  1034. +    return(1);
  1035. +}
  1036. +
  1037. +int aha274x_detect(Scsi_Host_Template *template)
  1038. +{
  1039. +    enum aha_type type;
  1040. +    int found = 0, slot, base;
  1041. +
  1042. +    for (slot = MINEISA; slot <= MAXEISA; slot++) {
  1043. +
  1044. +        base = SLOTBASE(slot);
  1045. +        
  1046. +        if (check_region(O_MINREG(base),
  1047. +                 O_MAXREG(base)-O_MINREG(base)))
  1048. +        {
  1049. +            /*
  1050. +             *  Some other driver has staked a
  1051. +             *  claim to this i/o region already.
  1052. +             */
  1053. +            continue;
  1054. +        }
  1055. +
  1056. +        type = aha274x_probe(slot, O_BIDx(base));
  1057. +
  1058. +        if (type != T_NONE) {
  1059. +            /*
  1060. +             *  We "find" a 274x if we locate the card
  1061. +             *  signature and we can set it up and register
  1062. +             *  it with the kernel without incident.
  1063. +             */
  1064. +            found += aha274x_register(template, type, base);
  1065. +        }
  1066. +    }
  1067. +    template->name = (char *)aha274x_info();
  1068. +    return(found);
  1069. +}
  1070. +
  1071. +const char *aha274x_info(void)
  1072. +{
  1073. +    return("Adaptec AHA274x/284x (EISA/VL-bus -> Fast SCSI) "
  1074. +           AHA274X_SEQ_VERSION "/"
  1075. +           AHA274X_H_VERSION "/"
  1076. +           "1.25");
  1077. +}
  1078. +
  1079. +int aha274x_command(Scsi_Cmnd *cmd)
  1080. +{
  1081. +    /*
  1082. +     *  This is a relic of non-interrupt-driven SCSI
  1083. +     *  drivers.  With the can_queue variable set, this
  1084. +     *  should never be called.
  1085. +     */
  1086. +    panic("aha274x_command was called\n");
  1087. +}
  1088. +
  1089. +static
  1090. +void aha274x_buildscb(struct aha274x_host *p,
  1091. +              Scsi_Cmnd *cmd,
  1092. +              struct aha274x_scb *scb)
  1093. +{
  1094. +    void *addr;
  1095. +    unsigned length;
  1096. +
  1097. +    memset(scb, 0, sizeof(*scb));
  1098. +
  1099. +    /*
  1100. +     *  NB. channel selection (bit 3) is always zero.
  1101. +     */
  1102. +    scb->target_channel_lun = ((cmd->target << 4) & 0xf0) |
  1103. +                   (cmd->lun & 0x7);
  1104. +
  1105. +    /*
  1106. +     *  The interpretation of request_buffer and request_bufflen
  1107. +     *  changes depending on whether or not use_sg is zero; a
  1108. +     *  non-zero use_sg indicates the number of elements in the
  1109. +     *  scatter-gather array.
  1110. +     *
  1111. +     *  The AIC-7770 can't support transfers of any sort larger
  1112. +     *  than 2^24 (three-byte count) without backflips.  For what
  1113. +     *  the kernel is doing, this shouldn't occur.  I hope.
  1114. +     */
  1115. +    length = aha274x_length(cmd, 0);
  1116. +
  1117. +    /*
  1118. +     *  The sequencer code cannot yet handle scatter-gather segments
  1119. +     *  larger than 64k (two-byte length).  The 1.1.x kernels, however,
  1120. +     *  have a four-byte length field in the struct scatterlist, so
  1121. +     *  make sure we don't exceed 64k on these kernels for now.
  1122. +     */
  1123. +    aha274x_sg_check(cmd);
  1124. +
  1125. +    if (length > 0xffffff) {
  1126. +        panic("aha274x_buildscb: can't transfer > 2^24 - 1 bytes\n");
  1127. +    }
  1128. +
  1129. +    /*
  1130. +     *  XXX - this relies on the host data being stored in a
  1131. +     *      little-endian format.
  1132. +     */
  1133. +    addr = cmd->cmnd;
  1134. +    scb->SCSI_cmd_length = COMMAND_SIZE(cmd->cmnd[0]);
  1135. +    memcpy(scb->SCSI_cmd_pointer, &addr, sizeof(scb->SCSI_cmd_pointer));
  1136. +
  1137. +    if (cmd->use_sg) {
  1138. +#if 0
  1139. +        debug("aha274x_buildscb: SG used, %d segments, length %u\n",
  1140. +              cmd->use_sg,
  1141. +              length);
  1142. +#endif
  1143. +        scb->SG_segment_count = cmd->use_sg;
  1144. +        memcpy(scb->SG_list_pointer,
  1145. +               &cmd->request_buffer,
  1146. +               sizeof(scb->SG_list_pointer));
  1147. +    } else {
  1148. +        scb->SG_segment_count = 0;
  1149. +        memcpy(scb->data_pointer,
  1150. +               &cmd->request_buffer,
  1151. +               sizeof(scb->data_pointer));
  1152. +        memcpy(scb->data_count,
  1153. +               &cmd->request_bufflen,
  1154. +               sizeof(scb->data_count));
  1155. +    }
  1156. +}
  1157. +
  1158. +static
  1159. +void aha274x_putscb(int base, struct aha274x_scb *scb)
  1160. +{
  1161. +    /*
  1162. +     *  By turning on the SCB auto increment, any reference
  1163. +     *  to the SCB I/O space postincrements the SCB address
  1164. +     *  we're looking at.  So turn this on and dump the relevant
  1165. +     *  portion of the SCB to the card.
  1166. +     */
  1167. +    outb(0x80, O_SCBCNT(base));    /* SCBAUTO */
  1168. +
  1169. +    asm volatile("cld\n\t"
  1170. +             "rep\n\t"
  1171. +             "outsb"
  1172. +             : /* no output */
  1173. +             :"S" (scb), "c" (sizeof(*scb)), "d" (O_SCBARRAY(base))
  1174. +             :"si", "cx", "dx");
  1175. +
  1176. +    outb(0, O_SCBCNT(base));
  1177. +}
  1178. +
  1179. +int aha274x_queue(Scsi_Cmnd *cmd, void (*fn)(Scsi_Cmnd *))
  1180. +{
  1181. +    long flags;
  1182. +    int empty, old_scbptr;
  1183. +    struct aha274x_host *p;
  1184. +    struct aha274x_scb scb;
  1185. +
  1186. +#if 0
  1187. +    debug("aha274x_queue: cmd 0x%x (size %u), target %d, lun %d\n",
  1188. +          cmd->cmnd[0],
  1189. +          COMMAND_SIZE(cmd->cmnd[0]),
  1190. +          cmd->target,
  1191. +          cmd->lun);
  1192. +#endif
  1193. +
  1194. +    p = (struct aha274x_host *)cmd->host->hostdata;
  1195. +
  1196. +    /*
  1197. +     *  Construct the SCB beforehand, so the sequencer is
  1198. +     *  paused a minimal amount of time.
  1199. +     */
  1200. +    aha274x_buildscb(p, cmd, &scb);
  1201. +
  1202. +    /*
  1203. +     *  This is a critical section, since we don't want the
  1204. +     *  interrupt routine mucking with the host data or the
  1205. +     *  card.  Since the kernel documentation is vague on
  1206. +     *  whether or not we are in a cli/sti pair already, save
  1207. +     *  the flags to be on the safe side.
  1208. +     */
  1209. +    save_flags(flags);
  1210. +    cli();
  1211. +
  1212. +    /*
  1213. +     *  Find a free slot in the SCB array to load this command
  1214. +     *  into.  Since can_queue is set to AHA274X_MAXSCB, we
  1215. +     *  should always find one.
  1216. +     */
  1217. +    for (empty = 0; empty < AHA274X_MAXSCB; empty++)
  1218. +        if (!p->SCB_array[empty])
  1219. +            break;
  1220. +    if (empty == AHA274X_MAXSCB)
  1221. +        panic("aha274x_queue: couldn't find a free scb\n");
  1222. +
  1223. +    /*
  1224. +     *  Pause the sequencer so we can play with its registers -
  1225. +     *  wait for it to acknowledge the pause.
  1226. +     *
  1227. +     *  XXX - should the interrupts be left on while doing this?
  1228. +     */
  1229. +    PAUSE_SEQUENCER(p);
  1230. +
  1231. +    /*
  1232. +     *  Save the SCB pointer and put our own pointer in - this
  1233. +     *  selects one of the four banks of SCB registers.  Load
  1234. +     *  the SCB, then write its pointer into the queue in FIFO
  1235. +     *  and restore the saved SCB pointer.
  1236. +     */
  1237. +    old_scbptr = inb(O_SCBPTR(p->base));
  1238. +    outb(empty, O_SCBPTR(p->base));
  1239. +    
  1240. +    aha274x_putscb(p->base, &scb);
  1241. +
  1242. +    outb(empty, O_QINFIFO(p->base));
  1243. +    outb(old_scbptr, O_SCBPTR(p->base));
  1244. +
  1245. +    /*
  1246. +     *  Make sure the Scsi_Cmnd pointer is saved, the struct it
  1247. +     *  points to is set up properly, and the parity error flag
  1248. +     *  is reset, then unpause the sequencer and watch the fun
  1249. +     *  begin.
  1250. +     */
  1251. +    cmd->scsi_done = fn;
  1252. +    p->SCB_array[empty] = cmd;
  1253. +    aha274x_parity(cmd) = DID_OK;
  1254. +
  1255. +    UNPAUSE_SEQUENCER(p);
  1256. +
  1257. +    restore_flags(flags);
  1258. +    return(0);
  1259. +}
  1260. +
  1261. +/* return values from aha274x_kill */
  1262. +
  1263. +enum k_state {
  1264. +    k_ok,                /* scb found and message sent */
  1265. +    k_busy,                /* message already present */
  1266. +    k_absent,            /* couldn't locate scb */
  1267. +    k_disconnect,            /* scb found, but disconnected */
  1268. +};
  1269. +
  1270. +/*
  1271. + *  This must be called with interrupts disabled - it's going to
  1272. + *  be messing around with the host data, and an interrupt being
  1273. + *  fielded in the middle could get ugly.
  1274. + *
  1275. + *  Since so much of the abort and reset code is shared, this
  1276. + *  function performs more magic than it really should.  If the
  1277. + *  command completes ok, then it will call scsi_done with the
  1278. + *  result code passed in.  The unpause parameter controls whether
  1279. + *  or not the sequencer gets unpaused - the reset function, for
  1280. + *  instance, may want to do something more aggressive.
  1281. + *
  1282. + *  Note that the command is checked for in our SCB_array first
  1283. + *  before the sequencer is paused, so if k_absent is returned,
  1284. + *  then the sequencer is NOT paused.
  1285. + */
  1286. +
  1287. +static
  1288. +enum k_state aha274x_kill(Scsi_Cmnd *cmd, unsigned char message,
  1289. +              unsigned int result, int unpause)
  1290. +{
  1291. +    struct aha274x_host *p;
  1292. +    int i, scb, found, queued;
  1293. +    unsigned char scbsave[AHA274X_MAXSCB];
  1294. +
  1295. +    p = (struct aha274x_host *)cmd->host->hostdata;
  1296. +
  1297. +    /*
  1298. +     *  If we can't find the command, assume it just completed
  1299. +     *  and shrug it away.
  1300. +     */
  1301. +    for (scb = 0; scb < AHA274X_MAXSCB; scb++)
  1302. +        if (p->SCB_array[scb] == cmd)
  1303. +            break;
  1304. +
  1305. +    if (scb == AHA274X_MAXSCB)
  1306. +        return(k_absent);
  1307. +
  1308. +    PAUSE_SEQUENCER(p);
  1309. +
  1310. +    /*
  1311. +     *  This is the best case, really.  Check to see if the
  1312. +     *  command is still in the sequencer's input queue.  If
  1313. +     *  so, simply remove it.  Reload the queue afterward.
  1314. +     */
  1315. +    queued = inb(O_QINCNT(p->base));
  1316. +    
  1317. +    for (i = found = 0; i < queued; i++) {
  1318. +        scbsave[i] = inb(O_QINFIFO(p->base));
  1319. +
  1320. +        if (scbsave[i] == scb) {
  1321. +            found = 1;
  1322. +            i -= 1;
  1323. +        }
  1324. +    }
  1325. +
  1326. +    queued -= found;
  1327. +    for (i = 0; i < queued; i++)
  1328. +        outb(scbsave[i], O_QINFIFO(p->base));
  1329. +
  1330. +    if (found)
  1331. +        goto complete;
  1332. +
  1333. +    /*
  1334. +     *  Check the current SCB bank.  If it's not the one belonging
  1335. +     *  to the command we want to kill, assume that the command
  1336. +     *  is disconnected.  It's rather a pain to force a reconnect
  1337. +     *  and send a message to the target, so we abdicate responsibility
  1338. +     *  in this case.
  1339. +     */
  1340. +    if (inb(O_SCBPTR(p->base)) != scb) {
  1341. +        if (unpause)
  1342. +            UNPAUSE_SEQUENCER(p);
  1343. +        return(k_disconnect);
  1344. +    }
  1345. +
  1346. +    /*
  1347. +     *  Presumably at this point our target command is active.  Check
  1348. +     *  to see if there's a message already in effect.  If not, place
  1349. +     *  our message in and assert ATN so the target goes into MESSAGE
  1350. +     *  OUT phase.
  1351. +     */
  1352. +    if (inb(HA_MSG_FLAGS(p->base)) & 0x80) {
  1353. +        if (unpause)
  1354. +            UNPAUSE_SEQUENCER(p);
  1355. +        return(k_busy);
  1356. +    }
  1357. +
  1358. +    outb(0x80, HA_MSG_FLAGS(p->base));        /* active message */
  1359. +    outb(1, HA_MSG_LEN(p->base));            /* length = 1 */
  1360. +    outb(message, HA_MSG_START(p->base));        /* message body */
  1361. +
  1362. +    /*
  1363. +     *  Assert ATN.  Use the value of SCSISIGO saved by the
  1364. +     *  sequencer code so we don't alter its contents radically
  1365. +     *  in the middle of something critical.
  1366. +     */
  1367. +    outb(inb(HA_SIGSTATE(p->base)) | 0x10, O_SCSISIGO(p->base));
  1368. +
  1369. +    /*
  1370. +     *  The command has been killed.  Do the bookkeeping, unpause
  1371. +     *  the sequencer, and notify the higher-level SCSI code.
  1372. +     */
  1373. +complete:
  1374. +    p->SCB_array[scb] = NULL;
  1375. +    if (unpause)
  1376. +        UNPAUSE_SEQUENCER(p);
  1377. +
  1378. +    cmd->result = result << 16;
  1379. +    cmd->scsi_done(cmd);
  1380. +    return(k_ok);
  1381. +}
  1382. +
  1383. +int aha274x_abort(Scsi_Cmnd *cmd)
  1384. +{
  1385. +    int rv;
  1386. +    long flags;
  1387. +
  1388. +    save_flags(flags);
  1389. +    cli();
  1390. +
  1391. +    switch (aha274x_kill(cmd, ABORT, DID_ABORT, !0)) {
  1392. +        case k_ok:        rv = SCSI_ABORT_SUCCESS;    break;
  1393. +        case k_busy:    rv = SCSI_ABORT_BUSY;        break;
  1394. +        case k_absent:    rv = SCSI_ABORT_NOT_RUNNING;    break;
  1395. +        case k_disconnect:    rv = SCSI_ABORT_SNOOZE;        break;
  1396. +        default:
  1397. +        panic("aha274x_do_abort: internal error\n");
  1398. +    }
  1399. +
  1400. +    restore_flags(flags);
  1401. +    return(rv);
  1402. +}
  1403. +
  1404. +/*
  1405. + *  Resetting the bus always succeeds - is has to, otherwise the
  1406. + *  kernel will panic!  Try a surgical technique - sending a BUS
  1407. + *  DEVICE RESET message - on the offending target before pulling
  1408. + *  the SCSI bus reset line.
  1409. + */
  1410. +
  1411. +int aha274x_reset(Scsi_Cmnd *cmd)
  1412. +{
  1413. +    int i;
  1414. +    long flags;
  1415. +    Scsi_Cmnd *reset;
  1416. +    struct aha274x_host *p;
  1417. +
  1418. +    p = (struct aha274x_host *)cmd->host->hostdata;
  1419. +    save_flags(flags);
  1420. +    cli();
  1421. +
  1422. +    switch (aha274x_kill(cmd, BUS_DEVICE_RESET, DID_RESET, 0)) {
  1423. +
  1424. +        case k_ok:
  1425. +        /*
  1426. +         *  The RESET message was sent to the target
  1427. +         *  with no problems.  Flag that target as
  1428. +         *  needing a SDTR negotiation on the next
  1429. +         *  connection and restart the sequencer.
  1430. +         */
  1431. +        outb((1 << cmd->target), HA_NEEDSDTR(p->base));
  1432. +        UNPAUSE_SEQUENCER(p);
  1433. +        break;
  1434. +
  1435. +        case k_absent:
  1436. +        /*
  1437. +         *  The sequencer will not be paused if aha274x_kill()
  1438. +         *  couldn't find the command.
  1439. +         */
  1440. +        PAUSE_SEQUENCER(p);
  1441. +        /* falls through */
  1442. +
  1443. +        case k_busy:
  1444. +        case k_disconnect:
  1445. +        /*
  1446. +         *  Do a hard reset of the SCSI bus.  According to the
  1447. +         *  SCSI-2 draft specification, reset has to be asserted
  1448. +         *  for at least 25us.  I'm invoking the kernel delay
  1449. +         *  function for 30us since I'm not totally trusting of
  1450. +         *  the busy loop timing.
  1451. +         *
  1452. +         *  XXX - I'm not convinced this works.  I tried resetting
  1453. +         *      the bus before, trying to get the devices on the
  1454. +         *      bus to revert to asynchronous transfer, and it
  1455. +         *      never seemed to work.
  1456. +         */
  1457. +        debug("aha274x: attempting to reset scsi bus and card\n");
  1458. +
  1459. +        outb(1, O_SCSISEQ(p->base));        /* SCSIRSTO */
  1460. +        udelay(30);
  1461. +        outb(0, O_SCSISEQ(p->base));        /* !SCSIRSTO */
  1462. +
  1463. +        outb(0xff, HA_NEEDSDTR(p->base));
  1464. +        UNPAUSE_SEQUENCER(p);
  1465. +
  1466. +        /*
  1467. +         *  Locate the command and return a "reset" status
  1468. +         *  for it.  This is not completely correct and will
  1469. +         *  probably return to haunt me later.
  1470. +         */
  1471. +        for (i = 0; i < AHA274X_MAXSCB; i++) {
  1472. +            if (cmd == p->SCB_array[i]) {
  1473. +                reset = (Scsi_Cmnd *)p->SCB_array[i];
  1474. +                p->SCB_array[i] = NULL;
  1475. +                reset->result = DID_RESET << 16;
  1476. +                reset->scsi_done(reset);
  1477. +                break;
  1478. +            }
  1479. +        }
  1480. +        break;
  1481. +
  1482. +        default:
  1483. +        panic("aha274x_reset: internal error\n");
  1484. +    }
  1485. +
  1486. +    restore_flags(flags);
  1487. +    return(SCSI_RESET_SUCCESS);
  1488. +}
  1489. +
  1490. +int aha274x_biosparam(Disk *disk, int devno, int geom[])
  1491. +{
  1492. +    /*
  1493. +     *  XXX - when I find the EISA configuration information,
  1494. +     *      this should change to handle the "extended translation
  1495. +     *      for drives >1G" option, which uses 255 heads and
  1496. +     *      63 sectors/track for drives >1G.  Right now, just
  1497. +     *      assume it's turned off.
  1498. +     */
  1499. +    debug("aha274x_biosparam warning: don't know translation config\n");
  1500. +
  1501. +    geom[0] = 64;
  1502. +    geom[1] = 32;
  1503. +    geom[2] = disk->capacity / (64 * 32);
  1504. +
  1505. +    return(0);
  1506. +}
  1507. +
  1508. diff -u --recursive --new-file linux-1.1.49/drivers/scsi/aha274x.h linux/drivers/scsi/aha274x.h
  1509. --- linux-1.1.49/drivers/scsi/aha274x.h    Wed Dec 31 16:00:00 1969
  1510. +++ linux/drivers/scsi/aha274x.h    Thu Sep  8 23:20:59 1994
  1511. @@ -0,0 +1,62 @@
  1512. +/* @(#)aha274x.h 1.11 94/09/06 jda */
  1513. +
  1514. +/*
  1515. + * Adaptec 274x device driver for Linux.
  1516. + * Copyright (c) 1994 The University of Calgary Department of Computer Science.
  1517. + * 
  1518. + * This program is free software; you can redistribute it and/or modify
  1519. + * it under the terms of the GNU General Public License as published by
  1520. + * the Free Software Foundation; either version 2 of the License, or
  1521. + * (at your option) any later version.
  1522. + * 
  1523. + * This program is distributed in the hope that it will be useful,
  1524. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1525. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1526. + * GNU General Public License for more details.
  1527. + * 
  1528. + * You should have received a copy of the GNU General Public License
  1529. + * along with this program; if not, write to the Free Software
  1530. + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1531. + */
  1532. +
  1533. +#ifndef aha274x_h
  1534. +#define aha274x_h
  1535. +
  1536. +#define    AHA274X_MAXSCB        4
  1537. +#define AHA274X_H_VERSION    "1.11"
  1538. +
  1539. +/*
  1540. + *  Scsi_Host_Template (see hosts.h) for 274x - some fields
  1541. + *  to do with card config are filled in after the card is
  1542. + *  detected.
  1543. + */
  1544. +#define AHA274X    {                        \
  1545. +    NULL,                            \
  1546. +    "",                            \
  1547. +    aha274x_detect,                        \
  1548. +    NULL,                            \
  1549. +    aha274x_info,                        \
  1550. +    aha274x_command,                    \
  1551. +    aha274x_queue,                        \
  1552. +    aha274x_abort,                        \
  1553. +    aha274x_reset,                        \
  1554. +    NULL,                            \
  1555. +    aha274x_biosparam,                    \
  1556. +    AHA274X_MAXSCB,        /* max simultaneous cmds      */\
  1557. +    -1,            /* scsi id of host adapter    */\
  1558. +    SG_ALL,            /* max scatter-gather cmds    */\
  1559. +    1,            /* cmds per lun (linked cmds) */\
  1560. +    0,            /* number of 274x's present   */\
  1561. +    0,            /* no memory DMA restrictions */\
  1562. +    DISABLE_CLUSTERING                    \
  1563. +}
  1564. +
  1565. +extern int aha274x_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *));
  1566. +extern int aha274x_biosparam(Disk *, int, int[]);
  1567. +extern int aha274x_detect(Scsi_Host_Template *);
  1568. +extern int aha274x_command(Scsi_Cmnd *);
  1569. +extern int aha274x_abort(Scsi_Cmnd *);
  1570. +extern int aha274x_reset(Scsi_Cmnd *);
  1571. +extern const char *aha274x_info(void);
  1572. +
  1573. +#endif
  1574. diff -u --recursive --new-file linux-1.1.49/drivers/scsi/aha274x.seq linux/drivers/scsi/aha274x.seq
  1575. --- linux-1.1.49/drivers/scsi/aha274x.seq    Wed Dec 31 16:00:00 1969
  1576. +++ linux/drivers/scsi/aha274x.seq    Thu Sep  8 23:20:59 1994
  1577. @@ -0,0 +1,1013 @@
  1578. +# @(#)aha274x.seq 1.26 94/09/06 jda
  1579. +#
  1580. +# Adaptec 274x device driver for Linux.
  1581. +# Copyright (c) 1994 The University of Calgary Department of Computer Science.
  1582. +# 
  1583. +# This program is free software; you can redistribute it and/or modify
  1584. +# it under the terms of the GNU General Public License as published by
  1585. +# the Free Software Foundation; either version 2 of the License, or
  1586. +# (at your option) any later version.
  1587. +# 
  1588. +# This program is distributed in the hope that it will be useful,
  1589. +# but WITHOUT ANY WARRANTY; without even the implied warranty of
  1590. +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1591. +# GNU General Public License for more details.
  1592. +# 
  1593. +# You should have received a copy of the GNU General Public License
  1594. +# along with this program; if not, write to the Free Software
  1595. +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1596. +
  1597. +VERSION AHA274X_SEQ_VERSION 1.26
  1598. +
  1599. +MAXSCB        = 4
  1600. +
  1601. +SCSISEQ        = 0x00
  1602. +SXFRCTL0    = 0x01
  1603. +SXFRCTL1    = 0x02
  1604. +SCSISIGI    = 0x03
  1605. +SCSISIGO    = 0x03
  1606. +SCSIRATE    = 0x04
  1607. +SCSIID        = 0x05
  1608. +SCSIDATL    = 0x06
  1609. +STCNT        = 0x08
  1610. +STCNT+0        = 0x08
  1611. +STCNT+1        = 0x09
  1612. +STCNT+2        = 0x0a
  1613. +SSTAT0        = 0x0b
  1614. +CLRSINT1    = 0x0c
  1615. +SSTAT1        = 0x0c
  1616. +SIMODE1        = 0x11
  1617. +SCSIBUSL    = 0x12
  1618. +SHADDR        = 0x14
  1619. +SELID        = 0x19
  1620. +SBLKCTL        = 0x1f
  1621. +SEQCTL        = 0x60
  1622. +A        = 0x64                # == ACCUM
  1623. +SINDEX        = 0x65
  1624. +DINDEX        = 0x66
  1625. +ALLZEROS    = 0x6a
  1626. +NONE        = 0x6a
  1627. +SINDIR        = 0x6c
  1628. +DINDIR        = 0x6d
  1629. +FUNCTION1    = 0x6e
  1630. +HADDR        = 0x88
  1631. +HCNT        = 0x8c
  1632. +HCNT+0        = 0x8c
  1633. +HCNT+1        = 0x8d
  1634. +HCNT+2        = 0x8e
  1635. +SCBPTR        = 0x90
  1636. +INTSTAT        = 0x91
  1637. +DFCNTRL        = 0x93
  1638. +DFSTATUS    = 0x94
  1639. +DFDAT        = 0x99
  1640. +QINFIFO        = 0x9b
  1641. +QINCNT        = 0x9c
  1642. +QOUTFIFO    = 0x9d
  1643. +
  1644. +SCSICONF    = 0x5a
  1645. +
  1646. +#  The two reserved bytes at SCBARRAY+1[23] are expected to be set to
  1647. +#  zero, and the reserved bit in SCBARRAY+0 is used as an internal flag
  1648. +#  to indicate whether or not to reload scatter-gather parameters after
  1649. +#  a disconnect.
  1650. +#
  1651. +SCBARRAY+0    = 0xa0
  1652. +SCBARRAY+1    = 0xa1
  1653. +SCBARRAY+2    = 0xa2
  1654. +SCBARRAY+3    = 0xa3
  1655. +SCBARRAY+7    = 0xa7
  1656. +SCBARRAY+11    = 0xab
  1657. +SCBARRAY+14    = 0xae
  1658. +SCBARRAY+15    = 0xaf
  1659. +SCBARRAY+16    = 0xb0
  1660. +SCBARRAY+17    = 0xb1
  1661. +SCBARRAY+18    = 0xb2
  1662. +SCBARRAY+19    = 0xb3
  1663. +SCBARRAY+20    = 0xb4
  1664. +SCBARRAY+21    = 0xb5
  1665. +SCBARRAY+22    = 0xb6
  1666. +SCBARRAY+23    = 0xb7
  1667. +SCBARRAY+24    = 0xb8
  1668. +SCBARRAY+25    = 0xb9
  1669. +
  1670. +SIGNAL_0    = 0x01                # unknown scsi bus phase
  1671. +SIGNAL_1    = 0x11                # message reject
  1672. +SIGNAL_2    = 0x21                # no IDENTIFY after reconnect
  1673. +SIGNAL_3    = 0x31                # no cmd match for reconnect
  1674. +SIGNAL_4    = 0x41                # SDTR -> SCSIRATE conversion
  1675. +
  1676. +#  The host adapter card (at least the BIOS) uses 20-2f for SCSI
  1677. +#  device information, 32-33 and 5a-5f as well.  Since we don't support
  1678. +#  wide or twin-bus SCSI, 28-2f can be reclaimed.  As it turns out, the
  1679. +#  BIOS trashes 20-27 anyway, writing the synchronous negotiation results
  1680. +#  on top of the BIOS values, so we re-use those for our per-target
  1681. +#  scratchspace (actually a value that can be copied directly into
  1682. +#  SCSIRATE).  This implies, since we can't get the BIOS config values,
  1683. +#  that all targets will be negotiated with for synchronous transfer.
  1684. +#  NEEDSDTR has one bit per target indicating if an SDTR message is
  1685. +#  needed for that device - this will be set initially, as well as
  1686. +#  after a bus reset condition.
  1687. +#
  1688. +#  The high bit of DROPATN is set if ATN should be dropped before the ACK
  1689. +#  when outb is called.  REJBYTE contains the first byte of a MESSAGE IN
  1690. +#  message, so the driver can report an intelligible error if a message is
  1691. +#  rejected.
  1692. +#
  1693. +#  RESELECT's high bit is true if we are currently handling a reselect;
  1694. +#  its next-highest bit is true ONLY IF we've seen an IDENTIFY message
  1695. +#  from the reselecting target.  If we haven't had IDENTIFY, then we have
  1696. +#  no idea what the lun is, and we can't select the right SCB register
  1697. +#  bank, so force a kernel panic if the target attempts a data in/out or
  1698. +#  command phase instead of corrupting something.
  1699. +#
  1700. +#  Note that LAST_SHADDR and SG_NEXT occupy four bytes each.
  1701. +#
  1702. +SYNCNEG        = 0x20
  1703. +DISC_DSB_A    = 0x32
  1704. +
  1705. +DROPATN        = 0x30
  1706. +REJBYTE        = 0x31
  1707. +RESELECT    = 0x34
  1708. +
  1709. +MSG_FLAGS    = 0x35
  1710. +MSG_LEN        = 0x36
  1711. +MSG_START+0    = 0x37
  1712. +MSG_START+1    = 0x38
  1713. +MSG_START+2    = 0x39
  1714. +MSG_START+3    = 0x3a
  1715. +MSG_START+4    = 0x3b
  1716. +MSG_START+5    = 0x3c
  1717. +-MSG_START+0    = 0xc9                # 2's complement of MSG_START+0
  1718. +
  1719. +ARG_1        = 0x4c                # sdtr conversion args & return
  1720. +ARG_2        = 0x4d
  1721. +RETURN_1    = 0x4c
  1722. +
  1723. +SIGSTATE    = 0x4e                # value written to SCSISIGO
  1724. +NEEDSDTR    = 0x4f                # send SDTR message, 1 bit/trgt
  1725. +LAST_SHADDR    = 0x50                # value after last dma transfer
  1726. +
  1727. +SG_SIZEOF    = 12                # sizeof(struct scatterlist)
  1728. +SG_NOLOAD    = 0x54                # load SG pointer/length?
  1729. +SG_COUNT    = 0x55                # working value of SG count
  1730. +SG_NEXT        = 0x56                # working value of SG pointer
  1731. +SG_NEXT+0    = 0x56
  1732. +SG_NEXT+1    = 0x57
  1733. +SG_NEXT+2    = 0x58
  1734. +SG_NEXT+3    = 0x59
  1735. +
  1736. +#  Poll QINCNT for work - the lower three bits contain
  1737. +#  the number of entries in the Queue In FIFO.
  1738. +#
  1739. +start:
  1740. +    test    SCSISIGI,0x4    jnz reselect    # BSYI
  1741. +    test    QINCNT,0x7    jz start
  1742. +
  1743. +#  We have at least one queued SCB now.  Set the SCB pointer
  1744. +#  from the FIFO so we see the right bank of SCB registers,
  1745. +#  then set SCSI options and set the initiator and target
  1746. +#  SCSI IDs.
  1747. +#
  1748. +    mov    SCBPTR,QINFIFO
  1749. +    mov    SCBARRAY+1    call initialize
  1750. +    clr    SG_NOLOAD
  1751. +    clr    RESELECT
  1752. +
  1753. +#  As soon as we get a successful selection, the target should go
  1754. +#  into the message out phase since we have ATN asserted.  Prepare
  1755. +#  the message to send, locking out the device driver.  If the device
  1756. +#  driver hasn't beaten us with an ABORT or RESET message, then tack
  1757. +#  on a SDTR negotation if required.
  1758. +#
  1759. +#  Messages are stored in scratch RAM starting with a flag byte (high bit
  1760. +#  set means active message), one length byte, and then the message itself.
  1761. +#
  1762. +    mov    SCBARRAY+1    call disconnect    # disconnect ok?
  1763. +
  1764. +    and    SINDEX,0x7,SCBARRAY+1        # lun
  1765. +    or    SINDEX,A            # return value from disconnect
  1766. +    or    SINDEX,0x80    call mk_mesg    # IDENTIFY message
  1767. +
  1768. +    mov    A,SINDEX
  1769. +    cmp    MSG_START+0,A    jne !message    # did driver beat us?
  1770. +    mvi    MSG_START+1    call mk_sdtr    # build SDTR message if needed
  1771. +
  1772. +!message:
  1773. +
  1774. +#  Enable selection phase as an initiator, and do automatic ATN
  1775. +#  after the selection.
  1776. +#
  1777. +    mvi    SCSISEQ,0x48            # ENSELO|ENAUTOATNO
  1778. +
  1779. +#  Wait for successful arbitration.  The AIC-7770 documentation says
  1780. +#  that SELINGO indicates successful arbitration, and that it should
  1781. +#  be used to look for SELDO.  However, if the sequencer is paused at
  1782. +#  just the right time - a parallel fsck(8) on two drives did it for
  1783. +#  me - then SELINGO can flip back to false before we've seen it.  This
  1784. +#  makes the sequencer sit in the arbitration loop forever.  This is
  1785. +#  Not Good.
  1786. +#
  1787. +#  Therefore, I've added a check in the arbitration loop for SELDO
  1788. +#  too.  This could arguably be made a critical section by disabling
  1789. +#  pauses, but I don't want to make a potentially infinite loop a CS.
  1790. +#  I suppose you could fold it into the select loop, too, but since
  1791. +#  I've been hunting this bug for four days it's kinda like a trophy.
  1792. +#
  1793. +arbitrate:
  1794. +    test    SSTAT0,0x40    jnz *select    # SELDO
  1795. +    test    SSTAT0,0x10    jz arbitrate    # SELINGO
  1796. +
  1797. +#  Wait for a successful selection.  If the hardware selection
  1798. +#  timer goes off, then the driver gets the interrupt, so we don't
  1799. +#  need to worry about it.
  1800. +#
  1801. +select:
  1802. +    test    SSTAT0,0x40    jz select    # SELDO
  1803. +    jmp    *select
  1804. +
  1805. +#  Reselection is being initiated by a target - we've seen the BSY
  1806. +#  line driven active, and we didn't do it!  Enable the reselection
  1807. +#  hardware, and wait for it to finish.  Make a note that we've been
  1808. +#  reselected, but haven't seen an IDENTIFY message from the target
  1809. +#  yet.
  1810. +#
  1811. +reselect:
  1812. +    mvi    SCSISEQ,0x10            # ENRSELI
  1813. +
  1814. +reselect1:
  1815. +    test    SSTAT0,0x20    jz reselect1    # SELDI
  1816. +    mov    SELID        call initialize
  1817. +
  1818. +    mvi    RESELECT,0x80            # reselected, no IDENTIFY
  1819. +
  1820. +#  After the [re]selection, make sure that the [re]selection enable
  1821. +#  bit is off.  This chip is flaky enough without extra things
  1822. +#  turned on.  Also clear the BUSFREE bit in SSTAT1 since we'll be
  1823. +#  using it shortly.
  1824. +#
  1825. +*select:
  1826. +    clr    SCSISEQ
  1827. +    mvi    CLRSINT1,0x8            # CLRBUSFREE
  1828. +
  1829. +#  Main loop for information transfer phases.  If BSY is false, then
  1830. +#  we have a bus free condition, expected or not.  Otherwise, wait
  1831. +#  for the target to assert REQ before checking MSG, C/D and I/O
  1832. +#  for the bus phase.
  1833. +#
  1834. +#  We can't simply look at the values of SCSISIGI here (if we want
  1835. +#  to do synchronous data transfer), because the target won't assert
  1836. +#  REQ if it's already sent us some data that we haven't acknowledged
  1837. +#  yet.
  1838. +#
  1839. +ITloop:
  1840. +    test    SSTAT1,0x8    jnz p_busfree    # BUSFREE
  1841. +    test    SSTAT1,0x1    jz ITloop    # REQINIT
  1842. +
  1843. +    and    A,0xe0,SCSISIGI            # CDI|IOI|MSGI
  1844. +
  1845. +    cmp    ALLZEROS,A    je p_dataout
  1846. +    cmp    A,0x40        je p_datain
  1847. +    cmp    A,0x80        je p_command
  1848. +    cmp    A,0xc0        je p_status
  1849. +    cmp    A,0xa0        je p_mesgout
  1850. +    cmp    A,0xe0        je p_mesgin
  1851. +
  1852. +    mvi    INTSTAT,SIGNAL_0        # unknown - signal driver
  1853. +
  1854. +p_dataout:
  1855. +    mvi    0        call scsisig    # !CDO|!IOO|!MSGO
  1856. +    call    assert
  1857. +    call    sg_load
  1858. +
  1859. +    mvi    A,3
  1860. +    mvi    DINDEX,HCNT
  1861. +    mvi    SCBARRAY+23    call bcopy
  1862. +
  1863. +    mvi    A,3
  1864. +    mvi    DINDEX,STCNT
  1865. +    mvi    SCBARRAY+23    call bcopy
  1866. +
  1867. +    mvi    A,4
  1868. +    mvi    DINDEX,HADDR
  1869. +    mvi    SCBARRAY+19    call bcopy
  1870. +
  1871. +    mvi    0x3d        call dma    # SCSIEN|SDMAEN|HDMAEN|
  1872. +                        #   DIRECTION|FIFORESET
  1873. +
  1874. +    call    sg_advance
  1875. +    mov    SCBARRAY+18,SG_COUNT        # residual S/G count
  1876. +
  1877. +    jmp    ITloop
  1878. +
  1879. +p_datain:
  1880. +    mvi    0x40        call scsisig    # !CDO|IOO|!MSGO
  1881. +    call    assert
  1882. +    call    sg_load
  1883. +
  1884. +    mvi    A,3
  1885. +    mvi    DINDEX,HCNT
  1886. +    mvi    SCBARRAY+23    call bcopy
  1887. +
  1888. +    mvi    A,3
  1889. +    mvi    DINDEX,STCNT
  1890. +    mvi    SCBARRAY+23    call bcopy
  1891. +
  1892. +    mvi    A,4
  1893. +    mvi    DINDEX,HADDR
  1894. +    mvi    SCBARRAY+19    call bcopy
  1895. +
  1896. +    mvi    0x39        call dma    # SCSIEN|SDMAEN|HDMAEN|
  1897. +                        #   !DIRECTION|FIFORESET
  1898. +    call    sg_advance
  1899. +    mov    SCBARRAY+18,SG_COUNT        # residual S/G count
  1900. +
  1901. +    jmp    ITloop
  1902. +
  1903. +#  Command phase.  Set up the DMA registers and let 'er rip - the
  1904. +#  two bytes after the SCB SCSI_cmd_length are zeroed by the driver,
  1905. +#  so we can copy those three bytes directly into HCNT.
  1906. +#
  1907. +p_command:
  1908. +    mvi    0x80        call scsisig    # CDO|!IOO|!MSGO
  1909. +    call    assert
  1910. +
  1911. +    mvi    A,3
  1912. +    mvi    DINDEX,HCNT
  1913. +    mvi    SCBARRAY+11    call bcopy
  1914. +
  1915. +    mvi    A,3
  1916. +    mvi    DINDEX,STCNT
  1917. +    mvi    SCBARRAY+11    call bcopy
  1918. +
  1919. +    mvi    A,4
  1920. +    mvi    DINDEX,HADDR
  1921. +    mvi    SCBARRAY+7    call bcopy
  1922. +
  1923. +    mvi    0x3d        call dma    # SCSIEN|SDMAEN|HDMAEN|
  1924. +                        #   DIRECTION|FIFORESET
  1925. +    jmp    ITloop
  1926. +
  1927. +#  Status phase.  Wait for the data byte to appear, then read it
  1928. +#  and store it into the SCB.
  1929. +#
  1930. +p_status:
  1931. +    mvi    0xc0        call scsisig    # CDO|IOO|!MSGO
  1932. +
  1933. +    mvi    SCBARRAY+14    call inb
  1934. +    jmp    ITloop
  1935. +
  1936. +#  Message out phase.  If there is no active message, but the target
  1937. +#  took us into this phase anyway, build a no-op message and send it.
  1938. +#
  1939. +p_mesgout:
  1940. +    mvi    0xa0        call scsisig    # CDO|!IOO|MSGO
  1941. +    mvi    0x8        call mk_mesg    # build NOP message
  1942. +
  1943. +#  Set up automatic PIO transfer from MSG_START.  Bit 3 in
  1944. +#  SXFRCTL0 (SPIOEN) is already on.
  1945. +#
  1946. +    mvi    SINDEX,MSG_START+0
  1947. +    mov    DINDEX,MSG_LEN
  1948. +    clr    A
  1949. +
  1950. +#  When target asks for a byte, drop ATN if it's the last one in
  1951. +#  the message.  Otherwise, keep going until the message is exhausted.
  1952. +#  (We can't use outb for this since it wants the input in SINDEX.)
  1953. +#
  1954. +p_mesgout2:
  1955. +    test    SSTAT0,0x2    jz p_mesgout2    # SPIORDY
  1956. +
  1957. +    cmp    DINDEX,1    jne p_mesgout3    # last byte?
  1958. +    mvi    CLRSINT1,0x40            # CLRATNO - drop ATN
  1959. +
  1960. +#  Write a byte to the SCSI bus.  The AIC-7770 refuses to automatically
  1961. +#  send ACKs in automatic PIO or DMA mode unless you make sure that the
  1962. +#  "expected" bus phase in SCSISIGO matches the actual bus phase.  This
  1963. +#  behaviour is completely undocumented and caused me several days of
  1964. +#  grief.
  1965. +#
  1966. +#  After plugging in different drives to test with and using a longer
  1967. +#  SCSI cable, I found that I/O in Automatic PIO mode ceased to function,
  1968. +#  especially when transferring >1 byte.  It seems to be much more stable
  1969. +#  if STCNT is set to one before the transfer, and SDONE (in SSTAT0) is
  1970. +#  polled for transfer completion - for both output _and_ input.  The
  1971. +#  only theory I have is that SPIORDY doesn't drop right away when SCSIDATL
  1972. +#  is accessed (like the documentation says it does), and that on a longer
  1973. +#  cable run, the sequencer code was fast enough to loop back and see
  1974. +#  an SPIORDY that hadn't dropped yet.
  1975. +#
  1976. +p_mesgout3:
  1977. +    call    one_stcnt
  1978. +    mov    SCSIDATL,SINDIR
  1979. +
  1980. +p_mesgout4:
  1981. +    test    SSTAT0,0x4    jz p_mesgout4    # SDONE
  1982. +    dec    DINDEX
  1983. +    inc    A
  1984. +    cmp    MSG_LEN,A    jne p_mesgout2
  1985. +
  1986. +#  If the next bus phase after ATN drops is a message out, it means
  1987. +#  that the target is requesting that the last message(s) be resent.
  1988. +#
  1989. +p_mesgout5:
  1990. +    test    SSTAT1,0x8    jnz p_mesgout6    # BUSFREE
  1991. +    test    SSTAT1,0x1    jz p_mesgout5    # REQINIT
  1992. +
  1993. +    and    A,0xe0,SCSISIGI            # CDI|IOI|MSGI
  1994. +    cmp    A,0xa0        jne p_mesgout6
  1995. +    mvi    0x10        call scsisig    # ATNO - re-assert ATN
  1996. +
  1997. +    jmp    ITloop
  1998. +
  1999. +p_mesgout6:
  2000. +    clr    MSG_FLAGS            # no active msg
  2001. +    jmp    ITloop
  2002. +
  2003. +#  Message in phase.  Bytes are read using Automatic PIO mode, but not
  2004. +#  using inb.  This alleviates a race condition, namely that if ATN had
  2005. +#  to be asserted under Automatic PIO mode, it had to beat the SCSI
  2006. +#  circuitry sending an ACK to the target.  This showed up under heavy
  2007. +#  loads and really confused things, since ABORT commands wouldn't be
  2008. +#  seen by the drive after an IDENTIFY message in until it had changed
  2009. +#  to a data I/O phase.
  2010. +#
  2011. +p_mesgin:
  2012. +    mvi    0xe0        call scsisig    # CDO|IOO|MSGO
  2013. +    mvi    A        call inb_first    # read the 1st message byte
  2014. +    mvi    REJBYTE,A            # save it for the driver
  2015. +
  2016. +    cmp    ALLZEROS,A    jne p_mesgin1
  2017. +
  2018. +#  We got a "command complete" message, so put the SCB pointer
  2019. +#  into the Queue Out, and trigger a completion interrupt.
  2020. +#
  2021. +    mov    QOUTFIFO,SCBPTR
  2022. +    mvi    INTSTAT,0x2            # CMDCMPLT
  2023. +    jmp    p_mesgin_done
  2024. +
  2025. +#  Is it an extended message?  We only support the synchronous data
  2026. +#  transfer request message, which will probably be in response to
  2027. +#  an SDTR message out from us.  If it's not an SDTR, reject it -
  2028. +#  apparently this can be done after any message in byte, according
  2029. +#  to the SCSI-2 spec.
  2030. +#
  2031. +#  XXX - we should really reject this if we didn't initiate the SDTR
  2032. +#     negotiation; this may cause problems with unusual devices.
  2033. +#
  2034. +p_mesgin1:
  2035. +    cmp    A,1        jne p_mesgin2    # extended message code?
  2036. +    
  2037. +    mvi    A        call inb_next
  2038. +    cmp    A,3        jne p_mesginN    # extended mesg length = 3
  2039. +    mvi    A        call inb_next
  2040. +    cmp    A,1        jne p_mesginN    # SDTR code
  2041. +
  2042. +    mvi    ARG_1        call inb_next    # xfer period
  2043. +    mvi    ARG_2        call inb_next    # REQ/ACK offset
  2044. +    mvi    INTSTAT,SIGNAL_4        # call driver to convert
  2045. +
  2046. +    call    ndx_sdtr            # index sync config for target
  2047. +    mov    DINDEX,SINDEX
  2048. +    mov    DINDIR,RETURN_1            # save returned value
  2049. +
  2050. +    not    A                # turn off "need sdtr" flag
  2051. +    and    NEEDSDTR,A
  2052. +
  2053. +#  Even though the SCSI-2 specification says that a device responding
  2054. +#  to our SDTR message should honor our parameters for transmitting
  2055. +#  to us, it doesn't seem to work too well in real life.  In particular,
  2056. +#  a lot of CD-ROM and tape units don't function: try using the SDTR
  2057. +#  parameters the device sent us for both transmitting and receiving.
  2058. +#
  2059. +    mov    SCSIRATE,RETURN_1
  2060. +    jmp    p_mesgin_done
  2061. +
  2062. +#  Is it a disconnect message?  Set a flag in the SCB to remind us
  2063. +#  and await the bus going free.
  2064. +#
  2065. +p_mesgin2:
  2066. +    cmp    A,4        jne p_mesgin3    # disconnect code?
  2067. +
  2068. +    or    SCBARRAY+0,0x4            # set "disconnected" bit
  2069. +    jmp    p_mesgin_done
  2070. +
  2071. +#  Save data pointers message?  Use SHADDR and STCNT instead of HADDR
  2072. +#  and HCNT, since it's a reflection of how many bytes were transferred
  2073. +#  on the SCSI (as opposed to the host) bus.  Make sure to use the values
  2074. +#  saved after the last DMA transfer - reading the message in byte changes
  2075. +#  the values in them.
  2076. +#
  2077. +p_mesgin3:
  2078. +    cmp    A,2        jne p_mesgin4    # save data pointers code?
  2079. +
  2080. +    mvi    A,4
  2081. +    mvi    DINDEX,SCBARRAY+19
  2082. +    mvi    LAST_SHADDR    call bcopy
  2083. +
  2084. +    mvi    A,3
  2085. +    mvi    DINDEX,SCBARRAY+23
  2086. +    mvi    SCBARRAY+15    call bcopy    # residual data count (stcnt)
  2087. +
  2088. +    call    sg_ram2scb
  2089. +
  2090. +    jmp    p_mesgin_done
  2091. +
  2092. +#  Restore pointers message?  Data pointers are recopied from the
  2093. +#  SCB anyway at the start of any DMA operation, so the only thing
  2094. +#  to copy is the scatter-gather values.
  2095. +#
  2096. +p_mesgin4:
  2097. +    cmp    A,3        jne p_mesgin5    # restore pointers code?
  2098. +
  2099. +    call    sg_scb2ram
  2100. +    jmp    p_mesgin_done
  2101. +
  2102. +#  Identify message?  For a reconnecting target, this tells us the lun
  2103. +#  that the reconnection is for - find the correct SCB and switch to it,
  2104. +#  clearing the "disconnected" bit so we don't "find" it by accident later.
  2105. +#
  2106. +p_mesgin5:
  2107. +    test    A,0x80        jz p_mesgin6    # identify message?
  2108. +
  2109. +    test    A,0x78        jnz p_mesginN    # !DiscPriv|!LUNTAR|!Reserved
  2110. +
  2111. +    mov    A        call findSCB    # switch to correct SCB
  2112. +
  2113. +#  If a active message is present after calling findSCB, then either it
  2114. +#  or the driver is trying to abort the command.  Either way, something
  2115. +#  untoward has happened and we should just leave it alone.
  2116. +#
  2117. +    test    MSG_FLAGS,0x80    jnz p_mesgin_done
  2118. +
  2119. +    xor    SCBARRAY+0,0x4            # clear disconnect bit in SCB
  2120. +    mvi    RESELECT,0xc0            # make note of IDENTIFY
  2121. +
  2122. +    call    sg_scb2ram            # implied restore pointers
  2123. +                        #   required on reselect
  2124. +    jmp    p_mesgin_done
  2125. +
  2126. +#  Message reject?  If we have an outstanding SDTR negotiation, assume
  2127. +#  that it's a response from the target selecting asynchronous transfer,
  2128. +#  otherwise just ignore it since we have no clue what it pertains to.
  2129. +#
  2130. +#  XXX - I don't have a device that responds this way.  Does this code
  2131. +#     actually work?
  2132. +#
  2133. +p_mesgin6:
  2134. +    cmp    A,7        jne p_mesgin7    # message reject code?
  2135. +
  2136. +    and    FUNCTION1,0x70,SCSIID        # outstanding SDTR message?
  2137. +    mov    A,FUNCTION1
  2138. +    test    NEEDSDTR,A    jz p_mesgin_done  # no - ignore rejection
  2139. +
  2140. +    call    ndx_sdtr            # note use of asynch xfer
  2141. +    mov    DINDEX,SINDEX
  2142. +    clr    DINDIR
  2143. +
  2144. +    not    A                # turn off "active sdtr" flag
  2145. +    and    NEEDSDTR,A
  2146. +
  2147. +    clr    SCSIRATE            # select asynch xfer
  2148. +    jmp    p_mesgin_done
  2149. +
  2150. +#  [ ADD MORE MESSAGE HANDLING HERE ]
  2151. +#
  2152. +p_mesgin7:
  2153. +
  2154. +#  We have no idea what this message in is, and there's no way
  2155. +#  to pass it up to the kernel, so we issue a message reject and
  2156. +#  hope for the best.  Since we're now using manual PIO mode to
  2157. +#  read in the message, there should no longer be a race condition
  2158. +#  present when we assert ATN.  In any case, rejection should be a
  2159. +#  rare occurrence - signal the driver when it happens.
  2160. +#
  2161. +p_mesginN:
  2162. +    or    SINDEX,0x10,SIGSTATE        # turn on ATNO
  2163. +    call    scsisig
  2164. +    mvi    INTSTAT,SIGNAL_1        # let driver know
  2165. +
  2166. +    mvi    0x7        call mk_mesg    # MESSAGE REJECT message
  2167. +
  2168. +p_mesgin_done:
  2169. +    call    inb_last            # ack & turn auto PIO back on
  2170. +    jmp    ITloop
  2171. +
  2172. +#  Bus free phase.  It might be useful to interrupt the device
  2173. +#  driver if we aren't expecting this.  For now, make sure that
  2174. +#  ATN isn't being asserted and look for a new command.
  2175. +#
  2176. +p_busfree:
  2177. +    mvi    CLRSINT1,0x40            # CLRATNO
  2178. +    clr    SIGSTATE
  2179. +    jmp    start
  2180. +
  2181. +#  Bcopy: number of bytes to transfer should be in A, DINDEX should
  2182. +#  contain the destination address, and SINDEX should contain the
  2183. +#  source address.  All input parameters are trashed on return.
  2184. +#
  2185. +bcopy:
  2186. +    mov    DINDIR,SINDIR
  2187. +    dec    A
  2188. +    cmp    ALLZEROS,A    jne bcopy
  2189. +    ret
  2190. +
  2191. +#  Locking the driver out, build a one-byte message passed in SINDEX
  2192. +#  if there is no active message already.  SINDEX is returned intact.
  2193. +#
  2194. +mk_mesg:
  2195. +    mvi    SEQCTL,0x40            # PAUSEDIS
  2196. +    test    MSG_FLAGS,0x80    jnz mk_mesg1    # active message?
  2197. +
  2198. +    mvi    MSG_FLAGS,0x80            # if not, there is now
  2199. +    mvi    MSG_LEN,1            # length = 1
  2200. +    mov    MSG_START+0,SINDEX        # 1-byte message
  2201. +
  2202. +mk_mesg1:
  2203. +    clr    SEQCTL                # !PAUSEDIS
  2204. +    ret
  2205. +
  2206. +#  Input byte in Automatic PIO mode.  The address to store the byte
  2207. +#  in should be in SINDEX.  DINDEX will be used by this routine.
  2208. +#
  2209. +inb:
  2210. +    test    SSTAT0,0x2    jz inb        # SPIORDY
  2211. +    mov    DINDEX,SINDEX
  2212. +    call    one_stcnt            # xfer one byte
  2213. +    mov    DINDIR,SCSIDATL
  2214. +inb1:
  2215. +    test    SSTAT0,0x4    jz inb1        # SDONE - wait to "finish"
  2216. +    ret
  2217. +
  2218. +#  Carefully read data in Automatic PIO mode.  I first tried this using
  2219. +#  Manual PIO mode, but it gave me continual underrun errors, probably
  2220. +#  indicating that I did something wrong, but I feel more secure leaving
  2221. +#  Automatic PIO on all the time.
  2222. +#
  2223. +#  According to Adaptec's documentation, an ACK is not sent on input from
  2224. +#  the target until SCSIDATL is read from.  So we wait until SCSIDATL is
  2225. +#  latched (the usual way), then read the data byte directly off the bus
  2226. +#  using SCSIBUSL.  When we have pulled the ATN line, or we just want to
  2227. +#  acknowledge the byte, then we do a dummy read from SCISDATL.  The SCSI
  2228. +#  spec guarantees that the target will hold the data byte on the bus until
  2229. +#  we send our ACK.
  2230. +#
  2231. +#  The assumption here is that these are called in a particular sequence,
  2232. +#  and that REQ is already set when inb_first is called.  inb_{first,next}
  2233. +#  use the same calling convention as inb.
  2234. +#
  2235. +inb_first:
  2236. +    mov    DINDEX,SINDEX
  2237. +    mov    DINDIR,SCSIBUSL    ret        # read byte directly from bus
  2238. +
  2239. +inb_next:
  2240. +    mov    DINDEX,SINDEX            # save SINDEX
  2241. +
  2242. +    call    one_stcnt            # xfer one byte
  2243. +    mov    NONE,SCSIDATL            # dummy read from latch to ACK
  2244. +inb_next1:
  2245. +    test    SSTAT0,0x4    jz inb_next1    # SDONE
  2246. +inb_next2:
  2247. +    test    SSTAT0,0x2    jz inb_next2    # SPIORDY - wait for next byte
  2248. +    mov    DINDIR,SCSIBUSL    ret        # read byte directly from bus
  2249. +
  2250. +inb_last:
  2251. +    call    one_stcnt            # ACK with dummy read
  2252. +    mov    NONE,SCSIDATL
  2253. +inb_last1:
  2254. +    test    SSTAT0,0x4    jz inb_last1    # wait for completion
  2255. +    ret
  2256. +
  2257. +#  Output byte in Automatic PIO mode.  The byte to output should be
  2258. +#  in SINDEX.  If DROPATN's high bit is set, then ATN will be dropped
  2259. +#  before the byte is output.
  2260. +#
  2261. +outb:
  2262. +    test    SSTAT0,0x2    jz outb        # SPIORDY
  2263. +    call    one_stcnt            # xfer one byte
  2264. +
  2265. +    test    DROPATN,0x80    jz outb1
  2266. +    mvi    CLRSINT1,0x40            # CLRATNO
  2267. +    clr    DROPATN
  2268. +outb1:
  2269. +    mov    SCSIDATL,SINDEX
  2270. +outb2:
  2271. +    test    SSTAT0,0x4    jz outb2    # SDONE
  2272. +    ret
  2273. +
  2274. +#  Write the value "1" into the STCNT registers, for Automatic PIO
  2275. +#  transfers.
  2276. +#
  2277. +one_stcnt:
  2278. +    clr    STCNT+2
  2279. +    clr    STCNT+1
  2280. +    mvi    STCNT+0,1    ret
  2281. +
  2282. +#  DMA data transfer.  HADDR and HCNT must be loaded first, and
  2283. +#  SINDEX should contain the value to load DFCNTRL with - 0x3d for
  2284. +#  host->scsi, or 0x39 for scsi->host.  The SCSI channel is cleared
  2285. +#  during initialization.
  2286. +#
  2287. +dma:
  2288. +    mov    DFCNTRL,SINDEX
  2289. +dma1:
  2290. +dma2:
  2291. +    test    SSTAT0,0x1    jnz dma3    # DMADONE
  2292. +    test    SSTAT1,0x10    jz dma1        # PHASEMIS, ie. underrun
  2293. +
  2294. +#  We will be "done" DMAing when the transfer count goes to zero, or
  2295. +#  the target changes the phase (in light of this, it makes sense that
  2296. +#  the DMA circuitry doesn't ACK when PHASEMIS is active).  If we are
  2297. +#  doing a SCSI->Host transfer, flush the data FIFO.
  2298. +#
  2299. +dma3:
  2300. +    test    SINDEX,0x4    jnz dma5    # DIRECTION
  2301. +    and    SINDEX,0xfe            # mask out FIFORESET
  2302. +    or    DFCNTRL,0x2,SINDEX        # FIFOFLUSH
  2303. +dma4:
  2304. +    test    DFCNTRL,0x2    jnz dma4    # FIFOFLUSHACK
  2305. +
  2306. +#  Now shut the DMA enables off, and copy STCNT (ie. the underrun
  2307. +#  amount, if any) to the SCB registers; SG_COUNT will get copied to
  2308. +#  the SCB's residual S/G count field after sg_advance is called.  Make
  2309. +#  sure that the DMA enables are actually off first lest we get an ILLSADDR.
  2310. +#  Save the value of SHADDR into scratch RAM in case we need to save data
  2311. +#  pointers.
  2312. +#
  2313. +dma5:
  2314. +    clr    DFCNTRL                # disable DMA
  2315. +dma6:
  2316. +    test    DFCNTRL,0x38    jnz dma6    # SCSIENACK|SDMAENACK|HDMAENACK
  2317. +
  2318. +    mvi    A,4
  2319. +    mvi    DINDEX,LAST_SHADDR
  2320. +    mvi    SHADDR        call bcopy
  2321. +
  2322. +    mvi    A,3
  2323. +    mvi    DINDEX,SCBARRAY+15
  2324. +    mvi    STCNT        call bcopy
  2325. +
  2326. +    ret
  2327. +
  2328. +#  Common SCSI initialization for selection and reselection.  Expects
  2329. +#  the target SCSI ID to be in the upper four bits of SINDEX, and A's
  2330. +#  contents are stomped on return.
  2331. +#
  2332. +initialize:
  2333. +    clr    SBLKCTL                # channel A, !wide
  2334. +    and    SCSIID,0xf0,SINDEX        # target ID
  2335. +    and    A,0x7,SCSICONF            # SCSI_ID_A[210]
  2336. +    or    SCSIID,A
  2337. +
  2338. +#  Esundry initialization.
  2339. +#
  2340. +    clr    DROPATN
  2341. +    clr    SIGSTATE
  2342. +
  2343. +#  Turn on Automatic PIO mode now, before we expect to see an REQ
  2344. +#  from the target.  It shouldn't hurt anything to leave it on.  Set
  2345. +#  CLRCHN here before the target has entered a data transfer mode -
  2346. +#  with synchronous SCSI, if you do it later, you blow away some
  2347. +#  data in the SCSI FIFO that the target has already sent to you.
  2348. +#
  2349. +    mvi    SXFRCTL0,0xa            # SPIOEN|CLRCHN
  2350. +
  2351. +#  Set SCSI bus parity checking and the selection timeout value,
  2352. +#  and enable the hardware selection timer.  Set the SELTO interrupt
  2353. +#  to signal the driver.
  2354. +#
  2355. +    and    A,0x38,SCSICONF            # PARITY_ENB_A|SEL_TIM_A[10]
  2356. +    or    SXFRCTL1,0x4,A            # ENSTIMER
  2357. +    mvi    SIMODE1,0x84            # ENSELTIMO|ENSCSIPERR
  2358. +    
  2359. +#  Initialize scatter-gather pointers by setting up the working copy
  2360. +#  in scratch RAM.
  2361. +#
  2362. +    call    sg_scb2ram
  2363. +
  2364. +#  Initialize SCSIRATE with the appropriate value for this target.
  2365. +#
  2366. +    call    ndx_sdtr
  2367. +    mov    SCSIRATE,SINDIR
  2368. +    ret
  2369. +
  2370. +#  Assert that if we've been reselected, then we've seen an IDENTIFY
  2371. +#  message.
  2372. +#
  2373. +assert:
  2374. +    test    RESELECT,0x80    jz assert1    # reselected?
  2375. +    test    RESELECT,0x40    jnz assert1    # seen IDENTIFY?
  2376. +
  2377. +    mvi    INTSTAT,SIGNAL_2        # no - cause a kernel panic
  2378. +
  2379. +assert1:
  2380. +    ret
  2381. +
  2382. +#  Find out if disconnection is ok from the information the BIOS has left
  2383. +#  us.  The target ID should be in the upper four bits of SINDEX; A will
  2384. +#  contain either 0x40 (disconnection ok) or 0x00 (diconnection not ok)
  2385. +#  on exit.
  2386. +#
  2387. +#  This is the only place the target ID is limited to three bits, so we
  2388. +#  can use the FUNCTION1 register.
  2389. +#
  2390. +disconnect:
  2391. +    and    FUNCTION1,0x70,SINDEX        # strip off extra just in case
  2392. +    mov    A,FUNCTION1
  2393. +    test    DISC_DSB_A,A    jz disconnect1    # bit nonzero if DISabled
  2394. +
  2395. +    clr    A        ret
  2396. +disconnect1:
  2397. +    mvi    A,0x40        ret
  2398. +
  2399. +#  Locate the SCB matching the target ID in SELID and the lun in the lower
  2400. +#  three bits of SINDEX, and switch the SCB to it.  Have the kernel print
  2401. +#  a warning message if it can't be found - this seems to happen occasionally
  2402. +#  under high loads.  Also, if not found, generate an ABORT message to the
  2403. +#  target.
  2404. +#
  2405. +findSCB:
  2406. +    and    A,0x7,SINDEX            # lun in lower three bits
  2407. +    or    A,A,SELID            # can I do this?
  2408. +    and    A,0xf7                # only channel A implemented
  2409. +
  2410. +    clr    SINDEX
  2411. +
  2412. +findSCB1:
  2413. +    mov    SCBPTR,SINDEX            # switch to new SCB
  2414. +    cmp    SCBARRAY+1,A    jne findSCB2    # target ID/channel/lun match?
  2415. +    test    SCBARRAY+0,0x4    jz findSCB2    # should be disconnected
  2416. +
  2417. +    ret
  2418. +
  2419. +findSCB2:
  2420. +    inc    SINDEX
  2421. +    cmp    SINDEX,MAXSCB    jne findSCB1
  2422. +
  2423. +    mvi    INTSTAT,SIGNAL_3        # not found - signal kernel
  2424. +    mvi    0x6        call mk_mesg    # ABORT message
  2425. +
  2426. +    or    SINDEX,0x10,SIGSTATE        # assert ATNO
  2427. +    call    scsisig
  2428. +    ret
  2429. +
  2430. +#  Make a working copy of the scatter-gather parameters in the SCB.
  2431. +#
  2432. +sg_scb2ram:
  2433. +    mov    SG_COUNT,SCBARRAY+2
  2434. +
  2435. +    mvi    A,4
  2436. +    mvi    DINDEX,SG_NEXT
  2437. +    mvi    SCBARRAY+3    call bcopy
  2438. +
  2439. +    mvi    SG_NOLOAD,0x80
  2440. +    test    SCBARRAY+0,0x10    jnz sg_scb2ram1    # don't reload s/g?
  2441. +    clr    SG_NOLOAD
  2442. +
  2443. +sg_scb2ram1:
  2444. +    ret
  2445. +
  2446. +#  Copying RAM values back to SCB, for Save Data Pointers message.
  2447. +#
  2448. +sg_ram2scb:
  2449. +    mov    SCBARRAY+2,SG_COUNT
  2450. +
  2451. +    mvi    A,4
  2452. +    mvi    DINDEX,SCBARRAY+3
  2453. +    mvi    SG_NEXT        call bcopy
  2454. +
  2455. +    and    SCBARRAY+0,0xef,SCBARRAY+0
  2456. +    test    SG_NOLOAD,0x80    jz sg_ram2scb1    # reload s/g?
  2457. +    or    SCBARRAY+0,0x10
  2458. +
  2459. +sg_ram2scb1:
  2460. +    ret
  2461. +
  2462. +#  Load a struct scatter if needed and set up the data address and
  2463. +#  length.  If the working value of the SG count is nonzero, then
  2464. +#  we need to load a new set of values.
  2465. +#
  2466. +#  This, like the above DMA, assumes a little-endian host data storage.
  2467. +#
  2468. +sg_load:
  2469. +    test    SG_COUNT,0xff    jz sg_load3    # SG being used?
  2470. +    test    SG_NOLOAD,0x80    jnz sg_load3    # don't reload s/g?
  2471. +
  2472. +    clr    HCNT+2
  2473. +    clr    HCNT+1
  2474. +    mvi    HCNT+0,SG_SIZEOF
  2475. +
  2476. +    mvi    A,4
  2477. +    mvi    DINDEX,HADDR
  2478. +    mvi    SG_NEXT        call bcopy
  2479. +
  2480. +    mvi    DFCNTRL,0xd            # HDMAEN|DIRECTION|FIFORESET
  2481. +
  2482. +#  Wait for DMA from host memory to data FIFO to complete, then disable
  2483. +#  DMA and wait for it to acknowledge that it's off.
  2484. +#
  2485. +sg_load1:
  2486. +    test    DFSTATUS,0x8    jz sg_load1    # HDONE
  2487. +
  2488. +    clr    DFCNTRL                # disable DMA
  2489. +sg_load2:
  2490. +    test    DFCNTRL,0x8    jnz sg_load2    # HDMAENACK
  2491. +
  2492. +#  Copy data from FIFO into SCB data pointer and data count.  This assumes
  2493. +#  that the struct scatterlist has this structure (this and sizeof(struct
  2494. +#  scatterlist) == 12 are asserted in aha274x.c):
  2495. +#
  2496. +#    struct scatterlist {
  2497. +#        char *address;        /* four bytes, little-endian order */
  2498. +#        ...            /* four bytes, ignored */
  2499. +#        unsigned short length;    /* two bytes, little-endian order */
  2500. +#    }
  2501. +#
  2502. +    mov    SCBARRAY+19,DFDAT        # new data address
  2503. +    mov    SCBARRAY+20,DFDAT
  2504. +    mov    SCBARRAY+21,DFDAT
  2505. +    mov    SCBARRAY+22,DFDAT
  2506. +
  2507. +    mov    NONE,DFDAT            # throw away four bytes
  2508. +    mov    NONE,DFDAT
  2509. +    mov    NONE,DFDAT
  2510. +    mov    NONE,DFDAT
  2511. +
  2512. +    mov    SCBARRAY+23,DFDAT
  2513. +    mov    SCBARRAY+24,DFDAT
  2514. +    clr    SCBARRAY+25
  2515. +
  2516. +sg_load3:
  2517. +    ret
  2518. +
  2519. +#  Advance the scatter-gather pointers only IF NEEDED.  If SG is enabled,
  2520. +#  and the SCSI transfer count is zero (note that this should be called
  2521. +#  right after a DMA finishes), then move the working copies of the SG
  2522. +#  pointer/length along.  If the SCSI transfer count is not zero, then
  2523. +#  presumably the target is disconnecting - do not reload the SG values
  2524. +#  next time.
  2525. +#
  2526. +sg_advance:
  2527. +    test    SG_COUNT,0xff    jz sg_advance2    # s/g enabled?
  2528. +
  2529. +    test    STCNT+0,0xff    jnz sg_advance1    # SCSI transfer count nonzero?
  2530. +    test    STCNT+1,0xff    jnz sg_advance1
  2531. +    test    STCNT+2,0xff    jnz sg_advance1
  2532. +
  2533. +    clr    SG_NOLOAD            # reload s/g next time
  2534. +    dec    SG_COUNT            # one less segment to go
  2535. +
  2536. +    clr    A                # add sizeof(struct scatter)
  2537. +    add    SG_NEXT+0,SG_SIZEOF,SG_NEXT+0
  2538. +    adc    SG_NEXT+1,A,SG_NEXT+1
  2539. +    adc    SG_NEXT+2,A,SG_NEXT+2
  2540. +    adc    SG_NEXT+3,A,SG_NEXT+3
  2541. +
  2542. +    ret
  2543. +
  2544. +sg_advance1:
  2545. +    mvi    SG_NOLOAD,0x80            # don't reload s/g next time
  2546. +sg_advance2:
  2547. +    ret
  2548. +
  2549. +#  Add the array base SYNCNEG to the target offset (the target address
  2550. +#  is in SCSIID), and return the result in SINDEX.  The accumulator
  2551. +#  contains the 3->8 decoding of the target ID on return.
  2552. +#
  2553. +ndx_sdtr:
  2554. +    shr    A,SCSIID,4
  2555. +    and    A,0x7
  2556. +    add    SINDEX,SYNCNEG,A
  2557. +
  2558. +    and    FUNCTION1,0x70,SCSIID        # 3-bit target address decode
  2559. +    mov    A,FUNCTION1    ret
  2560. +
  2561. +#  If we need to negotiate transfer parameters, build the SDTR message
  2562. +#  starting at the address passed in SINDEX.  DINDEX is modified on return.
  2563. +#
  2564. +mk_sdtr:
  2565. +    mov    DINDEX,SINDEX            # save SINDEX
  2566. +
  2567. +    call    ndx_sdtr
  2568. +    test    NEEDSDTR,A    jnz mk_sdtr1    # do we need negotiation?
  2569. +    ret
  2570. +
  2571. +mk_sdtr1:
  2572. +    mvi    DINDIR,1            # extended message
  2573. +    mvi    DINDIR,3            # extended message length = 3
  2574. +    mvi    DINDIR,1            # SDTR code
  2575. +    mvi    DINDIR,25            # REQ/ACK transfer period
  2576. +    mvi    DINDIR,15            # REQ/ACK offset
  2577. +
  2578. +    add    MSG_LEN,-MSG_START+0,DINDEX    # update message length
  2579. +    ret
  2580. +
  2581. +#  Set SCSI bus control signal state.  This also saves the last-written
  2582. +#  value into a location where the higher-level driver can read it - if
  2583. +#  it has to send an ABORT or RESET message, then it needs to know this
  2584. +#  so it can assert ATN without upsetting SCSISIGO.  The new value is
  2585. +#  expected in SINDEX.  Change the actual state last to avoid contention
  2586. +#  from the driver.
  2587. +#
  2588. +scsisig:
  2589. +    mov    SIGSTATE,SINDEX
  2590. +    mov    SCSISIGO,SINDEX    ret
  2591. diff -u --recursive --new-file linux-1.1.49/drivers/scsi/aic7770.c linux/drivers/scsi/aic7770.c
  2592. --- linux-1.1.49/drivers/scsi/aic7770.c    Wed Dec 31 16:00:00 1969
  2593. +++ linux/drivers/scsi/aic7770.c    Thu Sep  8 23:18:26 1994
  2594. @@ -0,0 +1,584 @@
  2595. +/*
  2596. + * Adaptec 274x device driver for Linux.
  2597. + * Copyright (c) 1994 The University of Calgary Department of Computer Science.
  2598. + * 
  2599. + * This program is free software; you can redistribute it and/or modify
  2600. + * it under the terms of the GNU General Public License as published by
  2601. + * the Free Software Foundation; either version 2 of the License, or
  2602. + * (at your option) any later version.
  2603. + * 
  2604. + * This program is distributed in the hope that it will be useful,
  2605. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2606. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  2607. + * GNU General Public License for more details.
  2608. + * 
  2609. + * You should have received a copy of the GNU General Public License
  2610. + * along with this program; if not, write to the Free Software
  2611. + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  2612. + *
  2613. + *  Comments are started by `#' and continue to the end of the line; lines
  2614. + *  may be of the form:
  2615. + *
  2616. + *    <label>*
  2617. + *    <label>*  <undef-sym> = <value>
  2618. + *    <label>*  <opcode> <operand>*
  2619. + *
  2620. + *  A <label> is an <undef-sym> ending in a colon.  Spaces, tabs, and commas
  2621. + *  are token separators.
  2622. + */
  2623. +
  2624. +#define _POSIX_SOURCE    1
  2625. +#define _POSIX_C_SOURCE    2
  2626. +
  2627. +#include <ctype.h>
  2628. +#include <stdio.h>
  2629. +#include <string.h>
  2630. +#include <stdlib.h>
  2631. +#include <unistd.h>
  2632. +
  2633. +#define MEMORY        512        /* 2^9 29-bit words */
  2634. +#define MAXLINE        1024
  2635. +#define MAXTOKEN    32
  2636. +#define ADOTOUT        "a.out"
  2637. +#define NOVALUE        -1
  2638. +
  2639. +/*
  2640. + *  AIC-7770 register definitions
  2641. + */
  2642. +#define R_SINDEX    0x65
  2643. +#define R_ALLONES    0x69
  2644. +#define R_ALLZEROS    0x6a
  2645. +#define R_NONE        0x6a
  2646. +
  2647. +static
  2648. +char sccsid[] =
  2649. +    "@(#)aic7770.c 1.10 94/07/22 jda";
  2650. +
  2651. +int debug;
  2652. +int lineno, LC;
  2653. +char *filename;
  2654. +FILE *ifp, *ofp;
  2655. +unsigned char M[MEMORY][4];
  2656. +
  2657. +void error(char *s)
  2658. +{
  2659. +    fprintf(stderr, "%s: %s at line %d\n", filename, s, lineno);
  2660. +    exit(EXIT_FAILURE);
  2661. +}
  2662. +
  2663. +void *Malloc(size_t size)
  2664. +{
  2665. +    void *p = malloc(size);
  2666. +    if (!p)
  2667. +        error("out of memory");
  2668. +    return(p);
  2669. +}
  2670. +
  2671. +void *Realloc(void *ptr, size_t size)
  2672. +{
  2673. +    void *p = realloc(ptr, size);
  2674. +    if (!p)
  2675. +        error("out of memory");
  2676. +    return(p);
  2677. +}
  2678. +
  2679. +char *Strdup(char *s)
  2680. +{
  2681. +    char *p = (char *)Malloc(strlen(s) + 1);
  2682. +    strcpy(p, s);
  2683. +    return(p);
  2684. +}
  2685. +
  2686. +typedef struct sym_t {
  2687. +    struct sym_t *next;        /* MUST BE FIRST */
  2688. +    char *name;
  2689. +    int value;
  2690. +    int npatch, *patch;
  2691. +} sym_t;
  2692. +
  2693. +sym_t *head;
  2694. +
  2695. +void define(char *name, int value)
  2696. +{
  2697. +    sym_t *p, *q;
  2698. +
  2699. +    for (p = head, q = (sym_t *)&head; p; p = p->next) {
  2700. +        if (!strcmp(p->name, name))
  2701. +            error("redefined symbol");
  2702. +        q = p;
  2703. +    }
  2704. +
  2705. +    p = q->next = (sym_t *)Malloc(sizeof(sym_t));
  2706. +    p->next = NULL;
  2707. +    p->name = Strdup(name);
  2708. +    p->value = value;
  2709. +    p->npatch = 0;
  2710. +    p->patch = NULL;
  2711. +
  2712. +    if (debug) {
  2713. +        fprintf(stderr, "\"%s\" ", p->name);
  2714. +        if (p->value != NOVALUE)
  2715. +            fprintf(stderr, "defined as 0x%x\n", p->value);
  2716. +        else
  2717. +            fprintf(stderr, "undefined\n");
  2718. +    }
  2719. +}
  2720. +
  2721. +sym_t *lookup(char *name)
  2722. +{
  2723. +    sym_t *p;
  2724. +
  2725. +    for (p = head; p; p = p->next)
  2726. +        if (!strcmp(p->name, name))
  2727. +            return(p);
  2728. +    return(NULL);
  2729. +}
  2730. +
  2731. +void patch(sym_t *p, int location)
  2732. +{
  2733. +    p->npatch += 1;
  2734. +    p->patch = (int *)Realloc(p->patch, p->npatch * sizeof(int *));
  2735. +
  2736. +    p->patch[p->npatch - 1] = location;
  2737. +}
  2738. +
  2739. +void backpatch(void)
  2740. +{
  2741. +    int i;
  2742. +    sym_t *p;
  2743. +
  2744. +    for (p = head; p; p = p->next) {
  2745. +
  2746. +        if (p->value == NOVALUE) {
  2747. +            fprintf(stderr,
  2748. +                "%s: undefined symbol \"%s\"\n",
  2749. +                filename, p->name);
  2750. +            exit(EXIT_FAILURE);
  2751. +        }
  2752. +
  2753. +        if (p->npatch) {
  2754. +            if (debug)
  2755. +                fprintf(stderr,
  2756. +                    "\"%s\" (0x%x) patched at",
  2757. +                    p->name, p->value);
  2758. +
  2759. +            for (i = 0; i < p->npatch; i++) {
  2760. +                M[p->patch[i]][0] &= ~1;
  2761. +                M[p->patch[i]][0] |= ((p->value >> 8) & 1);
  2762. +                M[p->patch[i]][1] = p->value & 0xff;
  2763. +
  2764. +                if (debug)
  2765. +                    fprintf(stderr, " 0x%x", p->patch[i]);
  2766. +            }
  2767. +
  2768. +            if (debug)
  2769. +                fputc('\n', stderr);
  2770. +        }
  2771. +    }
  2772. +}
  2773. +
  2774. +/*
  2775. + *  Output words in byte-reversed order (least significant first)
  2776. + *  since the sequencer RAM is loaded that way.
  2777. + */
  2778. +void output(FILE *fp)
  2779. +{
  2780. +    int i;
  2781. +
  2782. +    for (i = 0; i < LC; i++)
  2783. +        fprintf(fp, "\t0x%02x, 0x%02x, 0x%02x, 0x%02x,\n",
  2784. +            M[i][3],
  2785. +            M[i][2],
  2786. +            M[i][1],
  2787. +            M[i][0]);
  2788. +}
  2789. +
  2790. +char **getl(int *n)
  2791. +{
  2792. +    int i;
  2793. +    char *p;
  2794. +    static char buf[MAXLINE];
  2795. +    static char *a[MAXTOKEN];
  2796. +
  2797. +    i = 0;
  2798. +
  2799. +    while (fgets(buf, sizeof(buf), ifp)) {
  2800. +
  2801. +        lineno += 1;
  2802. +
  2803. +        if (buf[strlen(buf)-1] != '\n')
  2804. +            error("line too long");
  2805. +
  2806. +        p = strchr(buf, '#');
  2807. +        if (p)
  2808. +            *p = '\0';
  2809. +
  2810. +        for (p = strtok(buf, ", \t\n"); p; p = strtok(NULL, ", \t\n"))
  2811. +            if (i < MAXTOKEN-1)
  2812. +                a[i++] = p;
  2813. +            else
  2814. +                error("too many tokens");
  2815. +        if (i) {
  2816. +            *n = i;
  2817. +            return(a);
  2818. +        }
  2819. +    }
  2820. +    return(NULL);
  2821. +}
  2822. +
  2823. +#define A    0x8000        /* `A'ccumulator ok */
  2824. +#define I    0x4000        /* use as immediate value */
  2825. +#define SL    0x2000        /* shift left */
  2826. +#define SR    0x1000        /* shift right */
  2827. +#define RL    0x0800        /* rotate left */
  2828. +#define RR    0x0400        /* rotate right */
  2829. +#define LO    0x8000        /* lookup: ori-{jmp,jc,jnc,call} */
  2830. +#define LA    0x4000        /* lookup: and-{jz,jnz} */
  2831. +#define LX    0x2000        /* lookup: xor-{je,jne} */
  2832. +#define NA    -1        /* not applicable */
  2833. +
  2834. +struct {
  2835. +    char *name;
  2836. +    int n;            /* number of operands, including opcode */
  2837. +    unsigned int op;    /* immediate or L?|pos_from_0 */
  2838. +    unsigned int dest;    /* NA, pos_from_0, or I|immediate */
  2839. +    unsigned int src;    /* NA, pos_from_0, or I|immediate */
  2840. +    unsigned int imm;    /* pos_from_0, A|pos_from_0, or I|immediate */
  2841. +    unsigned int addr;    /* NA or pos_from_0 */
  2842. +    int fmt;        /* instruction format - 1, 2, or 3 */
  2843. +} instr[] = {
  2844. +/*
  2845. + *        N  OP     DEST        SRC        IMM    ADDR FMT
  2846. + */
  2847. +    "mov",    3, 1,     1,        2,        I|0xff,    NA,  1,
  2848. +    "mov",    4, LO|2, NA,        1,        I|0,    3,   3,
  2849. +    "mvi",    3, 0,     1,        I|R_ALLZEROS,    A|2,    NA,  1,
  2850. +    "mvi",    4, LO|2, NA,        I|R_ALLZEROS,    1,    3,   3,
  2851. +    "not",    2, 2,     1,        1,        I|0xff,    NA,  1,
  2852. +    "not",    3, 2,     1,        2,        I|0xff,    NA,  1,
  2853. +    "and",    3, 1,     1,        1,        A|2,    NA,  1,
  2854. +    "and",  4, 1,     1,        3,        A|2,    NA,  1,
  2855. +    "or",    3, 0,     1,        1,        A|2,    NA,  1,
  2856. +    "or",    4, 0,     1,        3,        A|2,    NA,  1,
  2857. +    "or",    5, LO|3, NA,        1,        2,    4,   3,
  2858. +    "xor",    3, 2,     1,        1,        A|2,    NA,  1,
  2859. +    "xor",    4, 2,     1,        3,        A|2,    NA,  1,
  2860. +    "nop",    1, 1,     I|R_NONE,    I|R_ALLZEROS,    I|0xff,    NA,  1,
  2861. +    "inc",    2, 3,     1,        1,        I|1,    NA,  1,
  2862. +    "inc",    3, 3,     1,        2,        I|1,    NA,  1,
  2863. +    "dec",    2, 3,     1,        1,        I|0xff,    NA,  1,
  2864. +    "dec",    3, 3,     1,        2,        I|0xff,    NA,  1,
  2865. +    "jmp",    2, LO|0, NA,        I|R_SINDEX,    I|0,    1,   3,
  2866. +    "jc",    2, LO|0, NA,        I|R_SINDEX,    I|0,    1,   3,
  2867. +    "jnc",    2, LO|0, NA,        I|R_SINDEX,    I|0,    1,   3,
  2868. +    "call",    2, LO|0, NA,        I|R_SINDEX,    I|0,    1,   3,
  2869. +    "test",    5, LA|3, NA,        1,        A|2,    4,   3,
  2870. +    "cmp",    5, LX|3, NA,        1,        A|2,    4,   3,
  2871. +    "ret",    1, 1,     I|R_NONE,    I|R_ALLZEROS,    I|0xff,    NA,  1,
  2872. +    "clc",    1, 3,     I|R_NONE,    I|R_ALLZEROS,    I|1,    NA,  1,
  2873. +    "clc",    4, 3,     2,        I|R_ALLZEROS,    A|3,    NA,  1,
  2874. +    "stc",    1, 3,     I|R_NONE,    I|R_ALLONES,    I|1,    NA,  1,
  2875. +    "stc",    2, 3,     1,        I|R_ALLONES,    I|1,    NA,  1,
  2876. +    "add",    3, 3,     1,        1,        A|2,    NA,  1,
  2877. +    "add",    4, 3,     1,        3,        A|2,    NA,  1,
  2878. +    "adc",    3, 4,     1,        1,        A|2,    NA,  1,
  2879. +    "adc",    4, 4,     1,        3,        A|2,    NA,  1,
  2880. +    "shl",    3, 5,     1,        1,        SL|2,    NA,  2,
  2881. +    "shl",    4, 5,     1,        2,        SL|3,    NA,  2,
  2882. +    "shr",    3, 5,     1,        1,        SR|2,    NA,  2,
  2883. +    "shr",    4, 5,     1,        2,        SR|3,    NA,  2,
  2884. +    "rol",    3, 5,     1,        1,        RL|2,    NA,  2,
  2885. +    "rol",    4, 5,     1,        2,        RL|3,    NA,  2,
  2886. +    "ror",    3, 5,     1,        1,        RR|2,    NA,  2,
  2887. +    "ror",    4, 5,     1,        2,        RR|3,    NA,  2,
  2888. +    /*
  2889. +     *  Extensions (note also that mvi allows A)
  2890. +     */
  2891. +     "clr",    2, 1,     1,        I|R_ALLZEROS,    I|0xff,    NA,  1,
  2892. +    0
  2893. +};
  2894. +
  2895. +int eval_operand(char **a, int spec)
  2896. +{
  2897. +    int i;
  2898. +    unsigned int want = spec & (LO|LA|LX);
  2899. +
  2900. +    static struct {
  2901. +        unsigned int what;
  2902. +        char *name;
  2903. +        int value;
  2904. +    } jmptab[] = {
  2905. +        LO,    "jmp",        8,
  2906. +        LO,    "jc",        9,
  2907. +        LO,    "jnc",        10,
  2908. +        LO,    "call",        11,
  2909. +        LA,    "jz",        15,
  2910. +        LA,    "jnz",        13,
  2911. +        LX,    "je",        14,
  2912. +        LX,    "jne",        12,
  2913. +    };
  2914. +
  2915. +    spec &= ~(LO|LA|LX);
  2916. +
  2917. +    for (i = 0; i < sizeof(jmptab)/sizeof(jmptab[0]); i++)
  2918. +        if (jmptab[i].what == want &&
  2919. +            !strcmp(jmptab[i].name, a[spec]))
  2920. +        {
  2921. +            return(jmptab[i].value);
  2922. +        }
  2923. +
  2924. +    if (want)
  2925. +        error("invalid jump");
  2926. +
  2927. +    return(spec);        /* "case 0" - no flags set */
  2928. +}
  2929. +
  2930. +int eval_sdi(char **a, int spec)
  2931. +{
  2932. +    sym_t *p;
  2933. +    unsigned val;
  2934. +
  2935. +    if (spec == NA)
  2936. +        return(NA);
  2937. +
  2938. +    switch (spec & (A|I|SL|SR|RL|RR)) {
  2939. +        case SL:
  2940. +        case SR:
  2941. +        case RL:
  2942. +        case RR:
  2943. +        if (isdigit(*a[spec &~ (SL|SR|RL|RR)]))
  2944. +            val = strtol(a[spec &~ (SL|SR|RL|RR)], NULL, 0);
  2945. +        else {
  2946. +            p = lookup(a[spec &~ (SL|SR|RL|RR)]);
  2947. +            if (!p)
  2948. +                error("undefined symbol used");
  2949. +            val = p->value;
  2950. +        }
  2951. +
  2952. +        switch (spec & (SL|SR|RL|RR)) {        /* blech */
  2953. +            case SL:
  2954. +            if (val > 7)
  2955. +                return(0xf0);
  2956. +            return(((val % 8) << 4) |
  2957. +                   (val % 8));
  2958. +            case SR:
  2959. +            if (val > 7)
  2960. +                return(0xf0);
  2961. +            return(((val % 8) << 4) |
  2962. +                   (1 << 3) |
  2963. +                   ((8 - (val % 8)) % 8));
  2964. +            case RL:
  2965. +            return(val % 8);
  2966. +            case RR:
  2967. +            return((8 - (val % 8)) % 8);
  2968. +        }
  2969. +        case I:
  2970. +        return(spec &~ I);
  2971. +        case A:
  2972. +        /*
  2973. +         *  An immediate field of zero selects
  2974. +         *  the accumulator.  Vigorously object
  2975. +         *  if zero is given otherwise - it's
  2976. +         *  most likely an error.
  2977. +         */
  2978. +        spec &= ~A;
  2979. +        if (!strcmp("A", a[spec]))
  2980. +            return(0);
  2981. +        if (isdigit(*a[spec]) &&
  2982. +            strtol(a[spec], NULL, 0) == 0)
  2983. +        {
  2984. +            error("immediate value of zero selects accumulator");
  2985. +        }
  2986. +        /* falls through */
  2987. +        case 0:
  2988. +        if (isdigit(*a[spec]))
  2989. +            return(strtol(a[spec], NULL, 0));
  2990. +        p = lookup(a[spec]);
  2991. +        if (p)
  2992. +            return(p->value);
  2993. +        error("undefined symbol used");
  2994. +    }
  2995. +
  2996. +    return(NA);        /* shut the compiler up */
  2997. +}
  2998. +
  2999. +int eval_addr(char **a, int spec)
  3000. +{
  3001. +    sym_t *p;
  3002. +
  3003. +    if (spec == NA)
  3004. +        return(NA);
  3005. +    if (isdigit(*a[spec]))
  3006. +        return(strtol(a[spec], NULL, 0));
  3007. +
  3008. +    p = lookup(a[spec]);
  3009. +
  3010. +    if (p) {
  3011. +        if (p->value != NOVALUE)
  3012. +            return(p->value);
  3013. +        patch(p, LC);
  3014. +    } else {
  3015. +        define(a[spec], NOVALUE);
  3016. +        p = lookup(a[spec]);
  3017. +        patch(p, LC);
  3018. +    }
  3019. +
  3020. +    return(NA);        /* will be patched in later */
  3021. +}
  3022. +
  3023. +int crack(char **a, int n)
  3024. +{
  3025. +    int i;
  3026. +    int I_imm, I_addr;
  3027. +    int I_op, I_dest, I_src, I_ret;
  3028. +
  3029. +    /*
  3030. +     *  Check for "ret" at the end of the line; remove
  3031. +     *  it unless it's "ret" alone - we still want to
  3032. +     *  look it up in the table.
  3033. +     */
  3034. +    I_ret = (strcmp(a[n-1], "ret") ? 0 : !0);
  3035. +    if (I_ret && n > 1)
  3036. +        n -= 1;
  3037. +
  3038. +    for (i = 0; instr[i].name; i++) {
  3039. +        /*
  3040. +         *  Look for match in table given constraints,
  3041. +         *  currently just the name and the number of
  3042. +         *  operands.
  3043. +         */
  3044. +        if (!strcmp(instr[i].name, *a) && instr[i].n == n)
  3045. +            break;
  3046. +    }
  3047. +    if (!instr[i].name)
  3048. +        error("unknown opcode or wrong number of operands");
  3049. +
  3050. +    I_op    = eval_operand(a, instr[i].op);
  3051. +    I_src    = eval_sdi(a, instr[i].src);
  3052. +    I_imm    = eval_sdi(a, instr[i].imm);
  3053. +    I_dest    = eval_sdi(a, instr[i].dest);
  3054. +    I_addr    = eval_addr(a, instr[i].addr);
  3055. +
  3056. +    switch (instr[i].fmt) {
  3057. +        case 1:
  3058. +        case 2:
  3059. +        M[LC][0] = (I_op << 1) | I_ret;
  3060. +        M[LC][1] = I_dest;
  3061. +        M[LC][2] = I_src;
  3062. +        M[LC][3] = I_imm;
  3063. +        break;
  3064. +        case 3:
  3065. +        if (I_ret)
  3066. +            error("illegal use of \"ret\"");
  3067. +        M[LC][0] = (I_op << 1) | ((I_addr >> 8) & 1);
  3068. +        M[LC][1] = I_addr & 0xff;
  3069. +        M[LC][2] = I_src;
  3070. +        M[LC][3] = I_imm;
  3071. +        break;
  3072. +    }
  3073. +
  3074. +    return(1);        /* no two-byte instructions yet */
  3075. +}
  3076. +
  3077. +#undef SL
  3078. +#undef SR
  3079. +#undef RL
  3080. +#undef RR
  3081. +#undef LX
  3082. +#undef LA
  3083. +#undef LO
  3084. +#undef I
  3085. +#undef A
  3086. +
  3087. +void assemble(void)
  3088. +{
  3089. +    int n;
  3090. +    char **a;
  3091. +    sym_t *p;
  3092. +
  3093. +    while ((a = getl(&n))) {
  3094. +
  3095. +        while (a[0][strlen(*a)-1] == ':') {
  3096. +            a[0][strlen(*a)-1] = '\0';
  3097. +            p = lookup(*a);
  3098. +            if (p)
  3099. +                p->value = LC;
  3100. +            else
  3101. +                define(*a, LC);
  3102. +            a += 1;
  3103. +            n -= 1;
  3104. +        }
  3105. +
  3106. +        if (!n)            /* line was all labels */
  3107. +            continue;
  3108. +
  3109. +        if (n == 3 && !strcmp("VERSION", *a))
  3110. +            fprintf(ofp, "#define %s \"%s\"\n", a[1], a[2]);
  3111. +        else {
  3112. +            if (n == 3 && !strcmp("=", a[1]))
  3113. +                define(*a, strtol(a[2], NULL, 0));
  3114. +            else
  3115. +                LC += crack(a, n);
  3116. +        }
  3117. +    }
  3118. +
  3119. +    backpatch();
  3120. +    output(ofp);
  3121. +
  3122. +    if (debug)
  3123. +        output(stderr);
  3124. +}
  3125. +
  3126. +int main(int argc, char **argv)
  3127. +{
  3128. +    int c;
  3129. +
  3130. +    while ((c = getopt(argc, argv, "dho:")) != EOF) {
  3131. +        switch (c) {
  3132. +            case 'd':
  3133. +            debug = !0;
  3134. +            break;
  3135. +            case 'o':
  3136. +                ofp = fopen(optarg, "w");
  3137. +            if (!ofp) {
  3138. +                perror(optarg);
  3139. +                exit(EXIT_FAILURE);
  3140. +            }
  3141. +            break;
  3142. +            case 'h':
  3143. +            printf("usage: %s [-d] [-ooutput] input\n", *argv);
  3144. +            exit(EXIT_SUCCESS);
  3145. +            case NULL:
  3146. +            /*
  3147. +             *  An impossible option to shut the compiler
  3148. +             *  up about sccsid[].
  3149. +             */
  3150. +            exit((int)sccsid);
  3151. +            default:
  3152. +            exit(EXIT_FAILURE);
  3153. +        }
  3154. +    }
  3155. +
  3156. +    if (argc - optind != 1) {
  3157. +        fprintf(stderr, "%s: must have one input file\n", *argv);
  3158. +        exit(EXIT_FAILURE);
  3159. +    }
  3160. +    filename = argv[optind];
  3161. +
  3162. +    ifp = fopen(filename, "r");
  3163. +    if (!ifp) {
  3164. +        perror(filename);
  3165. +        exit(EXIT_FAILURE);
  3166. +    }
  3167. +
  3168. +    if (!ofp) {
  3169. +        ofp = fopen(ADOTOUT, "w");
  3170. +        if (!ofp) {
  3171. +            perror(ADOTOUT);
  3172. +            exit(EXIT_FAILURE);
  3173. +        }
  3174. +    }
  3175. +
  3176. +    assemble();
  3177. +    exit(EXIT_SUCCESS);
  3178. +}
  3179. diff -u --recursive --new-file linux-1.1.49/drivers/scsi/hosts.c linux/drivers/scsi/hosts.c
  3180. --- linux-1.1.49/drivers/scsi/hosts.c    Thu Sep  8 22:33:33 1994
  3181. +++ linux/drivers/scsi/hosts.c    Thu Sep  8 23:20:59 1994
  3182. @@ -39,6 +39,10 @@
  3183.  #include "aha1740.h"
  3184.  #endif
  3185.  
  3186. +#ifdef CONFIG_SCSI_AHA274X
  3187. +#include "aha274x.h"
  3188. +#endif
  3189. +
  3190.  #ifdef CONFIG_SCSI_BUSLOGIC
  3191.  #include "buslogic.h"
  3192.  #endif
  3193. @@ -131,6 +135,9 @@
  3194.  #endif
  3195.  #ifdef CONFIG_SCSI_AHA1740
  3196.      AHA1740,
  3197. +#endif
  3198. +#ifdef CONFIG_SCSI_AHA274X
  3199. +    AHA274X,
  3200.  #endif
  3201.  #ifdef CONFIG_SCSI_FUTURE_DOMAIN
  3202.      FDOMAIN_16X0,
  3203.