Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 12 Mar 1995 14:12:26 +1596657 (MET)
From:      Wilko Bulte <wilko@yedi.iaf.nl>
To:        FreeBSD-hackers@FreeBSD.org (FreeBSD hackers list)
Subject:   patch for probing multiple Ultrastore U24f
Message-ID:  <199503121312.OAA00159@yedi.iaf.nl>

next in thread | raw e-mail | index | archive | help
Hi

Attached is a change to uha24_init() that allows multiple Ultrastore
24 cards to be probed correctly. The problem with the original version
was that for each card listed in the kernel config file the uha24_init()
was called that started its search for boards EACH TIME with slot 1.
Result was that the first board (lowest slot#) was found multiple
times, causing havoc with the SCSI devices attached to it.
Note that the source below is based on 1.1.5.

Could someone close to the WC source machine check how 2.0-current looks
like and if necessary fix the problem there?

Thanks, Wilko

/*
 *  Initialize an Ultrastor 24F
 */
int
uha24_init(unit)
int     unit;
{
  unsigned char p0, p1, p2, p3, p5, p6, p7;
  unsigned char id[7], rev, emu, haid;
  int port = 0, irq, i;
  static int slot = 1;
  int resetcount = 4000;
  struct uha_data *uha = uhadata[unit];
  struct uha_reg *ur = uhareg[unit];
  struct uha_bits *ub = uhabits[unit];

  /* Search for the 24F's product ID */
  while (slot < 15) {
        /*
         *  Prepare to use a 24F.
         */
        port = EISA_CONFIG | (slot << 12);
        ur->id          = port + 0x00;
        ur->type        = port + 0x02;
        ur->ectl        = port + 0x04;
        ur->config      = port + 0x05;          /* 0-2 for 24F */
        ur->lmask       = port + 0x0c;
        ur->lint        = port + 0x0d;
        ur->smask       = port + 0x0e;
        ur->sint        = port + 0x0f;
        ur->ogmcmd      = port + 0x16;
        ur->ogmptr      = port + 0x17;
        ur->icmcmd      = port + 0x1b;
        ur->icmptr      = port + 0x1c;

        ub->ldip        = U24_LDIP;
        ub->adrst       = U24_ADRST;
        ub->sbrst       = U24_SBRST;
        ub->asrst       = U24_ASRST;
        ub->abort       = U24_ABORT;
        ub->ogmint      = U24_OGMINT;
        ub->sintp       = U24_SINTP;
        ub->abort_succ  = U24_ABORT_SUCC;
        ub->abort_fail  = U24_ABORT_FAIL;
        ub->abort_ack   = U24_ABORT_ACK;
        ub->icm_ack     = U24_ICM_ACK;

        /* Make sure an EISA card is installed in this slot. */
        outb(ur->id, 0xff);
        p0 = inb(ur->id);
        if (p0 == 0xff || (p0 & 0x80) != 0) {
                slot++;
               continue;
        }

        /* It's EISA, so make sure the card is enabled. */
        if ((inb(ur->ectl) & EISA_DISABLE) == 0) {
                slot++;
                continue;
        }

        /* Found an enabled card.  Grab the product ID. */
        p1 = inb(ur->id+1);
        p2 = inb(ur->type);
        p3 = inb(ur->type+1);
        id[0] = 0x40 + ((p0 >> 2) & 0x1f);
        id[1] = 0x40 + (((p0 & 0x03) << 3) | ((p1 >> 5) & 0x07));
        id[2] = 0x40 + (p1 & 0x1f);
        id[3] = "0123456789abcdef"[(p2 >> 4) & 0x0f];
        id[4] = "0123456789abcdef"[p2 & 0x0f];
        id[5] = "0123456789abcdef"[(p3 >> 4) & 0x0f];
        id[6] = '\0';
        rev = p3 & 0xf;

        slot++;
        /* We only want the 24F product ID. */
        if (!strcmp(id, "USC024")) break;
  }
  if (slot == 15) return(ENODEV);

  /* We have the card!  Grab remaining config. */
  p5 = inb(ur->config);
  p6 = inb(ur->config+1);
  p7 = inb(ur->config+2);

  /* If the 24F is currently emulating an ISA device, leave. */
  emu = ((p6 & 0x04) >> 1) | ((p5 & 0x08) >> 3);
  if (emu != 3) return(ENODEV);

  switch (p5 & 0xf0) {
     case 0x10: irq = 15; break;
     case 0x20: irq = 14; break;
     case 0x40: irq = 11; break;
     case 0x80: irq = 10; break;
     default:
        printf("uha%d: bad 24F irq\n", unit);
        return(ENXIO);
  }

  haid = (p7 & 0x07);
  printf("uha%d: UltraStor 24F int=%d id=%d\n", unit, irq, haid);

  /* Issue SCSI and adapter reset */
  outb(ur->lint, ub->asrst);
  while (--resetcount) {
        if (inb(ur->lint))
                break;
        DELAY(1000);    /* 1 mSec per loop */
  }
  if (resetcount == 0) {
        printf("uha%d: board timed out during reset\n", unit);
        return (ENXIO);
  }
  outb(ur->smask, 0xc2);        /* make sure interrupts are enabled */
  uha->flags |= (UHA_INIT | UHA_24F);
  uha->baseport = port;
  uha->our_id = haid;
  uha->vect = irq;
  uha->dma = -1;
  return(0);
}
_     __________________________________________________________________________
 |   / o / /  _   Wilko Bulte             email: wilko@yedi.iaf.nl
 |/|/ / / /( (_)  Private FreeBSD site  - Arnhem - The Netherlands
--------------------------------------------------------------------------------



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199503121312.OAA00159>