The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/usb/umass_isdata.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: umass_isdata.c,v 1.9 2003/12/30 19:30:39 thorpej Exp $ */
    2 
    3 /*
    4  * TODO:
    5  *  get ATA registers on any kind of error
    6  *  implement more commands (what is needed)
    7  */
    8 
    9 /*
   10  * Copyright (c) 2001 The NetBSD Foundation, Inc.
   11  * All rights reserved.
   12  *
   13  * This code is derived from software contributed to The NetBSD Foundation
   14  * by Lennart Augustsson (lennart@augustsson.net) at
   15  * Carlstedt Research & Technology.
   16  *
   17  * Redistribution and use in source and binary forms, with or without
   18  * modification, are permitted provided that the following conditions
   19  * are met:
   20  * 1. Redistributions of source code must retain the above copyright
   21  *    notice, this list of conditions and the following disclaimer.
   22  * 2. Redistributions in binary form must reproduce the above copyright
   23  *    notice, this list of conditions and the following disclaimer in the
   24  *    documentation and/or other materials provided with the distribution.
   25  * 3. All advertising materials mentioning features or use of this software
   26  *    must display the following acknowledgement:
   27  *        This product includes software developed by the NetBSD
   28  *        Foundation, Inc. and its contributors.
   29  * 4. Neither the name of The NetBSD Foundation nor the names of its
   30  *    contributors may be used to endorse or promote products derived
   31  *    from this software without specific prior written permission.
   32  *
   33  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   34  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   35  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   36  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   37  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   38  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   39  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   40  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   41  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   42  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   43  * POSSIBILITY OF SUCH DAMAGE.
   44  */
   45 
   46 #include <sys/cdefs.h>
   47 __KERNEL_RCSID(0, "$NetBSD: umass_isdata.c,v 1.9 2003/12/30 19:30:39 thorpej Exp $");
   48 
   49 #include <sys/param.h>
   50 #include <sys/systm.h>
   51 #include <sys/kernel.h>
   52 #include <sys/conf.h>
   53 #include <sys/buf.h>
   54 #include <sys/device.h>
   55 #include <sys/proc.h>
   56 #include <sys/disklabel.h>
   57 #include <sys/malloc.h>
   58 
   59 #include <dev/usb/usb.h>
   60 #include <dev/usb/usbdi.h>
   61 #include <dev/usb/usbdi_util.h>
   62 
   63 #include <dev/usb/umassvar.h>
   64 #include <dev/usb/umass_isdata.h>
   65 
   66 int umass_wd_attach(struct umass_softc *);
   67 
   68 #include <dev/ata/atareg.h>
   69 #include <dev/ata/atavar.h>
   70 
   71 /* XXX move this */
   72 struct isd200_config {
   73         uByte EventNotification;
   74         uByte ExternalClock;
   75         uByte ATAInitTimeout;
   76         uByte ATAMisc1;
   77 #define ATATiming               0x0f
   78 #define ATAPIReset              0x10
   79 #define MasterSlaveSelection    0x20
   80 #define ATAPICommandBlockSize   0xc0
   81         uByte ATAMajorCommand;
   82         uByte ATAMinorCommand;
   83         uByte ATAMisc2;
   84 #define LastLUNIdentifier       0x07
   85 #define DescriptOverride        0x08
   86 #define ATA3StateSuspend        0x10
   87 #define SkipDeviceBoot          0x20
   88 #define ConfigDescriptor2       0x40
   89 #define InitStatus              0x80
   90         uByte ATAMisc3;
   91 #define SRSTEnable              0x01
   92 };
   93 
   94 struct uisdata_softc {
   95         struct umassbus_softc   base;
   96 
   97         struct ata_drive_datas  sc_drv_data;
   98         struct isd200_config    sc_isd_config;
   99         void                    *sc_ata_bio;
  100         u_long                  sc_skip;
  101 };
  102 
  103 #undef DPRINTF
  104 #undef DPRINTFN
  105 #ifdef UISDATA_DEBUG
  106 #define DPRINTF(x)      if (uisdatadebug) logprintf x
  107 #define DPRINTFN(n,x)   if (uisdatadebug>(n)) logprintf x
  108 int     uisdatadebug = 0;
  109 #else
  110 #define DPRINTF(x)
  111 #define DPRINTFN(n,x)
  112 #endif
  113 
  114 int  uisdata_bio(struct ata_drive_datas *, struct ata_bio *);
  115 int  uisdata_bio1(struct ata_drive_datas *, struct ata_bio *);
  116 void uisdata_reset_channel(struct ata_drive_datas *, int);
  117 int  uisdata_exec_command(struct ata_drive_datas *, struct wdc_command *);
  118 int  uisdata_get_params(struct ata_drive_datas *, u_int8_t, struct ataparams *);
  119 int  uisdata_addref(struct ata_drive_datas *);
  120 void uisdata_delref(struct ata_drive_datas *);
  121 void uisdata_kill_pending(struct ata_drive_datas *);
  122 
  123 void uisdata_bio_cb(struct umass_softc *, void *, int, int);
  124 void uisdata_exec_cb(struct umass_softc *, void *, int, int);
  125 int  uwdprint(void *, const char *);
  126 
  127 const struct ata_bustype uisdata_bustype = {
  128         SCSIPI_BUSTYPE_ATA,
  129         uisdata_bio,
  130         uisdata_reset_channel,
  131         uisdata_exec_command,
  132         uisdata_get_params,
  133         uisdata_addref,
  134         uisdata_delref,
  135         uisdata_kill_pending,
  136 };
  137 
  138 struct ata_cmd {
  139         u_int8_t ac_signature0;
  140         u_int8_t ac_signature1;
  141 
  142         u_int8_t ac_action_select;
  143 #define AC_ReadRegisterAccess           0x01
  144 #define AC_NoDeviceSelectionBit         0x02
  145 #define AC_NoBSYPollBit                 0x04
  146 #define AC_IgnorePhaseErrorBit          0x08
  147 #define AC_IgnoreDeviceErrorBit         0x10
  148 
  149         u_int8_t ac_register_select;
  150 #define AC_SelectAlternateStatus        0x01 /* R */
  151 #define AC_SelectDeviceControl          0x01 /* W */
  152 #define AC_SelectError                  0x02 /* R */
  153 #define AC_SelectFeatures               0x02 /* W */
  154 #define AC_SelectSectorCount            0x04 /* RW */
  155 #define AC_SelectSectorNumber           0x08 /* RW */
  156 #define AC_SelectCylinderLow            0x10 /* RW */
  157 #define AC_SelectCylinderHigh           0x20 /* RW */
  158 #define AC_SelectDeviceHead             0x40 /* RW */
  159 #define AC_SelectStatus                 0x80 /* R */
  160 #define AC_SelectCommand                0x80 /* W */
  161 
  162         u_int8_t ac_transfer_blocksize;
  163 
  164         u_int8_t ac_alternate_status;
  165 #define ac_device_control ac_alternate_status
  166         u_int8_t ac_error;
  167 #define ac_features ac_error
  168 
  169         u_int8_t ac_sector_count;
  170         u_int8_t ac_sector_number;
  171         u_int8_t ac_cylinder_low;
  172         u_int8_t ac_cylinder_high;
  173         u_int8_t ac_device_head;
  174 
  175         u_int8_t ac_status;
  176 #define ac_command ac_status
  177 
  178         u_int8_t ac_reserved[3];
  179 };
  180 
  181 #define ATA_DELAY 10000 /* 10s for a drive I/O */
  182 
  183 int
  184 umass_isdata_attach(struct umass_softc *sc)
  185 {
  186         usb_device_request_t req;
  187         usbd_status err;
  188         struct ata_device adev;
  189         struct uisdata_softc *scbus;
  190         struct isd200_config *cf;
  191 
  192         scbus = malloc(sizeof *scbus, M_DEVBUF, M_WAITOK | M_ZERO);
  193         sc->bus = &scbus->base;
  194         cf = &scbus->sc_isd_config;
  195 
  196         req.bmRequestType = UT_READ_VENDOR_DEVICE;
  197         req.bRequest = 0x02;
  198         USETW(req.wValue, 0);
  199         USETW(req.wIndex, 2);
  200         USETW(req.wLength, sizeof *cf);
  201 
  202         err = usbd_do_request(sc->sc_udev, &req, cf);
  203         if (err)
  204                 return (EIO);
  205         DPRINTF(("umass_wd_attach info:\n  EventNotification=0x%02x "
  206                  "ExternalClock=0x%02x ATAInitTimeout=0x%02x\n"
  207                  "  ATAMisc1=0x%02x ATAMajorCommand=0x%02x "
  208                  "ATAMinorCommand=0x%02x\n"
  209                  "  ATAMisc2=0x%02x ATAMisc3=0x%02x\n",
  210                  cf->EventNotification, cf->ExternalClock, cf->ATAInitTimeout,
  211                  cf->ATAMisc1, cf->ATAMajorCommand, cf->ATAMinorCommand,
  212                  cf->ATAMisc2, cf->ATAMisc3));
  213 
  214         memset(&adev, 0, sizeof(struct ata_device));
  215         adev.adev_bustype = &uisdata_bustype;
  216         adev.adev_channel = 1;  /* XXX */
  217         adev.adev_openings = 1;
  218         adev.adev_drv_data = &scbus->sc_drv_data;
  219         scbus->sc_drv_data.drive_flags = DRIVE_ATA;
  220         scbus->sc_drv_data.chnl_softc = sc;
  221         scbus->base.sc_child = config_found(&sc->sc_dev, &adev, uwdprint);
  222 
  223         return (0);
  224 }
  225 
  226 
  227 void
  228 uisdata_bio_cb(struct umass_softc *sc, void *priv, int residue, int status)
  229 {
  230         struct uisdata_softc *scbus = (struct uisdata_softc *)sc->bus;
  231         struct ata_bio *ata_bio = priv;
  232         int s;
  233 
  234         DPRINTF(("%s: residue=%d status=%d\n", __func__, residue, status));
  235 
  236         s = splbio();
  237         scbus->sc_ata_bio = NULL;
  238         if (status != STATUS_CMD_OK)
  239                 ata_bio->error = ERR_DF; /* ??? */
  240         else
  241                 ata_bio->error = NOERROR;
  242         ata_bio->flags |= ATA_ITSDONE;
  243 
  244         ata_bio->blkdone += ata_bio->nblks;
  245         ata_bio->blkno += ata_bio->nblks;
  246         ata_bio->bcount -= ata_bio->nbytes;
  247         scbus->sc_skip += ata_bio->nbytes;
  248         if (residue != 0) {
  249                 ata_bio->bcount += residue;
  250         } else if (ata_bio->bcount > 0) {
  251                 DPRINTF(("%s: continue\n", __func__));
  252                 (void)uisdata_bio1(&scbus->sc_drv_data, ata_bio); /*XXX save drv*/
  253                 splx(s);
  254                 return;
  255         }
  256 
  257         if (ata_bio->flags & ATA_POLL) {
  258                 DPRINTF(("%s: wakeup %p\n", __func__, ata_bio));
  259                 wakeup(ata_bio);
  260         } else {
  261                 (*scbus->sc_drv_data.drv_done)(scbus->sc_drv_data.drv_softc);
  262         }
  263         splx(s);
  264 }
  265 
  266 int
  267 uisdata_bio(struct ata_drive_datas *drv, struct ata_bio *ata_bio)
  268 {
  269         struct umass_softc *sc = drv->chnl_softc;
  270         struct uisdata_softc *scbus = (struct uisdata_softc *)sc->bus;
  271 
  272         scbus->sc_skip = 0;
  273         return (uisdata_bio1(drv, ata_bio));
  274 }
  275 
  276 int
  277 uisdata_bio1(struct ata_drive_datas *drv, struct ata_bio *ata_bio)
  278 {
  279         struct umass_softc *sc = drv->chnl_softc;
  280         struct uisdata_softc *scbus = (struct uisdata_softc *)sc->bus;
  281         struct isd200_config *cf = &scbus->sc_isd_config;
  282         struct ata_cmd ata;
  283         u_int16_t cyl;
  284         u_int8_t head, sect;
  285         int dir;
  286         long nbytes;
  287         u_int nblks;
  288 
  289         DPRINTF(("%s\n", __func__));
  290         /* XXX */
  291 
  292         if (ata_bio->flags & ATA_NOSLEEP) {
  293                 printf("%s: ATA_NOSLEEP not supported\n", __func__);
  294                 ata_bio->error = TIMEOUT;
  295                 ata_bio->flags |= ATA_ITSDONE;
  296                 return (WDC_COMPLETE);
  297         }
  298 
  299         if (scbus->sc_ata_bio != NULL) {
  300                 printf("%s: multiple uisdata_bio\n", __func__);
  301                 return (WDC_TRY_AGAIN);
  302         } else
  303                 scbus->sc_ata_bio = ata_bio;
  304 
  305         if (ata_bio->flags & ATA_LBA) {
  306                 sect = (ata_bio->blkno >> 0) & 0xff;
  307                 cyl = (ata_bio->blkno >> 8) & 0xffff;
  308                 head = (ata_bio->blkno >> 24) & 0x0f;
  309                 head |= WDSD_LBA;
  310         } else {
  311                 int blkno = ata_bio->blkno;
  312                 sect = blkno % ata_bio->lp->d_nsectors;
  313                 sect++;    /* Sectors begin with 1, not 0. */
  314                 blkno /= ata_bio->lp->d_nsectors;
  315                 head = blkno % ata_bio->lp->d_ntracks;
  316                 blkno /= ata_bio->lp->d_ntracks;
  317                 cyl = blkno;
  318                 head |= WDSD_CHS;
  319         }
  320 
  321         nbytes = ata_bio->bcount;
  322         if (ata_bio->flags & ATA_SINGLE)
  323                 nblks = 1;
  324         else
  325                 nblks = min(ata_bio->multi, nbytes / ata_bio->lp->d_secsize);
  326         nbytes = nblks * ata_bio->lp->d_secsize;
  327         ata_bio->nblks = nblks;
  328         ata_bio->nbytes = nbytes;
  329 
  330         memset(&ata, 0, sizeof ata);
  331         ata.ac_signature0 = cf->ATAMajorCommand;
  332         ata.ac_signature1 = cf->ATAMinorCommand;
  333         ata.ac_transfer_blocksize = 1;
  334         ata.ac_sector_count = nblks;
  335         ata.ac_sector_number = sect;
  336         ata.ac_cylinder_high = cyl >> 8;
  337         ata.ac_cylinder_low = cyl;
  338         ata.ac_device_head = head;
  339         ata.ac_register_select = AC_SelectSectorCount | AC_SelectSectorNumber |
  340             AC_SelectCylinderLow | AC_SelectCylinderHigh | AC_SelectDeviceHead |
  341             AC_SelectCommand;
  342 
  343         dir = DIR_NONE;
  344         if (ata_bio->bcount != 0) {
  345                 if (ata_bio->flags & ATA_READ)
  346                         dir = DIR_IN;
  347                 else
  348                         dir = DIR_OUT;
  349         }
  350 
  351         if (ata_bio->flags & ATA_READ) {
  352                 ata.ac_command = WDCC_READ;
  353         } else {
  354                 ata.ac_command = WDCC_WRITE;
  355         }
  356         DPRINTF(("%s: bno=%" PRId64 " LBA=%d cyl=%d head=%d sect=%d "
  357                  "count=%d multi=%d\n",
  358                  __func__, ata_bio->blkno,
  359                  (ata_bio->flags & ATA_LBA) != 0, cyl, head, sect,
  360                  ata.ac_sector_count, ata_bio->multi));
  361         DPRINTF(("    data=%p bcount=%ld, drive=%d\n", ata_bio->databuf,
  362                  ata_bio->bcount, drv->drive));
  363         sc->sc_methods->wire_xfer(sc, drv->drive, &ata, sizeof ata,
  364                                   ata_bio->databuf + scbus->sc_skip, nbytes,
  365                                   dir, ATA_DELAY, uisdata_bio_cb, ata_bio);
  366 
  367         while (ata_bio->flags & ATA_POLL) {
  368                 DPRINTF(("%s: tsleep %p\n", __func__, ata_bio));
  369                 if (tsleep(ata_bio, PZERO, "uisdatabl", 0)) {
  370                         ata_bio->error = TIMEOUT;
  371                         ata_bio->flags |= ATA_ITSDONE;
  372                         return (WDC_COMPLETE);
  373                 }
  374         }
  375 
  376         return (ata_bio->flags & ATA_ITSDONE) ? WDC_COMPLETE : WDC_QUEUED;
  377 }
  378 
  379 void
  380 uisdata_reset_channel(struct ata_drive_datas *drv, int flags)
  381 {
  382         DPRINTFN(-1,("%s\n", __func__));
  383         /* XXX what? */
  384 }
  385 
  386 void
  387 uisdata_exec_cb(struct umass_softc *sc, void *priv, int residue, int status)
  388 {
  389         struct wdc_command *cmd = priv;
  390 
  391         DPRINTF(("%s: status=%d\n", __func__, status));
  392         if (status != STATUS_CMD_OK)
  393                 cmd->flags |= AT_DF; /* XXX */
  394         cmd->flags |= AT_DONE;
  395         if (cmd->flags & (AT_POLL | AT_WAIT)) {
  396                 DPRINTF(("%s: wakeup %p\n", __func__, cmd));
  397                 wakeup(cmd);
  398         }
  399 }
  400 
  401 int
  402 uisdata_exec_command(struct ata_drive_datas *drv, struct wdc_command *cmd)
  403 {
  404         struct umass_softc *sc = drv->chnl_softc;
  405         struct uisdata_softc *scbus = (struct uisdata_softc *)sc->bus;
  406         struct isd200_config *cf = &scbus->sc_isd_config;
  407         int dir;
  408         struct ata_cmd ata;
  409 
  410         DPRINTF(("%s\n", __func__));
  411         DPRINTF(("  r_command=0x%02x timeout=%d flags=0x%x bcount=%d\n",
  412                  cmd->r_command, cmd->timeout, cmd->flags, cmd->bcount));
  413 
  414         dir = DIR_NONE;
  415         if (cmd->bcount != 0) {
  416                 if (cmd->flags & AT_READ)
  417                         dir = DIR_IN;
  418                 else
  419                         dir = DIR_OUT;
  420         }
  421 
  422         if (cmd->bcount > UMASS_MAX_TRANSFER_SIZE) {
  423                 printf("uisdata_exec_command: large datalen %d\n", cmd->bcount);
  424                 cmd->flags |= AT_ERROR;
  425                 goto done;
  426         }
  427 
  428         memset(&ata, 0, sizeof ata);
  429         ata.ac_signature0 = cf->ATAMajorCommand;
  430         ata.ac_signature1 = cf->ATAMinorCommand;
  431         ata.ac_transfer_blocksize = 1;
  432 
  433         switch (cmd->r_command) {
  434         case WDCC_IDENTIFY:
  435                 ata.ac_register_select |= AC_SelectCommand;
  436                 ata.ac_command = WDCC_IDENTIFY;
  437                 break;
  438         default:
  439                 printf("uisdata_exec_command: bad command 0x%02x\n",
  440                        cmd->r_command);
  441                 cmd->flags |= AT_ERROR;
  442                 goto done;
  443         }
  444 
  445         DPRINTF(("%s: execute ATA command 0x%02x, drive=%d\n", __func__,
  446                  ata.ac_command, drv->drive));
  447         sc->sc_methods->wire_xfer(sc, drv->drive, &ata,
  448                                   sizeof ata, cmd->data, cmd->bcount, dir,
  449                                   cmd->timeout, uisdata_exec_cb, cmd);
  450         if (cmd->flags & (AT_POLL | AT_WAIT)) {
  451 #if 0
  452                 if (cmd->flags & AT_POLL)
  453                         printf("%s: AT_POLL not supported\n", __func__);
  454 #endif
  455                 DPRINTF(("%s: tsleep %p\n", __func__, cmd));
  456                 if (tsleep(cmd, PZERO, "uisdataex", 0)) {
  457                         cmd->flags |= AT_ERROR;
  458                         goto done;
  459                 }
  460         }
  461 
  462 done:
  463         return (WDC_COMPLETE);
  464 }
  465 
  466 int
  467 uisdata_addref(struct ata_drive_datas *drv)
  468 {
  469         DPRINTF(("%s\n", __func__));
  470         /* Nothing to do */
  471         return (0);
  472 }
  473 
  474 void
  475 uisdata_delref(struct ata_drive_datas *drv)
  476 {
  477         DPRINTF(("%s\n", __func__));
  478         /* Nothing to do */
  479 }
  480 
  481 void
  482 uisdata_kill_pending(struct ata_drive_datas *drv)
  483 {
  484         struct umass_softc *sc = drv->chnl_softc;
  485         struct uisdata_softc *scbus = (struct uisdata_softc *)sc->bus;
  486         struct ata_bio *ata_bio = scbus->sc_ata_bio;
  487 
  488         DPRINTFN(-1,("%s\n", __func__));
  489 
  490         if (ata_bio == NULL)
  491                 return;
  492         scbus->sc_ata_bio = NULL;
  493         ata_bio->flags |= ATA_ITSDONE;
  494         ata_bio->error = ERR_NODEV;
  495         ata_bio->r_error = WDCE_ABRT;
  496         (*scbus->sc_drv_data.drv_done)(scbus->sc_drv_data.drv_softc);
  497 }
  498 
  499 int
  500 uisdata_get_params(struct ata_drive_datas *drvp, u_int8_t flags,
  501                 struct ataparams *prms)
  502 {
  503         char tb[DEV_BSIZE];
  504         struct wdc_command wdc_c;
  505 
  506 #if BYTE_ORDER == LITTLE_ENDIAN
  507         int i;
  508         u_int16_t *p;
  509 #endif
  510 
  511         DPRINTF(("%s\n", __func__));
  512 
  513         memset(tb, 0, DEV_BSIZE);
  514         memset(prms, 0, sizeof(struct ataparams));
  515         memset(&wdc_c, 0, sizeof(struct wdc_command));
  516 
  517         wdc_c.r_command = WDCC_IDENTIFY;
  518         wdc_c.timeout = 1000; /* 1s */
  519         wdc_c.flags = AT_READ | flags;
  520         wdc_c.data = tb;
  521         wdc_c.bcount = DEV_BSIZE;
  522         if (uisdata_exec_command(drvp, &wdc_c) != WDC_COMPLETE) {
  523                 DPRINTF(("uisdata_get_parms: wdc_exec_command failed\n"));
  524                 return (CMD_AGAIN);
  525         }
  526         if (wdc_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
  527                 DPRINTF(("uisdata_get_parms: wdc_c.flags=0x%x\n",
  528                          wdc_c.flags));
  529                 return (CMD_ERR);
  530         } else {
  531                 /* Read in parameter block. */
  532                 memcpy(prms, tb, sizeof(struct ataparams));
  533 #if BYTE_ORDER == LITTLE_ENDIAN
  534                 /* XXX copied from ata.c */
  535                 /*
  536                  * Shuffle string byte order.
  537                  * ATAPI Mitsumi and NEC drives don't need this.
  538                  */
  539                 if ((prms->atap_config & WDC_CFG_ATAPI_MASK) ==
  540                     WDC_CFG_ATAPI &&
  541                     ((prms->atap_model[0] == 'N' &&
  542                         prms->atap_model[1] == 'E') ||
  543                      (prms->atap_model[0] == 'F' &&
  544                          prms->atap_model[1] == 'X')))
  545                         return 0;
  546                 for (i = 0; i < sizeof(prms->atap_model); i += 2) {
  547                         p = (u_short *)(prms->atap_model + i);
  548                         *p = ntohs(*p);
  549                 }
  550                 for (i = 0; i < sizeof(prms->atap_serial); i += 2) {
  551                         p = (u_short *)(prms->atap_serial + i);
  552                         *p = ntohs(*p);
  553                 }
  554                 for (i = 0; i < sizeof(prms->atap_revision); i += 2) {
  555                         p = (u_short *)(prms->atap_revision + i);
  556                         *p = ntohs(*p);
  557                 }
  558 #endif
  559                 return CMD_OK;
  560         }
  561 }
  562 
  563 
  564 /* XXX join with wdc.c routine? */
  565 int
  566 uwdprint(void *aux, const char *pnp)
  567 {
  568         //struct ata_device *adev = aux;
  569         if (pnp)
  570                 aprint_normal("wd at %s", pnp);
  571 #if 0
  572         aprint_normal(" channel %d drive %d", adev->adev_channel,
  573             adev->adev_drv_data->drive);
  574 #endif
  575         return (UNCONF);
  576 }
  577 
  578 
  579 #if 0
  580 
  581 int umass_wd_attach(struct umass_softc *);
  582 
  583 #if NWD > 0
  584         case UMASS_CPROTO_ISD_ATA:
  585                 return (umass_wd_attach(sc));
  586 #endif
  587 
  588 #endif

Cache object: 96ea9def041e9158f177bebf3775abca


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.