[BACK]Return to esiop.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / ic

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/dev/ic/esiop.c between version 1.42.4.6 and 1.43

version 1.42.4.6, 2010/10/09 03:32:06 version 1.43, 2009/03/14 15:36:17
Line 11 
Line 11 
  * 2. Redistributions in binary form must reproduce the above copyright   * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the   *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.   *    documentation and/or other materials provided with the distribution.
    * 3. All advertising materials mentioning features or use of this software
    *    must display the following acknowledgement:
    *      This product includes software developed by Manuel Bouyer.
    * 4. The name of the author may not be used to endorse or promote products
    *    derived from this software without specific prior written permission.
  *   *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
Line 56  __KERNEL_RCSID(0, "$NetBSD$");
Line 61  __KERNEL_RCSID(0, "$NetBSD$");
   
 #include "opt_siop.h"  #include "opt_siop.h"
   
   #ifndef DEBUG
   #undef DEBUG
   #endif
 /*  /*
 #define SIOP_DEBUG  #define SIOP_DEBUG
 #define SIOP_DEBUG_DR  #define SIOP_DEBUG_DR
 #define SIOP_DEBUG_INTR  #define SIOP_DEBUG_INTR
 #define SIOP_DEBUG_SCHED  #define SIOP_DEBUG_SCHED
 #define SIOP_DUMP_SCRIPT  #define DUMP_SCRIPT
 */  */
   
 #define SIOP_STATS  #define SIOP_STATS
Line 80  void esiop_scsicmd_end(struct esiop_cmd 
Line 88  void esiop_scsicmd_end(struct esiop_cmd 
 void    esiop_unqueue(struct esiop_softc *, int, int);  void    esiop_unqueue(struct esiop_softc *, int, int);
 int     esiop_handle_qtag_reject(struct esiop_cmd *);  int     esiop_handle_qtag_reject(struct esiop_cmd *);
 static void     esiop_start(struct esiop_softc *, struct esiop_cmd *);  static void     esiop_start(struct esiop_softc *, struct esiop_cmd *);
 void    esiop_timeout(void *);  void    esiop_timeout(void *);
 void    esiop_scsipi_request(struct scsipi_channel *,  void    esiop_scsipi_request(struct scsipi_channel *,
                         scsipi_adapter_req_t, void *);                          scsipi_adapter_req_t, void *);
 void    esiop_dump_script(struct esiop_softc *);  void    esiop_dump_script(struct esiop_softc *);
 void    esiop_morecbd(struct esiop_softc *);  void    esiop_morecbd(struct esiop_softc *);
 void    esiop_moretagtbl(struct esiop_softc *);  void    esiop_moretagtbl(struct esiop_softc *);
 void    siop_add_reselsw(struct esiop_softc *, int);  void    siop_add_reselsw(struct esiop_softc *, int);
 void    esiop_target_register(struct esiop_softc *, uint32_t);  void    esiop_target_register(struct esiop_softc *, u_int32_t);
   
 void    esiop_update_scntl3(struct esiop_softc *, struct siop_common_target *);  void    esiop_update_scntl3(struct esiop_softc *, struct siop_common_target *);
   
Line 109  static inline void esiop_script_sync(str
Line 117  static inline void esiop_script_sync(str
 static inline void  static inline void
 esiop_script_sync(struct esiop_softc *sc, int ops)  esiop_script_sync(struct esiop_softc *sc, int ops)
 {  {
   
         if ((sc->sc_c.features & SF_CHIP_RAM) == 0)          if ((sc->sc_c.features & SF_CHIP_RAM) == 0)
                 bus_dmamap_sync(sc->sc_c.sc_dmat, sc->sc_c.sc_scriptdma, 0,                  bus_dmamap_sync(sc->sc_c.sc_dmat, sc->sc_c.sc_scriptdma, 0,
                     PAGE_SIZE, ops);                      PAGE_SIZE, ops);
 }  }
   
 static inline uint32_t esiop_script_read(struct esiop_softc *, u_int);  static inline u_int32_t esiop_script_read(struct esiop_softc *, u_int);
 static inline uint32_t  static inline u_int32_t
 esiop_script_read(struct esiop_softc *sc, u_int offset)  esiop_script_read(struct esiop_softc *sc, u_int offset)
 {  {
   
         if (sc->sc_c.features & SF_CHIP_RAM) {          if (sc->sc_c.features & SF_CHIP_RAM) {
                 return bus_space_read_4(sc->sc_c.sc_ramt, sc->sc_c.sc_ramh,                  return bus_space_read_4(sc->sc_c.sc_ramt, sc->sc_c.sc_ramh,
                     offset * 4);                      offset * 4);
Line 129  esiop_script_read(struct esiop_softc *sc
Line 135  esiop_script_read(struct esiop_softc *sc
 }  }
   
 static inline void esiop_script_write(struct esiop_softc *, u_int,  static inline void esiop_script_write(struct esiop_softc *, u_int,
         uint32_t);          u_int32_t);
 static inline void  static inline void
 esiop_script_write(struct esiop_softc *sc, u_int offset, uint32_t val)  esiop_script_write(struct esiop_softc *sc, u_int offset, u_int32_t val)
 {  {
   
         if (sc->sc_c.features & SF_CHIP_RAM) {          if (sc->sc_c.features & SF_CHIP_RAM) {
                 bus_space_write_4(sc->sc_c.sc_ramt, sc->sc_c.sc_ramh,                  bus_space_write_4(sc->sc_c.sc_ramt, sc->sc_c.sc_ramh,
                     offset * 4, val);                      offset * 4, val);
Line 156  esiop_attach(struct esiop_softc *sc)
Line 161  esiop_attach(struct esiop_softc *sc)
         TAILQ_INIT(&sc->tag_tblblk);          TAILQ_INIT(&sc->tag_tblblk);
         sc->sc_currschedslot = 0;          sc->sc_currschedslot = 0;
 #ifdef SIOP_DEBUG  #ifdef SIOP_DEBUG
         aprint_debug_dev(sc->sc_c.sc_dev,          aprint_debug_dev(&sc->sc_c.sc_dev, "script size = %d, PHY addr=0x%x, VIRT=%p\n",
             "script size = %d, PHY addr=0x%x, VIRT=%p\n",  
             (int)sizeof(esiop_script),              (int)sizeof(esiop_script),
             (uint32_t)sc->sc_c.sc_scriptaddr, sc->sc_c.sc_script);              (u_int32_t)sc->sc_c.sc_scriptaddr, sc->sc_c.sc_script);
 #endif  #endif
   
         sc->sc_c.sc_adapt.adapt_max_periph = ESIOP_NTAG;          sc->sc_c.sc_adapt.adapt_max_periph = ESIOP_NTAG;
Line 171  esiop_attach(struct esiop_softc *sc)
Line 175  esiop_attach(struct esiop_softc *sc)
          */           */
 #ifdef DIAGNOSTIC  #ifdef DIAGNOSTIC
         if (ESIOP_NTAG != A_ndone_slots) {          if (ESIOP_NTAG != A_ndone_slots) {
                 aprint_error_dev(sc->sc_c.sc_dev,                  aprint_error_dev(&sc->sc_c.sc_dev, "size of tag DSA table different from the done"
                      "size of tag DSA table different from the done ring\n");                      " ring\n");
                 return;                  return;
         }          }
 #endif  #endif
         esiop_moretagtbl(sc);          esiop_moretagtbl(sc);
         tagtbl_donering = TAILQ_FIRST(&sc->free_tagtbl);          tagtbl_donering = TAILQ_FIRST(&sc->free_tagtbl);
         if (tagtbl_donering == NULL) {          if (tagtbl_donering == NULL) {
                 aprint_error_dev(sc->sc_c.sc_dev,                  aprint_error_dev(&sc->sc_c.sc_dev, "no memory for command done ring\n");
                     "no memory for command done ring\n");  
                 return;                  return;
         }          }
         TAILQ_REMOVE(&sc->free_tagtbl, tagtbl_donering, next);          TAILQ_REMOVE(&sc->free_tagtbl, tagtbl_donering, next);
Line 194  esiop_attach(struct esiop_softc *sc)
Line 197  esiop_attach(struct esiop_softc *sc)
          * siop_reset() will reset the chip, thus clearing pending interrupts           * siop_reset() will reset the chip, thus clearing pending interrupts
          */           */
         esiop_reset(sc);          esiop_reset(sc);
 #ifdef SIOP_DUMP_SCRIPT  #ifdef DUMP_SCRIPT
         esiop_dump_script(sc);          esiop_dump_script(sc);
 #endif  #endif
   
         config_found(sc->sc_c.sc_dev, &sc->sc_c.sc_chan, scsiprint);          config_found((struct device*)sc, &sc->sc_c.sc_chan, scsiprint);
 }  }
   
 void  void
 esiop_reset(struct esiop_softc *sc)  esiop_reset(struct esiop_softc *sc)
 {  {
         int i, j;          int i, j;
         uint32_t addr;          u_int32_t addr;
         uint32_t msgin_addr, sem_addr;          u_int32_t msgin_addr, sem_addr;
   
         siop_common_reset(&sc->sc_c);          siop_common_reset(&sc->sc_c);
   
Line 214  esiop_reset(struct esiop_softc *sc)
Line 217  esiop_reset(struct esiop_softc *sc)
          * we copy the script at the beggining of RAM. Then there is 4 bytes           * we copy the script at the beggining of RAM. Then there is 4 bytes
          * for messages in, and 4 bytes for semaphore           * for messages in, and 4 bytes for semaphore
          */           */
         sc->sc_free_offset = __arraycount(esiop_script);          sc->sc_free_offset = sizeof(esiop_script) / sizeof(esiop_script[0]);
         msgin_addr =          msgin_addr =
             sc->sc_free_offset * sizeof(uint32_t) + sc->sc_c.sc_scriptaddr;              sc->sc_free_offset * sizeof(u_int32_t) + sc->sc_c.sc_scriptaddr;
         sc->sc_free_offset += 1;          sc->sc_free_offset += 1;
         sc->sc_semoffset = sc->sc_free_offset;          sc->sc_semoffset = sc->sc_free_offset;
         sem_addr =          sem_addr =
             sc->sc_semoffset * sizeof(uint32_t) + sc->sc_c.sc_scriptaddr;              sc->sc_semoffset * sizeof(u_int32_t) + sc->sc_c.sc_scriptaddr;
         sc->sc_free_offset += 1;          sc->sc_free_offset += 1;
         /* then we have the scheduler ring */          /* then we have the scheduler ring */
         sc->sc_shedoffset = sc->sc_free_offset;          sc->sc_shedoffset = sc->sc_free_offset;
Line 232  esiop_reset(struct esiop_softc *sc)
Line 235  esiop_reset(struct esiop_softc *sc)
         if (sc->sc_c.features & SF_CHIP_RAM) {          if (sc->sc_c.features & SF_CHIP_RAM) {
                 bus_space_write_region_4(sc->sc_c.sc_ramt, sc->sc_c.sc_ramh, 0,                  bus_space_write_region_4(sc->sc_c.sc_ramt, sc->sc_c.sc_ramh, 0,
                     esiop_script,                      esiop_script,
                     __arraycount(esiop_script));                      sizeof(esiop_script) / sizeof(esiop_script[0]));
                 for (j = 0; j < __arraycount(E_tlq_offset_Used); j++) {                  for (j = 0; j <
                       (sizeof(E_tlq_offset_Used) / sizeof(E_tlq_offset_Used[0]));
                       j++) {
                         bus_space_write_4(sc->sc_c.sc_ramt, sc->sc_c.sc_ramh,                          bus_space_write_4(sc->sc_c.sc_ramt, sc->sc_c.sc_ramh,
                             E_tlq_offset_Used[j] * 4,                              E_tlq_offset_Used[j] * 4,
                             sizeof(struct siop_common_xfer));                              sizeof(struct siop_common_xfer));
                 }                  }
                 for (j = 0; j < __arraycount(E_saved_offset_offset_Used); j++) {                  for (j = 0; j <
                       (sizeof(E_saved_offset_offset_Used) /
                        sizeof(E_saved_offset_offset_Used[0]));
                       j++) {
                         bus_space_write_4(sc->sc_c.sc_ramt, sc->sc_c.sc_ramh,                          bus_space_write_4(sc->sc_c.sc_ramt, sc->sc_c.sc_ramh,
                             E_saved_offset_offset_Used[j] * 4,                              E_saved_offset_offset_Used[j] * 4,
                             sizeof(struct siop_common_xfer) + 4);                              sizeof(struct siop_common_xfer) + 4);
                 }                  }
                 for (j = 0; j < __arraycount(E_abs_msgin2_Used); j++) {                  for (j = 0; j <
                       (sizeof(E_abs_msgin2_Used) / sizeof(E_abs_msgin2_Used[0]));
                       j++) {
                         bus_space_write_4(sc->sc_c.sc_ramt, sc->sc_c.sc_ramh,                          bus_space_write_4(sc->sc_c.sc_ramt, sc->sc_c.sc_ramh,
                             E_abs_msgin2_Used[j] * 4, msgin_addr);                              E_abs_msgin2_Used[j] * 4, msgin_addr);
                 }                  }
                 for (j = 0; j < __arraycount(E_abs_sem_Used); j++) {                  for (j = 0; j <
                       (sizeof(E_abs_sem_Used) / sizeof(E_abs_sem_Used[0]));
                       j++) {
                         bus_space_write_4(sc->sc_c.sc_ramt, sc->sc_c.sc_ramh,                          bus_space_write_4(sc->sc_c.sc_ramt, sc->sc_c.sc_ramh,
                             E_abs_sem_Used[j] * 4, sem_addr);                              E_abs_sem_Used[j] * 4, sem_addr);
                 }                  }
Line 256  esiop_reset(struct esiop_softc *sc)
Line 268  esiop_reset(struct esiop_softc *sc)
                         bus_space_write_region_4(sc->sc_c.sc_ramt,                          bus_space_write_region_4(sc->sc_c.sc_ramt,
                             sc->sc_c.sc_ramh,                              sc->sc_c.sc_ramh,
                             Ent_led_on1, esiop_led_on,                              Ent_led_on1, esiop_led_on,
                             __arraycount(esiop_led_on));                              sizeof(esiop_led_on) / sizeof(esiop_led_on[0]));
                         bus_space_write_region_4(sc->sc_c.sc_ramt,                          bus_space_write_region_4(sc->sc_c.sc_ramt,
                             sc->sc_c.sc_ramh,                              sc->sc_c.sc_ramh,
                             Ent_led_on2, esiop_led_on,                              Ent_led_on2, esiop_led_on,
                             __arraycount(esiop_led_on));                              sizeof(esiop_led_on) / sizeof(esiop_led_on[0]));
                         bus_space_write_region_4(sc->sc_c.sc_ramt,                          bus_space_write_region_4(sc->sc_c.sc_ramt,
                             sc->sc_c.sc_ramh,                              sc->sc_c.sc_ramh,
                             Ent_led_off, esiop_led_off,                              Ent_led_off, esiop_led_off,
                             __arraycount(esiop_led_off));                              sizeof(esiop_led_off) / sizeof(esiop_led_off[0]));
                 }                  }
         } else {          } else {
                 for (j = 0; j < __arraycount(esiop_script); j++) {                  for (j = 0;
                       j < (sizeof(esiop_script) / sizeof(esiop_script[0])); j++) {
                         sc->sc_c.sc_script[j] = htole32(esiop_script[j]);                          sc->sc_c.sc_script[j] = htole32(esiop_script[j]);
                 }                  }
                 for (j = 0; j < __arraycount(E_tlq_offset_Used); j++) {                  for (j = 0; j <
                       (sizeof(E_tlq_offset_Used) / sizeof(E_tlq_offset_Used[0]));
                       j++) {
                         sc->sc_c.sc_script[E_tlq_offset_Used[j]] =                          sc->sc_c.sc_script[E_tlq_offset_Used[j]] =
                             htole32(sizeof(struct siop_common_xfer));                              htole32(sizeof(struct siop_common_xfer));
                 }                  }
                 for (j = 0; j < __arraycount(E_saved_offset_offset_Used); j++) {                  for (j = 0; j <
                       (sizeof(E_saved_offset_offset_Used) /
                        sizeof(E_saved_offset_offset_Used[0]));
                       j++) {
                         sc->sc_c.sc_script[E_saved_offset_offset_Used[j]] =                          sc->sc_c.sc_script[E_saved_offset_offset_Used[j]] =
                             htole32(sizeof(struct siop_common_xfer) + 4);                              htole32(sizeof(struct siop_common_xfer) + 4);
                 }                  }
                 for (j = 0; j < __arraycount(E_abs_msgin2_Used); j++) {                  for (j = 0; j <
                       (sizeof(E_abs_msgin2_Used) / sizeof(E_abs_msgin2_Used[0]));
                       j++) {
                         sc->sc_c.sc_script[E_abs_msgin2_Used[j]] =                          sc->sc_c.sc_script[E_abs_msgin2_Used[j]] =
                             htole32(msgin_addr);                              htole32(msgin_addr);
                 }                  }
                 for (j = 0; j < __arraycount(E_abs_sem_Used); j++) {                  for (j = 0; j <
                       (sizeof(E_abs_sem_Used) / sizeof(E_abs_sem_Used[0]));
                       j++) {
                         sc->sc_c.sc_script[E_abs_sem_Used[j]] =                          sc->sc_c.sc_script[E_abs_sem_Used[j]] =
                             htole32(sem_addr);                              htole32(sem_addr);
                 }                  }
   
                 if (sc->sc_c.features & SF_CHIP_LED0) {                  if (sc->sc_c.features & SF_CHIP_LED0) {
                         for (j = 0; j < __arraycount(esiop_led_on); j++)                          for (j = 0; j < (sizeof(esiop_led_on) /
                               sizeof(esiop_led_on[0])); j++)
                                 sc->sc_c.sc_script[                                  sc->sc_c.sc_script[
                                     Ent_led_on1 / sizeof(esiop_led_on[0]) + j                                      Ent_led_on1 / sizeof(esiop_led_on[0]) + j
                                     ] = htole32(esiop_led_on[j]);                                      ] = htole32(esiop_led_on[j]);
                         for (j = 0; j < __arraycount(esiop_led_on); j++)                          for (j = 0; j < (sizeof(esiop_led_on) /
                               sizeof(esiop_led_on[0])); j++)
                                 sc->sc_c.sc_script[                                  sc->sc_c.sc_script[
                                     Ent_led_on2 / sizeof(esiop_led_on[0]) + j                                      Ent_led_on2 / sizeof(esiop_led_on[0]) + j
                                     ] = htole32(esiop_led_on[j]);                                      ] = htole32(esiop_led_on[j]);
                         for (j = 0; j < __arraycount(esiop_led_off); j++)                          for (j = 0; j < (sizeof(esiop_led_off) /
                               sizeof(esiop_led_off[0])); j++)
                                 sc->sc_c.sc_script[                                  sc->sc_c.sc_script[
                                     Ent_led_off / sizeof(esiop_led_off[0]) + j                                     Ent_led_off / sizeof(esiop_led_off[0]) + j
                                     ] = htole32(esiop_led_off[j]);                                     ] = htole32(esiop_led_off[j]);
                 }                  }
         }          }
         /* get base of scheduler ring */          /* get base of scheduler ring */
         addr = sc->sc_c.sc_scriptaddr + sc->sc_shedoffset * sizeof(uint32_t);          addr = sc->sc_c.sc_scriptaddr + sc->sc_shedoffset * sizeof(u_int32_t);
         /* init scheduler */          /* init scheduler */
         for (i = 0; i < A_ncmd_slots; i++) {          for (i = 0; i < A_ncmd_slots; i++) {
                 esiop_script_write(sc,                  esiop_script_write(sc,
Line 328  esiop_reset(struct esiop_softc *sc)
Line 353  esiop_reset(struct esiop_softc *sc)
         for (i = 0; i < A_ndone_slots; i++)          for (i = 0; i < A_ndone_slots; i++)
                 sc->sc_done_slot[i] = 0;                  sc->sc_done_slot[i] = 0;
         bus_dmamap_sync(sc->sc_c.sc_dmat, sc->sc_done_map,          bus_dmamap_sync(sc->sc_c.sc_dmat, sc->sc_done_map,
             sc->sc_done_offset, A_ndone_slots * sizeof(uint32_t),              sc->sc_done_offset, A_ndone_slots * sizeof(u_int32_t),
             BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);              BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
         addr = sc->sc_done_map->dm_segs[0].ds_addr + sc->sc_done_offset;          addr = sc->sc_done_map->dm_segs[0].ds_addr + sc->sc_done_offset;
         sc->sc_currdoneslot = 0;          sc->sc_currdoneslot = 0;
Line 346  esiop_reset(struct esiop_softc *sc)
Line 371  esiop_reset(struct esiop_softc *sc)
         /* set flags */          /* set flags */
         bus_space_write_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_SCRATCHC, 0);          bus_space_write_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_SCRATCHC, 0);
         /* write pointer of base of target DSA table */          /* write pointer of base of target DSA table */
         addr = (sc->sc_target_table_offset * sizeof(uint32_t)) +          addr = (sc->sc_target_table_offset * sizeof(u_int32_t)) +
             sc->sc_c.sc_scriptaddr;              sc->sc_c.sc_scriptaddr;
         esiop_script_write(sc, (Ent_load_targtable / 4) + 0,          esiop_script_write(sc, (Ent_load_targtable / 4) + 0,
             esiop_script_read(sc,(Ent_load_targtable / 4) + 0) |              esiop_script_read(sc,(Ent_load_targtable / 4) + 0) |
Line 362  esiop_reset(struct esiop_softc *sc)
Line 387  esiop_reset(struct esiop_softc *sc)
             ((addr & 0xff000000) >> 16));              ((addr & 0xff000000) >> 16));
 #ifdef SIOP_DEBUG  #ifdef SIOP_DEBUG
         printf("%s: target table offset %d free offset %d\n",          printf("%s: target table offset %d free offset %d\n",
             device_xname(sc->sc_c.sc_dev), sc->sc_target_table_offset,              device_xname(&sc->sc_c.sc_dev), sc->sc_target_table_offset,
             sc->sc_free_offset);              sc->sc_free_offset);
 #endif  #endif
   
Line 381  esiop_reset(struct esiop_softc *sc)
Line 406  esiop_reset(struct esiop_softc *sc)
 }  }
   
 #if 0  #if 0
 #define CALL_SCRIPT(ent) do {                                           \  #define CALL_SCRIPT(ent) do {\
         printf ("start script DSA 0x%lx DSP 0x%lx\n",                   \          printf ("start script DSA 0x%lx DSP 0x%lx\n", \
             esiop_cmd->cmd_c.dsa,                                       \              esiop_cmd->cmd_c.dsa, \
             sc->sc_c.sc_scriptaddr + ent);                              \              sc->sc_c.sc_scriptaddr + ent); \
         bus_space_write_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh,               \  bus_space_write_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_DSP, sc->sc_c.sc_scriptaddr + ent); \
             SIOP_DSP, sc->sc_c.sc_scriptaddr + ent);                    \  } while (0)
 } while (/* CONSTCOND */0)  
 #else  #else
 #define CALL_SCRIPT(ent) do {                                           \  #define CALL_SCRIPT(ent) do {\
         bus_space_write_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh,               \  bus_space_write_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_DSP, sc->sc_c.sc_scriptaddr + ent); \
             SIOP_DSP, sc->sc_c.sc_scriptaddr + ent);                    \  } while (0)
 } while (/* CONSTCOND */0)  
 #endif  #endif
   
 int  int
Line 404  esiop_intr(void *v)
Line 427  esiop_intr(void *v)
         struct esiop_lun *esiop_lun;          struct esiop_lun *esiop_lun;
         struct scsipi_xfer *xs;          struct scsipi_xfer *xs;
         int istat, sist, sstat1, dstat = 0; /* XXX: gcc */          int istat, sist, sstat1, dstat = 0; /* XXX: gcc */
         uint32_t irqcode;          u_int32_t irqcode;
         int need_reset = 0;          int need_reset = 0;
         int offset, target, lun, tag;          int offset, target, lun, tag;
         uint32_t tflags;          u_int32_t tflags;
         uint32_t addr;          u_int32_t addr;
         int freetarget = 0;          int freetarget = 0;
         int slot;          int slot;
         int retval = 0;          int retval = 0;
Line 466  again:
Line 489  again:
                 esiop_cmd =                  esiop_cmd =
                     (tag >= 0) ? esiop_lun->tactive[tag] : esiop_lun->active;                      (tag >= 0) ? esiop_lun->tactive[tag] : esiop_lun->active;
                 if (esiop_cmd == NULL) {                  if (esiop_cmd == NULL) {
                         printf("esiop_cmd (target %d lun %d tag %d)"                          printf("esiop_cmd (target %d lun %d tag %d) not valid\n",
                             " not valid\n",  
                             target, lun, tag);                              target, lun, tag);
                         goto none;                          goto none;
                 }                  }
                 xs = esiop_cmd->cmd_c.xs;                  xs = esiop_cmd->cmd_c.xs;
 #ifdef DIAGNOSTIC  #ifdef DIAGNOSTIC
                 if (esiop_cmd->cmd_c.status != CMDST_ACTIVE) {                  if (esiop_cmd->cmd_c.status != CMDST_ACTIVE) {
                         printf("esiop_cmd (target %d lun %d) "                          printf("esiop_cmd (target %d lun %d) "
                             "not active (%d)\n", target, lun,                              "not active (%d)\n", target, lun,
                             esiop_cmd->cmd_c.status);                              esiop_cmd->cmd_c.status);
                         goto none;                          goto none;
Line 516  none:
Line 538  none:
                 }                  }
   
                 if (dstat & ~(DSTAT_SIR | DSTAT_DFE | DSTAT_SSI)) {                  if (dstat & ~(DSTAT_SIR | DSTAT_DFE | DSTAT_SSI)) {
                 printf("%s: DMA IRQ:", device_xname(sc->sc_c.sc_dev));                  printf("%s: DMA IRQ:", device_xname(&sc->sc_c.sc_dev));
                 if (dstat & DSTAT_IID)                  if (dstat & DSTAT_IID)
                         printf(" Illegal instruction");                          printf(" Illegal instruction");
                 if (dstat & DSTAT_BF)                  if (dstat & DSTAT_BF)
Line 568  none:
Line 590  none:
                         if (esiop_cmd)                          if (esiop_cmd)
                                 scsipi_printaddr(xs->xs_periph);                                  scsipi_printaddr(xs->xs_periph);
                         else                          else
                                 printf("%s:", device_xname(sc->sc_c.sc_dev));                                  printf("%s:", device_xname(&sc->sc_c.sc_dev));
                         printf("scsi gross error\n");                          printf("scsi gross error\n");
                         if (esiop_target)                          if (esiop_target)
                                 esiop_target->target_c.flags &= ~TARF_DT;                                  esiop_target->target_c.flags &= ~TARF_DT;
 #ifdef SIOP_DEBUG  #ifdef DEBUG
                         printf("DSA=0x%x DSP=0x%lx\n",                          printf("DSA=0x%x DSP=0x%lx\n",
                             bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh,                              bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_DSA),
                             SIOP_DSA),                              (u_long)(bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh,
                             (u_long)(bus_space_read_4(sc->sc_c.sc_rt,                                  SIOP_DSP) -
                                 sc->sc_c.sc_rh, SIOP_DSP) -  
                             sc->sc_c.sc_scriptaddr));                              sc->sc_c.sc_scriptaddr));
                         printf("SDID 0x%x SCNTL3 0x%x SXFER 0x%x SCNTL4 0x%x\n",                          printf("SDID 0x%x SCNTL3 0x%x SXFER 0x%x SCNTL4 0x%x\n",
                             bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh,                              bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_SDID),
                             SIOP_SDID),                               bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_SCNTL3),
                             bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh,                               bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_SXFER),
                             SIOP_SCNTL3),                               bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_SCNTL4));
                             bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh,  
                             SIOP_SXFER),  
                             bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh,  
                             SIOP_SCNTL4));  
   
 #endif  #endif
                         goto reset;                          goto reset;
Line 639  none:
Line 656  none:
                                         CALL_SCRIPT(Ent_msgin);                                          CALL_SCRIPT(Ent_msgin);
                                         return 1;                                          return 1;
                                 }                                  }
                                 aprint_error_dev(sc->sc_c.sc_dev,                                  aprint_error_dev(&sc->sc_c.sc_dev, "unexpected phase mismatch %d\n",
                                     "unexpected phase mismatch %d\n",  
                                     sstat1 & SSTAT1_PHASE_MASK);                                      sstat1 & SSTAT1_PHASE_MASK);
                         } else {                          } else {
                                 aprint_error_dev(sc->sc_c.sc_dev,                                  aprint_error_dev(&sc->sc_c.sc_dev, "phase mismatch without command\n");
                                     "phase mismatch without command\n");  
                         }                          }
                         need_reset = 1;                          need_reset = 1;
                 }                  }
Line 653  none:
Line 668  none:
                         if (esiop_cmd)                          if (esiop_cmd)
                                 scsipi_printaddr(xs->xs_periph);                                  scsipi_printaddr(xs->xs_periph);
                         else                          else
                                 printf("%s:", device_xname(sc->sc_c.sc_dev));                                  printf("%s:", device_xname(&sc->sc_c.sc_dev));
                         printf("parity error\n");                          printf("parity error\n");
                         if (esiop_target)                          if (esiop_target)
                                 esiop_target->target_c.flags &= ~TARF_DT;                                  esiop_target->target_c.flags &= ~TARF_DT;
Line 669  none:
Line 684  none:
                         esiop_script_sync(sc,                          esiop_script_sync(sc,
                             BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);                              BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
 #ifdef SIOP_DEBUG_SCHED  #ifdef SIOP_DEBUG_SCHED
                         printf("sel timeout target %d, slot %d\n",                          printf("sel timeout target %d, slot %d\n", target, slot);
                             target, slot);  
 #endif  #endif
                         /*                          /*
                          * mark this slot as free, and advance to next slot                           * mark this slot as free, and advance to next slot
Line 688  none:
Line 702  none:
                                 bus_space_write_1(sc->sc_c.sc_rt,                                  bus_space_write_1(sc->sc_c.sc_rt,
                                     sc->sc_c.sc_rh, SIOP_SCRATCHE, 0);                                      sc->sc_c.sc_rh, SIOP_SCRATCHE, 0);
                                 addr = sc->sc_c.sc_scriptaddr +                                  addr = sc->sc_c.sc_scriptaddr +
                                     sc->sc_shedoffset * sizeof(uint32_t);                                      sc->sc_shedoffset * sizeof(u_int32_t);
                         }                          }
                         bus_space_write_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh,                          bus_space_write_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh,
                             SIOP_SCRATCHD, addr);                              SIOP_SCRATCHD, addr);
Line 703  none:
Line 717  none:
                                 printf("%s: selection timeout without "                                  printf("%s: selection timeout without "
                                     "command, target %d (sdid 0x%x), "                                      "command, target %d (sdid 0x%x), "
                                     "slot %d\n",                                      "slot %d\n",
                                     device_xname(sc->sc_c.sc_dev), target,                                      device_xname(&sc->sc_c.sc_dev), target,
                                     bus_space_read_1(sc->sc_c.sc_rt,                                      bus_space_read_1(sc->sc_c.sc_rt,
                                     sc->sc_c.sc_rh, SIOP_SDID), slot);                                      sc->sc_c.sc_rh, SIOP_SDID), slot);
                                 need_reset = 1;                                  need_reset = 1;
Line 719  none:
Line 733  none:
                                     htole32(SCSI_CHECK);                                      htole32(SCSI_CHECK);
                                 goto end;                                  goto end;
                         }                          }
                         aprint_error_dev(sc->sc_c.sc_dev,                          aprint_error_dev(&sc->sc_c.sc_dev, "unexpected disconnect without "
                             "unexpected disconnect without command\n");                              "command\n");
                         goto reset;                          goto reset;
                 }                  }
                 if (sist & (SIST1_SBMC << 8)) {                  if (sist & (SIST1_SBMC << 8)) {
Line 745  none:
Line 759  none:
                         return 1;                          return 1;
                 }                  }
                 /* Else it's an unhandled exception (for now). */                  /* Else it's an unhandled exception (for now). */
                 aprint_error_dev(sc->sc_c.sc_dev,                  aprint_error_dev(&sc->sc_c.sc_dev, "unhandled scsi interrupt, sist=0x%x sstat1=0x%x "
                     "unhandled scsi interrupt, sist=0x%x sstat1=0x%x "  
                     "DSA=0x%x DSP=0x%x\n", sist,                      "DSA=0x%x DSP=0x%x\n", sist,
                     bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh,                      bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh,
                         SIOP_SSTAT1),                          SIOP_SSTAT1),
Line 781  scintr:
Line 794  scintr:
                  */                   */
                 if ((irqcode & 0x80) == 0) {                  if ((irqcode & 0x80) == 0) {
                         if (esiop_cmd == NULL) {                          if (esiop_cmd == NULL) {
                                 aprint_error_dev(sc->sc_c.sc_dev,                                  aprint_error_dev(&sc->sc_c.sc_dev,
                         "script interrupt (0x%x) with invalid DSA !!!\n",                          "script interrupt (0x%x) with invalid DSA !!!\n",
                                     irqcode);                                      irqcode);
                                 goto reset;                                  goto reset;
                         }                          }
                         if (esiop_cmd->cmd_c.status != CMDST_ACTIVE) {                          if (esiop_cmd->cmd_c.status != CMDST_ACTIVE) {
                                 aprint_error_dev(sc->sc_c.sc_dev,                                  aprint_error_dev(&sc->sc_c.sc_dev, "command with invalid status "
                                     "command with invalid status "  
                                     "(IRQ code 0x%x current status %d) !\n",                                      "(IRQ code 0x%x current status %d) !\n",
                                     irqcode, esiop_cmd->cmd_c.status);                                      irqcode, esiop_cmd->cmd_c.status);
                                 xs = NULL;                                  xs = NULL;
Line 798  scintr:
Line 810  scintr:
                 case A_int_err:                  case A_int_err:
                         printf("error, DSP=0x%x\n",                          printf("error, DSP=0x%x\n",
                             (int)(bus_space_read_4(sc->sc_c.sc_rt,                              (int)(bus_space_read_4(sc->sc_c.sc_rt,
                             sc->sc_c.sc_rh, SIOP_DSP) -                              sc->sc_c.sc_rh, SIOP_DSP) - sc->sc_c.sc_scriptaddr));
                             sc->sc_c.sc_scriptaddr));  
                         if (xs) {                          if (xs) {
                                 xs->error = XS_SELTIMEOUT;                                  xs->error = XS_SELTIMEOUT;
                                 goto end;                                  goto end;
Line 833  scintr:
Line 844  scintr:
                                         if (xs)                                          if (xs)
                                                 scsipi_printaddr(xs->xs_periph);                                                  scsipi_printaddr(xs->xs_periph);
                                         else                                          else
                                                 printf("%s: ", device_xname(                                                  printf("%s: ",
                                                     sc->sc_c.sc_dev));                                                     device_xname(&sc->sc_c.sc_dev));
                                         printf("our reject message was "                                          printf("our reject message was "
                                             "rejected\n");                                              "rejected\n");
                                         goto reset;                                          goto reset;
Line 899  scintr:
Line 910  scintr:
                                         scsipi_printaddr(xs->xs_periph);                                          scsipi_printaddr(xs->xs_periph);
                                 else                                  else
                                         printf("%s: ",                                          printf("%s: ",
                                             device_xname(sc->sc_c.sc_dev));                                              device_xname(&sc->sc_c.sc_dev));
                                 if (msg == MSG_EXTENDED) {                                  if (msg == MSG_EXTENDED) {
                                         printf("scsi message reject, extended "                                          printf("scsi message reject, extended "
                                             "message sent was 0x%x\n", extmsg);                                              "message sent was 0x%x\n", extmsg);
Line 923  scintr:
Line 934  scintr:
                         if (xs)                          if (xs)
                                 scsipi_printaddr(xs->xs_periph);                                  scsipi_printaddr(xs->xs_periph);
                         else                          else
                                 printf("%s: ", device_xname(sc->sc_c.sc_dev));                                  printf("%s: ", device_xname(&sc->sc_c.sc_dev));
                         printf("unhandled message 0x%x\n", msgin);                          printf("unhandled message 0x%x\n", msgin);
                         esiop_cmd->cmd_tables->msg_out[0] = MSG_MESSAGE_REJECT;                          esiop_cmd->cmd_tables->msg_out[0] = MSG_MESSAGE_REJECT;
                         esiop_cmd->cmd_tables->t_msgout.count= htole32(1);                          esiop_cmd->cmd_tables->t_msgout.count= htole32(1);
Line 940  scintr:
Line 951  scintr:
 #endif  #endif
                         if (esiop_cmd->cmd_tables->msg_in[1] >                          if (esiop_cmd->cmd_tables->msg_in[1] >
                             sizeof(esiop_cmd->cmd_tables->msg_in) - 2)                              sizeof(esiop_cmd->cmd_tables->msg_in) - 2)
                                 aprint_error_dev(sc->sc_c.sc_dev,                                  aprint_error_dev(&sc->sc_c.sc_dev, "extended message too big (%d)\n",
                                     "extended message too big (%d)\n",  
                                     esiop_cmd->cmd_tables->msg_in[1]);                                      esiop_cmd->cmd_tables->msg_in[1]);
                         esiop_cmd->cmd_tables->t_extmsgdata.count =                          esiop_cmd->cmd_tables->t_extmsgdata.count =
                             htole32(esiop_cmd->cmd_tables->msg_in[1] - 1);                              htole32(esiop_cmd->cmd_tables->msg_in[1] - 1);
Line 1077  scintr:
Line 1087  scintr:
                 case A_int_done:                  case A_int_done:
                         if (xs == NULL) {                          if (xs == NULL) {
                                 printf("%s: done without command\n",                                  printf("%s: done without command\n",
                                     device_xname(sc->sc_c.sc_dev));                                      device_xname(&sc->sc_c.sc_dev));
                                 CALL_SCRIPT(Ent_script_sched);                                  CALL_SCRIPT(Ent_script_sched);
                                 return 1;                                  return 1;
                         }                          }
 #ifdef SIOP_DEBUG_INTR  #ifdef SIOP_DEBUG_INTR
                         printf("done, DSA=0x%lx target id 0x%x last msg "                          printf("done, DSA=0x%lx target id 0x%x last msg "
                             "in=0x%x status=0x%x\n",                              "in=0x%x status=0x%x\n", (u_long)esiop_cmd->cmd_c.dsa,
                             (u_long)esiop_cmd->cmd_c.dsa,  
                             le32toh(esiop_cmd->cmd_tables->id),                              le32toh(esiop_cmd->cmd_tables->id),
                             esiop_cmd->cmd_tables->msg_in[0],                              esiop_cmd->cmd_tables->msg_in[0],
                             le32toh(esiop_cmd->cmd_tables->status));                              le32toh(esiop_cmd->cmd_tables->status));
Line 1124  end:
Line 1133  end:
         /*          /*
          * if we got a disconnect between the last data phase           * if we got a disconnect between the last data phase
          * and the status phase, offset will be 0. In this           * and the status phase, offset will be 0. In this
          * case, cmd_tables->saved_offset will have the proper value           * case, cmd_tables->saved_offset will have the proper value
          * if it got updated by the controller           * if it got updated by the controller
          */           */
         if (offset == 0 &&          if (offset == 0 &&
Line 1164  esiop_scsicmd_end(struct esiop_cmd *esio
Line 1173  esiop_scsicmd_end(struct esiop_cmd *esio
                 INCSTAT(esiop_stat_intr_qfull);                  INCSTAT(esiop_stat_intr_qfull);
 #ifdef SIOP_DEBUG  #ifdef SIOP_DEBUG
                 printf("%s:%d:%d: queue full (tag %d)\n",                  printf("%s:%d:%d: queue full (tag %d)\n",
                     device_xname(sc->sc_c.sc_dev),                      device_xname(&sc->sc_c.sc_dev),
                     xs->xs_periph->periph_target,                      xs->xs_periph->periph_target,
                     xs->xs_periph->periph_lun, esiop_cmd->cmd_c.tag);                      xs->xs_periph->periph_lun, esiop_cmd->cmd_c.tag);
 #endif  #endif
Line 1215  esiop_checkdone(struct esiop_softc *sc)
Line 1224  esiop_checkdone(struct esiop_softc *sc)
         struct esiop_target *esiop_target;          struct esiop_target *esiop_target;
         struct esiop_lun *esiop_lun;          struct esiop_lun *esiop_lun;
         struct esiop_cmd *esiop_cmd;          struct esiop_cmd *esiop_cmd;
         uint32_t slot;          u_int32_t slot;
         int needsync = 0;          int needsync = 0;
         int status;          int status;
         uint32_t sem, offset;          u_int32_t sem, offset;
   
         esiop_script_sync(sc, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);          esiop_script_sync(sc, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
         sem = esiop_script_read(sc, sc->sc_semoffset);          sem = esiop_script_read(sc, sc->sc_semoffset);
Line 1239  esiop_checkdone(struct esiop_softc *sc)
Line 1248  esiop_checkdone(struct esiop_softc *sc)
         }          }
   
         bus_dmamap_sync(sc->sc_c.sc_dmat, sc->sc_done_map,          bus_dmamap_sync(sc->sc_c.sc_dmat, sc->sc_done_map,
             sc->sc_done_offset, A_ndone_slots * sizeof(uint32_t),              sc->sc_done_offset, A_ndone_slots * sizeof(u_int32_t),
             BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);              BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
 next:  next:
         if (sc->sc_done_slot[sc->sc_currdoneslot] == 0) {          if (sc->sc_done_slot[sc->sc_currdoneslot] == 0) {
                 if (needsync)                  if (needsync)
                         bus_dmamap_sync(sc->sc_c.sc_dmat, sc->sc_done_map,                          bus_dmamap_sync(sc->sc_c.sc_dmat, sc->sc_done_map,
                             sc->sc_done_offset,                              sc->sc_done_offset,
                             A_ndone_slots * sizeof(uint32_t),                              A_ndone_slots * sizeof(u_int32_t),
                             BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);                              BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
                 return;                  return;
         }          }
Line 1283  next:
Line 1292  next:
         }          }
   
         esiop_table_sync(esiop_cmd,          esiop_table_sync(esiop_cmd,
             BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);                      BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
         status = le32toh(esiop_cmd->cmd_tables->status);          status = le32toh(esiop_cmd->cmd_tables->status);
 #ifdef DIAGNOSTIC  #ifdef DIAGNOSTIC
         if (status != SCSI_OK) {          if (status != SCSI_OK) {
Line 1314  next:
Line 1323  next:
 void  void
 esiop_unqueue(struct esiop_softc *sc, int target, int lun)  esiop_unqueue(struct esiop_softc *sc, int target, int lun)
 {  {
         int slot, tag;          int slot, tag;
         uint32_t slotdsa;          u_int32_t slotdsa;
         struct esiop_cmd *esiop_cmd;          struct esiop_cmd *esiop_cmd;
         struct esiop_lun *esiop_lun =          struct esiop_lun *esiop_lun =
             ((struct esiop_target *)sc->sc_c.targets[target])->esiop_lun[lun];              ((struct esiop_target *)sc->sc_c.targets[target])->esiop_lun[lun];
Line 1368  esiop_handle_qtag_reject(struct esiop_cm
Line 1377  esiop_handle_qtag_reject(struct esiop_cm
   
 #ifdef SIOP_DEBUG  #ifdef SIOP_DEBUG
         printf("%s:%d:%d: tag message %d (%d) rejected (status %d)\n",          printf("%s:%d:%d: tag message %d (%d) rejected (status %d)\n",
             device_xname(sc->sc_c.sc_dev), target, lun, tag,              device_xname(&sc->sc_c.sc_dev), target, lun, tag, esiop_cmd->cmd_c.tag,
             esiop_cmd->cmd_c.tag, esiop_cmd->cmd_c.status);              esiop_cmd->cmd_c.status);
 #endif  #endif
   
         if (esiop_lun->active != NULL) {          if (esiop_lun->active != NULL) {
                 aprint_error_dev(sc->sc_c.sc_dev,                  aprint_error_dev(&sc->sc_c.sc_dev, "untagged command already running for target %d "
                     "untagged command already running for target %d "  
                     "lun %d (status %d)\n",                      "lun %d (status %d)\n",
                     target, lun, esiop_lun->active->cmd_c.status);                      target, lun, esiop_lun->active->cmd_c.status);
                 return -1;                  return -1;
Line 1387  esiop_handle_qtag_reject(struct esiop_cm
Line 1395  esiop_handle_qtag_reject(struct esiop_cm
         esiop_cmd->cmd_c.tag = -1;          esiop_cmd->cmd_c.tag = -1;
         /* update DSA table */          /* update DSA table */
         esiop_script_write(sc, esiop_target->lun_table_offset +          esiop_script_write(sc, esiop_target->lun_table_offset +
             lun * 2 + A_target_luntbl / sizeof(uint32_t),              lun * 2 + A_target_luntbl / sizeof(u_int32_t),
             esiop_cmd->cmd_c.dsa);              esiop_cmd->cmd_c.dsa);
         esiop_script_sync(sc, BUS_DMASYNC_PREREAD |  BUS_DMASYNC_PREWRITE);          esiop_script_sync(sc, BUS_DMASYNC_PREREAD |  BUS_DMASYNC_PREWRITE);
         return 0;          return 0;
Line 1409  esiop_handle_reset(struct esiop_softc *s
Line 1417  esiop_handle_reset(struct esiop_softc *s
          * scsi bus reset. reset the chip and restart           * scsi bus reset. reset the chip and restart
          * the queue. Need to clean up all active commands           * the queue. Need to clean up all active commands
          */           */
         printf("%s: scsi bus reset\n", device_xname(sc->sc_c.sc_dev));          printf("%s: scsi bus reset\n", device_xname(&sc->sc_c.sc_dev));
         /* stop, reset and restart the chip */          /* stop, reset and restart the chip */
         esiop_reset(sc);          esiop_reset(sc);
   
Line 1423  esiop_handle_reset(struct esiop_softc *s
Line 1431  esiop_handle_reset(struct esiop_softc *s
          * being executed           * being executed
          */           */
         esiop_checkdone(sc);          esiop_checkdone(sc);
         for (target = 0; target < sc->sc_c.sc_chan.chan_ntargets; target++) {          for (target = 0; target < sc->sc_c.sc_chan.chan_ntargets;
               target++) {
                 struct esiop_target *esiop_target =                  struct esiop_target *esiop_target =
                     (struct esiop_target *)sc->sc_c.targets[target];                      (struct esiop_target *)sc->sc_c.targets[target];
                 if (esiop_target == NULL)                  if (esiop_target == NULL)
Line 1442  esiop_handle_reset(struct esiop_softc *s
Line 1451  esiop_handle_reset(struct esiop_softc *s
                                         esiop_cmd = esiop_lun->active;                                          esiop_cmd = esiop_lun->active;
                                 if (esiop_cmd == NULL)                                  if (esiop_cmd == NULL)
                                         continue;                                          continue;
                                 scsipi_printaddr(                                  scsipi_printaddr(esiop_cmd->cmd_c.xs->xs_periph);
                                     esiop_cmd->cmd_c.xs->xs_periph);  
                                 printf("command with tag id %d reset\n", tag);                                  printf("command with tag id %d reset\n", tag);
                                 esiop_cmd->cmd_c.xs->error =                                  esiop_cmd->cmd_c.xs->error =
                                     (esiop_cmd->cmd_c.flags & CMDFL_TIMEOUT) ?                                      (esiop_cmd->cmd_c.flags & CMDFL_TIMEOUT) ?
                                     XS_TIMEOUT : XS_RESET;                                      XS_TIMEOUT : XS_RESET;
                                 esiop_cmd->cmd_c.xs->status = SCSI_SIOP_NOCHECK;                                  esiop_cmd->cmd_c.xs->status = SCSI_SIOP_NOCHECK;
                                 if (tag >= 0)                                  if (tag >= 0)
                                         esiop_lun->tactive[tag] = NULL;                                          esiop_lun->tactive[tag] = NULL;
Line 1468  esiop_handle_reset(struct esiop_softc *s
Line 1476  esiop_handle_reset(struct esiop_softc *s
 }  }
   
 void  void
 esiop_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req,  esiop_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req, void *arg)
     void *arg)  
 {  {
         struct scsipi_xfer *xs;          struct scsipi_xfer *xs;
         struct scsipi_periph *periph;          struct scsipi_periph *periph;
         struct esiop_softc *sc = device_private(chan->chan_adapter->adapt_dev);          struct esiop_softc *sc = (void *)chan->chan_adapter->adapt_dev;
         struct esiop_cmd *esiop_cmd;          struct esiop_cmd *esiop_cmd;
         struct esiop_target *esiop_target;          struct esiop_target *esiop_target;
         int s, error, i;          int s, error, i;
Line 1518  esiop_scsipi_request(struct scsipi_chann
Line 1525  esiop_scsipi_request(struct scsipi_chann
                 if (esiop_target == NULL) {                  if (esiop_target == NULL) {
 #ifdef SIOP_DEBUG  #ifdef SIOP_DEBUG
                         printf("%s: alloc siop_target for target %d\n",                          printf("%s: alloc siop_target for target %d\n",
                                 device_xname(sc->sc_c.sc_dev), target);                                  device_xname(&sc->sc_c.sc_dev), target);
 #endif  #endif
                         sc->sc_c.targets[target] =                          sc->sc_c.targets[target] =
                             malloc(sizeof(struct esiop_target),                              malloc(sizeof(struct esiop_target),
                                 M_DEVBUF, M_NOWAIT | M_ZERO);                                  M_DEVBUF, M_NOWAIT | M_ZERO);
                         if (sc->sc_c.targets[target] == NULL) {                          if (sc->sc_c.targets[target] == NULL) {
                                 aprint_error_dev(sc->sc_c.sc_dev,                                  aprint_error_dev(&sc->sc_c.sc_dev, "can't malloc memory for "
                                     "can't malloc memory for "                                      "target %d\n", target);
                                     "target %d\n",  
                                     target);  
                                 xs->error = XS_RESOURCE_SHORTAGE;                                  xs->error = XS_RESOURCE_SHORTAGE;
                                 scsipi_done(xs);                                  scsipi_done(xs);
                                 TAILQ_INSERT_TAIL(&sc->free_list,  
                                     esiop_cmd, next);  
                                 splx(s);                                  splx(s);
                                 return;                                  return;
                         }                          }
Line 1553  esiop_scsipi_request(struct scsipi_chann
Line 1556  esiop_scsipi_request(struct scsipi_chann
                             malloc(sizeof(struct esiop_lun), M_DEVBUF,                              malloc(sizeof(struct esiop_lun), M_DEVBUF,
                             M_NOWAIT|M_ZERO);                              M_NOWAIT|M_ZERO);
                         if (esiop_target->esiop_lun[lun] == NULL) {                          if (esiop_target->esiop_lun[lun] == NULL) {
                                 aprint_error_dev(sc->sc_c.sc_dev,                                  aprint_error_dev(&sc->sc_c.sc_dev, "can't alloc esiop_lun for "
                                     "can't alloc esiop_lun for "  
                                     "target %d lun %d\n",                                      "target %d lun %d\n",
                                     target, lun);                                      target, lun);
                                 xs->error = XS_RESOURCE_SHORTAGE;                                  xs->error = XS_RESOURCE_SHORTAGE;
                                 scsipi_done(xs);                                  scsipi_done(xs);
                                 TAILQ_INSERT_TAIL(&sc->free_list,  
                                     esiop_cmd, next);  
                                 splx(s);                                  splx(s);
                                 return;                                  return;
                         }                          }
Line 1575  esiop_scsipi_request(struct scsipi_chann
Line 1575  esiop_scsipi_request(struct scsipi_chann
                     esiop_cmd->cmd_c.dmamap_cmd,                      esiop_cmd->cmd_c.dmamap_cmd,
                     xs->cmd, xs->cmdlen, NULL, BUS_DMA_NOWAIT);                      xs->cmd, xs->cmdlen, NULL, BUS_DMA_NOWAIT);
                 if (error) {                  if (error) {
                         aprint_error_dev(sc->sc_c.sc_dev,                          aprint_error_dev(&sc->sc_c.sc_dev, "unable to load cmd DMA map: %d\n",
                             "unable to load cmd DMA map: %d\n",  
                             error);                              error);
                         xs->error = (error == EAGAIN) ?                          xs->error = XS_DRIVER_STUFFUP;
                             XS_RESOURCE_SHORTAGE : XS_DRIVER_STUFFUP;  
                         scsipi_done(xs);                          scsipi_done(xs);
                         esiop_cmd->cmd_c.status = CMDST_FREE;  
                         TAILQ_INSERT_TAIL(&sc->free_list, esiop_cmd, next);  
                         splx(s);                          splx(s);
                         return;                          return;
                 }                  }
Line 1593  esiop_scsipi_request(struct scsipi_chann
Line 1589  esiop_scsipi_request(struct scsipi_chann
                             ((xs->xs_control & XS_CTL_DATA_IN) ?                              ((xs->xs_control & XS_CTL_DATA_IN) ?
                              BUS_DMA_READ : BUS_DMA_WRITE));                               BUS_DMA_READ : BUS_DMA_WRITE));
                         if (error) {                          if (error) {
                                 aprint_error_dev(sc->sc_c.sc_dev,                                  aprint_error_dev(&sc->sc_c.sc_dev, "unable to load cmd DMA map: %d",
                                     "unable to load data DMA map: %d\n",  
                                     error);                                      error);
                                 xs->error = (error == EAGAIN) ?                                  xs->error = XS_DRIVER_STUFFUP;
                                     XS_RESOURCE_SHORTAGE : XS_DRIVER_STUFFUP;  
                                 scsipi_done(xs);                                  scsipi_done(xs);
                                 bus_dmamap_unload(sc->sc_c.sc_dmat,                                  bus_dmamap_unload(sc->sc_c.sc_dmat,
                                     esiop_cmd->cmd_c.dmamap_cmd);                                      esiop_cmd->cmd_c.dmamap_cmd);
                                 esiop_cmd->cmd_c.status = CMDST_FREE;  
                                 TAILQ_INSERT_TAIL(&sc->free_list,  
                                     esiop_cmd, next);  
                                 splx(s);                                  splx(s);
                                 return;                                  return;
                         }                          }
Line 1647  esiop_scsipi_request(struct scsipi_chann
Line 1638  esiop_scsipi_request(struct scsipi_chann
   
         case ADAPTER_REQ_GROW_RESOURCES:          case ADAPTER_REQ_GROW_RESOURCES:
 #ifdef SIOP_DEBUG  #ifdef SIOP_DEBUG
                 printf("%s grow resources (%d)\n",                  printf("%s grow resources (%d)\n", device_xname(&sc->sc_c.sc_dev),
                     device_xname(sc->sc_c.sc_dev),  
                     sc->sc_c.sc_adapt.adapt_openings);                      sc->sc_c.sc_adapt.adapt_openings);
 #endif  #endif
                 esiop_morecbd(sc);                  esiop_morecbd(sc);
                 return;                  return;
   
         case ADAPTER_REQ_SET_XFER_MODE:          case ADAPTER_REQ_SET_XFER_MODE:
             {          {
                 struct scsipi_xfer_mode *xm = arg;                  struct scsipi_xfer_mode *xm = arg;
                 if (sc->sc_c.targets[xm->xm_target] == NULL)                  if (sc->sc_c.targets[xm->xm_target] == NULL)
                         return;                          return;
Line 1684  esiop_scsipi_request(struct scsipi_chann
Line 1674  esiop_scsipi_request(struct scsipi_chann
                         sc->sc_c.targets[xm->xm_target]->status = TARST_ASYNC;                          sc->sc_c.targets[xm->xm_target]->status = TARST_ASYNC;
   
                 splx(s);                  splx(s);
             }          }
         }          }
 }  }
   
Line 1764  esiop_start(struct esiop_softc *sc, stru
Line 1754  esiop_start(struct esiop_softc *sc, stru
                 bus_dmamap_sync(sc->sc_c.sc_dmat,                  bus_dmamap_sync(sc->sc_c.sc_dmat,
                     esiop_lun->lun_tagtbl->tblblk->blkmap,                      esiop_lun->lun_tagtbl->tblblk->blkmap,
                     esiop_lun->lun_tagtbl->tbl_offset,                      esiop_lun->lun_tagtbl->tbl_offset,
                     sizeof(uint32_t) * ESIOP_NTAG, BUS_DMASYNC_PREWRITE);                      sizeof(u_int32_t) * ESIOP_NTAG, BUS_DMASYNC_PREWRITE);
         } else {          } else {
                 esiop_lun->active = esiop_cmd;                  esiop_lun->active = esiop_cmd;
                 esiop_script_write(sc,                  esiop_script_write(sc,
                     esiop_target->lun_table_offset +                      esiop_target->lun_table_offset +
                     lun * 2 + A_target_luntbl / sizeof(uint32_t),                      lun * 2 + A_target_luntbl / sizeof(u_int32_t),
                     esiop_cmd->cmd_c.dsa);                      esiop_cmd->cmd_c.dsa);
         }          }
         /* scheduler slot: DSA */          /* scheduler slot: DSA */
Line 1793  esiop_start(struct esiop_softc *sc, stru
Line 1783  esiop_start(struct esiop_softc *sc, stru
         sc->sc_currschedslot++;          sc->sc_currschedslot++;
         if (sc->sc_currschedslot >= A_ncmd_slots)          if (sc->sc_currschedslot >= A_ncmd_slots)
                 sc->sc_currschedslot = 0;                  sc->sc_currschedslot = 0;
           return;
 }  }
   
 void  void
Line 1808  esiop_timeout(void *v)
Line 1799  esiop_timeout(void *v)
   
         s = splbio();          s = splbio();
         esiop_table_sync(esiop_cmd,          esiop_table_sync(esiop_cmd,
             BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);              BUS_DMASYNC_POSTREAD |
               BUS_DMASYNC_POSTWRITE);
         scsipi_printaddr(esiop_cmd->cmd_c.xs->xs_periph);          scsipi_printaddr(esiop_cmd->cmd_c.xs->xs_periph);
 #ifdef SIOP_DEBUG  #ifdef SIOP_DEBUG
         printf("command timeout (status %d)\n",          printf("command timeout (status %d)\n", le32toh(esiop_cmd->cmd_tables->status));
             le32toh(esiop_cmd->cmd_tables->status));  
   
         esiop_script_sync(sc, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);          esiop_script_sync(sc, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
         for (slot = 0; slot < A_ncmd_slots; slot++) {          for (slot = 0; slot < A_ncmd_slots; slot++) {
Line 1821  esiop_timeout(void *v)
Line 1812  esiop_timeout(void *v)
                 if ((slotdsa & 0x01) == 0)                  if ((slotdsa & 0x01) == 0)
                         printf("slot %d not free (0x%x)\n", slot, slotdsa);                          printf("slot %d not free (0x%x)\n", slot, slotdsa);
         }          }
         printf("istat 0x%x ",          printf("istat 0x%x ", bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_ISTAT));
             bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_ISTAT));  
         printf("DSP 0x%lx DSA 0x%x\n",          printf("DSP 0x%lx DSA 0x%x\n",
             (u_long)(bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_DSP)              (u_long)(bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_DSP) - sc->sc_c.sc_scriptaddr),
             - sc->sc_c.sc_scriptaddr),  
             bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_DSA));              bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_DSA));
         (void)bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_CTEST2);          bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_CTEST2);
         printf("istat 0x%x\n",          printf("istat 0x%x\n", bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_ISTAT));
             bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_ISTAT));  
 #else  #else
         printf("command timeout, CDB: ");          printf("command timeout, CDB: ");
         scsipi_print_cdb(esiop_cmd->cmd_c.xs->cmd);          scsipi_print_cdb(esiop_cmd->cmd_c.xs->cmd);
Line 1847  esiop_timeout(void *v)
Line 1835  esiop_timeout(void *v)
          */           */
         esiop_cmd->cmd_c.flags |= CMDFL_TIMEOUT;          esiop_cmd->cmd_c.flags |= CMDFL_TIMEOUT;
         splx(s);          splx(s);
           return;
   
 }  }
   
 void  void
 esiop_dump_script(struct esiop_softc *sc)  esiop_dump_script(struct esiop_softc *sc)
 {  {
         int i;          int i;
   
         for (i = 0; i < PAGE_SIZE / 4; i += 2) {          for (i = 0; i < PAGE_SIZE / 4; i += 2) {
                 printf("0x%04x: 0x%08x 0x%08x", i * 4,                  printf("0x%04x: 0x%08x 0x%08x", i * 4,
                     esiop_script_read(sc, i),                      le32toh(sc->sc_c.sc_script[i]),
                     esiop_script_read(sc, i + 1));                      le32toh(sc->sc_c.sc_script[i+1]));
                 if ((esiop_script_read(sc, i) & 0xe0000000) == 0xc0000000) {                  if ((le32toh(sc->sc_c.sc_script[i]) & 0xe0000000) ==
                       0xc0000000) {
                         i++;                          i++;
                         printf(" 0x%08x", esiop_script_read(sc, i + 1));                          printf(" 0x%08x", le32toh(sc->sc_c.sc_script[i+1]));
                 }                  }
                 printf("\n");                  printf("\n");
         }          }
Line 1879  esiop_morecbd(struct esiop_softc *sc)
Line 1869  esiop_morecbd(struct esiop_softc *sc)
         /* allocate a new list head */          /* allocate a new list head */
         newcbd = malloc(sizeof(struct esiop_cbd), M_DEVBUF, M_NOWAIT|M_ZERO);          newcbd = malloc(sizeof(struct esiop_cbd), M_DEVBUF, M_NOWAIT|M_ZERO);
         if (newcbd == NULL) {          if (newcbd == NULL) {
                 aprint_error_dev(sc->sc_c.sc_dev,                  aprint_error_dev(&sc->sc_c.sc_dev, "can't allocate memory for command descriptors "
                     "can't allocate memory for command descriptors "  
                     "head\n");                      "head\n");
                 return;                  return;
         }          }
Line 1889  esiop_morecbd(struct esiop_softc *sc)
Line 1878  esiop_morecbd(struct esiop_softc *sc)
         newcbd->cmds = malloc(sizeof(struct esiop_cmd) * SIOP_NCMDPB,          newcbd->cmds = malloc(sizeof(struct esiop_cmd) * SIOP_NCMDPB,
             M_DEVBUF, M_NOWAIT|M_ZERO);              M_DEVBUF, M_NOWAIT|M_ZERO);
         if (newcbd->cmds == NULL) {          if (newcbd->cmds == NULL) {
                 aprint_error_dev(sc->sc_c.sc_dev,                  aprint_error_dev(&sc->sc_c.sc_dev, "can't allocate memory for command descriptors\n");
                     "can't allocate memory for command descriptors\n");  
                 goto bad3;                  goto bad3;
         }          }
         error = bus_dmamem_alloc(sc->sc_c.sc_dmat, PAGE_SIZE, PAGE_SIZE, 0,          error = bus_dmamem_alloc(sc->sc_c.sc_dmat, PAGE_SIZE, PAGE_SIZE, 0,
             &seg, 1, &rseg, BUS_DMA_NOWAIT);              &seg, 1, &rseg, BUS_DMA_NOWAIT);
         if (error) {          if (error) {
                 aprint_error_dev(sc->sc_c.sc_dev,                  aprint_error_dev(&sc->sc_c.sc_dev, "unable to allocate cbd DMA memory, error = %d\n",
                     "unable to allocate cbd DMA memory, error = %d\n",  
                     error);                      error);
                 goto bad2;                  goto bad2;
         }          }
         error = bus_dmamem_map(sc->sc_c.sc_dmat, &seg, rseg, PAGE_SIZE,          error = bus_dmamem_map(sc->sc_c.sc_dmat, &seg, rseg, PAGE_SIZE,
             (void **)&newcbd->xfers, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);              (void **)&newcbd->xfers, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
         if (error) {          if (error) {
                 aprint_error_dev(sc->sc_c.sc_dev,                  aprint_error_dev(&sc->sc_c.sc_dev, "unable to map cbd DMA memory, error = %d\n",
                     "unable to map cbd DMA memory, error = %d\n",  
                     error);                      error);
                 goto bad2;                  goto bad2;
         }          }
         error = bus_dmamap_create(sc->sc_c.sc_dmat, PAGE_SIZE, 1, PAGE_SIZE, 0,          error = bus_dmamap_create(sc->sc_c.sc_dmat, PAGE_SIZE, 1, PAGE_SIZE, 0,
             BUS_DMA_NOWAIT, &newcbd->xferdma);              BUS_DMA_NOWAIT, &newcbd->xferdma);
         if (error) {          if (error) {
                 aprint_error_dev(sc->sc_c.sc_dev,                  aprint_error_dev(&sc->sc_c.sc_dev, "unable to create cbd DMA map, error = %d\n", error);
                     "unable to create cbd DMA map, error = %d\n", error);  
                 goto bad1;                  goto bad1;
         }          }
         error = bus_dmamap_load(sc->sc_c.sc_dmat, newcbd->xferdma,          error = bus_dmamap_load(sc->sc_c.sc_dmat, newcbd->xferdma,
             newcbd->xfers, PAGE_SIZE, NULL, BUS_DMA_NOWAIT);              newcbd->xfers, PAGE_SIZE, NULL, BUS_DMA_NOWAIT);
         if (error) {          if (error) {
                 aprint_error_dev(sc->sc_c.sc_dev,                  aprint_error_dev(&sc->sc_c.sc_dev, "unable to load cbd DMA map, error = %d\n", error);
                     "unable to load cbd DMA map, error = %d\n", error);  
                 goto bad0;                  goto bad0;
         }          }
 #ifdef SIOP_DEBUG  #ifdef DEBUG
         aprint_debug_dev(sc->sc_c.sc_dev, "alloc newcdb at PHY addr 0x%lx\n",          printf("%s: alloc newcdb at PHY addr 0x%lx\n", device_xname(&sc->sc_c.sc_dev),
             (unsigned long)newcbd->xferdma->dm_segs[0].ds_addr);              (unsigned long)newcbd->xferdma->dm_segs[0].ds_addr);
 #endif  #endif
         for (i = 0; i < SIOP_NCMDPB; i++) {          for (i = 0; i < SIOP_NCMDPB; i++) {
Line 1932  esiop_morecbd(struct esiop_softc *sc)
Line 1916  esiop_morecbd(struct esiop_softc *sc)
                     MAXPHYS, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,                      MAXPHYS, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
                     &newcbd->cmds[i].cmd_c.dmamap_data);                      &newcbd->cmds[i].cmd_c.dmamap_data);
                 if (error) {                  if (error) {
                         aprint_error_dev(sc->sc_c.sc_dev,                          aprint_error_dev(&sc->sc_c.sc_dev, "unable to create data DMA map for cbd: "
                             "unable to create data DMA map for cbd: "  
                             "error %d\n", error);                              "error %d\n", error);
                         goto bad0;                          goto bad0;
                 }                  }
Line 1943  esiop_morecbd(struct esiop_softc *sc)
Line 1926  esiop_morecbd(struct esiop_softc *sc)
                     BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,                      BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
                     &newcbd->cmds[i].cmd_c.dmamap_cmd);                      &newcbd->cmds[i].cmd_c.dmamap_cmd);
                 if (error) {                  if (error) {
                         aprint_error_dev(sc->sc_c.sc_dev,                          aprint_error_dev(&sc->sc_c.sc_dev, "unable to create cmd DMA map for cbd %d\n", error);
                             "unable to create cmd DMA map for cbd %d\n", error);  
                         goto bad0;                          goto bad0;
                 }                  }
                 newcbd->cmds[i].cmd_c.siop_sc = &sc->sc_c;                  newcbd->cmds[i].cmd_c.siop_sc = &sc->sc_c;
Line 1961  esiop_morecbd(struct esiop_softc *sc)
Line 1943  esiop_morecbd(struct esiop_softc *sc)
                 xfer->siop_tables.t_msgout.addr = htole32(dsa);                  xfer->siop_tables.t_msgout.addr = htole32(dsa);
                 xfer->siop_tables.t_msgin.count= htole32(1);                  xfer->siop_tables.t_msgin.count= htole32(1);
                 xfer->siop_tables.t_msgin.addr = htole32(dsa +                  xfer->siop_tables.t_msgin.addr = htole32(dsa +
                     offsetof(struct siop_common_xfer, msg_in));                          offsetof(struct siop_common_xfer, msg_in));
                 xfer->siop_tables.t_extmsgin.count= htole32(2);                  xfer->siop_tables.t_extmsgin.count= htole32(2);
                 xfer->siop_tables.t_extmsgin.addr = htole32(dsa +                  xfer->siop_tables.t_extmsgin.addr = htole32(dsa +
                     offsetof(struct siop_common_xfer, msg_in) + 1);                          offsetof(struct siop_common_xfer, msg_in) + 1);
                 xfer->siop_tables.t_extmsgdata.addr = htole32(dsa +                  xfer->siop_tables.t_extmsgdata.addr = htole32(dsa +
                     offsetof(struct siop_common_xfer, msg_in) + 3);                          offsetof(struct siop_common_xfer, msg_in) + 3);
                 xfer->siop_tables.t_status.count= htole32(1);                  xfer->siop_tables.t_status.count= htole32(1);
                 xfer->siop_tables.t_status.addr = htole32(dsa +                  xfer->siop_tables.t_status.addr = htole32(dsa +
                     offsetof(struct siop_common_xfer, status));                          offsetof(struct siop_common_xfer, status));
   
                 s = splbio();                  s = splbio();
                 TAILQ_INSERT_TAIL(&sc->free_list, &newcbd->cmds[i], next);                  TAILQ_INSERT_TAIL(&sc->free_list, &newcbd->cmds[i], next);
Line 1995  bad2:
Line 1977  bad2:
         free(newcbd->cmds, M_DEVBUF);          free(newcbd->cmds, M_DEVBUF);
 bad3:  bad3:
         free(newcbd, M_DEVBUF);          free(newcbd, M_DEVBUF);
           return;
 }  }
   
 void  void
Line 2005  esiop_moretagtbl(struct esiop_softc *sc)
Line 1988  esiop_moretagtbl(struct esiop_softc *sc)
         int rseg;          int rseg;
         struct esiop_dsatblblk *newtblblk;          struct esiop_dsatblblk *newtblblk;
         struct esiop_dsatbl *newtbls;          struct esiop_dsatbl *newtbls;
         uint32_t *tbls;          u_int32_t *tbls;
   
         /* allocate a new list head */          /* allocate a new list head */
         newtblblk = malloc(sizeof(struct esiop_dsatblblk),          newtblblk = malloc(sizeof(struct esiop_dsatblblk),
             M_DEVBUF, M_NOWAIT|M_ZERO);              M_DEVBUF, M_NOWAIT|M_ZERO);
         if (newtblblk == NULL) {          if (newtblblk == NULL) {
                 aprint_error_dev(sc->sc_c.sc_dev,                  aprint_error_dev(&sc->sc_c.sc_dev, "can't allocate memory for tag DSA table block\n");
                     "can't allocate memory for tag DSA table block\n");  
                 return;                  return;
         }          }
   
Line 2020  esiop_moretagtbl(struct esiop_softc *sc)
Line 2002  esiop_moretagtbl(struct esiop_softc *sc)
         newtbls = malloc(sizeof(struct esiop_dsatbl) * ESIOP_NTPB,          newtbls = malloc(sizeof(struct esiop_dsatbl) * ESIOP_NTPB,
             M_DEVBUF, M_NOWAIT|M_ZERO);              M_DEVBUF, M_NOWAIT|M_ZERO);
         if (newtbls == NULL) {          if (newtbls == NULL) {
                 aprint_error_dev(sc->sc_c.sc_dev,                  aprint_error_dev(&sc->sc_c.sc_dev, "can't allocate memory for command descriptors\n");
                     "can't allocate memory for command descriptors\n");  
                 goto bad3;                  goto bad3;
         }          }
         error = bus_dmamem_alloc(sc->sc_c.sc_dmat, PAGE_SIZE, PAGE_SIZE, 0,          error = bus_dmamem_alloc(sc->sc_c.sc_dmat, PAGE_SIZE, PAGE_SIZE, 0,
             &seg, 1, &rseg, BUS_DMA_NOWAIT);              &seg, 1, &rseg, BUS_DMA_NOWAIT);
         if (error) {          if (error) {
                 aprint_error_dev(sc->sc_c.sc_dev,                  aprint_error_dev(&sc->sc_c.sc_dev, "unable to allocate tbl DMA memory, error = %d\n", error);
                     "unable to allocate tbl DMA memory, error = %d\n", error);  
                 goto bad2;                  goto bad2;
         }          }
         error = bus_dmamem_map(sc->sc_c.sc_dmat, &seg, rseg, PAGE_SIZE,          error = bus_dmamem_map(sc->sc_c.sc_dmat, &seg, rseg, PAGE_SIZE,
             (void *)&tbls, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);              (void *)&tbls, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
         if (error) {          if (error) {
                 aprint_error_dev(sc->sc_c.sc_dev,                  aprint_error_dev(&sc->sc_c.sc_dev, "unable to map tbls DMA memory, error = %d\n", error);
                     "unable to map tbls DMA memory, error = %d\n", error);  
                 goto bad2;                  goto bad2;
         }          }
         error = bus_dmamap_create(sc->sc_c.sc_dmat, PAGE_SIZE, 1, PAGE_SIZE, 0,          error = bus_dmamap_create(sc->sc_c.sc_dmat, PAGE_SIZE, 1, PAGE_SIZE, 0,
             BUS_DMA_NOWAIT, &newtblblk->blkmap);              BUS_DMA_NOWAIT, &newtblblk->blkmap);
         if (error) {          if (error) {
                 aprint_error_dev(sc->sc_c.sc_dev,                  aprint_error_dev(&sc->sc_c.sc_dev, "unable to create tbl DMA map, error = %d\n", error);
                     "unable to create tbl DMA map, error = %d\n", error);  
                 goto bad1;                  goto bad1;
         }          }
         error = bus_dmamap_load(sc->sc_c.sc_dmat, newtblblk->blkmap,          error = bus_dmamap_load(sc->sc_c.sc_dmat, newtblblk->blkmap,
             tbls, PAGE_SIZE, NULL, BUS_DMA_NOWAIT);              tbls, PAGE_SIZE, NULL, BUS_DMA_NOWAIT);
         if (error) {          if (error) {
                 aprint_error_dev(sc->sc_c.sc_dev,                  aprint_error_dev(&sc->sc_c.sc_dev, "unable to load tbl DMA map, error = %d\n", error);
                     "unable to load tbl DMA map, error = %d\n", error);  
                 goto bad0;                  goto bad0;
         }          }
 #ifdef SIOP_DEBUG  #ifdef DEBUG
         printf("%s: alloc new tag DSA table at PHY addr 0x%lx\n",          printf("%s: alloc new tag DSA table at PHY addr 0x%lx\n",
             device_xname(sc->sc_c.sc_dev),              device_xname(&sc->sc_c.sc_dev),
             (unsigned long)newtblblk->blkmap->dm_segs[0].ds_addr);              (unsigned long)newtblblk->blkmap->dm_segs[0].ds_addr);
 #endif  #endif
         for (i = 0; i < ESIOP_NTPB; i++) {          for (i = 0; i < ESIOP_NTPB; i++) {
                 newtbls[i].tblblk = newtblblk;                  newtbls[i].tblblk = newtblblk;
                 newtbls[i].tbl = &tbls[i * ESIOP_NTAG];                  newtbls[i].tbl = &tbls[i * ESIOP_NTAG];
                 newtbls[i].tbl_offset = i * ESIOP_NTAG * sizeof(uint32_t);                  newtbls[i].tbl_offset = i * ESIOP_NTAG * sizeof(u_int32_t);
                 newtbls[i].tbl_dsa = newtblblk->blkmap->dm_segs[0].ds_addr +                  newtbls[i].tbl_dsa = newtblblk->blkmap->dm_segs[0].ds_addr +
                     newtbls[i].tbl_offset;                      newtbls[i].tbl_offset;
                 for (j = 0; j < ESIOP_NTAG; j++)                  for (j = 0; j < ESIOP_NTAG; j++)
Line 2082  bad2:
Line 2059  bad2:
         free(newtbls, M_DEVBUF);          free(newtbls, M_DEVBUF);
 bad3:  bad3:
         free(newtblblk, M_DEVBUF);          free(newtblblk, M_DEVBUF);
           return;
 }  }
   
 void  void
 esiop_update_scntl3(struct esiop_softc *sc,  esiop_update_scntl3(sc, _siop_target)
     struct siop_common_target *_siop_target)          struct esiop_softc *sc;
           struct siop_common_target *_siop_target;
 {  {
         struct esiop_target *esiop_target = (struct esiop_target *)_siop_target;          struct esiop_target *esiop_target = (struct esiop_target *)_siop_target;
   
         esiop_script_write(sc, esiop_target->lun_table_offset,          esiop_script_write(sc, esiop_target->lun_table_offset,
             esiop_target->target_c.id);              esiop_target->target_c.id);
         esiop_script_sync(sc, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);          esiop_script_sync(sc, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
Line 2119  esiop_add_dev(struct esiop_softc *sc, in
Line 2097  esiop_add_dev(struct esiop_softc *sc, in
         TAILQ_REMOVE(&sc->free_tagtbl, esiop_lun->lun_tagtbl, next);          TAILQ_REMOVE(&sc->free_tagtbl, esiop_lun->lun_tagtbl, next);
         /* Update LUN DSA table */          /* Update LUN DSA table */
         esiop_script_write(sc, esiop_target->lun_table_offset +          esiop_script_write(sc, esiop_target->lun_table_offset +
            lun * 2 + A_target_luntbl_tag / sizeof(uint32_t),             lun * 2 + A_target_luntbl_tag / sizeof(u_int32_t),
             esiop_lun->lun_tagtbl->tbl_dsa);              esiop_lun->lun_tagtbl->tbl_dsa);
         esiop_script_sync(sc, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);          esiop_script_sync(sc, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 }  }
Line 2128  void
Line 2106  void
 esiop_del_dev(struct esiop_softc *sc, int target, int lun)  esiop_del_dev(struct esiop_softc *sc, int target, int lun)
 {  {
         struct esiop_target *esiop_target;          struct esiop_target *esiop_target;
   
 #ifdef SIOP_DEBUG  #ifdef SIOP_DEBUG
                 printf("%s:%d:%d: free lun sw entry\n",                  printf("%s:%d:%d: free lun sw entry\n",
                     device_xname(sc->sc_c.sc_dev), target, lun);                      device_xname(&sc->sc_c.sc_dev), target, lun);
 #endif  #endif
         if (sc->sc_c.targets[target] == NULL)          if (sc->sc_c.targets[target] == NULL)
                 return;                  return;
Line 2141  esiop_del_dev(struct esiop_softc *sc, in
Line 2118  esiop_del_dev(struct esiop_softc *sc, in
 }  }
   
 void  void
 esiop_target_register(struct esiop_softc *sc, uint32_t target)  esiop_target_register(struct esiop_softc *sc, u_int32_t target)
 {  {
         struct esiop_target *esiop_target =          struct esiop_target *esiop_target =
             (struct esiop_target *)sc->sc_c.targets[target];              (struct esiop_target *)sc->sc_c.targets[target];
Line 2153  esiop_target_register(struct esiop_softc
Line 2130  esiop_target_register(struct esiop_softc
         sc->sc_free_offset += sc->sc_c.sc_chan.chan_nluns * 2 + 2;          sc->sc_free_offset += sc->sc_c.sc_chan.chan_nluns * 2 + 2;
 #ifdef SIOP_DEBUG  #ifdef SIOP_DEBUG
         printf("%s: lun table for target %d offset %d free offset %d\n",          printf("%s: lun table for target %d offset %d free offset %d\n",
             device_xname(sc->sc_c.sc_dev), target,              device_xname(&sc->sc_c.sc_dev), target, esiop_target->lun_table_offset,
             esiop_target->lun_table_offset,  
             sc->sc_free_offset);              sc->sc_free_offset);
 #endif  #endif
         /* first 32 bytes are ID (for select) */          /* first 32 bytes are ID (for select) */
Line 2163  esiop_target_register(struct esiop_softc
Line 2139  esiop_target_register(struct esiop_softc
         /* Record this table in the target DSA table */          /* Record this table in the target DSA table */
         esiop_script_write(sc,          esiop_script_write(sc,
             sc->sc_target_table_offset + target,              sc->sc_target_table_offset + target,
             (esiop_target->lun_table_offset * sizeof(uint32_t)) +              (esiop_target->lun_table_offset * sizeof(u_int32_t)) +
             sc->sc_c.sc_scriptaddr);              sc->sc_c.sc_scriptaddr);
         /* if we have a tag table, register it */          /* if we have a tag table, register it */
         for (lun = 0; lun < sc->sc_c.sc_chan.chan_nluns; lun++) {          for (lun = 0; lun < sc->sc_c.sc_chan.chan_nluns; lun++) {
Line 2172  esiop_target_register(struct esiop_softc
Line 2148  esiop_target_register(struct esiop_softc
                         continue;                          continue;
                 if (esiop_lun->lun_tagtbl)                  if (esiop_lun->lun_tagtbl)
                         esiop_script_write(sc, esiop_target->lun_table_offset +                          esiop_script_write(sc, esiop_target->lun_table_offset +
                            lun * 2 + A_target_luntbl_tag / sizeof(uint32_t),                             lun * 2 + A_target_luntbl_tag / sizeof(u_int32_t),
                             esiop_lun->lun_tagtbl->tbl_dsa);                              esiop_lun->lun_tagtbl->tbl_dsa);
         }          }
         esiop_script_sync(sc, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);          esiop_script_sync(sc,
               BUS_DMASYNC_PREREAD |  BUS_DMASYNC_PREWRITE);
 }  }
   
 #ifdef SIOP_STATS  #ifdef SIOP_STATS
 void  void
 esiop_printstats(void)  esiop_printstats()
 {  {
   
         printf("esiop_stat_intr %d\n", esiop_stat_intr);          printf("esiop_stat_intr %d\n", esiop_stat_intr);
         printf("esiop_stat_intr_shortxfer %d\n", esiop_stat_intr_shortxfer);          printf("esiop_stat_intr_shortxfer %d\n", esiop_stat_intr_shortxfer);
         printf("esiop_stat_intr_xferdisc %d\n", esiop_stat_intr_xferdisc);          printf("esiop_stat_intr_xferdisc %d\n", esiop_stat_intr_xferdisc);

Legend:
Removed from v.1.42.4.6  
changed lines
  Added in v.1.43

CVSweb <webmaster@jp.NetBSD.org>