NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kern/44002: 3ware 9690 (ld driver) doesn't respond after transfer big amount of data



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

From: David Holland <dholland-bugs%netbsd.org@localhost>
To: gnats-bugs%NetBSD.org@localhost
Cc: salvet%ics.muni.cz@localhost, novotny%ics.muni.cz@localhost
Subject: Re: kern/44002: 3ware 9690 (ld driver) doesn't respond after
 transfer big amount of data
Date: Wed, 10 Nov 2010 20:15:52 +0000

 On Wed, Nov 10, 2010 at 11:00:08AM +0000, Jiri Novotny wrote:
  >  I guess we found it. The 9690 has the same bug as 9650, but in
  >  NetBSD twa.c driver is fix just for 9650. In Linux driver is
  >  the fix for both. We did ugly hack (just rename 9650 -> 9690)
  >  in twa.c and now it work (O.K. the test which freeze the machine)
  >  pass many times. Of course we need to go through bigger set of tests.
 
 Good to hear.
 
 Which of the 9650-specific things is it? The full queue issue (as
 described in the comment at the beginning of twa_start), the behavior
 in twa_drain_response_queue_large, or the queue errors during reset
 thing in twa_check_ctlr_state?
 
 I'm assuming the full queue thing as the others pertain to device
 reset and you were seeing hangs during operation; please correct me if
 I'm wrong.
 
  >  As I am not kernel hacker nor experienced programmer I ask my
  >  friend Zdenek Slavet to prepare the patch.
 
 Something like the enclosed?
 
  > P.S. keep my and Zdenek adress in cc: I am not member of
  > gnats-bugs%NetBSD.org@localhost maillist
 
 It will mail to you because you submitted the PR, but it won't mail
 him, so I'm keeping the Cc:. In theory you can add his address to the
 PR, but I'm not sure that actually works and it probably isn't worth
 the trouble.
 
 untested candidate patch based on the above assumptions:
 
 
 Index: twa.c
 ===================================================================
 RCS file: /cvsroot/src/sys/dev/pci/twa.c,v
 retrieving revision 1.33
 diff -u -p -r1.33 twa.c
 --- twa.c      18 Aug 2009 11:15:43 -0000      1.33
 +++ twa.c      10 Nov 2010 20:15:17 -0000
 @@ -1056,16 +1056,18 @@ twa_start(struct twa_request *tr)
        s = splbio();
  
        /*
 -       * The 9650 has a bug in the detection of the full queue condition.
 +       * The 9650 and 9690 have a bug in the detection of the full queue
 +       * condition.
 +       *
         * If a write operation has filled the queue and is directly followed
         * by a status read, it sometimes doesn't return the correct result.
         * To work around this, the upper 32bit are written first.
         * This effectively serialises the hardware, but does not change
         * the state of the queue.
         */
 -      if (sc->sc_product_id == PCI_PRODUCT_3WARE_9650) {
 +      if (sc->sc_quirks & TWA_QUIRK_QUEUEFULL_BUG) {
                /* Write lower 32 bits of address */
 -              TWA_WRITE_9650_COMMAND_QUEUE_LOW(sc, tr->tr_cmd_phys +
 +              TWA_WRITE_COMMAND_QUEUE_LOW(sc, tr->tr_cmd_phys +
                        sizeof(struct twa_command_header));
        }
  
 @@ -1089,12 +1091,12 @@ twa_start(struct twa_request *tr)
                        sizeof(struct twa_command_packet),
                        BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  
 -              if (sc->sc_product_id == PCI_PRODUCT_3WARE_9650) {
 +              if (sc->sc_quirks & TWA_QUIRK_QUEUEFULL_BUG) {
                        /*
 -                       * Cmd queue is not full.  Post the command to 9650
 +                       * Cmd queue is not full.  Post the command
                         * by writing upper 32 bits of address.
                         */
 -                      TWA_WRITE_9650_COMMAND_QUEUE_HIGH(sc, tr->tr_cmd_phys +
 +                      TWA_WRITE_COMMAND_QUEUE_HIGH(sc, tr->tr_cmd_phys +
                                sizeof(struct twa_command_header));
                } else {
                        /* Cmd queue is not full.  Post the command. */
 @@ -1508,6 +1510,8 @@ twa_attach(device_t parent, device_t sel
  
        aprint_naive(": RAID controller\n");
        aprint_normal(": 3ware Apache\n");
 +
 +      sc->sc_quirks = 0;
                
        if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_3WARE_9000) {
                sc->sc_nunits = TWA_MAX_UNITS;
 @@ -1535,6 +1539,7 @@ twa_attach(device_t parent, device_t sel
                        aprint_error_dev(&sc->twa_dv, "can't map mem space\n");
                        return;
                }
 +              sc->sc_quirks |= TWA_QUIRK_QUEUEFULL_BUG;
        } else if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_3WARE_9690) {
                sc->sc_nunits = TWA_9690_MAX_UNITS;
                use_64bit = true;
 @@ -1544,6 +1549,7 @@ twa_attach(device_t parent, device_t sel
                        aprint_error_dev(&sc->twa_dv, "can't map mem space\n");
                        return;
                }
 +              sc->sc_quirks |= TWA_QUIRK_QUEUEFULL_BUG;
        } else {
                sc->sc_nunits = 0;
                use_64bit = false;
 Index: twareg.h
 ===================================================================
 RCS file: /cvsroot/src/sys/dev/pci/twareg.h,v
 retrieving revision 1.10
 diff -u -p -r1.10 twareg.h
 --- twareg.h   8 Sep 2008 23:36:54 -0000       1.10
 +++ twareg.h   10 Nov 2010 20:15:17 -0000
 @@ -102,13 +102,13 @@
        } while (0)
  #endif
  
 -#define TWA_WRITE_9650_COMMAND_QUEUE_HIGH(sc, val)                    \
 +#define TWA_WRITE_COMMAND_QUEUE_HIGH(sc, val)                         \
        do {                                                            \
                TWA_WRITE_REGISTER(sc, TWA_COMMAND_QUEUE_OFFSET_HIGH,   \
                                (uint32_t)(((uint64_t)val)>>32));       \
        } while (0)
  
 -#define TWA_WRITE_9650_COMMAND_QUEUE_LOW(sc, val)                     \
 +#define TWA_WRITE_COMMAND_QUEUE_LOW(sc, val)                          \
        do {                                                            \
                TWA_WRITE_REGISTER(sc, TWA_COMMAND_QUEUE_OFFSET_LOW,    \
                                (uint32_t)(val));                       \
 Index: twavar.h
 ===================================================================
 RCS file: /cvsroot/src/sys/dev/pci/twavar.h,v
 retrieving revision 1.9
 diff -u -p -r1.9 twavar.h
 --- twavar.h   6 May 2009 10:34:33 -0000       1.9
 +++ twavar.h   10 Nov 2010 20:15:17 -0000
 @@ -107,6 +107,7 @@ struct twa_softc {
  
        struct twa_request      *sc_twa_request;
        uint32_t                sc_product_id;
 +      unsigned                sc_quirks;
  };
  
  
 @@ -145,6 +146,9 @@ struct twa_softc {
  #define TWA_LOCK_FREE         0x0     /* lock is free */
  #define TWA_LOCK_HELD         0x1     /* lock is held */
  
 +/* Possible values of sc->sc_quirks. */
 +#define TWA_QUIRK_QUEUEFULL_BUG       0x1
 +
  /* Driver's request packet. */
  struct twa_request {
        struct twa_command_packet *tr_command;
 
 
 -- 
 David A. Holland
 dholland%netbsd.org@localhost
 


Home | Main Index | Thread Index | Old Index