[BACK]Return to wdc.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/wdc.c between version 1.172.2.4 and 1.172.2.5

version 1.172.2.4, 2004/06/24 13:57:07 version 1.172.2.5, 2004/08/11 19:43:58
Line 146  const struct ata_bustype wdc_ata_bustype
Line 146  const struct ata_bustype wdc_ata_bustype
 static int      wdcprobe1(struct wdc_channel*, int);  static int      wdcprobe1(struct wdc_channel*, int);
 static void     __wdcerror(struct wdc_channel*, char *);  static void     __wdcerror(struct wdc_channel*, char *);
 static int      __wdcwait_reset(struct wdc_channel *, int, int);  static int      __wdcwait_reset(struct wdc_channel *, int, int);
   static void     __wdc_reset_channel(struct wdc_channel *, int);
 static void     __wdccommand_done(struct wdc_channel *, struct ata_xfer *);  static void     __wdccommand_done(struct wdc_channel *, struct ata_xfer *);
   static void     __wdccommand_done_end(struct wdc_channel *, struct ata_xfer *);
   static void     __wdccommand_kill_xfer(struct wdc_channel *,
                                          struct ata_xfer *, int);
 static void     __wdccommand_start(struct wdc_channel *, struct ata_xfer *);  static void     __wdccommand_start(struct wdc_channel *, struct ata_xfer *);
 static int      __wdccommand_intr(struct wdc_channel *, struct ata_xfer *,  static int      __wdccommand_intr(struct wdc_channel *, struct ata_xfer *, int);
                                   int);  
 static int      __wdcwait(struct wdc_channel *, int, int, int);  static int      __wdcwait(struct wdc_channel *, int, int, int);
   
 #define DEBUG_INTR   0x01  #define DEBUG_INTR   0x01
Line 955  wdc_reset_channel(struct ata_drive_datas
Line 958  wdc_reset_channel(struct ata_drive_datas
 {  {
         struct wdc_channel *chp = drvp->chnl_softc;          struct wdc_channel *chp = drvp->chnl_softc;
         struct wdc_softc *wdc = chp->ch_wdc;          struct wdc_softc *wdc = chp->ch_wdc;
         int drive;  
   
         WDCDEBUG_PRINT(("ata_reset_channel %s:%d for drive %d\n",          WDCDEBUG_PRINT(("ata_reset_channel %s:%d for drive %d\n",
             wdc->sc_dev.dv_xname, chp->ch_channel, drvp->drive),              wdc->sc_dev.dv_xname, chp->ch_channel, drvp->drive),
             DEBUG_FUNCS);              DEBUG_FUNCS);
   
   
           __wdc_reset_channel(chp, flags);
   }
   
   static void
   __wdc_reset_channel(struct wdc_channel *chp, int flags)
   {
           struct ata_xfer *xfer;
           int drive;
   
           /*
            * look for pending xfers. If we have a shared queue, we'll also reset
            * the other channel if the current xfer is running on it.
            * Then we'll freese the queue, and dequeue only the xfers for this
            * channel. xfer->c_kill_xfer() will reset any ATAPI device when
            * needed.
            */
           chp->ch_queue->queue_freeze++;
           if ((flags & AT_RST_NOCMD) == 0) {
                   xfer = TAILQ_FIRST(&chp->ch_queue->queue_xfer);
                   if (xfer && xfer->c_chp != chp)
                           __wdc_reset_channel(xfer->c_chp, flags);
                   for (xfer = TAILQ_FIRST(&chp->ch_queue->queue_xfer);
                       xfer != 0; ) {
                           if (xfer->c_chp != chp)
                                   continue;
                           if ((flags & AT_RST_EMERG) == 0)
                                   xfer->c_kill_xfer(chp, xfer, KILL_RESET);
                   }
           }
         if ((flags & AT_POLL) == 0) {          if ((flags & AT_POLL) == 0) {
                 if (chp->ch_flags & WDCF_TH_RESET) {                  if (chp->ch_flags & WDCF_TH_RESET) {
                         /* no need to schedule a reset more than one time */                          /* no need to schedule a reset more than one time */
                         return;                          return;
                 }                  }
                 chp->ch_flags |= WDCF_TH_RESET;                  chp->ch_flags |= WDCF_TH_RESET;
                 chp->ch_queue->queue_freeze++;  
                 wakeup(&chp->ch_thread);                  wakeup(&chp->ch_thread);
                 return;                  return;
         }          }
Line 974  wdc_reset_channel(struct ata_drive_datas
Line 1005  wdc_reset_channel(struct ata_drive_datas
         for (drive = 0; drive < 2; drive++) {          for (drive = 0; drive < 2; drive++) {
                 chp->ch_drive[drive].state = 0;                  chp->ch_drive[drive].state = 0;
         }          }
           if ((flags & AT_RST_EMERG) == 0)  {
                   chp->ch_queue->queue_freeze--;
                   wdcstart(chp);
           } else {
                   /* make sure that we can use polled commands */
                   TAILQ_INIT(&chp->ch_queue->queue_xfer);
                   chp->ch_queue->queue_freeze = 0;
           }
 }  }
   
 int  int
Line 1567  wdc_downgrade_mode(struct ata_drive_data
Line 1606  wdc_downgrade_mode(struct ata_drive_data
         wdc->set_modes(chp);          wdc->set_modes(chp);
         wdc_print_modes(chp);          wdc_print_modes(chp);
         /* reset the channel, which will shedule all drives for setup */          /* reset the channel, which will shedule all drives for setup */
         wdc_reset_channel(drvp, flags);          wdc_reset_channel(drvp, flags | AT_RST_NOCMD);
         return 1;          return 1;
 }  }
   
Line 1600  wdc_exec_command(struct ata_drive_datas 
Line 1639  wdc_exec_command(struct ata_drive_datas 
         xfer->c_cmd = wdc_c;          xfer->c_cmd = wdc_c;
         xfer->c_start = __wdccommand_start;          xfer->c_start = __wdccommand_start;
         xfer->c_intr = __wdccommand_intr;          xfer->c_intr = __wdccommand_intr;
         xfer->c_kill_xfer = __wdccommand_done;          xfer->c_kill_xfer = __wdccommand_kill_xfer;
   
         s = splbio();          s = splbio();
         wdc_exec_xfer(chp, xfer);          wdc_exec_xfer(chp, xfer);
Line 1782  __wdccommand_done(struct wdc_channel *ch
Line 1821  __wdccommand_done(struct wdc_channel *ch
             wdc->sc_dev.dv_xname, chp->ch_channel, xfer->c_drive),              wdc->sc_dev.dv_xname, chp->ch_channel, xfer->c_drive),
             DEBUG_FUNCS);              DEBUG_FUNCS);
   
         callout_stop(&chp->ch_callout);  
   
         if (chp->ch_status & WDCS_DWF)          if (chp->ch_status & WDCS_DWF)
                 wdc_c->flags |= AT_DF;                  wdc_c->flags |= AT_DF;
Line 1790  __wdccommand_done(struct wdc_channel *ch
Line 1828  __wdccommand_done(struct wdc_channel *ch
                 wdc_c->flags |= AT_ERROR;                  wdc_c->flags |= AT_ERROR;
                 wdc_c->r_error = chp->ch_error;                  wdc_c->r_error = chp->ch_error;
         }          }
         wdc_c->flags |= AT_DONE;  
         if ((wdc_c->flags & AT_READREG) != 0 &&          if ((wdc_c->flags & AT_READREG) != 0 &&
             (wdc->sc_dev.dv_flags & DVF_ACTIVE) != 0 &&              (wdc->sc_dev.dv_flags & DVF_ACTIVE) != 0 &&
             (wdc_c->flags & (AT_ERROR | AT_DF)) == 0) {              (wdc_c->flags & (AT_ERROR | AT_DF)) == 0) {
Line 1809  __wdccommand_done(struct wdc_channel *ch
Line 1846  __wdccommand_done(struct wdc_channel *ch
                 wdc_c->r_precomp = bus_space_read_1(chp->cmd_iot,                  wdc_c->r_precomp = bus_space_read_1(chp->cmd_iot,
                     chp->cmd_iohs[wd_precomp], 0);                      chp->cmd_iohs[wd_precomp], 0);
         }          }
           __wdccommand_done_end(chp, xfer);
   }
   
   static void
   __wdccommand_done_end(struct wdc_channel *chp, struct ata_xfer *xfer)
   {
           struct wdc_command *wdc_c = xfer->c_cmd;
   
           callout_stop(&chp->ch_callout);
           wdc_c->flags |= AT_DONE;
         if (wdc_c->flags & AT_POLL) {          if (wdc_c->flags & AT_POLL) {
                 /* enable interrupts */                  /* enable interrupts */
                 bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr,                  bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr,
Line 1825  __wdccommand_done(struct wdc_channel *ch
Line 1871  __wdccommand_done(struct wdc_channel *ch
         return;          return;
 }  }
   
   static void
   __wdccommand_kill_xfer(struct wdc_channel *chp, struct ata_xfer *xfer,
       int reason)
   {
           struct wdc_command *wdc_c = xfer->c_cmd;
   
           switch (reason) {
           case KILL_GONE:
                   wdc_c->flags |= AT_GONE;
                   break;
           case KILL_RESET:
                   wdc_c->flags |= AT_RESET;
                   break;
           default:
                   printf("__wdccommand_kill_xfer: unknown reason %d\n",
                       reason);
                   panic("__wdccommand_kill_xfer");
           }
           __wdccommand_done_end(chp, xfer);
   
   }
   
 /*  /*
  * Send a command. The drive should be ready.   * Send a command. The drive should be ready.
  * Assumes interrupts are blocked.   * Assumes interrupts are blocked.
Line 1942  wdc_exec_xfer(struct wdc_channel *chp, s
Line 2010  wdc_exec_xfer(struct wdc_channel *chp, s
         /* complete xfer setup */          /* complete xfer setup */
         xfer->c_chp = chp;          xfer->c_chp = chp;
   
         /*  
          * If we are a polled command, and the list is not empty,  
          * we are doing a dump. Drop the list to allow the polled command  
          * to complete, we're going to reboot soon anyway.  
          */  
         if ((xfer->c_flags & C_POLL) != 0 &&  
             TAILQ_FIRST(&chp->ch_queue->queue_xfer) != NULL) {  
                 TAILQ_INIT(&chp->ch_queue->queue_xfer);  
         }  
         /* insert at the end of command list */          /* insert at the end of command list */
         TAILQ_INSERT_TAIL(&chp->ch_queue->queue_xfer, xfer, c_xferchain);          TAILQ_INSERT_TAIL(&chp->ch_queue->queue_xfer, xfer, c_xferchain);
         WDCDEBUG_PRINT(("wdcstart from wdc_exec_xfer, flags 0x%x\n",          WDCDEBUG_PRINT(("wdcstart from wdc_exec_xfer, flags 0x%x\n",
Line 2001  wdc_kill_pending(struct wdc_channel *chp
Line 2060  wdc_kill_pending(struct wdc_channel *chp
   
         while ((xfer = TAILQ_FIRST(&chp->ch_queue->queue_xfer)) != NULL) {          while ((xfer = TAILQ_FIRST(&chp->ch_queue->queue_xfer)) != NULL) {
                 chp = xfer->c_chp;                  chp = xfer->c_chp;
                 (*xfer->c_kill_xfer)(chp, xfer);                  (*xfer->c_kill_xfer)(chp, xfer, KILL_GONE);
         }          }
 }  }
   

Legend:
Removed from v.1.172.2.4  
changed lines
  Added in v.1.172.2.5

CVSweb <webmaster@jp.NetBSD.org>