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

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

Diff for /src/sys/dev/scsipi/atapi_wdc.c between version 1.129 and 1.129.4.1

version 1.129, 2017/10/17 18:52:51 version 1.129.4.1, 2019/06/10 22:07:32
Line 67  __KERNEL_RCSID(0, "$NetBSD$");
Line 67  __KERNEL_RCSID(0, "$NetBSD$");
 #define DEBUG_FUNCS  0x08  #define DEBUG_FUNCS  0x08
 #define DEBUG_PROBE  0x10  #define DEBUG_PROBE  0x10
 #ifdef ATADEBUG  #ifdef ATADEBUG
 int wdcdebug_atapi_mask = 0;  #ifndef ATADEBUG_ATAPI_MASK
   #define ATADEBUG_ATAPI_MASK 0x0
   #endif
   int wdcdebug_atapi_mask = ATADEBUG_ATAPI_MASK;
 #define ATADEBUG_PRINT(args, level) \  #define ATADEBUG_PRINT(args, level) \
         if (wdcdebug_atapi_mask & (level)) \          if (wdcdebug_atapi_mask & (level)) \
                 printf args                  printf args
Line 86  static int wdc_atapi_start(struct ata_ch
Line 89  static int wdc_atapi_start(struct ata_ch
 static int      wdc_atapi_intr(struct ata_channel *, struct ata_xfer *, int);  static int      wdc_atapi_intr(struct ata_channel *, struct ata_xfer *, int);
 static void     wdc_atapi_kill_xfer(struct ata_channel *,  static void     wdc_atapi_kill_xfer(struct ata_channel *,
                                     struct ata_xfer *, int);                                      struct ata_xfer *, int);
 static void     wdc_atapi_phase_complete(struct ata_xfer *);  static void     wdc_atapi_phase_complete(struct ata_xfer *, int);
 static void     wdc_atapi_poll(struct ata_channel *, struct ata_xfer *);  static void     wdc_atapi_poll(struct ata_channel *, struct ata_xfer *);
 static void     wdc_atapi_done(struct ata_channel *, struct ata_xfer *);  static void     wdc_atapi_done(struct ata_channel *, struct ata_xfer *);
 static void     wdc_atapi_reset(struct ata_channel *, struct ata_xfer *);  static void     wdc_atapi_reset(struct ata_channel *, struct ata_xfer *);
Line 208  wdc_atapi_get_params(struct scsipi_chann
Line 211  wdc_atapi_get_params(struct scsipi_chann
         struct ata_xfer *xfer;          struct ata_xfer *xfer;
         int rv;          int rv;
   
         xfer = ata_get_xfer(chp);          xfer = ata_get_xfer(chp, false);
         if (xfer == NULL) {          if (xfer == NULL) {
                 printf("wdc_atapi_get_params: no xfer\n");                  printf("wdc_atapi_get_params: no xfer\n");
                 return EBUSY;                  return EBUSY;
Line 359  wdc_atapi_probe_device(struct atapibus_s
Line 362  wdc_atapi_probe_device(struct atapibus_s
         }          }
 }  }
   
   static const struct ata_xfer_ops wdc_atapi_xfer_ops = {
           .c_start = wdc_atapi_start,
           .c_intr = wdc_atapi_intr,
           .c_poll = wdc_atapi_poll,
           .c_abort = wdc_atapi_reset,
           .c_kill_xfer = wdc_atapi_kill_xfer,
   };
   
 static void  static void
 wdc_atapi_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req,  wdc_atapi_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req,
     void *arg)      void *arg)
Line 387  wdc_atapi_scsipi_request(struct scsipi_c
Line 398  wdc_atapi_scsipi_request(struct scsipi_c
                         return;                          return;
                 }                  }
   
                 xfer = ata_get_xfer_ext(atac->atac_channels[channel], false, 0);                  xfer = ata_get_xfer(atac->atac_channels[channel], false);
                 if (xfer == NULL) {                  if (xfer == NULL) {
                         sc_xfer->error = XS_RESOURCE_SHORTAGE;                          sc_xfer->error = XS_RESOURCE_SHORTAGE;
                         scsipi_done(sc_xfer);                          scsipi_done(sc_xfer);
Line 449  wdc_atapi_scsipi_request(struct scsipi_c
Line 460  wdc_atapi_scsipi_request(struct scsipi_c
                         xfer->c_flags &= ~C_DMA;                          xfer->c_flags &= ~C_DMA;
 #endif  /* NATA_DMA */  #endif  /* NATA_DMA */
   
                 xfer->c_scsipi = sc_xfer;  
                 xfer->c_databuf = sc_xfer->data;                  xfer->c_databuf = sc_xfer->data;
                 xfer->c_bcount = sc_xfer->datalen;                  xfer->c_bcount = sc_xfer->datalen;
                 xfer->c_start = wdc_atapi_start;                  xfer->ops = &wdc_atapi_xfer_ops;
                 xfer->c_intr = wdc_atapi_intr;                  xfer->c_scsipi = sc_xfer;
                 xfer->c_poll = wdc_atapi_poll;                  xfer->c_atapi.c_dscpoll = 0;
                 xfer->c_abort = wdc_atapi_reset;  
                 xfer->c_kill_xfer = wdc_atapi_kill_xfer;  
                 xfer->c_dscpoll = 0;  
                 s = splbio();                  s = splbio();
                 ata_exec_xfer(atac->atac_channels[channel], xfer);                  ata_exec_xfer(atac->atac_channels[channel], xfer);
 #ifdef DIAGNOSTIC  #ifdef DIAGNOSTIC
Line 595  ready:
Line 602  ready:
         }          }
         /* start timeout machinery */          /* start timeout machinery */
         if ((sc_xfer->xs_control & XS_CTL_POLL) == 0)          if ((sc_xfer->xs_control & XS_CTL_POLL) == 0)
                 callout_reset(&xfer->c_timo_callout, mstohz(sc_xfer->timeout),                  callout_reset(&chp->c_timo_callout, mstohz(sc_xfer->timeout),
                     wdctimeout, xfer);                      wdctimeout, chp);
   
         if (wdc->select)          if (wdc->select)
                 wdc->select(chp, xfer->c_drive);                  wdc->select(chp, xfer->c_drive);
Line 777  wdc_atapi_intr(struct ata_channel *chp, 
Line 784  wdc_atapi_intr(struct ata_channel *chp, 
   
                 /* restore transfer length */                  /* restore transfer length */
                 len = xfer->c_bcount;                  len = xfer->c_bcount;
                 if (xfer->c_lenoff < 0)                  if (xfer->c_atapi.c_lenoff < 0)
                         len += xfer->c_lenoff;                          len += xfer->c_atapi.c_lenoff;
   
                 if (sc_xfer->xs_control & XS_CTL_DATA_IN)                  if (sc_xfer->xs_control & XS_CTL_DATA_IN)
                         goto end_piobm_datain;                          goto end_piobm_datain;
Line 801  wdc_atapi_intr(struct ata_channel *chp, 
Line 808  wdc_atapi_intr(struct ata_channel *chp, 
                 printf("%s:%d:%d: device timeout, c_bcount=%d, c_skip=%d\n",                  printf("%s:%d:%d: device timeout, c_bcount=%d, c_skip=%d\n",
                     device_xname(atac->atac_dev), chp->ch_channel,                      device_xname(atac->atac_dev), chp->ch_channel,
                     xfer->c_drive, xfer->c_bcount, xfer->c_skip);                      xfer->c_drive, xfer->c_bcount, xfer->c_skip);
                 ata_channel_unlock(chp);  
 #if NATA_DMA  #if NATA_DMA
                 if (xfer->c_flags & C_DMA) {                  if (xfer->c_flags & C_DMA) {
                         ata_dmaerr(drvp,                          ata_dmaerr(drvp,
Line 809  wdc_atapi_intr(struct ata_channel *chp, 
Line 815  wdc_atapi_intr(struct ata_channel *chp, 
                 }                  }
 #endif  #endif
                 sc_xfer->error = XS_TIMEOUT;                  sc_xfer->error = XS_TIMEOUT;
                   ata_channel_unlock(chp);
                 wdc_atapi_reset(chp, xfer);                  wdc_atapi_reset(chp, xfer);
                 return 1;                  return 1;
         }          }
Line 821  wdc_atapi_intr(struct ata_channel *chp, 
Line 828  wdc_atapi_intr(struct ata_channel *chp, 
          * and reset device.           * and reset device.
          */           */
         if ((xfer->c_flags & C_TIMEOU) && (xfer->c_flags & C_DMA)) {          if ((xfer->c_flags & C_TIMEOU) && (xfer->c_flags & C_DMA)) {
                 ata_channel_unlock(chp);  
                 ata_dmaerr(drvp, (xfer->c_flags & C_POLL) ? AT_POLL : 0);                  ata_dmaerr(drvp, (xfer->c_flags & C_POLL) ? AT_POLL : 0);
                 sc_xfer->error = XS_RESET;                  sc_xfer->error = XS_RESET;
                   ata_channel_unlock(chp);
                 wdc_atapi_reset(chp, xfer);                  wdc_atapi_reset(chp, xfer);
                 return (1);                  return (1);
         }          }
Line 901  again:
Line 908  again:
                 if ((sc_xfer->xs_control & XS_CTL_DATA_OUT) == 0 ||                  if ((sc_xfer->xs_control & XS_CTL_DATA_OUT) == 0 ||
                     (xfer->c_flags & C_DMA) != 0) {                      (xfer->c_flags & C_DMA) != 0) {
                         printf("wdc_atapi_intr: bad data phase DATAOUT\n");                          printf("wdc_atapi_intr: bad data phase DATAOUT\n");
                         ata_channel_unlock(chp);  
                         if (xfer->c_flags & C_DMA) {                          if (xfer->c_flags & C_DMA) {
                                 ata_dmaerr(drvp,                                  ata_dmaerr(drvp,
                                     (xfer->c_flags & C_POLL) ? AT_POLL : 0);                                      (xfer->c_flags & C_POLL) ? AT_POLL : 0);
                         }                          }
                         sc_xfer->error = XS_TIMEOUT;                          sc_xfer->error = XS_TIMEOUT;
                           ata_channel_unlock(chp);
                         wdc_atapi_reset(chp, xfer);                          wdc_atapi_reset(chp, xfer);
                         return 1;                          return 1;
                 }                  }
 #endif  #endif
                 xfer->c_lenoff = len - xfer->c_bcount;                  xfer->c_atapi.c_lenoff = len - xfer->c_bcount;
                 if (xfer->c_bcount < len) {                  if (xfer->c_bcount < len) {
                         printf("wdc_atapi_intr: warning: write only "                          printf("wdc_atapi_intr: warning: write only "
                             "%d of %d requested bytes\n", xfer->c_bcount, len);                              "%d of %d requested bytes\n", xfer->c_bcount, len);
Line 936  again:
Line 943  again:
 #if NATA_PIOBM  #if NATA_PIOBM
         end_piobm_dataout:          end_piobm_dataout:
 #endif  #endif
                 for (i = xfer->c_lenoff; i > 0; i -= 2)                  for (i = xfer->c_atapi.c_lenoff; i > 0; i -= 2)
                         bus_space_write_2(wdr->cmd_iot,                          bus_space_write_2(wdr->cmd_iot,
                             wdr->cmd_iohs[wd_data], 0, 0);                              wdr->cmd_iohs[wd_data], 0, 0);
   
Line 955  again:
Line 962  again:
                 if ((sc_xfer->xs_control & XS_CTL_DATA_IN) == 0 ||                  if ((sc_xfer->xs_control & XS_CTL_DATA_IN) == 0 ||
                     (xfer->c_flags & C_DMA) != 0) {                      (xfer->c_flags & C_DMA) != 0) {
                         printf("wdc_atapi_intr: bad data phase DATAIN\n");                          printf("wdc_atapi_intr: bad data phase DATAIN\n");
                         ata_channel_unlock(chp);  
                         if (xfer->c_flags & C_DMA) {                          if (xfer->c_flags & C_DMA) {
                                 ata_dmaerr(drvp,                                  ata_dmaerr(drvp,
                                     (xfer->c_flags & C_POLL) ? AT_POLL : 0);                                      (xfer->c_flags & C_POLL) ? AT_POLL : 0);
                         }                          }
                         sc_xfer->error = XS_TIMEOUT;                          sc_xfer->error = XS_TIMEOUT;
                           ata_channel_unlock(chp);
                         wdc_atapi_reset(chp, xfer);                          wdc_atapi_reset(chp, xfer);
                         return 1;                          return 1;
                 }                  }
 #endif  #endif
                 xfer->c_lenoff = len - xfer->c_bcount;                  xfer->c_atapi.c_lenoff = len - xfer->c_bcount;
                 if (xfer->c_bcount < len) {                  if (xfer->c_bcount < len) {
                         printf("wdc_atapi_intr: warning: reading only "                          printf("wdc_atapi_intr: warning: reading only "
                             "%d of %d bytes\n", xfer->c_bcount, len);                              "%d of %d bytes\n", xfer->c_bcount, len);
Line 990  again:
Line 997  again:
 #if NATA_PIOBM  #if NATA_PIOBM
         end_piobm_datain:          end_piobm_datain:
 #endif  #endif
                 if (xfer->c_lenoff > 0)                  if (xfer->c_atapi.c_lenoff > 0)
                         wdcbit_bucket(chp, xfer->c_lenoff);                          wdcbit_bucket(chp, xfer->c_atapi.c_lenoff);
   
                 xfer->c_skip += len;                  xfer->c_skip += len;
                 xfer->c_bcount -= len;                  xfer->c_bcount -= len;
Line 1011  again:
Line 1018  again:
 #endif  #endif
                 sc_xfer->resid = xfer->c_bcount;                  sc_xfer->resid = xfer->c_bcount;
                 /* this will unlock channel lock too */                  /* this will unlock channel lock too */
                 wdc_atapi_phase_complete(xfer);                  wdc_atapi_phase_complete(xfer, tfd);
                 return(1);                  return(1);
   
         default:          default:
Line 1030  again:
Line 1037  again:
                         sc_xfer->error = XS_SHORTSENSE;                          sc_xfer->error = XS_SHORTSENSE;
                         sc_xfer->sense.atapi_sense = ATACH_ERR(tfd);                          sc_xfer->sense.atapi_sense = ATACH_ERR(tfd);
                 } else {                  } else {
                         ata_channel_unlock(chp);  
 #if NATA_DMA  #if NATA_DMA
                         if (xfer->c_flags & C_DMA) {                          if (xfer->c_flags & C_DMA) {
                                 ata_dmaerr(drvp,                                  ata_dmaerr(drvp,
Line 1038  again:
Line 1044  again:
                         }                          }
 #endif  #endif
                         sc_xfer->error = XS_RESET;                          sc_xfer->error = XS_RESET;
                           ata_channel_unlock(chp);
                         wdc_atapi_reset(chp, xfer);                          wdc_atapi_reset(chp, xfer);
                         return (1);                          return (1);
                 }                  }
Line 1051  again:
Line 1058  again:
 }  }
   
 static void  static void
 wdc_atapi_phase_complete(struct ata_xfer *xfer)  wdc_atapi_phase_complete(struct ata_xfer *xfer, int tfd)
 {  {
         struct ata_channel *chp = xfer->c_chp;          struct ata_channel *chp = xfer->c_chp;
         struct atac_softc *atac = chp->ch_atac;          struct atac_softc *atac = chp->ch_atac;
Line 1060  wdc_atapi_phase_complete(struct ata_xfer
Line 1067  wdc_atapi_phase_complete(struct ata_xfer
 #endif  #endif
         struct scsipi_xfer *sc_xfer = xfer->c_scsipi;          struct scsipi_xfer *sc_xfer = xfer->c_scsipi;
         struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive];          struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive];
         int tfd = 0;  
   
         ata_channel_lock_owned(chp);          ata_channel_lock_owned(chp);
   
Line 1069  wdc_atapi_phase_complete(struct ata_xfer
Line 1075  wdc_atapi_phase_complete(struct ata_xfer
                 ATADEBUG_PRINT(("wdc_atapi_phase_complete(%s:%d:%d) "                  ATADEBUG_PRINT(("wdc_atapi_phase_complete(%s:%d:%d) "
                     "polldsc %d\n", device_xname(atac->atac_dev),                      "polldsc %d\n", device_xname(atac->atac_dev),
                     chp->ch_channel,                      chp->ch_channel,
                     xfer->c_drive, xfer->c_dscpoll), DEBUG_XFERS);                      xfer->c_drive, xfer->c_atapi.c_dscpoll), DEBUG_XFERS);
 #if 1  #if 1
                 if (cold)                  if (cold)
                         panic("wdc_atapi_phase_complete: cold");                          panic("wdc_atapi_phase_complete: cold");
Line 1077  wdc_atapi_phase_complete(struct ata_xfer
Line 1083  wdc_atapi_phase_complete(struct ata_xfer
                 if (wdcwait(chp, WDCS_DSC, WDCS_DSC, 10,                  if (wdcwait(chp, WDCS_DSC, WDCS_DSC, 10,
                     AT_POLL, &tfd) == WDCWAIT_TOUT) {                      AT_POLL, &tfd) == WDCWAIT_TOUT) {
                         /* 10ms not enough, try again in 1 tick */                          /* 10ms not enough, try again in 1 tick */
                         if (xfer->c_dscpoll++ >                          if (xfer->c_atapi.c_dscpoll++ >
                             mstohz(sc_xfer->timeout)) {                              mstohz(sc_xfer->timeout)) {
                                 printf("%s:%d:%d: wait_for_dsc "                                  printf("%s:%d:%d: wait_for_dsc "
                                     "failed\n",                                      "failed\n",
Line 1087  wdc_atapi_phase_complete(struct ata_xfer
Line 1093  wdc_atapi_phase_complete(struct ata_xfer
                                 sc_xfer->error = XS_TIMEOUT;                                  sc_xfer->error = XS_TIMEOUT;
                                 wdc_atapi_reset(chp, xfer);                                  wdc_atapi_reset(chp, xfer);
                         } else {                          } else {
                                 callout_reset(&xfer->c_timo_callout, 1,                                  callout_reset(&chp->c_timo_callout, 1,
                                     wdc_atapi_polldsc, xfer);                                      wdc_atapi_polldsc, chp);
                                 ata_channel_unlock(chp);                                  ata_channel_unlock(chp);
                         }                          }
                         return;                          return;
Line 1116  wdc_atapi_phase_complete(struct ata_xfer
Line 1122  wdc_atapi_phase_complete(struct ata_xfer
 #if NATA_DMA || NATA_PIOBM  #if NATA_DMA || NATA_PIOBM
                 else if (wdc->dma_status &                  else if (wdc->dma_status &
                     (WDC_DMAST_NOIRQ | WDC_DMAST_ERR)) {                      (WDC_DMAST_NOIRQ | WDC_DMAST_ERR)) {
                         ata_channel_unlock(chp);  
 #if NATA_DMA  #if NATA_DMA
                         ata_dmaerr(drvp,                          ata_dmaerr(drvp,
                             (xfer->c_flags & C_POLL) ? AT_POLL : 0);                              (xfer->c_flags & C_POLL) ? AT_POLL : 0);
 #endif  #endif
                         sc_xfer->error = XS_RESET;                          sc_xfer->error = XS_RESET;
                           ata_channel_unlock(chp);
                         wdc_atapi_reset(chp, xfer);                          wdc_atapi_reset(chp, xfer);
                         return;                          return;
                 }                  }
Line 1192  wdc_atapi_reset(struct ata_channel *chp,
Line 1198  wdc_atapi_reset(struct ata_channel *chp,
 static void  static void
 wdc_atapi_polldsc(void *arg)  wdc_atapi_polldsc(void *arg)
 {  {
         struct ata_xfer *xfer = arg;          struct ata_channel *chp = arg;
         struct ata_channel *chp = xfer->c_chp;          struct ata_xfer *xfer = ata_queue_get_active_xfer(chp);
   
           KASSERT(xfer != NULL);
   
         ata_channel_lock(chp);          ata_channel_lock(chp);
   
         /* this will unlock channel lock too */          /* this will unlock channel lock too */
         wdc_atapi_phase_complete(xfer);          wdc_atapi_phase_complete(xfer, 0);
 }  }

Legend:
Removed from v.1.129  
changed lines
  Added in v.1.129.4.1

CVSweb <webmaster@jp.NetBSD.org>