Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 15 Sep 2008 16:10:04 GMT
From:      Ross West <westr@connection.ca>
To:        freebsd-scsi@FreeBSD.org
Subject:   Re: kern/126866: [isp] [panic] kernel panic on card initialization
Message-ID:  <200809151610.m8FGA4Jh025158@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/126866; it has been noted by GNATS.

From: Ross West <westr@connection.ca>
To: bug-followup@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@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
 



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