kern/126866: [isp] [panic] kernel panic on card initialization

Ross West westr at connection.ca
Mon Sep 15 16:10:05 UTC 2008


The following reply was made to PR kern/126866; it has been noted by GNATS.

From: Ross West <westr at connection.ca>
To: bug-followup at FreeBSD.org
Cc:  
Subject: Re: kern/126866: [isp] [panic] kernel panic on card initialization
Date: Mon, 15 Sep 2008 11:42:59 -0400

 Bug solved: issue is with the driver not doing a reset of the HBA
 before attempting to read the firmware version from the HBA mailbox
 and getting a different response than expected.
 
 Patch that appears to fix the issue by doing the HBA reset first, then
 full card initialization.
 
 Many thanks to Alexander Sack (pisymbol at gmail.com) for the hard work
 in finding the proper solution.
 
 Patch as follows:
 -= start
 --- isp.c       2008-09-02 12:45:07.000000000 -0400
 +++ isp.c.0     2008-09-02 11:06:55.000000000 -0400
 @@ -171,61 +171,6 @@
  
         isp->isp_state = ISP_NILSTATE;
  
 -       /*
 -        * Basic types (SCSI, FibreChannel and PCI or SBus)
 -        * have been set in the MD code. We figure out more
 -        * here. Possibly more refined types based upon PCI
 -        * identification. Chip revision has been gathered.
 -        *
 -        * After we've fired this chip up, zero out the conf1 register
 -        * for SCSI adapters and do other settings for the 2100.
 -        */
 -
 -       /*
 -        * Get the current running firmware revision out of the
 -        * chip before we hit it over the head (if this is our
 -        * first time through). Note that we store this as the
 -        * 'ROM' firmware revision- which it may not be. In any
 -        * case, we don't really use this yet, but we may in
 -        * the future.
 -        */
 -       if (isp->isp_touched == 0) {
 -               /*
 -                * First see whether or not we're sitting in the ISP PROM.
 -                * If we've just been reset, we'll have the string "ISP   "
 -                * spread through outgoing mailbox registers 1-3. We do
 -                * this for PCI cards because otherwise we really don't
 -                * know what state the card is in and we could hang if
 -                * we try this command otherwise.
 -                *
 -                * For SBus cards, we just do this because they almost
 -                * certainly will be running firmware by now.
 -                */
 -               if (ISP_READ(isp, OUTMAILBOX1) != 0x4953 ||
 -                   ISP_READ(isp, OUTMAILBOX2) != 0x5020 ||
 -                   ISP_READ(isp, OUTMAILBOX3) != 0x2020) {
 -                       /*
 -                        * Just in case it was paused...
 -                        */
 -                       if (IS_24XX(isp)) {
 -                               ISP_WRITE(isp, BIU2400_HCCR,
 -                                   HCCR_2400_CMD_RELEASE);
 -                       } else {
 -                               ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
 -                       }
 -                       MEMZERO(&mbs, sizeof (mbs));
 -                       mbs.param[0] = MBOX_ABOUT_FIRMWARE;
 -                       mbs.logval = MBLOGNONE;
 -                       isp_mboxcmd(isp, &mbs);
 -                       if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
 -                               isp->isp_romfw_rev[0] = mbs.param[1];
 -                               isp->isp_romfw_rev[1] = mbs.param[2];
 -                               isp->isp_romfw_rev[2] = mbs.param[3];
 -                       }
 -               }
 -               isp->isp_touched = 1;
 -       }
 -
         ISP_DISABLE_INTS(isp);
  
         /*
 @@ -254,7 +199,6 @@
                 return;
         }
  
 -
         /*
          * Set up default request/response queue in-pointer/out-pointer
          * register indices.
 @@ -680,7 +624,6 @@
         ISP_WRITE(isp, isp->isp_respinrp, 0);
         ISP_WRITE(isp, isp->isp_respoutrp, 0);
  
 -
         /*
          * Do MD specific post initialization
          */
 @@ -706,6 +649,52 @@
                         }
                 }
         }
 +       
 +       /*
 +        * Basic types (SCSI, FibreChannel and PCI or SBus)
 +        * have been set in the MD code. We figure out more
 +        * here. Possibly more refined types based upon PCI
 +        * identification. Chip revision has been gathered.
 +        *
 +        * After we've fired this chip up, zero out the conf1 register
 +        * for SCSI adapters and do other settings for the 2100.
 +        */
 +       if (isp->isp_touched == 0) {
 +               /*
 +                * First see whether or not we're sitting in the ISP PROM.
 +                * If we've just been reset, we'll have the string "ISP   "
 +                * spread through outgoing mailbox registers 1-3. We do
 +                * this for PCI cards because otherwise we really don't
 +                * know what state the card is in and we could hang if
 +                * we try this command otherwise.
 +                *
 +                * For SBus cards, we just do this because they almost
 +                * certainly will be running firmware by now.
 +                */
 +               if (ISP_READ(isp, OUTMAILBOX1) != 0x4953 ||
 +                   ISP_READ(isp, OUTMAILBOX2) != 0x5020 ||
 +                   ISP_READ(isp, OUTMAILBOX3) != 0x2020) {
 +                       /*
 +                        * Just in case it was paused...
 +                        */
 +                       if (IS_24XX(isp)) {
 +                               ISP_WRITE(isp, BIU2400_HCCR,
 +                                   HCCR_2400_CMD_RELEASE);
 +                       } else {
 +                               ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
 +                       }
 +                       MEMZERO(&mbs, sizeof (mbs));
 +                       mbs.param[0] = MBOX_ABOUT_FIRMWARE;
 +                       mbs.logval = MBLOGNONE;
 +                       isp_mboxcmd(isp, &mbs);
 +                       if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
 +                               isp->isp_romfw_rev[0] = mbs.param[1];
 +                               isp->isp_romfw_rev[1] = mbs.param[2];
 +                               isp->isp_romfw_rev[2] = mbs.param[3];
 +                       }
 +               }
 +               isp->isp_touched = 1;
 +       }
  
         /*
          * Up until this point we've done everything by just reading or
 -= end
 


More information about the freebsd-scsi mailing list