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/ieee1394/sbpscsi.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: sbpscsi.c,v 1.7 2004/02/13 21:22:13 enami Exp $        */
    2 
    3 /*
    4  * Copyright (c) 2002 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by James Chacon.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *      This product includes software developed by the NetBSD
   21  *      Foundation, Inc. and its contributors.
   22  * 4. Neither the name of The NetBSD Foundation nor the names of its
   23  *    contributors may be used to endorse or promote products derived
   24  *    from this software without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36  * POSSIBILITY OF SUCH DAMAGE.
   37  */
   38 
   39 #include <sys/cdefs.h>
   40 __KERNEL_RCSID(0, "$NetBSD: sbpscsi.c,v 1.7 2004/02/13 21:22:13 enami Exp $");
   41 
   42 #include <sys/param.h>
   43 #include <sys/kernel.h>
   44 #include <sys/device.h>
   45 #include <sys/systm.h>
   46 #include <sys/malloc.h>
   47 #include <sys/buf.h>
   48 
   49 #include <machine/bus.h>
   50 #include <machine/limits.h>
   51 
   52 #include <dev/scsipi/scsi_all.h>
   53 #include <dev/scsipi/scsipi_all.h>
   54 #include <dev/scsipi/scsiconf.h>
   55 
   56 #include <dev/ieee1394/ieee1394reg.h>
   57 #include <dev/ieee1394/ieee1394var.h>
   58 #include <dev/ieee1394/sbp2reg.h>
   59 #include <dev/ieee1394/sbp2var.h>
   60 #include <dev/ieee1394/sbpscsireg.h>
   61 #include <dev/ieee1394/sbpscsivar.h>
   62 
   63 #ifdef SBPSCSI_DEBUG
   64 #define DPRINTF(x)      if (sbpscsidebug) printf x
   65 #define DPRINTFN(n,x)   if (sbpscsidebug>(n)) printf x
   66 int     sbpscsidebug = 3;
   67 #else
   68 #define DPRINTF(x)
   69 #define DPRINTFN(n,x)
   70 #endif
   71 
   72 static int sbpscsi_match(struct device *, struct cfdata *, void *);
   73 static void sbpscsi_attach(struct device *, struct device *, void *);
   74 static int sbpscsi_detach(struct device *, int);
   75 static void sbpscsi_scsipi_request(struct scsipi_channel *,
   76     scsipi_adapter_req_t, void *);
   77 static void sbpscsi_status(struct sbp2_status *, void *);
   78 static void sbpscsi_timeout(void *);
   79 static void sbpscsi_minphys(struct buf *);
   80 
   81 CFATTACH_DECL(sbpscsi, sizeof(struct sbpscsi_softc),
   82     sbpscsi_match, sbpscsi_attach, sbpscsi_detach, NULL);
   83 
   84 static int
   85 sbpscsi_match(struct device *parent, struct cfdata *match, void *aux)
   86 {
   87         struct p1212_dir **udirs = aux;
   88         struct sbp2* sbp2;
   89         struct sbp2_lun *lun;
   90         int ret;
   91 
   92         sbp2 = NULL;
   93         ret = 0;
   94         if (sbp2_match(*udirs)) {
   95                 sbp2 = sbp2_init((struct ieee1394_softc *) parent, *udirs);
   96                 TAILQ_FOREACH(lun, &sbp2->luns, lun_list) {
   97                         if ((lun->cmd_spec_id == SBPSCSI_COMMAND_SET_SPEC_ID) &&
   98                             (lun->cmd_set == SBPSCSI_COMMAND_SET))
   99                                 ret = 1;
  100                 }
  101         }
  102         if (sbp2)
  103                 sbp2_free(sbp2);
  104         return ret;
  105 }
  106 
  107 static void
  108 sbpscsi_attach(struct device *parent, struct device *self, void *aux)
  109 {
  110         struct p1212_dir **udirs = aux;
  111         struct sbpscsi_softc *sc = (struct sbpscsi_softc *)self;
  112         struct ieee1394_softc *psc = (struct ieee1394_softc *) parent;
  113         int found;
  114 
  115         found = 0;
  116 
  117         if (sbp2_match(*udirs)) {
  118                 sc->sbp2 = sbp2_init(psc, *udirs);
  119                 found = 1;
  120         }
  121         
  122         if (!found) {
  123                 DPRINTF(("Can't match an SBP capable scsi lun?"));
  124                 return;
  125         }               
  126         
  127         sc->sc_adapter.adapt_dev = &sc->sc_dev;
  128         sc->sc_adapter.adapt_nchannels = 1;
  129         sc->sc_adapter.adapt_max_periph = 1;
  130         sc->sc_adapter.adapt_request = sbpscsi_scsipi_request;
  131         sc->sc_adapter.adapt_minphys = sbpscsi_minphys;
  132         sc->sc_adapter.adapt_openings = 8; /*Start with some. Grow as needed.*/
  133         
  134         sc->sc_channel.chan_adapter = &sc->sc_adapter;
  135         sc->sc_channel.chan_bustype = &scsi_bustype;
  136         sc->sc_channel.chan_defquirks = PQUIRK_ONLYBIG;
  137         sc->sc_channel.chan_channel = 0;
  138         sc->sc_channel.chan_flags = SCSIPI_CHAN_CANGROW | SCSIPI_CHAN_NOSETTLE;
  139 
  140         sc->sc_channel.chan_ntargets = 1;
  141         sc->sc_channel.chan_nluns = sc->sbp2->luncnt;
  142         sc->sc_channel.chan_id = 1;
  143 
  144         printf("\n");
  145 
  146         sc->sc_bus = config_found(&sc->sc_dev, &sc->sc_channel, scsiprint);
  147         
  148         return;
  149 }
  150 
  151 static int
  152 sbpscsi_detach(struct device *self, int flags)
  153 {
  154         struct sbpscsi_softc *sc = (struct sbpscsi_softc *)self;
  155 
  156         if (sc->sbp2)
  157                 sbp2_free(sc->sbp2);
  158         if (sc->sc_bus)
  159                 config_detach(sc->sc_bus, 0);
  160         return 0;
  161 }
  162 
  163 static void
  164 sbpscsi_scsipi_request(struct scsipi_channel *channel, scsipi_adapter_req_t req,
  165     void *arg)
  166 {
  167         int i;
  168         void *handle;
  169         struct sbpscsi_softc *sc =
  170             (struct sbpscsi_softc *)channel->chan_adapter->adapt_dev;
  171         struct sbp2 *sbp2 = sc->sbp2;
  172         struct scsipi_xfer *xs = arg;
  173         struct sbp2_cmd cmd;
  174         
  175         DPRINTFN(1, ("Called sbpscsi_scsipi_request\n"));
  176 
  177         switch (req) {
  178         case ADAPTER_REQ_RUN_XFER:
  179                 DPRINTFN(1, ("Got req_run_xfer\n"));
  180                 DPRINTFN(1, ("xs control: 0x%08x, timeout: %d\n", 
  181                     xs->xs_control, xs->timeout));
  182                 DPRINTFN(1, ("opcode: 0x%02x\n", (int)xs->cmd->opcode));
  183                 for (i = 0; i < 15; i++)
  184                         DPRINTFN(1, ("0x%02x ",(int)xs->cmd->bytes[i]));
  185                 DPRINTFN(1, ("\n"));
  186                 if (xs->xs_control & XS_CTL_RESET) {
  187                         sbp2_reset_lun(sbp2, xs->xs_periph->periph_lun);
  188                         return;
  189                 }
  190                 if (xs->cmdlen > SBPSCSI_SBP2_MAX_CDB) {
  191                         DPRINTF(("sbp doesn't support cdb's larger than %d "
  192                                     "bytes\n", SBPSCSI_SBP2_MAX_CDB));
  193                         xs->error = XS_DRIVER_STUFFUP;
  194                         scsipi_done(xs);
  195                         return;
  196                 }
  197                 cmd.lun = xs->xs_periph->periph_lun;
  198                 cmd.data = xs->data;
  199                 cmd.datalen = xs->datalen;
  200                 memset(cmd.cmd, 0, 12);
  201                 cmd.cmd[0] = xs->cmd->opcode;
  202                 for (i = 0; i < xs->cmdlen; i++)
  203                         cmd.cmd[i + 1] = xs->cmd->bytes[i];
  204                 cmd.cmdlen = 12;
  205                 if (xs->xs_control & XS_CTL_DATA_IN)
  206                         cmd.rw = SBP_WRITE;
  207                 if (xs->xs_control & XS_CTL_DATA_OUT)
  208                         cmd.rw = SBP_READ;
  209                 cmd.cb = sbpscsi_status;
  210                 cmd.cb_arg = xs;
  211                 handle = sbp2_runcmd(sbp2, &cmd);
  212                 if (handle)
  213                         callout_reset(&xs->xs_callout, mstohz(xs->timeout),
  214                             sbpscsi_timeout, handle);
  215                 else {
  216                         DPRINTF(("Got an error from sbp2_runcmd\n"));
  217                         xs->error = XS_DRIVER_STUFFUP;
  218                         scsipi_done(xs);
  219                 }
  220                 break;
  221         case ADAPTER_REQ_GROW_RESOURCES:
  222                 DPRINTFN(1, ("Got req_grow_resources\n"));
  223                 break;
  224         case ADAPTER_REQ_SET_XFER_MODE:
  225                 DPRINTFN(1, ("Got set xfer mode\n"));
  226                 break;
  227         default:
  228                 panic("Unknown request: %d\n", (int)req);
  229         }
  230 }
  231 
  232 static void
  233 sbpscsi_timeout(void *arg)
  234 {
  235         struct scsipi_xfer *xs;
  236 
  237         xs = sbp2_abort(arg);
  238 
  239         xs->error = XS_TIMEOUT;
  240         scsipi_done(xs);
  241 }
  242 
  243 static void
  244 sbpscsi_status(struct sbp2_status *status, void *arg)
  245 {
  246         struct scsipi_xfer *xs = arg;
  247         u_int8_t smft, vflag, iflag, mflag, eflag;
  248         
  249         callout_stop(&xs->xs_callout);
  250 
  251         DPRINTFN(1, ("status: resp 0x%04x, sbp_status 0x%04x\n", status->resp,
  252             status->sbp_status));
  253 
  254         if ((status->resp != SBP2_STATUS_REQUEST_COMPLETE) ||
  255             (status->sbp_status != SBP2_STATUS_NOERROR)) {
  256 #ifdef SBPSCSI_DEBUG
  257 #endif
  258         } else {
  259                 xs->error = XS_NOERROR;
  260                 xs->resid = 0;
  261         }
  262         
  263         if (status->datalen) {
  264                 xs->sense.scsi_sense.error_code =
  265                     SBPSCSI_STATUS_GET_STATUS(status->data[0]);
  266                 vflag = SBPSCSI_STATUS_GET_VFLAG(status->data[0]);
  267                 mflag = SBPSCSI_STATUS_GET_MFLAG(status->data[0]);
  268                 eflag = SBPSCSI_STATUS_GET_EFLAG(status->data[0]);
  269                 iflag = SBPSCSI_STATUS_GET_IFLAG(status->data[0]);
  270                 smft = SBPSCSI_STATUS_GET_SMFT(status->data[0]);
  271                 
  272                 if (iflag)
  273                         xs->sense.scsi_sense.flags |= SSD_ILI;
  274                 if (eflag)
  275                         xs->sense.scsi_sense.flags |= SSD_EOM;
  276                 if (mflag)
  277                         xs->sense.scsi_sense.flags |= SSD_FILEMARK;
  278                 xs->sense.scsi_sense.flags |=
  279                     SBPSCSI_STATUS_GET_SENSEKEY(status->data[0]);
  280                 if (((smft == 0) || (smft == 1)) && vflag) {
  281                         xs->sense.scsi_sense.info[0] =
  282                             (status->data[1] & 0xff000000) >> 24;
  283                         xs->sense.scsi_sense.info[1] =
  284                             (status->data[1] & 0x00ff0000) >> 16;
  285                         xs->sense.scsi_sense.info[2] =
  286                             (status->data[1] & 0x0000ff00) >> 8;
  287                         xs->sense.scsi_sense.info[3] =
  288                             status->data[1] & 0x000000ff;
  289                 }
  290                 xs->sense.scsi_sense.cmd_spec_info[0] =
  291                     (status->data[2] & 0xff000000) >> 24;
  292                 xs->sense.scsi_sense.cmd_spec_info[1] =
  293                     (status->data[2] & 0x00ff0000) >> 16;
  294                 xs->sense.scsi_sense.cmd_spec_info[2] =
  295                     (status->data[2] & 0x0000ff00) >> 8;
  296                 xs->sense.scsi_sense.cmd_spec_info[3] =
  297                     status->data[2] & 0x000000ff;
  298                 xs->sense.scsi_sense.add_sense_code =
  299                     SBPSCSI_STATUS_GET_SENSECODE(status->data[0]);
  300                 xs->sense.scsi_sense.add_sense_code_qual =
  301                     SBPSCSI_STATUS_GET_SENSEQUAL(status->data[0]);
  302                 xs->sense.scsi_sense.fru =
  303                     SBPSCSI_STATUS_GET_FRU(status->data[3]);
  304                 xs->sense.scsi_sense.sense_key_spec_1 =
  305                     SBPSCSI_STATUS_GET_SENSE1(status->data[3]);
  306                 xs->sense.scsi_sense.sense_key_spec_2 =
  307                     SBPSCSI_STATUS_GET_SENSE2(status->data[3]);
  308                 xs->sense.scsi_sense.sense_key_spec_3 =
  309                     SBPSCSI_STATUS_GET_SENSE3(status->data[3]);
  310         }
  311         scsipi_done(xs);
  312 }
  313 
  314 static void
  315 sbpscsi_minphys(bp)
  316         struct buf *bp;
  317 {
  318 
  319         minphys(bp);
  320 }

Cache object: 064cba45e7f7f7b2bdd2ea2b3a2dc851


[ 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.