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/sbp.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: sbp.c,v 1.13 2006/11/16 01:32:59 christos Exp $        */
    2 /*-
    3  * Copyright (c) 2003 Hidetoshi Shimokawa
    4  * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. All advertising materials mentioning features or use of this software
   16  *    must display the acknowledgement as bellow:
   17  *
   18  *    This product includes software developed by K. Kobayashi and H. Shimokawa
   19  *
   20  * 4. The name of the author may not be used to endorse or promote products
   21  *    derived from this software without specific prior written permission.
   22  *
   23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   25  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   26  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
   27  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   28  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   29  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   31  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   33  * POSSIBILITY OF SUCH DAMAGE.
   34  * 
   35  * $FreeBSD: /repoman/r/ncvs/src/sys/dev/firewire/sbp.c,v 1.81 2005/01/06 01:42:41 imp Exp $
   36  *
   37  */
   38 
   39 #if defined(__FreeBSD__)
   40 #include <sys/param.h>
   41 #include <sys/systm.h>
   42 #include <sys/conf.h>
   43 #include <sys/module.h>
   44 #include <sys/bus.h>
   45 #include <sys/kernel.h>
   46 #include <sys/sysctl.h>
   47 #include <machine/bus.h>
   48 #include <sys/malloc.h>
   49 #if defined(__FreeBSD__) && __FreeBSD_version >= 501102
   50 #include <sys/lock.h>
   51 #include <sys/mutex.h>
   52 #endif
   53 
   54 #if defined(__DragonFly__) || __FreeBSD_version < 500106
   55 #include <sys/devicestat.h>     /* for struct devstat */
   56 #endif
   57 
   58 #ifdef __DragonFly__
   59 #include <bus/cam/cam.h>
   60 #include <bus/cam/cam_ccb.h>
   61 #include <bus/cam/cam_sim.h>
   62 #include <bus/cam/cam_xpt_sim.h>
   63 #include <bus/cam/cam_debug.h>
   64 #include <bus/cam/cam_periph.h>
   65 #include <bus/cam/scsi/scsi_all.h>
   66 
   67 #include <bus/firewire/fw_port.h>
   68 #include <bus/firewire/firewire.h>
   69 #include <bus/firewire/firewirereg.h>
   70 #include <bus/firewire/fwdma.h>
   71 #include <bus/firewire/iec13213.h>
   72 #include "sbp.h"
   73 #else
   74 #include <cam/cam.h>
   75 #include <cam/cam_ccb.h>
   76 #include <cam/cam_sim.h>
   77 #include <cam/cam_xpt_sim.h>
   78 #include <cam/cam_debug.h>
   79 #include <cam/cam_periph.h>
   80 #include <cam/scsi/scsi_all.h>
   81 
   82 #include <dev/firewire/fw_port.h>
   83 #include <dev/firewire/firewire.h>
   84 #include <dev/firewire/firewirereg.h>
   85 #include <dev/firewire/fwdma.h>
   86 #include <dev/firewire/iec13213.h>
   87 #include <dev/firewire/sbp.h>
   88 #endif
   89 #elif defined(__NetBSD__)
   90 #include <sys/param.h>
   91 #include <sys/device.h>
   92 #include <sys/errno.h>
   93 #include <sys/buf.h>
   94 #include <sys/kernel.h>
   95 #include <sys/kthread.h>
   96 #include <sys/malloc.h>
   97 #include <sys/proc.h>
   98 #include <sys/sysctl.h>
   99 
  100 #include <machine/bus.h>
  101 
  102 #include <dev/scsipi/scsi_spc.h>
  103 #include <dev/scsipi/scsi_all.h>
  104 #include <dev/scsipi/scsipi_all.h>
  105 #include <dev/scsipi/scsiconf.h>
  106 #include <dev/scsipi/scsipiconf.h>
  107 
  108 #include <dev/ieee1394/fw_port.h>
  109 #include <dev/ieee1394/firewire.h>
  110 #include <dev/ieee1394/firewirereg.h>
  111 #include <dev/ieee1394/fwdma.h>
  112 #include <dev/ieee1394/iec13213.h>
  113 #include <dev/ieee1394/sbp.h>
  114 
  115 #include "locators.h"
  116 #endif
  117 
  118 #define ccb_sdev_ptr    spriv_ptr0
  119 #define ccb_sbp_ptr     spriv_ptr1
  120 
  121 #define SBP_NUM_TARGETS 8 /* MAX 64 */
  122 /*
  123  * Scan_bus doesn't work for more than 8 LUNs
  124  * because of CAM_SCSI2_MAXLUN in cam_xpt.c
  125  */
  126 #define SBP_NUM_LUNS 64
  127 #define SBP_DMA_SIZE PAGE_SIZE
  128 #define SBP_LOGIN_SIZE sizeof(struct sbp_login_res)
  129 #define SBP_QUEUE_LEN ((SBP_DMA_SIZE - SBP_LOGIN_SIZE) / sizeof(struct sbp_ocb))
  130 #define SBP_NUM_OCB (SBP_QUEUE_LEN * SBP_NUM_TARGETS)
  131 
  132 /* 
  133  * STATUS FIFO addressing
  134  *   bit
  135  * -----------------------
  136  *  0- 1( 2): 0 (alignment)
  137  *  2- 9( 8): lun
  138  * 10-31(14): unit
  139  * 32-47(16): SBP_BIND_HI 
  140  * 48-64(16): bus_id, node_id 
  141  */
  142 #define SBP_BIND_HI 0x1
  143 #define SBP_DEV2ADDR(u, l) \
  144         (((u_int64_t)SBP_BIND_HI << 32) \
  145         | (((u) & 0x3fff) << 10) \
  146         | (((l) & 0xff) << 2))
  147 #define SBP_ADDR2UNIT(a)        (((a) >> 10) & 0x3fff)
  148 #define SBP_ADDR2LUN(a)         (((a) >> 2) & 0xff)
  149 #define SBP_INITIATOR 7
  150 
  151 static const char *orb_fun_name[] = {
  152         ORB_FUN_NAMES
  153 };
  154 
  155 static int debug = 0;
  156 static int auto_login = 1;
  157 static int max_speed = -1;
  158 static int sbp_cold = 1;
  159 static int ex_login = 1;
  160 static int login_delay = 1000;  /* msec */
  161 static int scan_delay = 500;    /* msec */
  162 static int use_doorbell = 0;
  163 static int sbp_tags = 0;
  164 
  165 #if defined(__FreeBSD__)
  166 SYSCTL_DECL(_hw_firewire);
  167 SYSCTL_NODE(_hw_firewire, OID_AUTO, sbp, CTLFLAG_RD, 0, "SBP-II Subsystem");
  168 SYSCTL_INT(_debug, OID_AUTO, sbp_debug, CTLFLAG_RW, &debug, 0,
  169         "SBP debug flag");
  170 SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, auto_login, CTLFLAG_RW, &auto_login, 0,
  171         "SBP perform login automatically");
  172 SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, max_speed, CTLFLAG_RW, &max_speed, 0,
  173         "SBP transfer max speed");
  174 SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, exclusive_login, CTLFLAG_RW,
  175         &ex_login, 0, "SBP enable exclusive login");
  176 SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, login_delay, CTLFLAG_RW,
  177         &login_delay, 0, "SBP login delay in msec");
  178 SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, scan_delay, CTLFLAG_RW,
  179         &scan_delay, 0, "SBP scan delay in msec");
  180 SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, use_doorbell, CTLFLAG_RW,
  181         &use_doorbell, 0, "SBP use doorbell request");
  182 SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, tags, CTLFLAG_RW, &sbp_tags, 0,
  183         "SBP tagged queuing support");
  184 
  185 TUNABLE_INT("hw.firewire.sbp.auto_login", &auto_login);
  186 TUNABLE_INT("hw.firewire.sbp.max_speed", &max_speed);
  187 TUNABLE_INT("hw.firewire.sbp.exclusive_login", &ex_login);
  188 TUNABLE_INT("hw.firewire.sbp.login_delay", &login_delay);
  189 TUNABLE_INT("hw.firewire.sbp.scan_delay", &scan_delay);
  190 TUNABLE_INT("hw.firewire.sbp.use_doorbell", &use_doorbell);
  191 TUNABLE_INT("hw.firewire.sbp.tags", &sbp_tags);
  192 #elif defined(__NetBSD__)
  193 static int sysctl_sbp_verify(SYSCTLFN_PROTO, int lower, int upper);
  194 static int sysctl_sbp_verify_max_speed(SYSCTLFN_PROTO);
  195 static int sysctl_sbp_verify_tags(SYSCTLFN_PROTO);
  196 
  197 /*
  198  * Setup sysctl(3) MIB, hw.sbp.*
  199  *
  200  * TBD condition CTLFLAG_PERMANENT on being an LKM or not
  201  */
  202 SYSCTL_SETUP(sysctl_sbp, "sysctl sbp(4) subtree setup")
  203 {
  204         int rc, sbp_node_num;
  205         const struct sysctlnode *node;
  206 
  207         if ((rc = sysctl_createv(clog, 0, NULL, NULL,
  208             CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", NULL,
  209             NULL, 0, NULL, 0, CTL_HW, CTL_EOL)) != 0) {
  210                 goto err;
  211         }
  212 
  213         if ((rc = sysctl_createv(clog, 0, NULL, &node,
  214             CTLFLAG_PERMANENT, CTLTYPE_NODE, "sbp",
  215             SYSCTL_DESCR("sbp controls"), NULL, 0, NULL,
  216             0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0) {
  217                 goto err;
  218         }
  219         sbp_node_num = node->sysctl_num;
  220 
  221         /* sbp auto login flag */
  222         if ((rc = sysctl_createv(clog, 0, NULL, &node,
  223             CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
  224             "auto_login", SYSCTL_DESCR("SBP perform login automatically"),
  225             NULL, 0, &auto_login,
  226             0, CTL_HW, sbp_node_num, CTL_CREATE, CTL_EOL)) != 0) {
  227                 goto err;
  228         }
  229 
  230         /* sbp max speed */
  231         if ((rc = sysctl_createv(clog, 0, NULL, &node,
  232             CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
  233             "max_speed", SYSCTL_DESCR("SBP transfer max speed"),
  234             sysctl_sbp_verify_max_speed, 0, &max_speed,
  235             0, CTL_HW, sbp_node_num, CTL_CREATE, CTL_EOL)) != 0) {
  236                 goto err;
  237         }
  238 
  239         /* sbp exclusive login flag */
  240         if ((rc = sysctl_createv(clog, 0, NULL, &node,
  241             CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
  242             "exclusive_login", SYSCTL_DESCR("SBP enable exclusive login"),
  243             NULL, 0, &ex_login,
  244             0, CTL_HW, sbp_node_num, CTL_CREATE, CTL_EOL)) != 0) {
  245                 goto err;
  246         }
  247 
  248         /* sbp login delay */
  249         if ((rc = sysctl_createv(clog, 0, NULL, &node,
  250             CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
  251             "login_delay", SYSCTL_DESCR("SBP login delay in msec"),
  252             NULL, 0, &login_delay,
  253             0, CTL_HW, sbp_node_num, CTL_CREATE, CTL_EOL)) != 0) {
  254                 goto err;
  255         }
  256 
  257         /* sbp scan delay */
  258         if ((rc = sysctl_createv(clog, 0, NULL, &node,
  259             CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
  260             "scan_delay", SYSCTL_DESCR("SBP scan delay in msec"),
  261             NULL, 0, &scan_delay,
  262             0, CTL_HW, sbp_node_num, CTL_CREATE, CTL_EOL)) != 0) {
  263                 goto err;
  264         }
  265 
  266         /* sbp use doorbell flag */
  267         if ((rc = sysctl_createv(clog, 0, NULL, &node,
  268             CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
  269             "use_doorbell", SYSCTL_DESCR("SBP use doorbell request"),
  270             NULL, 0, &use_doorbell,
  271             0, CTL_HW, sbp_node_num, CTL_CREATE, CTL_EOL)) != 0) {
  272                 goto err;
  273         }
  274 
  275         /* sbp force tagged queuing */
  276         if ((rc = sysctl_createv(clog, 0, NULL, &node,
  277             CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
  278             "tags", SYSCTL_DESCR("SBP tagged queuing support"),
  279             sysctl_sbp_verify_tags, 0, &sbp_tags,
  280             0, CTL_HW, sbp_node_num, CTL_CREATE, CTL_EOL)) != 0) {
  281                 goto err;
  282         }
  283 
  284         /* sbp driver debug flag */
  285         if ((rc = sysctl_createv(clog, 0, NULL, &node,
  286             CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
  287             "sbp_debug", SYSCTL_DESCR("SBP debug flag"),
  288             NULL, 0, &debug,
  289             0, CTL_HW, sbp_node_num, CTL_CREATE, CTL_EOL)) != 0) {
  290                 goto err;
  291         }
  292 
  293         return;
  294 
  295 err:
  296         printf("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
  297 }
  298 
  299 static int
  300 sysctl_sbp_verify(SYSCTLFN_ARGS, int lower, int upper)
  301 {
  302         int error, t;
  303         struct sysctlnode node;
  304 
  305         node = *rnode;
  306         t = *(int*)rnode->sysctl_data;
  307         node.sysctl_data = &t;
  308         error = sysctl_lookup(SYSCTLFN_CALL(&node));
  309         if (error || newp == NULL)
  310                 return (error);
  311 
  312         if (t < lower || t > upper)
  313                 return (EINVAL);
  314 
  315         *(int*)rnode->sysctl_data = t;
  316 
  317         return (0);
  318 }
  319 
  320 static int
  321 sysctl_sbp_verify_max_speed(SYSCTLFN_ARGS)
  322 {
  323         return (sysctl_sbp_verify(SYSCTLFN_CALL(rnode), 0, FWSPD_S400));
  324 }
  325 
  326 static int
  327 sysctl_sbp_verify_tags(SYSCTLFN_ARGS)
  328 {
  329         return (sysctl_sbp_verify(SYSCTLFN_CALL(rnode), -1, 1));
  330 }
  331 #endif
  332 
  333 #define NEED_RESPONSE 0
  334 
  335 #define SBP_SEG_MAX rounddown(0xffff, PAGE_SIZE)
  336 #ifdef __sparc64__ /* iommu */
  337 #define SBP_IND_MAX howmany(MAXPHYS, SBP_SEG_MAX)
  338 #else
  339 #define SBP_IND_MAX howmany(MAXPHYS, PAGE_SIZE)
  340 #endif
  341 struct sbp_ocb {
  342         STAILQ_ENTRY(sbp_ocb)   ocb;
  343         sbp_scsi_xfer *sxfer;
  344         bus_addr_t      bus_addr;
  345         uint32_t        orb[8];
  346 #define IND_PTR_OFFSET  (8*sizeof(uint32_t))
  347         struct ind_ptr  ind_ptr[SBP_IND_MAX];
  348         struct sbp_dev  *sdev;
  349         int             flags; /* XXX should be removed */
  350         bus_dmamap_t    dmamap;
  351 };
  352 
  353 #define OCB_ACT_MGM 0
  354 #define OCB_ACT_CMD 1
  355 #define OCB_MATCH(o,s)  ((o)->bus_addr == ntohl((s)->orb_lo))
  356 
  357 struct sbp_dev{
  358 #define SBP_DEV_RESET           0       /* accept login */
  359 #define SBP_DEV_LOGIN           1       /* to login */
  360 #if 0
  361 #define SBP_DEV_RECONN          2       /* to reconnect */
  362 #endif
  363 #define SBP_DEV_TOATTACH        3       /* to attach */
  364 #define SBP_DEV_PROBE           4       /* scan lun */
  365 #define SBP_DEV_ATTACHED        5       /* in operation */
  366 #define SBP_DEV_DEAD            6       /* unavailable unit */
  367 #define SBP_DEV_RETRY           7       /* unavailable unit */
  368         uint8_t status:4,
  369                  timeout:4;
  370         uint8_t type;
  371         uint16_t lun_id;
  372         uint16_t freeze;
  373 #define ORB_LINK_DEAD           (1 << 0)
  374 #define VALID_LUN               (1 << 1)
  375 #define ORB_POINTER_ACTIVE      (1 << 2)
  376 #define ORB_POINTER_NEED        (1 << 3)
  377 #define ORB_DOORBELL_ACTIVE     (1 << 4)
  378 #define ORB_DOORBELL_NEED       (1 << 5)
  379 #define ORB_SHORTAGE            (1 << 6)
  380         uint16_t flags;
  381 #if defined(__FreeBSD__)
  382         struct cam_path *path;
  383 #elif defined(__NetBSD__)
  384         struct scsipi_periph *periph;
  385 #endif
  386         struct sbp_target *target;
  387         struct fwdma_alloc dma;
  388         struct sbp_login_res *login;
  389         struct callout login_callout;
  390         struct sbp_ocb *ocb;
  391         STAILQ_HEAD(, sbp_ocb) ocbs;
  392         STAILQ_HEAD(, sbp_ocb) free_ocbs;
  393         struct sbp_ocb *last_ocb;
  394         char vendor[32];
  395         char product[32];
  396         char revision[10];
  397 };
  398 
  399 struct sbp_target {
  400         int target_id;
  401         int num_lun;
  402         struct sbp_dev  **luns;
  403         struct sbp_softc *sbp;
  404         struct fw_device *fwdev;
  405         uint32_t mgm_hi, mgm_lo;
  406         struct sbp_ocb *mgm_ocb_cur;
  407         STAILQ_HEAD(, sbp_ocb) mgm_ocb_queue;
  408         struct callout mgm_ocb_timeout;
  409         struct callout scan_callout;
  410         STAILQ_HEAD(, fw_xfer) xferlist;
  411         int n_xfer;
  412 };
  413 
  414 struct sbp_softc {
  415         struct firewire_dev_comm fd;
  416 #if defined(__FreeBSD__)
  417         struct cam_sim  *sim;
  418         struct cam_path  *path;
  419 #elif defined(__NetBSD__)
  420         struct scsipi_adapter sc_adapter; 
  421         struct scsipi_channel sc_channel;
  422         struct device *sc_bus;
  423         struct proc *proc;
  424 #endif
  425         struct sbp_target target;
  426         struct fw_bind fwb;
  427         fw_bus_dma_tag_t dmat;
  428         struct timeval last_busreset;
  429 #define SIMQ_FREEZED 1
  430         int flags;
  431 };
  432 
  433 #if defined(__NetBSD__)
  434 int sbpmatch (struct device *, struct cfdata *, void *);
  435 void sbpattach (struct device *parent, struct device *self, void *aux);
  436 int sbpdetach (struct device *self, int flags);
  437 #endif
  438 static void sbp_post_explore (void *);
  439 static void sbp_recv (struct fw_xfer *);
  440 static void sbp_mgm_callback (struct fw_xfer *);
  441 #if 0
  442 static void sbp_cmd_callback (struct fw_xfer *);
  443 #endif
  444 static void sbp_orb_pointer (struct sbp_dev *, struct sbp_ocb *);
  445 static void sbp_doorbell(struct sbp_dev *);
  446 static void sbp_execute_ocb (void *,  bus_dma_segment_t *, int, int);
  447 static void sbp_free_ocb (struct sbp_dev *, struct sbp_ocb *);
  448 static void sbp_abort_ocb (struct sbp_ocb *, int);
  449 static void sbp_abort_all_ocbs (struct sbp_dev *, int);
  450 static struct fw_xfer * sbp_write_cmd (struct sbp_dev *, int, int);
  451 static struct sbp_ocb * sbp_get_ocb (struct sbp_dev *);
  452 static struct sbp_ocb * sbp_enqueue_ocb (struct sbp_dev *, struct sbp_ocb *);
  453 static struct sbp_ocb * sbp_dequeue_ocb (struct sbp_dev *, struct sbp_status *);
  454 static void sbp_free_sdev(struct sbp_dev *);
  455 static void sbp_free_target (struct sbp_target *);
  456 static void sbp_mgm_timeout (void *arg);
  457 static void sbp_timeout (void *arg);
  458 static void sbp_mgm_orb (struct sbp_dev *, int, struct sbp_ocb *);
  459 #if defined(__FreeBSD__)
  460 
  461 MALLOC_DEFINE(M_SBP, "sbp", "SBP-II/FireWire");
  462 #elif defined(__NetBSD__)
  463 static void sbp_scsipi_request(
  464     struct scsipi_channel *, scsipi_adapter_req_t, void *);
  465 static void sbp_minphys(struct buf *);
  466 
  467 MALLOC_DEFINE(M_SBP, "sbp", "SBP-II/IEEE1394");
  468 #endif
  469 
  470 #if defined(__FreeBSD__)
  471 /* cam related functions */
  472 static void     sbp_action(struct cam_sim *, sbp_scsi_xfer *sxfer);
  473 static void     sbp_poll(struct cam_sim *);
  474 static void     sbp_cam_scan_lun(struct cam_periph *, sbp_scsi_xfer *);
  475 static void     sbp_cam_scan_target(void *);
  476 static void     sbp_cam_detach_sdev(struct sbp_dev *);
  477 static void     sbp_cam_detach_target (struct sbp_target *);
  478 #define SBP_DETACH_SDEV(sd)     sbp_cam_detach_sdev((sd))
  479 #define SBP_DETACH_TARGET(st)   sbp_cam_detach_target((st))
  480 #elif defined(__NetBSD__)
  481 /* scsipi related functions */
  482 static void     fw_kthread_create0(void *);
  483 static void     sbp_scsipi_scan_target(void *);
  484 static void     sbp_scsipi_detach_sdev(struct sbp_dev *);
  485 static void     sbp_scsipi_detach_target (struct sbp_target *);
  486 #define SBP_DETACH_SDEV(sd)     sbp_scsipi_detach_sdev((sd))
  487 #define SBP_DETACH_TARGET(st)   sbp_scsipi_detach_target((st))
  488 #endif
  489 
  490 static const char *orb_status0[] = {
  491         /* 0 */ "No additional information to report",
  492         /* 1 */ "Request type not supported",
  493         /* 2 */ "Speed not supported",
  494         /* 3 */ "Page size not supported",
  495         /* 4 */ "Access denied",
  496         /* 5 */ "Logical unit not supported",
  497         /* 6 */ "Maximum payload too small",
  498         /* 7 */ "Reserved for future standardization",
  499         /* 8 */ "Resources unavailable",
  500         /* 9 */ "Function rejected",
  501         /* A */ "Login ID not recognized",
  502         /* B */ "Dummy ORB completed",
  503         /* C */ "Request aborted",
  504         /* FF */ "Unspecified error"
  505 #define MAX_ORB_STATUS0 0xd
  506 };
  507 
  508 static const char *orb_status1_object[] = {
  509         /* 0 */ "Operation request block (ORB)",
  510         /* 1 */ "Data buffer",
  511         /* 2 */ "Page table",
  512         /* 3 */ "Unable to specify"
  513 };
  514 
  515 static const char *orb_status1_serial_bus_error[] = {
  516         /* 0 */ "Missing acknowledge",
  517         /* 1 */ "Reserved; not to be used",
  518         /* 2 */ "Time-out error",
  519         /* 3 */ "Reserved; not to be used",
  520         /* 4 */ "Busy retry limit exceeded(X)",
  521         /* 5 */ "Busy retry limit exceeded(A)",
  522         /* 6 */ "Busy retry limit exceeded(B)",
  523         /* 7 */ "Reserved for future standardization",
  524         /* 8 */ "Reserved for future standardization",
  525         /* 9 */ "Reserved for future standardization",
  526         /* A */ "Reserved for future standardization",
  527         /* B */ "Tardy retry limit exceeded",
  528         /* C */ "Conflict error",
  529         /* D */ "Data error",
  530         /* E */ "Type error",
  531         /* F */ "Address error"
  532 };
  533 
  534 #if defined(__FreeBSD__)
  535 #if 0
  536 static void
  537 sbp_identify(driver_t *driver, device_t parent)
  538 {
  539         device_t child;
  540 SBP_DEBUG(0)
  541         printf("sbp_identify\n");
  542 END_DEBUG
  543 
  544         child = BUS_ADD_CHILD(parent, 0, "sbp", device_get_unit(parent));
  545 }
  546 #endif
  547 
  548 /*
  549  * sbp_probe()
  550  */
  551 static int
  552 sbp_probe(device_t dev)
  553 {
  554         device_t pa;
  555 
  556 SBP_DEBUG(0)
  557         printf("sbp_probe\n");
  558 END_DEBUG
  559 
  560         pa = device_get_parent(dev);
  561         if(device_get_unit(dev) != device_get_unit(pa)){
  562                 return(ENXIO);
  563         }
  564 
  565         device_set_desc(dev, "SBP-2/SCSI over FireWire");
  566 
  567 #if 0
  568         if (bootverbose)
  569                 debug = bootverbose;
  570 #endif
  571 
  572         return (0);
  573 }
  574 #elif defined(__NetBSD__)
  575 int
  576 sbpmatch(struct device *parent, struct cfdata *cf, void *aux)
  577 {
  578         struct fw_attach_args *fwa = aux;
  579 
  580         if (strcmp(fwa->name, "sbp") == 0)
  581                 return (1);
  582         return (0);
  583 }
  584 #endif
  585 
  586 static void
  587 sbp_show_sdev_info(struct sbp_dev *sdev, int new)
  588 {
  589         struct fw_device *fwdev;
  590 
  591         printf("%s:%d:%d ",
  592                 device_get_nameunit(sdev->target->sbp->fd.dev),
  593                 sdev->target->target_id,
  594                 sdev->lun_id
  595         );
  596         if (new == 2) {
  597                 return;
  598         }
  599         fwdev = sdev->target->fwdev;
  600         printf("ordered:%d type:%d EUI:%08x%08x node:%d "
  601                 "speed:%d maxrec:%d",
  602                 (sdev->type & 0x40) >> 6,
  603                 (sdev->type & 0x1f),
  604                 fwdev->eui.hi,
  605                 fwdev->eui.lo,
  606                 fwdev->dst,
  607                 fwdev->speed,
  608                 fwdev->maxrec
  609         );
  610         if (new)
  611                 printf(" new!\n");
  612         else
  613                 printf("\n");
  614         sbp_show_sdev_info(sdev, 2);
  615         printf("'%s' '%s' '%s'\n", sdev->vendor, sdev->product, sdev->revision);
  616 }
  617 
  618 static void
  619 sbp_alloc_lun(struct sbp_target *target)
  620 {
  621         struct crom_context cc;
  622         struct csrreg *reg;
  623         struct sbp_dev *sdev, **newluns;
  624         struct sbp_softc *sbp;
  625         int maxlun, lun, i;
  626 
  627         sbp = target->sbp;
  628         crom_init_context(&cc, target->fwdev->csrrom);
  629         /* XXX shoud parse appropriate unit directories only */
  630         maxlun = -1;
  631         while (cc.depth >= 0) {
  632                 reg = crom_search_key(&cc, CROM_LUN);
  633                 if (reg == NULL)
  634                         break;
  635                 lun = reg->val & 0xffff;
  636 SBP_DEBUG(0)
  637                 printf("target %d lun %d found\n", target->target_id, lun);
  638 END_DEBUG
  639                 if (maxlun < lun)
  640                         maxlun = lun;
  641                 crom_next(&cc);
  642         }
  643         if (maxlun < 0)
  644                 printf("%s:%d no LUN found\n",
  645                     device_get_nameunit(target->sbp->fd.dev),
  646                     target->target_id);
  647 
  648         maxlun ++;
  649         if (maxlun >= SBP_NUM_LUNS)
  650                 maxlun = SBP_NUM_LUNS;
  651 
  652         /* Invalidiate stale devices */
  653         for (lun = 0; lun < target->num_lun; lun ++) {
  654                 sdev = target->luns[lun];
  655                 if (sdev == NULL)
  656                         continue;
  657                 sdev->flags &= ~VALID_LUN;
  658                 if (lun >= maxlun) {
  659                         /* lost device */
  660                         SBP_DETACH_SDEV(sdev);
  661                         sbp_free_sdev(sdev);
  662                 }
  663         }
  664 
  665         /* Reallocate */
  666         if (maxlun != target->num_lun) {
  667                 newluns = (struct sbp_dev **) realloc(target->luns,
  668                     sizeof(struct sbp_dev *) * maxlun,
  669                     M_SBP, M_NOWAIT | M_ZERO);
  670                 
  671                 if (newluns == NULL) {
  672                         printf("%s: realloc failed\n", __func__);
  673                         newluns = target->luns;
  674                         maxlun = target->num_lun;
  675                 }
  676 
  677                 /*
  678                  * We must zero the extended region for the case
  679                  * realloc() doesn't allocate new buffer.
  680                  */
  681                 if (maxlun > target->num_lun)
  682                         bzero(&newluns[target->num_lun],
  683                             sizeof(struct sbp_dev *) *
  684                             (maxlun - target->num_lun));
  685 
  686                 target->luns = newluns;
  687                 target->num_lun = maxlun;
  688         }
  689 
  690         crom_init_context(&cc, target->fwdev->csrrom);
  691         while (cc.depth >= 0) {
  692                 int new = 0;
  693 
  694                 reg = crom_search_key(&cc, CROM_LUN);
  695                 if (reg == NULL)
  696                         break;
  697                 lun = reg->val & 0xffff;
  698                 if (lun >= SBP_NUM_LUNS) {
  699                         printf("too large lun %d\n", lun);
  700                         goto next;
  701                 }
  702 
  703                 sdev = target->luns[lun];
  704                 if (sdev == NULL) {
  705                         sdev = malloc(sizeof(struct sbp_dev),
  706                             M_SBP, M_NOWAIT | M_ZERO);
  707                         if (sdev == NULL) {
  708                                 printf("%s: malloc failed\n", __func__);
  709                                 goto next;
  710                         }
  711                         target->luns[lun] = sdev;
  712                         sdev->lun_id = lun;
  713                         sdev->target = target;
  714                         STAILQ_INIT(&sdev->ocbs);
  715                         CALLOUT_INIT(&sdev->login_callout);
  716                         sdev->status = SBP_DEV_RESET;
  717                         new = 1;
  718                         SBP_DEVICE_PREATTACH();
  719                 }
  720                 sdev->flags |= VALID_LUN;
  721                 sdev->type = (reg->val & 0xff0000) >> 16;
  722 
  723                 if (new == 0)
  724                         goto next;
  725 
  726                 fwdma_malloc(sbp->fd.fc, 
  727                         /* alignment */ sizeof(uint32_t),
  728                         SBP_DMA_SIZE, &sdev->dma, BUS_DMA_NOWAIT);
  729                 if (sdev->dma.v_addr == NULL) {
  730                         printf("%s: dma space allocation failed\n",
  731                                                         __func__);
  732                         free(sdev, M_SBP);
  733                         target->luns[lun] = NULL;
  734                         goto next;
  735                 }
  736                 sdev->login = (struct sbp_login_res *) sdev->dma.v_addr;
  737                 sdev->ocb = (struct sbp_ocb *)
  738                                 ((char *)sdev->dma.v_addr + SBP_LOGIN_SIZE);
  739                 bzero((char *)sdev->ocb,
  740                         sizeof (struct sbp_ocb) * SBP_QUEUE_LEN);
  741 
  742                 STAILQ_INIT(&sdev->free_ocbs);
  743                 for (i = 0; i < SBP_QUEUE_LEN; i++) {
  744                         struct sbp_ocb *ocb;
  745                         ocb = &sdev->ocb[i];
  746                         ocb->bus_addr = sdev->dma.bus_addr
  747                                 + SBP_LOGIN_SIZE
  748                                 + sizeof(struct sbp_ocb) * i
  749                                 + offsetof(struct sbp_ocb, orb[0]);
  750                         if (fw_bus_dmamap_create(sbp->dmat, 0, &ocb->dmamap)) {
  751                                 printf("sbp_attach: cannot create dmamap\n");
  752                                 /* XXX */
  753                                 goto next;
  754                         }
  755                         sbp_free_ocb(sdev, ocb);
  756                 }
  757 next:
  758                 crom_next(&cc);
  759         }
  760 
  761         for (lun = 0; lun < target->num_lun; lun ++) {
  762                 sdev = target->luns[lun];
  763                 if (sdev != NULL && (sdev->flags & VALID_LUN) == 0) {
  764                         SBP_DETACH_SDEV(sdev);
  765                         sbp_free_sdev(sdev);
  766                         target->luns[lun] = NULL;
  767                 }
  768         }
  769 }
  770 
  771 static struct sbp_target *
  772 sbp_alloc_target(struct sbp_softc *sbp, struct fw_device *fwdev)
  773 {
  774         struct sbp_target *target;
  775         struct crom_context cc;
  776         struct csrreg *reg;
  777 
  778 SBP_DEBUG(1)
  779         printf("sbp_alloc_target\n");
  780 END_DEBUG
  781         /* new target */
  782         target = &sbp->target;
  783         target->sbp = sbp;
  784         target->fwdev = fwdev;
  785         target->target_id = 0;
  786         /* XXX we may want to reload mgm port after each bus reset */
  787         /* XXX there might be multiple management agents */
  788         crom_init_context(&cc, target->fwdev->csrrom);
  789         reg = crom_search_key(&cc, CROM_MGM);
  790         if (reg == NULL || reg->val == 0) {
  791                 printf("NULL management address\n");
  792                 target->fwdev = NULL;
  793                 return NULL;
  794         }
  795         target->mgm_hi = 0xffff;
  796         target->mgm_lo = 0xf0000000 | (reg->val << 2);
  797         target->mgm_ocb_cur = NULL;
  798 SBP_DEBUG(1)
  799         printf("target: mgm_port: %x\n", target->mgm_lo);
  800 END_DEBUG
  801         STAILQ_INIT(&target->xferlist);
  802         target->n_xfer = 0;
  803         STAILQ_INIT(&target->mgm_ocb_queue);
  804         CALLOUT_INIT(&target->mgm_ocb_timeout);
  805         CALLOUT_INIT(&target->scan_callout);
  806 
  807         target->luns = NULL;
  808         target->num_lun = 0;
  809         return target;
  810 }
  811 
  812 static void
  813 sbp_probe_lun(struct sbp_dev *sdev)
  814 {
  815         struct fw_device *fwdev;
  816         struct crom_context c, *cc = &c;
  817         struct csrreg *reg;
  818 
  819         bzero(sdev->vendor, sizeof(sdev->vendor));
  820         bzero(sdev->product, sizeof(sdev->product));
  821 
  822         fwdev = sdev->target->fwdev;
  823         crom_init_context(cc, fwdev->csrrom);
  824         /* get vendor string */
  825         crom_search_key(cc, CSRKEY_VENDOR);
  826         crom_next(cc);
  827         crom_parse_text(cc, sdev->vendor, sizeof(sdev->vendor));
  828         /* skip to the unit directory for SBP-2 */
  829         while ((reg = crom_search_key(cc, CSRKEY_VER)) != NULL) {
  830                 if (reg->val == CSRVAL_T10SBP2)
  831                         break;
  832                 crom_next(cc);
  833         }
  834         /* get firmware revision */
  835         reg = crom_search_key(cc, CSRKEY_FIRM_VER);
  836         if (reg != NULL)
  837                 snprintf(sdev->revision, sizeof(sdev->revision),
  838                                                 "%06x", reg->val);
  839         /* get product string */
  840         crom_search_key(cc, CSRKEY_MODEL);
  841         crom_next(cc);
  842         crom_parse_text(cc, sdev->product, sizeof(sdev->product));
  843 }
  844 
  845 static void
  846 sbp_login_callout(void *arg)
  847 {
  848         struct sbp_dev *sdev = (struct sbp_dev *)arg;
  849         sbp_mgm_orb(sdev, ORB_FUN_LGI, NULL);
  850 }
  851 
  852 static void
  853 sbp_login(struct sbp_dev *sdev)
  854 {
  855         struct timeval delta;
  856         struct timeval t;
  857         int ticks = 0;
  858 
  859         microtime(&delta);
  860         timevalsub(&delta, &sdev->target->sbp->last_busreset);
  861         t.tv_sec = login_delay / 1000;
  862         t.tv_usec = (login_delay % 1000) * 1000;
  863         timevalsub(&t, &delta);
  864         if (t.tv_sec >= 0 && t.tv_usec > 0)
  865                 ticks = (t.tv_sec * 1000 + t.tv_usec / 1000) * hz / 1000;
  866 SBP_DEBUG(0)
  867         printf("%s: sec = %ld usec = %ld ticks = %d\n", __func__,
  868             t.tv_sec, t.tv_usec, ticks);
  869 END_DEBUG
  870         callout_reset(&sdev->login_callout, ticks,
  871                         sbp_login_callout, (void *)(sdev));
  872 }
  873 
  874 static void
  875 sbp_probe_target(void *arg)
  876 {
  877         struct sbp_target *target = (struct sbp_target *)arg;
  878         struct sbp_softc *sbp;
  879         struct sbp_dev *sdev;
  880         struct firewire_comm *fc;
  881         int i;
  882 
  883 SBP_DEBUG(1)
  884         printf("sbp_probe_target %d\n", target->target_id);
  885 END_DEBUG
  886 
  887         sbp = target->sbp;
  888         fc = target->sbp->fd.fc;
  889         sbp_alloc_lun(target);
  890 
  891         /* XXX untimeout mgm_ocb and dequeue */
  892         for (i=0; i < target->num_lun; i++) {
  893                 sdev = target->luns[i];
  894                 if (sdev == NULL)
  895                         continue;
  896                 if (sdev->status != SBP_DEV_DEAD) {
  897                         if (SBP_DEVICE(sdev) != NULL) {
  898                                 SBP_DEVICE_FREEZE(sdev, 1);
  899                                 sdev->freeze ++;
  900                         }
  901                         sbp_probe_lun(sdev);
  902 SBP_DEBUG(0)
  903                         sbp_show_sdev_info(sdev, 
  904                                         (sdev->status == SBP_DEV_RESET));
  905 END_DEBUG
  906 
  907                         sbp_abort_all_ocbs(sdev, XS_SCSI_BUS_RESET);
  908                         switch (sdev->status) {
  909                         case SBP_DEV_RESET:
  910                                 /* new or revived target */
  911                                 if (auto_login)
  912                                         sbp_login(sdev);
  913                                 break;
  914                         case SBP_DEV_TOATTACH:
  915                         case SBP_DEV_PROBE:
  916                         case SBP_DEV_ATTACHED:
  917                         case SBP_DEV_RETRY:
  918                         default:
  919                                 sbp_mgm_orb(sdev, ORB_FUN_RCN, NULL);
  920                                 break;
  921                         }
  922                 } else {
  923                         switch (sdev->status) {
  924                         case SBP_DEV_ATTACHED:
  925 SBP_DEBUG(0)
  926                                 /* the device has gone */
  927                                 sbp_show_sdev_info(sdev, 2);
  928                                 printf("lost target\n");
  929 END_DEBUG
  930                                 if (SBP_DEVICE(sdev) != NULL) {
  931                                         SBP_DEVICE_FREEZE(sdev, 1);
  932                                         sdev->freeze ++;
  933                                 }
  934                                 sdev->status = SBP_DEV_RETRY;
  935                                 sbp_abort_all_ocbs(sdev, XS_SCSI_BUS_RESET);
  936                                 break;
  937                         case SBP_DEV_PROBE:
  938                         case SBP_DEV_TOATTACH:
  939                                 sdev->status = SBP_DEV_RESET;
  940                                 break;
  941                         case SBP_DEV_RETRY:
  942                         case SBP_DEV_RESET:
  943                         case SBP_DEV_DEAD:
  944                                 break;
  945                         }
  946                 }
  947         }
  948 }
  949 
  950 #define SBP_FWDEV_ALIVE(fwdev) (((fwdev)->status == FWDEVATTACHED) \
  951         && crom_has_specver((fwdev)->csrrom, CSRVAL_ANSIT10, CSRVAL_T10SBP2))
  952 
  953 static void
  954 sbp_post_busreset(void *arg)
  955 {
  956         struct sbp_softc *sbp = (struct sbp_softc *)arg;
  957         struct sbp_target *target = &sbp->target;
  958         struct fw_device *fwdev = target->fwdev;
  959         int alive;
  960 
  961         alive = SBP_FWDEV_ALIVE(fwdev);
  962 SBP_DEBUG(0)
  963         printf("sbp_post_busreset\n");
  964         if (!alive)
  965                 printf("not alive\n");
  966 END_DEBUG
  967         microtime(&sbp->last_busreset);
  968 
  969         if (!alive)
  970                 return;
  971 
  972         SBP_BUS_FREEZE(sbp);
  973 }
  974 
  975 static void
  976 sbp_post_explore(void *arg)
  977 {
  978         struct sbp_softc *sbp = (struct sbp_softc *)arg;
  979         struct sbp_target *target = &sbp->target;
  980         struct fw_device *fwdev = target->fwdev;
  981         int alive;
  982 
  983         alive = SBP_FWDEV_ALIVE(fwdev);
  984 SBP_DEBUG(0)
  985         printf("sbp_post_explore (sbp_cold=%d)\n", sbp_cold);
  986         if (!alive)
  987                 printf("not alive\n");
  988 END_DEBUG
  989         if (!alive)
  990                 return;
  991 
  992         if (sbp_cold > 0)
  993                 sbp_cold --;
  994 
  995 #if 0
  996         /*
  997          * XXX don't let CAM the bus rest.
  998          * CAM tries to do something with freezed (DEV_RETRY) devices.
  999          */
 1000         xpt_async(AC_BUS_RESET, sbp->path, /*arg*/ NULL);
 1001 #endif
 1002 
 1003 SBP_DEBUG(0)
 1004         printf("sbp_post_explore: EUI:%08x%08x ", fwdev->eui.hi, fwdev->eui.lo);
 1005 END_DEBUG
 1006         sbp_probe_target((void *)target);
 1007         if (target->num_lun == 0)
 1008                 sbp_free_target(target);
 1009 
 1010         SBP_BUS_THAW(sbp);
 1011 }
 1012 
 1013 #if NEED_RESPONSE
 1014 static void
 1015 sbp_loginres_callback(struct fw_xfer *xfer){
 1016         int s;
 1017         struct sbp_dev *sdev;
 1018         sdev = (struct sbp_dev *)xfer->sc;
 1019 SBP_DEBUG(1)
 1020         sbp_show_sdev_info(sdev, 2);
 1021         printf("sbp_loginres_callback\n");
 1022 END_DEBUG
 1023         /* recycle */
 1024         s = splfw();
 1025         STAILQ_INSERT_TAIL(&sdev->target->sbp->fwb.xferlist, xfer, link);
 1026         splx(s);
 1027         return;
 1028 }
 1029 #endif
 1030 
 1031 static inline void
 1032 sbp_xfer_free(struct fw_xfer *xfer)
 1033 {
 1034         struct sbp_dev *sdev;
 1035         int s;
 1036 
 1037         sdev = (struct sbp_dev *)xfer->sc;
 1038         fw_xfer_unload(xfer);
 1039         s = splfw();
 1040         STAILQ_INSERT_TAIL(&sdev->target->xferlist, xfer, link);
 1041         splx(s);
 1042 }
 1043 
 1044 static void
 1045 sbp_reset_start_callback(struct fw_xfer *xfer)
 1046 {
 1047         struct sbp_dev *tsdev, *sdev = (struct sbp_dev *)xfer->sc;
 1048         struct sbp_target *target = sdev->target;
 1049         int i;
 1050 
 1051         if (xfer->resp != 0) {
 1052                 sbp_show_sdev_info(sdev, 2);
 1053                 printf("sbp_reset_start failed: resp=%d\n", xfer->resp);
 1054         }
 1055 
 1056         for (i = 0; i < target->num_lun; i++) {
 1057                 tsdev = target->luns[i];
 1058                 if (tsdev != NULL && tsdev->status == SBP_DEV_LOGIN)
 1059                         sbp_login(tsdev);
 1060         }
 1061 }
 1062 
 1063 static void
 1064 sbp_reset_start(struct sbp_dev *sdev)
 1065 {
 1066         struct fw_xfer *xfer;
 1067         struct fw_pkt *fp;
 1068 
 1069 SBP_DEBUG(0)
 1070         sbp_show_sdev_info(sdev, 2);
 1071         printf("sbp_reset_start\n");
 1072 END_DEBUG
 1073 
 1074         xfer = sbp_write_cmd(sdev, FWTCODE_WREQQ, 0);
 1075         xfer->hand = sbp_reset_start_callback;
 1076         fp = &xfer->send.hdr;
 1077         fp->mode.wreqq.dest_hi = 0xffff;
 1078         fp->mode.wreqq.dest_lo = 0xf0000000 | RESET_START;
 1079         fp->mode.wreqq.data = htonl(0xf);
 1080         fw_asyreq(xfer->fc, -1, xfer);
 1081 }
 1082 
 1083 static void
 1084 sbp_mgm_callback(struct fw_xfer *xfer)
 1085 {
 1086         struct sbp_dev *sdev;
 1087         int resp;
 1088 
 1089         sdev = (struct sbp_dev *)xfer->sc;
 1090 
 1091 SBP_DEBUG(1)
 1092         sbp_show_sdev_info(sdev, 2);
 1093         printf("sbp_mgm_callback\n");
 1094 END_DEBUG
 1095         resp = xfer->resp;
 1096         sbp_xfer_free(xfer);
 1097 #if 0
 1098         if (resp != 0) {
 1099                 sbp_show_sdev_info(sdev, 2);
 1100                 printf("management ORB failed(%d) ... RESET_START\n", resp);
 1101                 sbp_reset_start(sdev);
 1102         }
 1103 #endif
 1104         return;
 1105 }
 1106 
 1107 #if defined(__FreeBSD__)
 1108 static struct sbp_dev *
 1109 sbp_next_dev(struct sbp_target *target, int lun)
 1110 {
 1111         struct sbp_dev **sdevp;
 1112         int i;
 1113 
 1114         for (i = lun, sdevp = &target->luns[lun]; i < target->num_lun;
 1115             i++, sdevp++)
 1116                 if (*sdevp != NULL && (*sdevp)->status == SBP_DEV_PROBE)
 1117                         return(*sdevp);
 1118         return(NULL);
 1119 }
 1120 
 1121 #define SCAN_PRI 1
 1122 static void
 1123 sbp_cam_scan_lun(struct cam_periph *periph, sbp_scsi_xfer *sxfer)
 1124 {
 1125         struct sbp_target *target;
 1126         struct sbp_dev *sdev;
 1127 
 1128         sdev = (struct sbp_dev *) sxfer->ccb_h.ccb_sdev_ptr;
 1129         target = sdev->target;
 1130 SBP_DEBUG(0)
 1131         sbp_show_sdev_info(sdev, 2);
 1132         printf("sbp_cam_scan_lun\n");
 1133 END_DEBUG
 1134         if ((SCSI_XFER_ERROR(sxfer) & CAM_STATUS_MASK) == XS_REQ_CMP) {
 1135                 sdev->status = SBP_DEV_ATTACHED;
 1136         } else {
 1137                 sbp_show_sdev_info(sdev, 2);
 1138                 printf("scan failed\n");
 1139         }
 1140         sdev = sbp_next_dev(target, sdev->lun_id + 1);
 1141         if (sdev == NULL) {
 1142                 free(sxfer, M_SBP);
 1143                 return;
 1144         }
 1145         /* reuse sxfer */
 1146         xpt_setup_ccb(&sxfer->ccb_h, sdev->path, SCAN_PRI);
 1147         sxfer->ccb_h.ccb_sdev_ptr = sdev;
 1148         xpt_action(sxfer);
 1149         xpt_release_devq(sdev->path, sdev->freeze, TRUE);
 1150         sdev->freeze = 1;
 1151 }
 1152 
 1153 static void
 1154 sbp_cam_scan_target(void *arg)
 1155 {
 1156         struct sbp_target *target = (struct sbp_target *)arg;
 1157         struct sbp_dev *sdev;
 1158         sbp_scsi_xfer *sxfer;
 1159 
 1160         sdev = sbp_next_dev(target, 0);
 1161         if (sdev == NULL) {
 1162                 printf("sbp_cam_scan_target: nothing to do for target%d\n",
 1163                                                         target->target_id);
 1164                 return;
 1165         }
 1166 SBP_DEBUG(0)
 1167         sbp_show_sdev_info(sdev, 2);
 1168         printf("sbp_cam_scan_target\n");
 1169 END_DEBUG
 1170         sxfer = malloc(sizeof(sbp_scsi_xfer), M_SBP, M_NOWAIT | M_ZERO);
 1171         if (sxfer == NULL) {
 1172                 printf("sbp_cam_scan_target: malloc failed\n");
 1173                 return;
 1174         }
 1175         xpt_setup_ccb(&sxfer->ccb_h, sdev->path, SCAN_PRI);
 1176         sxfer->ccb_h.func_code = XPT_SCAN_LUN;
 1177         sxfer->ccb_h.cbfcnp = sbp_cam_scan_lun;
 1178         sxfer->ccb_h.flags |= CAM_DEV_QFREEZE;
 1179         sxfer->crcn.flags = CAM_FLAG_NONE;
 1180         sxfer->ccb_h.ccb_sdev_ptr = sdev;
 1181 
 1182         /* The scan is in progress now. */
 1183         xpt_action(sxfer);
 1184         xpt_release_devq(sdev->path, sdev->freeze, TRUE);
 1185         sdev->freeze = 1;
 1186 }
 1187 
 1188 static inline void
 1189 sbp_scan_dev(struct sbp_dev *sdev)
 1190 {
 1191         sdev->status = SBP_DEV_PROBE;
 1192         callout_reset(&sdev->target->scan_callout, scan_delay * hz / 1000,
 1193                         sbp_cam_scan_target, (void *)sdev->target);
 1194 }
 1195 #else
 1196 static void
 1197 fw_kthread_create0(void *arg)
 1198 {
 1199         struct sbp_softc *sbp = (struct sbp_softc *)arg;
 1200 
 1201         /* create thread */
 1202         if (kthread_create1(sbp_scsipi_scan_target,
 1203             &sbp->target, &sbp->proc, "sbp%d_attach",
 1204             device_unit(sbp->fd.dev))) {
 1205 
 1206                 device_printf(sbp->fd.dev, "unable to create thread");
 1207                 panic("fw_kthread_create");
 1208         }
 1209 }
 1210 
 1211 static void
 1212 sbp_scsipi_scan_target(void *arg)
 1213 {
 1214         struct sbp_target *target = (struct sbp_target *)arg;
 1215         struct sbp_softc *sbp = target->sbp;
 1216         struct sbp_dev *sdev;
 1217         struct scsipi_channel *chan = &sbp->sc_channel;
 1218         struct scsibus_softc *sc_bus = (struct scsibus_softc *)sbp->sc_bus;
 1219         int lun, yet;
 1220 
 1221         do {
 1222                 tsleep(target, PWAIT|PCATCH, "-", 0);
 1223                 yet = 0;
 1224 
 1225                 for (lun = 0; lun < target->num_lun; lun ++) {
 1226                         sdev = target->luns[lun];
 1227                         if (sdev == NULL)
 1228                                 continue;
 1229                         if (sdev->status != SBP_DEV_PROBE) {
 1230                                 yet ++;
 1231                                 continue;
 1232                         }
 1233 
 1234                         if (sdev->periph == NULL) {
 1235                                 if (chan->chan_nluns < target->num_lun)
 1236                                         chan->chan_nluns = target->num_lun;
 1237 
 1238                                 scsi_probe_bus(sc_bus,
 1239                                     target->target_id, sdev->lun_id);
 1240                                 sdev->periph = scsipi_lookup_periph(
 1241                                     chan, target->target_id, lun);
 1242                         }
 1243                         sdev->status = SBP_DEV_ATTACHED;
 1244                 }
 1245         } while (yet > 0);
 1246 
 1247         sbp->proc = NULL;
 1248         kthread_exit(0);
 1249 }
 1250 
 1251 static inline void
 1252 sbp_scan_dev(struct sbp_dev *sdev)
 1253 {
 1254         sdev->status = SBP_DEV_PROBE;
 1255         wakeup(sdev->target);
 1256 }
 1257 #endif
 1258 
 1259 
 1260 static void
 1261 sbp_do_attach(struct fw_xfer *xfer)
 1262 {
 1263         struct sbp_dev *sdev;
 1264         struct sbp_target *target;
 1265         struct sbp_softc *sbp;
 1266 
 1267         sdev = (struct sbp_dev *)xfer->sc;
 1268         target = sdev->target;
 1269         sbp = target->sbp;
 1270 
 1271 SBP_DEBUG(0)
 1272         sbp_show_sdev_info(sdev, 2);
 1273         printf("sbp_do_attach\n");
 1274 END_DEBUG
 1275         sbp_xfer_free(xfer);
 1276 
 1277 #if defined(__FreeBSD__)
 1278         if (sdev->path == NULL)
 1279                 xpt_create_path(&sdev->path, xpt_periph,
 1280                         cam_sim_path(target->sbp->sim),
 1281                         target->target_id, sdev->lun_id);
 1282 
 1283         /*
 1284          * Let CAM scan the bus if we are in the boot process.
 1285          * XXX xpt_scan_bus cannot detect LUN larger than 0
 1286          * if LUN 0 doesn't exists.
 1287          */
 1288         if (sbp_cold > 0) {
 1289                 sdev->status = SBP_DEV_ATTACHED;
 1290                 return;
 1291         }
 1292 #endif
 1293 
 1294         sbp_scan_dev(sdev);
 1295         return;
 1296 }
 1297 
 1298 static void
 1299 sbp_agent_reset_callback(struct fw_xfer *xfer)
 1300 {
 1301         struct sbp_dev *sdev;
 1302 
 1303         sdev = (struct sbp_dev *)xfer->sc;
 1304 SBP_DEBUG(1)
 1305         sbp_show_sdev_info(sdev, 2);
 1306         printf("%s\n", __func__);
 1307 END_DEBUG
 1308         if (xfer->resp != 0) {
 1309                 sbp_show_sdev_info(sdev, 2);
 1310                 printf("%s: resp=%d\n", __func__, xfer->resp);
 1311         }
 1312 
 1313         sbp_xfer_free(xfer);
 1314         if (SBP_DEVICE(sdev)) {
 1315                 SBP_DEVICE_THAW(sdev, sdev->freeze);
 1316                 sdev->freeze = 0;
 1317         }
 1318 }
 1319 
 1320 static void
 1321 sbp_agent_reset(struct sbp_dev *sdev)
 1322 {
 1323         struct fw_xfer *xfer;
 1324         struct fw_pkt *fp;
 1325 
 1326 SBP_DEBUG(0)
 1327         sbp_show_sdev_info(sdev, 2);
 1328         printf("sbp_agent_reset\n");
 1329 END_DEBUG
 1330         xfer = sbp_write_cmd(sdev, FWTCODE_WREQQ, 0x04);
 1331         if (xfer == NULL)
 1332                 return;
 1333         if (sdev->status == SBP_DEV_ATTACHED || sdev->status == SBP_DEV_PROBE)
 1334                 xfer->hand = sbp_agent_reset_callback;
 1335         else
 1336                 xfer->hand = sbp_do_attach;
 1337         fp = &xfer->send.hdr;
 1338         fp->mode.wreqq.data = htonl(0xf);
 1339         fw_asyreq(xfer->fc, -1, xfer);
 1340         sbp_abort_all_ocbs(sdev, XS_BDR_SENT);
 1341 }
 1342 
 1343 static void
 1344 sbp_busy_timeout_callback(struct fw_xfer *xfer)
 1345 {
 1346         struct sbp_dev *sdev;
 1347 
 1348         sdev = (struct sbp_dev *)xfer->sc;
 1349 SBP_DEBUG(1)
 1350         sbp_show_sdev_info(sdev, 2);
 1351         printf("sbp_busy_timeout_callback\n");
 1352 END_DEBUG
 1353         sbp_xfer_free(xfer);
 1354         sbp_agent_reset(sdev);
 1355 }
 1356 
 1357 static void
 1358 sbp_busy_timeout(struct sbp_dev *sdev)
 1359 {
 1360         struct fw_pkt *fp;
 1361         struct fw_xfer *xfer;
 1362 SBP_DEBUG(0)
 1363         sbp_show_sdev_info(sdev, 2);
 1364         printf("sbp_busy_timeout\n");
 1365 END_DEBUG
 1366         xfer = sbp_write_cmd(sdev, FWTCODE_WREQQ, 0);
 1367 
 1368         xfer->hand = sbp_busy_timeout_callback;
 1369         fp = &xfer->send.hdr;
 1370         fp->mode.wreqq.dest_hi = 0xffff;
 1371         fp->mode.wreqq.dest_lo = 0xf0000000 | BUSY_TIMEOUT;
 1372         fp->mode.wreqq.data = htonl((1 << (13+12)) | 0xf);
 1373         fw_asyreq(xfer->fc, -1, xfer);
 1374 }
 1375 
 1376 static void
 1377 sbp_orb_pointer_callback(struct fw_xfer *xfer)
 1378 {
 1379         struct sbp_dev *sdev;
 1380         sdev = (struct sbp_dev *)xfer->sc;
 1381 
 1382 SBP_DEBUG(1)
 1383         sbp_show_sdev_info(sdev, 2);
 1384         printf("%s\n", __func__);
 1385 END_DEBUG
 1386         if (xfer->resp != 0) {
 1387                 /* XXX */
 1388                 printf("%s: xfer->resp = %d\n", __func__, xfer->resp);
 1389         }
 1390         sbp_xfer_free(xfer);
 1391         sdev->flags &= ~ORB_POINTER_ACTIVE;
 1392 
 1393         if ((sdev->flags & ORB_POINTER_NEED) != 0) {
 1394                 struct sbp_ocb *ocb;
 1395 
 1396                 sdev->flags &= ~ORB_POINTER_NEED;
 1397                 ocb = STAILQ_FIRST(&sdev->ocbs);
 1398                 if (ocb != NULL)
 1399                         sbp_orb_pointer(sdev, ocb);
 1400         }
 1401         return;
 1402 }
 1403 
 1404 static void
 1405 sbp_orb_pointer(struct sbp_dev *sdev, struct sbp_ocb *ocb)
 1406 {
 1407         struct fw_xfer *xfer;
 1408         struct fw_pkt *fp;
 1409 SBP_DEBUG(1)
 1410         sbp_show_sdev_info(sdev, 2);
 1411         printf("%s: 0x%08x\n", __func__, (uint32_t)ocb->bus_addr);
 1412 END_DEBUG
 1413 
 1414         if ((sdev->flags & ORB_POINTER_ACTIVE) != 0) {
 1415 SBP_DEBUG(0)
 1416                 printf("%s: orb pointer active\n", __func__);
 1417 END_DEBUG
 1418                 sdev->flags |= ORB_POINTER_NEED;
 1419                 return;
 1420         }
 1421 
 1422         sdev->flags |= ORB_POINTER_ACTIVE;
 1423         xfer = sbp_write_cmd(sdev, FWTCODE_WREQB, 0x08);
 1424         if (xfer == NULL)
 1425                 return;
 1426         xfer->hand = sbp_orb_pointer_callback;
 1427 
 1428         fp = &xfer->send.hdr;
 1429         fp->mode.wreqb.len = 8;
 1430         fp->mode.wreqb.extcode = 0;
 1431         xfer->send.payload[0] = 
 1432                 htonl(((sdev->target->sbp->fd.fc->nodeid | FWLOCALBUS )<< 16));
 1433         xfer->send.payload[1] = htonl((uint32_t)ocb->bus_addr);
 1434 
 1435         if(fw_asyreq(xfer->fc, -1, xfer) != 0){
 1436                         sbp_xfer_free(xfer);
 1437                         SCSI_XFER_ERROR(ocb->sxfer) = XS_REQ_INVALID;
 1438                         SCSI_TRANSFER_DONE(ocb->sxfer);
 1439         }
 1440 }
 1441 
 1442 static void
 1443 sbp_doorbell_callback(struct fw_xfer *xfer)
 1444 {
 1445         struct sbp_dev *sdev;
 1446         sdev = (struct sbp_dev *)xfer->sc;
 1447 
 1448 SBP_DEBUG(1)
 1449         sbp_show_sdev_info(sdev, 2);
 1450         printf("sbp_doorbell_callback\n");
 1451 END_DEBUG
 1452         if (xfer->resp != 0) {
 1453                 /* XXX */
 1454                 printf("%s: xfer->resp = %d\n", __func__, xfer->resp);
 1455         }
 1456         sbp_xfer_free(xfer);
 1457         sdev->flags &= ~ORB_DOORBELL_ACTIVE;
 1458         if ((sdev->flags & ORB_DOORBELL_NEED) != 0) {
 1459                 sdev->flags &= ~ORB_DOORBELL_NEED;
 1460                 sbp_doorbell(sdev);
 1461         }
 1462         return;
 1463 }
 1464 
 1465 static void
 1466 sbp_doorbell(struct sbp_dev *sdev)
 1467 {
 1468         struct fw_xfer *xfer;
 1469         struct fw_pkt *fp;
 1470 SBP_DEBUG(1)
 1471         sbp_show_sdev_info(sdev, 2);
 1472         printf("sbp_doorbell\n");
 1473 END_DEBUG
 1474 
 1475         if ((sdev->flags & ORB_DOORBELL_ACTIVE) != 0) {
 1476                 sdev->flags |= ORB_DOORBELL_NEED;
 1477                 return;
 1478         }
 1479         sdev->flags |= ORB_DOORBELL_ACTIVE;
 1480         xfer = sbp_write_cmd(sdev, FWTCODE_WREQQ, 0x10);
 1481         if (xfer == NULL)
 1482                 return;
 1483         xfer->hand = sbp_doorbell_callback;
 1484         fp = &xfer->send.hdr;
 1485         fp->mode.wreqq.data = htonl(0xf);
 1486         fw_asyreq(xfer->fc, -1, xfer);
 1487 }
 1488 
 1489 static struct fw_xfer *
 1490 sbp_write_cmd(struct sbp_dev *sdev, int tcode, int offset)
 1491 {
 1492         struct fw_xfer *xfer;
 1493         struct fw_pkt *fp;
 1494         struct sbp_target *target;
 1495         int s, new = 0;
 1496 
 1497         target = sdev->target;
 1498         s = splfw();
 1499         xfer = STAILQ_FIRST(&target->xferlist);
 1500         if (xfer == NULL) {
 1501                 if (target->n_xfer > 5 /* XXX */) {
 1502                         printf("sbp: no more xfer for this target\n");
 1503                         splx(s);
 1504                         return(NULL);
 1505                 }
 1506                 xfer = fw_xfer_alloc_buf(M_SBP, 8, 0);
 1507                 if(xfer == NULL){
 1508                         printf("sbp: fw_xfer_alloc_buf failed\n");
 1509                         splx(s);
 1510                         return NULL;
 1511                 }
 1512                 target->n_xfer ++;
 1513                 if (debug)
 1514                         printf("sbp: alloc %d xfer\n", target->n_xfer);
 1515                 new = 1;
 1516         } else {
 1517                 STAILQ_REMOVE_HEAD(&target->xferlist, link);
 1518         }
 1519         splx(s);
 1520 
 1521         microtime(&xfer->tv);
 1522 
 1523         if (new) {
 1524                 xfer->recv.pay_len = 0;
 1525                 xfer->send.spd = min(sdev->target->fwdev->speed, max_speed);
 1526                 xfer->fc = sdev->target->sbp->fd.fc;
 1527         }
 1528 
 1529         if (tcode == FWTCODE_WREQB)
 1530                 xfer->send.pay_len = 8;
 1531         else
 1532                 xfer->send.pay_len = 0;
 1533 
 1534         xfer->sc = (caddr_t)sdev;
 1535         fp = &xfer->send.hdr;
 1536         fp->mode.wreqq.dest_hi = sdev->login->cmd_hi;
 1537         fp->mode.wreqq.dest_lo = sdev->login->cmd_lo + offset;
 1538         fp->mode.wreqq.tlrt = 0;
 1539         fp->mode.wreqq.tcode = tcode;
 1540         fp->mode.wreqq.pri = 0;
 1541         fp->mode.wreqq.dst = FWLOCALBUS | sdev->target->fwdev->dst;
 1542 
 1543         return xfer;
 1544 
 1545 }
 1546 
 1547 static void
 1548 sbp_mgm_orb(struct sbp_dev *sdev, int func, struct sbp_ocb *aocb)
 1549 {
 1550         struct fw_xfer *xfer;
 1551         struct fw_pkt *fp;
 1552         struct sbp_ocb *ocb;
 1553         struct sbp_target *target;
 1554         int s, nid, dv_unit;
 1555 
 1556         target = sdev->target;
 1557         nid = target->sbp->fd.fc->nodeid | FWLOCALBUS;
 1558         dv_unit = device_get_unit(target->sbp->fd.dev);
 1559 
 1560         s = splfw();
 1561         if (func == ORB_FUN_RUNQUEUE) {
 1562                 ocb = STAILQ_FIRST(&target->mgm_ocb_queue);
 1563                 if (target->mgm_ocb_cur != NULL || ocb == NULL) {
 1564                         splx(s);
 1565                         return;
 1566                 }
 1567                 STAILQ_REMOVE_HEAD(&target->mgm_ocb_queue, ocb);
 1568                 goto start;
 1569         }
 1570         if ((ocb = sbp_get_ocb(sdev)) == NULL) {
 1571                 splx(s);
 1572                 /* XXX */
 1573                 return;
 1574         }
 1575         ocb->flags = OCB_ACT_MGM;
 1576         ocb->sdev = sdev;
 1577 
 1578         bzero((void *)ocb->orb, sizeof(ocb->orb));
 1579         ocb->orb[6] = htonl((nid << 16) | SBP_BIND_HI);
 1580         ocb->orb[7] = htonl(SBP_DEV2ADDR(dv_unit, sdev->lun_id));
 1581 
 1582 SBP_DEBUG(0)
 1583         sbp_show_sdev_info(sdev, 2);
 1584         printf("%s\n", orb_fun_name[(func>>16)&0xf]);
 1585 END_DEBUG
 1586         switch (func) {
 1587         case ORB_FUN_LGI:
 1588                 ocb->orb[0] = ocb->orb[1] = 0; /* password */
 1589                 ocb->orb[2] = htonl(nid << 16);
 1590                 ocb->orb[3] = htonl(sdev->dma.bus_addr);
 1591                 ocb->orb[4] = htonl(ORB_NOTIFY | sdev->lun_id);
 1592                 if (ex_login)
 1593                         ocb->orb[4] |= htonl(ORB_EXV);
 1594                 ocb->orb[5] = htonl(SBP_LOGIN_SIZE);
 1595                 break;
 1596         case ORB_FUN_ATA:
 1597                 ocb->orb[0] = htonl((0 << 16) | 0);
 1598                 ocb->orb[1] = htonl(aocb->bus_addr & 0xffffffff);
 1599                 /* fall through */
 1600         case ORB_FUN_RCN:
 1601         case ORB_FUN_LGO:
 1602         case ORB_FUN_LUR:
 1603         case ORB_FUN_RST:
 1604         case ORB_FUN_ATS:
 1605                 ocb->orb[4] = htonl(ORB_NOTIFY | func | sdev->login->id);
 1606                 break;
 1607         }
 1608 
 1609         if (target->mgm_ocb_cur != NULL) {
 1610                 /* there is a standing ORB */
 1611                 STAILQ_INSERT_TAIL(&sdev->target->mgm_ocb_queue, ocb, ocb);
 1612                 splx(s);
 1613                 return;
 1614         }
 1615 start:
 1616         target->mgm_ocb_cur = ocb;
 1617         splx(s);
 1618 
 1619         callout_reset(&target->mgm_ocb_timeout, 5*hz,
 1620                                 sbp_mgm_timeout, (caddr_t)ocb);
 1621         xfer = sbp_write_cmd(sdev, FWTCODE_WREQB, 0);
 1622         if(xfer == NULL){
 1623                 return;
 1624         }
 1625         xfer->hand = sbp_mgm_callback;
 1626 
 1627         fp = &xfer->send.hdr;
 1628         fp->mode.wreqb.dest_hi = sdev->target->mgm_hi;
 1629         fp->mode.wreqb.dest_lo = sdev->target->mgm_lo;
 1630         fp->mode.wreqb.len = 8;
 1631         fp->mode.wreqb.extcode = 0;
 1632         xfer->send.payload[0] = htonl(nid << 16);
 1633         xfer->send.payload[1] = htonl(ocb->bus_addr & 0xffffffff);
 1634 SBP_DEBUG(0)
 1635         sbp_show_sdev_info(sdev, 2);
 1636         printf("mgm orb: %08x\n", (uint32_t)ocb->bus_addr);
 1637 END_DEBUG
 1638 
 1639         /* cache writeback & invalidate(required ORB_FUN_LGI func) */
 1640         /* when abort_ocb, should sync POST ope ? */
 1641         fwdma_sync(&sdev->dma, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 1642         fw_asyreq(xfer->fc, -1, xfer);
 1643 }
 1644 
 1645 static void
 1646 sbp_print_scsi_cmd(struct sbp_ocb *ocb)
 1647 {
 1648 #if defined(__FreeBSD__)
 1649         struct ccb_scsiio *csio;
 1650 
 1651         csio = &ocb->sxfer->csio;
 1652 #endif
 1653         printf("%s:%d:%d XPT_SCSI_IO: "
 1654                 "cmd: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x"
 1655                 ", flags: 0x%02x, "
 1656                 "%db cmd/%db data/%db sense\n",
 1657                 device_get_nameunit(ocb->sdev->target->sbp->fd.dev),
 1658                 SCSI_XFER_TARGET(ocb->sxfer), SCSI_XFER_LUN(ocb->sxfer),
 1659                 SCSI_XFER_10BCMD_DUMP(ocb->sxfer),
 1660                 SCSI_XFER_DIR(ocb->sxfer),
 1661                 SCSI_XFER_CMDLEN(ocb->sxfer), SCSI_XFER_DATALEN(ocb->sxfer),
 1662                 SCSI_XFER_SENSELEN(ocb->sxfer));
 1663 }
 1664 
 1665 static void
 1666 sbp_scsi_status(struct sbp_status *sbp_status, struct sbp_ocb *ocb)
 1667 {
 1668         struct sbp_cmd_status *sbp_cmd_status;
 1669         scsi3_sense_data_t sense =
 1670             (scsi3_sense_data_t)SCSI_SENSE_DATA(ocb->sxfer);
 1671 
 1672         sbp_cmd_status = (struct sbp_cmd_status *)sbp_status->data;
 1673 
 1674 SBP_DEBUG(0)
 1675         sbp_print_scsi_cmd(ocb);
 1676         /* XXX need decode status */
 1677         sbp_show_sdev_info(ocb->sdev, 2);
 1678         printf("SCSI status %x sfmt %x valid %x key %x code %x qlfr %x len %d\n",
 1679                 sbp_cmd_status->status,
 1680                 sbp_cmd_status->sfmt,
 1681                 sbp_cmd_status->valid,
 1682                 sbp_cmd_status->s_key,
 1683                 sbp_cmd_status->s_code,
 1684                 sbp_cmd_status->s_qlfr,
 1685                 sbp_status->len
 1686         );
 1687 END_DEBUG
 1688 
 1689         switch (sbp_cmd_status->status) {
 1690         case SCSI_STATUS_CHECK_COND:
 1691         case SCSI_STATUS_BUSY:
 1692         case SCSI_STATUS_CMD_TERMINATED:
 1693                 if(sbp_cmd_status->sfmt == SBP_SFMT_CURR){
 1694                         sense->response_code = SSD_CURRENT_ERROR;
 1695                 }else{
 1696                         sense->response_code = SSD_DEFERRED_ERROR;
 1697                 }
 1698                 if(sbp_cmd_status->valid)
 1699                         sense->response_code |= SSD_RESPONSE_CODE_VALID;
 1700                 sense->flags = sbp_cmd_status->s_key;
 1701                 if(sbp_cmd_status->mark)
 1702                         sense->flags |= SSD_FILEMARK;
 1703                 if(sbp_cmd_status->eom)
 1704                         sense->flags |= SSD_EOM;
 1705                 if(sbp_cmd_status->ill_len)
 1706                         sense->flags |= SSD_ILI;
 1707 
 1708                 bcopy(&sbp_cmd_status->info, &sense->information[0], 4);
 1709 
 1710                 if (sbp_status->len <= 1)
 1711                         /* XXX not scsi status. shouldn't be happened */ 
 1712                         sense->asl = 0;
 1713                 else if (sbp_status->len <= 4)
 1714                         /* add_sense_code(_qual), info, cmd_spec_info */
 1715                         sense->asl = 6;
 1716                 else
 1717                         /* fru, sense_key_spec */
 1718                         sense->asl = 10;
 1719 
 1720                 bcopy(&sbp_cmd_status->cdb, &sense->csi[0], 4);
 1721 
 1722                 sense->asc = sbp_cmd_status->s_code;
 1723                 sense->ascq = sbp_cmd_status->s_qlfr;
 1724                 sense->fruc = sbp_cmd_status->fru;
 1725 
 1726                 bcopy(&sbp_cmd_status->s_keydep[0], &sense->sks[0], 3);
 1727                 SCSI_XFER_ERROR(ocb->sxfer) = XS_SENSE;
 1728                 SCSI_XFER_STATUS(ocb->sxfer) = sbp_cmd_status->status;
 1729 /*
 1730 {
 1731                 uint8_t j, *tmp;
 1732                 tmp = sense;
 1733                 for( j = 0 ; j < 32 ; j+=8){
 1734                         printf("sense %02x%02x %02x%02x %02x%02x %02x%02x\n", 
 1735                                 tmp[j], tmp[j+1], tmp[j+2], tmp[j+3],
 1736                                 tmp[j+4], tmp[j+5], tmp[j+6], tmp[j+7]);
 1737                 }
 1738 
 1739 }
 1740 */
 1741                 break;
 1742         default:
 1743                 sbp_show_sdev_info(ocb->sdev, 2);
 1744                 printf("sbp_scsi_status: unknown scsi status 0x%x\n",
 1745                                                 sbp_cmd_status->status);
 1746         }
 1747 }
 1748 
 1749 static void
 1750 sbp_fix_inq_data(struct sbp_ocb *ocb)
 1751 {
 1752         sbp_scsi_xfer *sxfer = ocb->sxfer;
 1753         struct sbp_dev *sdev;
 1754         scsi3_inquiry_data_t inq =
 1755             (scsi3_inquiry_data_t)SCSI_INQUIRY_DATA(sxfer);
 1756         sdev = ocb->sdev;
 1757 
 1758         if (SCSI_XFER_EVPD(sxfer))
 1759                 return;
 1760 SBP_DEBUG(1)
 1761         sbp_show_sdev_info(sdev, 2);
 1762         printf("sbp_fix_inq_data\n");
 1763 END_DEBUG
 1764         switch (inq->device & SID_TYPE) {
 1765         case T_DIRECT:
 1766 #if 0
 1767                 /* 
 1768                  * XXX Convert Direct Access device to RBC.
 1769                  * I've never seen FireWire DA devices which support READ_6.
 1770                  */
 1771                 if ((inq->device & SID_TYPE) == T_DIRECT)
 1772                         inq->device |= T_RBC; /*  T_DIRECT == 0 */
 1773 #endif
 1774                 /* fall through */
 1775         case T_RBC:
 1776                 /*
 1777                  * Override vendor/product/revision information.
 1778                  * Some devices sometimes return strange strings.
 1779                  */
 1780 #if 1
 1781                 bcopy(sdev->vendor, inq->vendor, sizeof(inq->vendor));
 1782                 bcopy(sdev->product, inq->product, sizeof(inq->product));
 1783                 bcopy(sdev->revision+2, inq->revision, sizeof(inq->revision));
 1784 #endif
 1785                 break;
 1786         }
 1787         /*
 1788          * Force to enable/disable tagged queuing.
 1789          * XXX CAM also checks SCP_QUEUE_DQUE flag in the control mode page.
 1790          */
 1791         if (sbp_tags > 0)
 1792                 inq->flags[1] |= SID_CmdQue;
 1793         else if (sbp_tags < 0)
 1794                 inq->flags[1] &= ~SID_CmdQue;
 1795 
 1796 }
 1797 
 1798 static void
 1799 sbp_recv1(struct fw_xfer *xfer)
 1800 {
 1801         struct fw_pkt *rfp;
 1802 #if NEED_RESPONSE
 1803         struct fw_pkt *sfp;
 1804 #endif
 1805         struct sbp_softc *sbp;
 1806         struct sbp_dev *sdev;
 1807         struct sbp_ocb *ocb;
 1808         struct sbp_login_res *login_res = NULL;
 1809         struct sbp_status *sbp_status;
 1810         struct sbp_target *target;
 1811         int     orb_fun, status_valid0, status_valid, l, reset_agent = 0;
 1812         uint32_t addr;
 1813 /*
 1814         uint32_t *ld;
 1815         ld = xfer->recv.buf;
 1816 printf("sbp %x %d %d %08x %08x %08x %08x\n",
 1817                         xfer->resp, xfer->recv.len, xfer->recv.off, ntohl(ld[0]), ntohl(ld[1]), ntohl(ld[2]), ntohl(ld[3]));
 1818 printf("sbp %08x %08x %08x %08x\n", ntohl(ld[4]), ntohl(ld[5]), ntohl(ld[6]), ntohl(ld[7]));
 1819 printf("sbp %08x %08x %08x %08x\n", ntohl(ld[8]), ntohl(ld[9]), ntohl(ld[10]), ntohl(ld[11]));
 1820 */
 1821         sbp = (struct sbp_softc *)xfer->sc;
 1822         if (xfer->resp != 0){
 1823                 printf("sbp_recv: xfer->resp = %d\n", xfer->resp);
 1824                 goto done0;
 1825         }
 1826         if (xfer->recv.payload == NULL){
 1827                 printf("sbp_recv: xfer->recv.payload == NULL\n");
 1828                 goto done0;
 1829         }
 1830         rfp = &xfer->recv.hdr;
 1831         if(rfp->mode.wreqb.tcode != FWTCODE_WREQB){
 1832                 printf("sbp_recv: tcode = %d\n", rfp->mode.wreqb.tcode);
 1833                 goto done0;
 1834         }
 1835         sbp_status = (struct sbp_status *)xfer->recv.payload;
 1836         addr = rfp->mode.wreqb.dest_lo;
 1837 SBP_DEBUG(2)
 1838         printf("received address 0x%x\n", addr);
 1839 END_DEBUG
 1840         target = &sbp->target;
 1841         l = SBP_ADDR2LUN(addr);
 1842         if (l >= target->num_lun || target->luns[l] == NULL) {
 1843                 device_printf(sbp->fd.dev,
 1844                         "sbp_recv1: invalid lun %d (target=%d)\n",
 1845                         l, target->target_id);
 1846                 goto done0;
 1847         }
 1848         sdev = target->luns[l];
 1849 
 1850         fwdma_sync(&sdev->dma, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
 1851 
 1852         ocb = NULL;
 1853         switch (sbp_status->src) {
 1854         case SRC_NEXT_EXISTS:
 1855         case SRC_NO_NEXT:
 1856                 /* check mgm_ocb_cur first */
 1857                 ocb  = target->mgm_ocb_cur;
 1858                 if (ocb != NULL) {
 1859                         if (OCB_MATCH(ocb, sbp_status)) {
 1860                                 callout_stop(&target->mgm_ocb_timeout);
 1861                                 target->mgm_ocb_cur = NULL;
 1862                                 break;
 1863                         }
 1864                 }
 1865                 ocb = sbp_dequeue_ocb(sdev, sbp_status);
 1866                 if (ocb == NULL) {
 1867                         sbp_show_sdev_info(sdev, 2);
 1868 #if defined(__DragonFly__) || \
 1869     (defined(__FreeBSD__) && __FreeBSD_version < 500000)
 1870                         printf("No ocb(%lx) on the queue\n",
 1871 #else
 1872                         printf("No ocb(%x) on the queue\n",
 1873 #endif
 1874                                         ntohl(sbp_status->orb_lo));
 1875                 }
 1876                 break;
 1877         case SRC_UNSOL:
 1878                 /* unsolicit */
 1879                 sbp_show_sdev_info(sdev, 2);
 1880                 printf("unsolicit status received\n");
 1881                 break;
 1882         default:
 1883                 sbp_show_sdev_info(sdev, 2);
 1884                 printf("unknown sbp_status->src\n");
 1885         }
 1886 
 1887         status_valid0 = (sbp_status->src < 2
 1888                         && sbp_status->resp == SBP_REQ_CMP
 1889                         && sbp_status->dead == 0);
 1890         status_valid = (status_valid0 && sbp_status->status == 0);
 1891 
 1892         if (!status_valid0 || debug > 2){
 1893                 int status;
 1894 SBP_DEBUG(0)
 1895                 sbp_show_sdev_info(sdev, 2);
 1896                 printf("ORB status src:%x resp:%x dead:%x"
 1897 #if defined(__DragonFly__) || \
 1898     (defined(__FreeBSD__) && __FreeBSD_version < 500000)
 1899                                 " len:%x stat:%x orb:%x%08lx\n",
 1900 #else
 1901                                 " len:%x stat:%x orb:%x%08x\n",
 1902 #endif
 1903                         sbp_status->src, sbp_status->resp, sbp_status->dead,
 1904                         sbp_status->len, sbp_status->status,
 1905                         ntohs(sbp_status->orb_hi), ntohl(sbp_status->orb_lo));
 1906 END_DEBUG
 1907                 sbp_show_sdev_info(sdev, 2);
 1908                 status = sbp_status->status;
 1909                 switch(sbp_status->resp) {
 1910                 case SBP_REQ_CMP:
 1911                         if (status > MAX_ORB_STATUS0)
 1912                                 printf("%s\n", orb_status0[MAX_ORB_STATUS0]);
 1913                         else
 1914                                 printf("%s\n", orb_status0[status]);
 1915                         break;
 1916                 case SBP_TRANS_FAIL:
 1917                         printf("Obj: %s, Error: %s\n",
 1918                                 orb_status1_object[(status>>6) & 3],
 1919                                 orb_status1_serial_bus_error[status & 0xf]);
 1920                         break;
 1921                 case SBP_ILLE_REQ:
 1922                         printf("Illegal request\n");
 1923                         break;
 1924                 case SBP_VEND_DEP:
 1925                         printf("Vendor dependent\n");
 1926                         break;
 1927                 default:
 1928                         printf("unknown respose code %d\n", sbp_status->resp);
 1929                 }
 1930         }
 1931 
 1932         /* we have to reset the fetch agent if it's dead */
 1933         if (sbp_status->dead) {
 1934                 if (SBP_DEVICE(sdev) != NULL) {
 1935                         SBP_DEVICE_FREEZE(sdev, 1);
 1936                         sdev->freeze ++;
 1937                 }
 1938                 reset_agent = 1;
 1939         }
 1940 
 1941         if (ocb == NULL)
 1942                 goto done;
 1943 
 1944         switch(ntohl(ocb->orb[4]) & ORB_FMT_MSK){
 1945         case ORB_FMT_NOP:
 1946                 break;
 1947         case ORB_FMT_VED:
 1948                 break;
 1949         case ORB_FMT_STD:
 1950                 switch(ocb->flags) {
 1951                 case OCB_ACT_MGM:
 1952                         orb_fun = ntohl(ocb->orb[4]) & ORB_FUN_MSK;
 1953                         reset_agent = 0;
 1954                         switch(orb_fun) {
 1955                         case ORB_FUN_LGI:
 1956                                 login_res = sdev->login;
 1957                                 login_res->len = ntohs(login_res->len);
 1958                                 login_res->id = ntohs(login_res->id);
 1959                                 login_res->cmd_hi = ntohs(login_res->cmd_hi);
 1960                                 login_res->cmd_lo = ntohl(login_res->cmd_lo);
 1961                                 if (status_valid) {
 1962 SBP_DEBUG(0)
 1963 sbp_show_sdev_info(sdev, 2);
 1964 printf("login: len %d, ID %d, cmd %08x%08x, recon_hold %d\n", login_res->len, login_res->id, login_res->cmd_hi, login_res->cmd_lo, ntohs(login_res->recon_hold));
 1965 END_DEBUG
 1966                                         sbp_busy_timeout(sdev);
 1967                                 } else {
 1968                                         /* forgot logout? */
 1969                                         sbp_show_sdev_info(sdev, 2);
 1970                                         printf("login failed\n");
 1971                                         sdev->status = SBP_DEV_RESET;
 1972                                 }
 1973                                 break;
 1974                         case ORB_FUN_RCN:
 1975                                 login_res = sdev->login;
 1976                                 if (status_valid) {
 1977 SBP_DEBUG(0)
 1978 sbp_show_sdev_info(sdev, 2);
 1979 printf("reconnect: len %d, ID %d, cmd %08x%08x\n", login_res->len, login_res->id, login_res->cmd_hi, login_res->cmd_lo);
 1980 END_DEBUG
 1981 #if 1
 1982 #if defined(__FreeBSD__)
 1983                                         if (sdev->status == SBP_DEV_ATTACHED)
 1984                                                 sbp_scan_dev(sdev);
 1985                                         else
 1986 #endif
 1987                                                 sbp_agent_reset(sdev);
 1988 #else
 1989                                         sdev->status = SBP_DEV_ATTACHED;
 1990                                         sbp_mgm_orb(sdev, ORB_FUN_ATS, NULL);
 1991 #endif
 1992                                 } else {
 1993                                         /* reconnection hold time exceed? */
 1994 SBP_DEBUG(0)
 1995                                         sbp_show_sdev_info(sdev, 2);
 1996                                         printf("reconnect failed\n");
 1997 END_DEBUG
 1998                                         sbp_login(sdev);
 1999                                 }
 2000                                 break;
 2001                         case ORB_FUN_LGO:
 2002                                 sdev->status = SBP_DEV_RESET;
 2003                                 break;
 2004                         case ORB_FUN_RST:
 2005                                 sbp_busy_timeout(sdev);
 2006                                 break;
 2007                         case ORB_FUN_LUR:
 2008                         case ORB_FUN_ATA:
 2009                         case ORB_FUN_ATS:
 2010                                 sbp_agent_reset(sdev);
 2011                                 break;
 2012                         default:
 2013                                 sbp_show_sdev_info(sdev, 2);
 2014                                 printf("unknown function %d\n", orb_fun);
 2015                                 break;
 2016                         }
 2017                         sbp_mgm_orb(sdev, ORB_FUN_RUNQUEUE, NULL);
 2018                         break;
 2019                 case OCB_ACT_CMD:
 2020                         sdev->timeout = 0;
 2021                         if(ocb->sxfer != NULL){
 2022                                 sbp_scsi_xfer *sxfer = ocb->sxfer;
 2023 /*
 2024                                 uint32_t *ld = SCSI_XFER_DATA(ocb->sxfer);
 2025                                 if(ld != NULL &&
 2026                                     SCSI_XFER_DATALEN(ocb->sxfer) != 0)
 2027                                         printf("ptr %08x %08x %08x %08x\n", ld[0], ld[1], ld[2], ld[3]);
 2028                                 else
 2029                                         printf("ptr NULL\n");
 2030 printf("len %d\n", sbp_status->len);
 2031 */
 2032                                 if(sbp_status->len > 1){
 2033                                         sbp_scsi_status(sbp_status, ocb);
 2034                                 }else{
 2035                                         if(sbp_status->resp != SBP_REQ_CMP){
 2036                                                 SCSI_XFER_ERROR(sxfer) =
 2037                                                     XS_REQ_CMP_ERR;
 2038                                         }else{
 2039                                                 SCSI_XFER_ERROR(sxfer) =
 2040                                                     XS_REQ_CMP;
 2041                                                 SCSI_XFER_REQUEST_COMPLETE(
 2042                                                     sxfer);
 2043                                         }
 2044                                 }
 2045                                 /* fix up inq data */
 2046                                 if (SCSI_XFER_OPECODE(sxfer) == INQUIRY)
 2047                                         sbp_fix_inq_data(ocb);
 2048                                 SCSI_TRANSFER_DONE(sxfer);
 2049                         }
 2050                         break;
 2051                 default:
 2052                         break;
 2053                 }
 2054         }
 2055 
 2056         if (!use_doorbell)
 2057                 sbp_free_ocb(sdev, ocb);
 2058 done:
 2059         if (reset_agent)
 2060                 sbp_agent_reset(sdev);
 2061 
 2062 done0:
 2063         xfer->recv.pay_len = SBP_RECV_LEN;
 2064 /* The received packet is usually small enough to be stored within
 2065  * the buffer. In that case, the controller return ack_complete and
 2066  * no respose is necessary.
 2067  *
 2068  * XXX fwohci.c and firewire.c should inform event_code such as 
 2069  * ack_complete or ack_pending to upper driver.
 2070  */
 2071 #if NEED_RESPONSE
 2072         xfer->send.off = 0;
 2073         sfp = (struct fw_pkt *)xfer->send.buf;
 2074         sfp->mode.wres.dst = rfp->mode.wreqb.src;
 2075         xfer->dst = sfp->mode.wres.dst;
 2076         xfer->spd = min(sdev->target->fwdev->speed, max_speed);
 2077         xfer->hand = sbp_loginres_callback;
 2078 
 2079         sfp->mode.wres.tlrt = rfp->mode.wreqb.tlrt;
 2080         sfp->mode.wres.tcode = FWTCODE_WRES;
 2081         sfp->mode.wres.rtcode = 0;
 2082         sfp->mode.wres.pri = 0;
 2083 
 2084         fw_asyreq(xfer->fc, -1, xfer);
 2085 #else
 2086         /* recycle */
 2087         STAILQ_INSERT_TAIL(&sbp->fwb.xferlist, xfer, link);
 2088 #endif
 2089 
 2090         return;
 2091 
 2092 }
 2093 
 2094 static void
 2095 sbp_recv(struct fw_xfer *xfer)
 2096 {
 2097         int s;
 2098 
 2099         s = splfwsbp();
 2100         sbp_recv1(xfer);
 2101         splx(s);
 2102 }
 2103 /*
 2104  * sbp_attach()
 2105  */
 2106 FW_ATTACH(sbp)
 2107 {
 2108         FW_ATTACH_START(sbp, sbp, fwa);
 2109         int dv_unit, error, s;
 2110         SBP_ATTACH_START;
 2111 
 2112 SBP_DEBUG(0)
 2113         printf("sbp_attach (cold=%d)\n", cold);
 2114 END_DEBUG
 2115 
 2116         if (cold)
 2117                 sbp_cold ++;
 2118         sbp->fd.fc = fwa->fc;
 2119 
 2120         if (max_speed < 0)
 2121                 max_speed = sbp->fd.fc->speed;
 2122 
 2123         error = fw_bus_dma_tag_create(/*parent*/sbp->fd.fc->dmat,
 2124                                 /* XXX shoud be 4 for sane backend? */
 2125                                 /*alignment*/1,
 2126                                 /*boundary*/0,
 2127                                 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
 2128                                 /*highaddr*/BUS_SPACE_MAXADDR,
 2129                                 /*filter*/NULL, /*filterarg*/NULL,
 2130                                 /*maxsize*/0x100000, /*nsegments*/SBP_IND_MAX,
 2131                                 /*maxsegsz*/SBP_SEG_MAX,
 2132                                 /*flags*/BUS_DMA_ALLOCNOW,
 2133                                 /*lockfunc*/busdma_lock_mutex,
 2134                                 /*lockarg*/&Giant,
 2135                                 &sbp->dmat);
 2136         if (error != 0) {
 2137                 printf("sbp_attach: Could not allocate DMA tag "
 2138                         "- error %d\n", error);
 2139                         FW_ATTACH_RETURN(ENOMEM);
 2140         }
 2141 
 2142 #if defined(__FreeBSD__)
 2143         devq = cam_simq_alloc(/*maxopenings*/SBP_NUM_OCB);
 2144         if (devq == NULL)
 2145                 return (ENXIO);
 2146 #endif
 2147 
 2148         sbp->target.fwdev = NULL;
 2149         sbp->target.luns = NULL;
 2150 
 2151         if (sbp_alloc_target(sbp, fwa->fwdev) == NULL)
 2152                 FW_ATTACH_RETURN(ENXIO);
 2153 
 2154         SBP_SCSIBUS_ATTACH;
 2155 
 2156         /* We reserve 16 bit space (4 bytes X 64 unit X 256 luns) */
 2157         dv_unit = device_get_unit(sbp->fd.dev);
 2158         sbp->fwb.start = SBP_DEV2ADDR(dv_unit, 0);
 2159         sbp->fwb.end = SBP_DEV2ADDR(dv_unit, -1);
 2160         /* pre-allocate xfer */
 2161         STAILQ_INIT(&sbp->fwb.xferlist);
 2162         fw_xferlist_add(&sbp->fwb.xferlist, M_SBP,
 2163             /*send*/ 0, /*recv*/ SBP_RECV_LEN, SBP_NUM_OCB/2,
 2164             sbp->fd.fc, (void *)sbp, sbp_recv);
 2165         fw_bindadd(sbp->fd.fc, &sbp->fwb);
 2166 
 2167         sbp->fd.post_busreset = sbp_post_busreset;
 2168         sbp->fd.post_explore = sbp_post_explore;
 2169 
 2170         if (sbp->fd.fc->status != -1) {
 2171                 s = splfw();
 2172                 sbp_post_busreset((void *)sbp);
 2173                 sbp_post_explore((void *)sbp);
 2174                 splx(s);
 2175         }
 2176 
 2177         FW_ATTACH_RETURN(0);
 2178 #if defined(__FreeBSD__)
 2179 fail:
 2180         cam_sim_free(sbp->sim, /*free_devq*/TRUE);
 2181         return (ENXIO);
 2182 #endif
 2183 }
 2184 
 2185 static int
 2186 sbp_logout_all(struct sbp_softc *sbp)
 2187 {
 2188         struct sbp_target *target;
 2189         struct sbp_dev *sdev;
 2190         int i;
 2191 
 2192 SBP_DEBUG(0)
 2193         printf("sbp_logout_all\n");
 2194 END_DEBUG
 2195         target = &sbp->target;
 2196         if (target->luns != NULL)
 2197                 for (i = 0; i < target->num_lun; i++) {
 2198                         sdev = target->luns[i];
 2199                         if (sdev == NULL)
 2200                                 continue;
 2201                         callout_stop(&sdev->login_callout);
 2202                         if (sdev->status >= SBP_DEV_TOATTACH &&
 2203                                         sdev->status <= SBP_DEV_ATTACHED)
 2204                                 sbp_mgm_orb(sdev, ORB_FUN_LGO, NULL);
 2205                 }
 2206 
 2207         return 0;
 2208 }
 2209 
 2210 #if defined(__FreeBSD__)
 2211 static int
 2212 sbp_shutdown(device_t dev)
 2213 {
 2214         struct sbp_softc *sbp = ((struct sbp_softc *)device_get_softc(dev));
 2215 
 2216         sbp_logout_all(sbp);
 2217         return (0);
 2218 }
 2219 #endif
 2220 
 2221 static void
 2222 sbp_free_sdev(struct sbp_dev *sdev)
 2223 {
 2224         int i;
 2225 
 2226         if (sdev == NULL)
 2227                 return;
 2228         for (i = 0; i < SBP_QUEUE_LEN; i++)
 2229                 fw_bus_dmamap_destroy(sdev->target->sbp->dmat,
 2230                     sdev->ocb[i].dmamap);
 2231         fwdma_free(sdev->target->sbp->fd.fc, &sdev->dma);
 2232         free(sdev, M_SBP);
 2233 }
 2234 
 2235 static void
 2236 sbp_free_target(struct sbp_target *target)
 2237 {
 2238         struct sbp_softc *sbp;
 2239         struct fw_xfer *xfer, *next;
 2240         int i;
 2241 
 2242         if (target->luns == NULL)
 2243                 return;
 2244         callout_stop(&target->mgm_ocb_timeout);
 2245         sbp = target->sbp;
 2246         for (i = 0; i < target->num_lun; i++)
 2247                 sbp_free_sdev(target->luns[i]);
 2248 
 2249         for (xfer = STAILQ_FIRST(&target->xferlist);
 2250                         xfer != NULL; xfer = next) {
 2251                 next = STAILQ_NEXT(xfer, link);
 2252                 fw_xfer_free_buf(xfer);
 2253         }
 2254         STAILQ_INIT(&target->xferlist);
 2255         free(target->luns, M_SBP);
 2256         target->num_lun = 0;;
 2257         target->luns = NULL;
 2258         target->fwdev = NULL;
 2259 }
 2260 
 2261 FW_DETACH(sbp)
 2262 {
 2263         FW_DETACH_START(sbp, sbp);
 2264         struct firewire_comm *fc = sbp->fd.fc;
 2265         int i;
 2266 
 2267 SBP_DEBUG(0)
 2268         printf("sbp_detach\n");
 2269 END_DEBUG
 2270 
 2271         SBP_DETACH_TARGET(&sbp->target);
 2272 #if defined(__FreeBSD__)
 2273         xpt_async(AC_LOST_DEVICE, sbp->path, NULL);
 2274         xpt_free_path(sbp->path);
 2275         xpt_bus_deregister(cam_sim_path(sbp->sim));
 2276         cam_sim_free(sbp->sim, /*free_devq*/ TRUE),
 2277 #endif
 2278 
 2279         sbp_logout_all(sbp);
 2280 
 2281         /* XXX wait for logout completion */
 2282         tsleep(&i, FWPRI, "sbpdtc", hz/2);
 2283 
 2284         sbp_free_target(&sbp->target);
 2285 
 2286         fw_bindremove(fc, &sbp->fwb);
 2287         fw_xferlist_remove(&sbp->fwb.xferlist);
 2288 
 2289         fw_bus_dma_tag_destroy(sbp->dmat);
 2290 
 2291         return (0);
 2292 }
 2293 
 2294 #if defined(__FreeBSD__)
 2295 static void
 2296 sbp_cam_detach_sdev(struct sbp_dev *sdev)
 2297 {
 2298         if (sdev == NULL)
 2299                 return;
 2300         if (sdev->status == SBP_DEV_DEAD)
 2301                 return;
 2302         if (sdev->status == SBP_DEV_RESET)
 2303                 return;
 2304         if (sdev->path) {
 2305                 xpt_release_devq(sdev->path,
 2306                                  sdev->freeze, TRUE);
 2307                 sdev->freeze = 0;
 2308                 xpt_async(AC_LOST_DEVICE, sdev->path, NULL);
 2309                 xpt_free_path(sdev->path);
 2310                 sdev->path = NULL;
 2311         }
 2312         sbp_abort_all_ocbs(sdev, XS_DEV_NOT_THERE);
 2313 }
 2314 
 2315 static void
 2316 sbp_cam_detach_target(struct sbp_target *target)
 2317 {
 2318         int i;
 2319 
 2320         if (target->luns != NULL) {
 2321 SBP_DEBUG(0)
 2322                 printf("sbp_detach_target %d\n", target->target_id);
 2323 END_DEBUG
 2324                 callout_stop(&target->scan_callout);
 2325                 for (i = 0; i < target->num_lun; i++)
 2326                         sbp_cam_detach_sdev(target->luns[i]);
 2327         }
 2328 }
 2329 #elif defined(__NetBSD__)
 2330 static void
 2331 sbp_scsipi_detach_sdev(struct sbp_dev *sdev)
 2332 {
 2333         struct sbp_target *target;
 2334         struct sbp_softc *sbp;
 2335 
 2336         if (sdev == NULL)
 2337                 return;
 2338 
 2339         target = sdev->target;
 2340         if (target == NULL)
 2341                 return;
 2342 
 2343         sbp = target->sbp;
 2344 
 2345         if (sdev->status == SBP_DEV_DEAD)
 2346                 return;
 2347         if (sdev->status == SBP_DEV_RESET)
 2348                 return;
 2349         if (sdev->periph) {
 2350                 scsipi_periph_thaw(sdev->periph, sdev->freeze);
 2351                 scsipi_channel_thaw(&sbp->sc_channel, 0);       /* XXXX */
 2352                 sdev->freeze = 0;
 2353                 if (scsipi_target_detach(&sbp->sc_channel,
 2354                     target->target_id, sdev->lun_id, DETACH_FORCE) != 0) {
 2355                         sbp_show_sdev_info(sdev, 2);
 2356                         printf("detach failed\n");
 2357                 }
 2358                 sdev->periph = NULL;
 2359         }
 2360         sbp_abort_all_ocbs(sdev, XS_DEV_NOT_THERE);
 2361 }
 2362 
 2363 static void
 2364 sbp_scsipi_detach_target(struct sbp_target *target)
 2365 {
 2366         struct sbp_softc *sbp = target->sbp;
 2367         int i;
 2368 
 2369         if (target->luns != NULL) {
 2370 SBP_DEBUG(0)
 2371                 printf("sbp_detach_target %d\n", target->target_id);
 2372 END_DEBUG
 2373                 callout_stop(&target->scan_callout);
 2374                 for (i = 0; i < target->num_lun; i++)
 2375                         sbp_scsipi_detach_sdev(target->luns[i]);
 2376                 if (config_detach(sbp->sc_bus, DETACH_FORCE) != 0)
 2377                         device_printf(sbp->fd.dev, "%d detach failed\n",
 2378                                 target->target_id);
 2379                 sbp->sc_bus = NULL;
 2380         }
 2381 }
 2382 #endif
 2383 
 2384 static void
 2385 sbp_target_reset(struct sbp_dev *sdev, int method)
 2386 {
 2387         int i;
 2388         struct sbp_target *target = sdev->target;
 2389         struct sbp_dev *tsdev;
 2390 
 2391         for (i = 0; i < target->num_lun; i++) {
 2392                 tsdev = target->luns[i];
 2393                 if (tsdev == NULL)
 2394                         continue;
 2395                 if (tsdev->status == SBP_DEV_DEAD)
 2396                         continue;
 2397                 if (tsdev->status == SBP_DEV_RESET)
 2398                         continue;
 2399                 SBP_DEVICE_FREEZE(tsdev, 1);
 2400                 tsdev->freeze ++;
 2401                 sbp_abort_all_ocbs(tsdev, XS_CMD_TIMEOUT);
 2402                 if (method == 2)
 2403                         tsdev->status = SBP_DEV_LOGIN;
 2404         }
 2405         switch(method) {
 2406         case 1:
 2407                 printf("target reset\n");
 2408                 sbp_mgm_orb(sdev, ORB_FUN_RST, NULL);
 2409                 break;
 2410         case 2:
 2411                 printf("reset start\n");
 2412                 sbp_reset_start(sdev);
 2413                 break;
 2414         }
 2415                         
 2416 }
 2417 
 2418 static void
 2419 sbp_mgm_timeout(void *arg)
 2420 {
 2421         struct sbp_ocb *ocb = (struct sbp_ocb *)arg;
 2422         struct sbp_dev *sdev = ocb->sdev;
 2423         struct sbp_target *target = sdev->target;
 2424 
 2425         sbp_show_sdev_info(sdev, 2);
 2426         printf("request timeout(mgm orb:0x%08x) ... ",
 2427             (uint32_t)ocb->bus_addr);
 2428         target->mgm_ocb_cur = NULL;
 2429         sbp_free_ocb(sdev, ocb);
 2430 #if 0
 2431         /* XXX */
 2432         printf("run next request\n");
 2433         sbp_mgm_orb(sdev, ORB_FUN_RUNQUEUE, NULL);
 2434 #endif
 2435 #if 1
 2436         printf("reset start\n");
 2437         sbp_reset_start(sdev);
 2438 #endif
 2439 }
 2440 
 2441 static void
 2442 sbp_timeout(void *arg)
 2443 {
 2444         struct sbp_ocb *ocb = (struct sbp_ocb *)arg;
 2445         struct sbp_dev *sdev = ocb->sdev;
 2446 
 2447         sbp_show_sdev_info(sdev, 2);
 2448         printf("request timeout(cmd orb:0x%08x) ... ",
 2449             (uint32_t)ocb->bus_addr);
 2450 
 2451         sdev->timeout ++;
 2452         switch(sdev->timeout) {
 2453         case 1:
 2454                 printf("agent reset\n");
 2455                 SBP_DEVICE_FREEZE(sdev, 1);
 2456                 sdev->freeze ++;
 2457                 sbp_abort_all_ocbs(sdev, XS_CMD_TIMEOUT);
 2458                 sbp_agent_reset(sdev);
 2459                 break;
 2460         case 2:
 2461         case 3:
 2462                 sbp_target_reset(sdev, sdev->timeout - 1);
 2463                 break;
 2464 #if 0
 2465         default:
 2466                 /* XXX give up */
 2467                 SBP_DETACH_TARGET(target);
 2468                 if (target->luns != NULL)
 2469                         free(target->luns, M_SBP);
 2470                 target->num_lun = 0;;
 2471                 target->luns = NULL;
 2472                 target->fwdev = NULL;
 2473 #endif
 2474         }
 2475 }
 2476 
 2477 static void
 2478 sbp_action1(struct sbp_softc *sbp, sbp_scsi_xfer *sxfer)
 2479 {
 2480 
 2481         struct sbp_target *target = NULL;
 2482         struct sbp_dev *sdev = NULL;
 2483 
 2484         /* target:lun -> sdev mapping */
 2485         if (sbp != NULL) {
 2486                 target = &sbp->target;
 2487                 if (target->fwdev != NULL
 2488                                 && NOT_LUN_WILDCARD(SCSI_XFER_LUN(sxfer))
 2489                                 && SCSI_XFER_LUN(sxfer) < target->num_lun) {
 2490                         sdev = target->luns[SCSI_XFER_LUN(sxfer)];
 2491                         if (sdev != NULL && sdev->status != SBP_DEV_ATTACHED &&
 2492                                 sdev->status != SBP_DEV_PROBE)
 2493                                 sdev = NULL;
 2494                 }
 2495         }
 2496 
 2497 SBP_DEBUG(1)
 2498         if (sdev == NULL)
 2499                 printf("invalid target %d lun %d\n",
 2500                         SCSI_XFER_TARGET(sxfer), SCSI_XFER_LUN(sxfer));
 2501 END_DEBUG
 2502 
 2503         switch (SCSI_XFER_FUNCCODE(sxfer)) {
 2504         case XPT_SCSI_IO:
 2505 #if defined(__FreeBSD__)
 2506         case XPT_RESET_DEV:
 2507         case XPT_GET_TRAN_SETTINGS:
 2508         case XPT_SET_TRAN_SETTINGS:
 2509         case XPT_CALC_GEOMETRY:
 2510 #endif
 2511                 if (sdev == NULL) {
 2512 SBP_DEBUG(1)
 2513                         printf("%s:%d:%d:func_code 0x%04x: "
 2514                                 "Invalid target (target needed)\n",
 2515                                 sbp ? device_get_nameunit(sbp->fd.dev) : "???",
 2516                                 SCSI_XFER_TARGET(sxfer), SCSI_XFER_LUN(sxfer),
 2517                                 SCSI_XFER_FUNCCODE(sxfer));
 2518 END_DEBUG
 2519 
 2520                         SCSI_XFER_ERROR(sxfer) = XS_DEV_NOT_THERE;
 2521                         SCSI_TRANSFER_DONE(sxfer);
 2522                         return;
 2523                 }
 2524                 break;
 2525 #if defined(__FreeBSD__)
 2526         case XPT_PATH_INQ:
 2527         case XPT_NOOP:
 2528                 /* The opcodes sometimes aimed at a target (sc is valid),
 2529                  * sometimes aimed at the SIM (sc is invalid and target is
 2530                  * CAM_TARGET_WILDCARD)
 2531                  */
 2532                 if (sbp == NULL && 
 2533                         sxfer->ccb_h.target_id != CAM_TARGET_WILDCARD) {
 2534 SBP_DEBUG(0)
 2535                         printf("%s:%d:%d func_code 0x%04x: "
 2536                                 "Invalid target (no wildcard)\n",
 2537                                 device_get_nameunit(sbp->fd.dev),
 2538                                 sxfer->ccb_h.target_id, sxfer->ccb_h.target_lun,
 2539                                 sxfer->ccb_h.func_code);
 2540 END_DEBUG
 2541                         SCSI_XFER_ERROR(sxfer) = XS_DEV_NOT_THERE;
 2542                         SCSI_TRANSFER_DONE(sxfer);
 2543                         return;
 2544                 }
 2545                 break;
 2546 #endif
 2547         default:
 2548                 /* XXX Hm, we should check the input parameters */
 2549                 break;
 2550         }
 2551 
 2552         switch (SCSI_XFER_FUNCCODE(sxfer)) {
 2553         case XPT_SCSI_IO:
 2554         {
 2555                 struct sbp_ocb *ocb;
 2556                 int speed;
 2557                 void *cdb;
 2558 
 2559 SBP_DEBUG(2)
 2560                 printf("%s:%d:%d XPT_SCSI_IO: "
 2561                         "cmd: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x"
 2562                         ", flags: 0x%02x, "
 2563                         "%db cmd/%db data/%db sense\n",
 2564                         device_get_nameunit(sbp->fd.dev),
 2565                         SCSI_XFER_TARGET(sxfer), SCSI_XFER_LUN(sxfer),
 2566                         SCSI_XFER_10BCMD_DUMP(sxfer),
 2567                         SCSI_XFER_DIR(sxfer),
 2568                         SCSI_XFER_CMDLEN(sxfer), SCSI_XFER_DATALEN(sxfer),
 2569                         SCSI_XFER_SENSELEN(sxfer));
 2570 END_DEBUG
 2571                 if(sdev == NULL){
 2572                         SCSI_XFER_ERROR(sxfer) = XS_DEV_NOT_THERE;
 2573                         SCSI_TRANSFER_DONE(sxfer);
 2574                         return;
 2575                 }
 2576 #if 0
 2577                 /* if we are in probe stage, pass only probe commands */
 2578                 if (sdev->status == SBP_DEV_PROBE) {
 2579                         char *name;
 2580                         name = xpt_path_periph(sxfer->ccb_h.path)->periph_name;
 2581                         printf("probe stage, periph name: %s\n", name);
 2582                         if (strcmp(name, "probe") != 0) {
 2583                                 SCSI_XFER_ERROR(sxfer) = XS_REQUEUE_REQ;
 2584                                 SCSI_TRANSFER_DONE(sxfer);
 2585                                 return;
 2586                         }
 2587                 }
 2588 #endif
 2589                 if ((ocb = sbp_get_ocb(sdev)) == NULL) {
 2590                         SCSI_XFER_ERROR(sxfer) = XS_REQUEUE_REQ;
 2591                         if (sdev->freeze == 0) {
 2592                                 SBP_DEVICE_FREEZE(sdev, 1);
 2593                                 sdev->freeze ++;
 2594                         }
 2595                         SCSI_TRANSFER_DONE(sxfer);
 2596                         return;
 2597                 }
 2598 
 2599                 ocb->flags = OCB_ACT_CMD;
 2600                 ocb->sdev = sdev;
 2601                 ocb->sxfer = sxfer;
 2602 #if defined(__FreeBSD__)
 2603                 sxfer->ccb_h.ccb_sdev_ptr = sdev;
 2604 #endif
 2605                 ocb->orb[0] = htonl(1 << 31);
 2606                 ocb->orb[1] = 0;
 2607                 ocb->orb[2] = htonl(((sbp->fd.fc->nodeid | FWLOCALBUS )<< 16) );
 2608                 ocb->orb[3] = htonl(ocb->bus_addr + IND_PTR_OFFSET);
 2609                 speed = min(target->fwdev->speed, max_speed);
 2610                 ocb->orb[4] = htonl(ORB_NOTIFY | ORB_CMD_SPD(speed)
 2611                                                 | ORB_CMD_MAXP(speed + 7));
 2612                 if(SCSI_XFER_DIR(sxfer) == SCSI_XFER_DATA_IN){
 2613                         ocb->orb[4] |= htonl(ORB_CMD_IN);
 2614                 }
 2615 
 2616                 if (CAM_XFER_FLAGS(sxfer) & CAM_SCATTER_VALID)
 2617                         printf("sbp: CAM_SCATTER_VALID\n");
 2618                 if (CAM_XFER_FLAGS(sxfer) & CAM_DATA_PHYS)
 2619                         printf("sbp: CAM_DATA_PHYS\n");
 2620 
 2621                 cdb = SCSI_XFER_CMD(sxfer);
 2622                 bcopy(cdb, (void *)&ocb->orb[5], SCSI_XFER_CMDLEN(sxfer));
 2623 /*
 2624 printf("ORB %08x %08x %08x %08x\n", ntohl(ocb->orb[0]), ntohl(ocb->orb[1]), ntohl(ocb->orb[2]), ntohl(ocb->orb[3]));
 2625 printf("ORB %08x %08x %08x %08x\n", ntohl(ocb->orb[4]), ntohl(ocb->orb[5]), ntohl(ocb->orb[6]), ntohl(ocb->orb[7]));
 2626 */
 2627                 if (SCSI_XFER_DATALEN(sxfer) > 0) {
 2628                         int s, error;
 2629 
 2630                         s = splsoftvm();
 2631                         error = fw_bus_dmamap_load(/*dma tag*/sbp->dmat,
 2632                                         /*dma map*/ocb->dmamap,
 2633                                         SCSI_XFER_DATA(sxfer),
 2634                                         SCSI_XFER_DATALEN(sxfer),
 2635                                         sbp_execute_ocb,
 2636                                         ocb,
 2637                                         /*flags*/0);
 2638                         splx(s);
 2639                         if (error)
 2640                                 printf("sbp: bus_dmamap_load error %d\n", error);
 2641                 } else
 2642                         sbp_execute_ocb(ocb, NULL, 0, 0);
 2643                 break;
 2644         }
 2645 #if defined(__FreeBSD__)
 2646         case XPT_CALC_GEOMETRY:
 2647         {
 2648                 struct ccb_calc_geometry *ccg;
 2649 #if defined(__DragonFly__) || __FreeBSD_version < 501100
 2650                 uint32_t size_mb;
 2651                 uint32_t secs_per_cylinder;
 2652                 int extended = 1;
 2653 #endif
 2654 
 2655                 ccg = &sxfer->ccg;
 2656                 if (ccg->block_size == 0) {
 2657                         printf("sbp_action1: block_size is 0.\n");
 2658                         SCSI_XFER_ERROR(sxfer) = XS_REQ_INVALID;
 2659                         SCSI_TRANSFER_DONE(sxfer);
 2660                         break;
 2661                 }
 2662 SBP_DEBUG(1)
 2663                 printf("%s:%d:%d:%d:XPT_CALC_GEOMETRY: "
 2664 #if defined(__DragonFly__) || __FreeBSD_version < 500000
 2665                         "Volume size = %d\n",
 2666 #else
 2667                         "Volume size = %jd\n",
 2668 #endif
 2669                         device_get_nameunit(sbp->fd.dev),
 2670                         cam_sim_path(sbp->sim),
 2671                         sxfer->ccb_h.target_id, sxfer->ccb_h.target_lun,
 2672 #if defined(__FreeBSD__) && __FreeBSD_version >= 500000
 2673                         (uintmax_t)
 2674 #endif
 2675                                 ccg->volume_size);
 2676 END_DEBUG
 2677 
 2678 #if defined(__DragonFly__) || __FreeBSD_version < 501100
 2679                 size_mb = ccg->volume_size
 2680                         / ((1024L * 1024L) / ccg->block_size);
 2681 
 2682                 if (size_mb > 1024 && extended) {
 2683                         ccg->heads = 255;
 2684                         ccg->secs_per_track = 63;
 2685                 } else {
 2686                         ccg->heads = 64;
 2687                         ccg->secs_per_track = 32;
 2688                 }
 2689                 secs_per_cylinder = ccg->heads * ccg->secs_per_track;
 2690                 ccg->cylinders = ccg->volume_size / secs_per_cylinder;
 2691                 SCSI_XFER_ERROR(sxfer) = XS_REQ_CMP;
 2692 #else
 2693                 cam_calc_geometry(ccg, /*extended*/1);
 2694 #endif
 2695                 SCSI_TRANSFER_DONE(sxfer);
 2696                 break;
 2697         }
 2698         case XPT_RESET_BUS:             /* Reset the specified SCSI bus */
 2699         {
 2700 
 2701 SBP_DEBUG(1)
 2702                 printf("%s:%d:XPT_RESET_BUS: \n",
 2703                         device_get_nameunit(sbp->fd.dev), cam_sim_path(sbp->sim));
 2704 END_DEBUG
 2705 
 2706                 SCSI_XFER_ERROR(sxfer) = XS_REQ_INVALID;
 2707                 SCSI_TRANSFER_DONE(sxfer);
 2708                 break;
 2709         }
 2710         case XPT_PATH_INQ:              /* Path routing inquiry */
 2711         {
 2712                 struct ccb_pathinq *cpi = &sxfer->cpi;
 2713                 struct cam_sim *sim = sbp->sim;
 2714                 
 2715 SBP_DEBUG(1)
 2716                 printf("%s:%d:%d XPT_PATH_INQ:.\n",
 2717                         device_get_nameunit(sbp->fd.dev),
 2718                         sxfer->ccb_h.target_id, sxfer->ccb_h.target_lun);
 2719 END_DEBUG
 2720                 cpi->version_num = 1; /* XXX??? */
 2721                 cpi->hba_inquiry = PI_TAG_ABLE;
 2722                 cpi->target_sprt = 0;
 2723                 cpi->hba_misc = PIM_NOBUSRESET | PIM_NO_6_BYTE;
 2724                 cpi->hba_eng_cnt = 0;
 2725                 cpi->max_target = SBP_NUM_TARGETS - 1;
 2726                 cpi->max_lun = SBP_NUM_LUNS - 1;
 2727                 cpi->initiator_id = SBP_INITIATOR;
 2728                 cpi->bus_id = sim->bus_id;
 2729                 cpi->base_transfer_speed = 400 * 1000 / 8;
 2730                 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
 2731                 strncpy(cpi->hba_vid, "SBP", HBA_IDLEN);
 2732                 strncpy(cpi->dev_name, sim->sim_name, DEV_IDLEN);
 2733                 cpi->unit_number = sim->unit_number;
 2734 
 2735                 SCSI_XFER_ERROR(cpi) = XS_REQ_CMP;
 2736                 SCSI_TRANSFER_DONE(sxfer);
 2737                 break;
 2738         }
 2739         case XPT_GET_TRAN_SETTINGS:
 2740         {
 2741                 struct ccb_trans_settings *cts = &sxfer->cts;
 2742 SBP_DEBUG(1)
 2743                 printf("%s:%d:%d XPT_GET_TRAN_SETTINGS:.\n",
 2744                         device_get_nameunit(sbp->fd.dev),
 2745                         sxfer->ccb_h.target_id, sxfer->ccb_h.target_lun);
 2746 END_DEBUG
 2747                 /* Enable disconnect and tagged queuing */
 2748                 cts->valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
 2749                 cts->flags = CCB_TRANS_DISC_ENB | CCB_TRANS_TAG_ENB;
 2750 
 2751                 SCSI_XFER_ERROR(cts) = XS_REQ_CMP;
 2752                 SCSI_TRANSFER_DONE(sxfer);
 2753                 break;
 2754         }
 2755         case XPT_ABORT:
 2756                 SCSI_XFER_ERROR(sxfer) = XS_UA_ABORT;
 2757                 SCSI_TRANSFER_DONE(sxfer);
 2758                 break;
 2759         case XPT_SET_TRAN_SETTINGS:
 2760                 /* XXX */
 2761         default:
 2762                 SCSI_XFER_ERROR(sxfer) = XS_REQ_INVALID;
 2763                 SCSI_TRANSFER_DONE(sxfer);
 2764                 break;
 2765 #endif
 2766         }
 2767         return;
 2768 }
 2769 
 2770 #if defined(__FreeBSD__)
 2771 static void
 2772 sbp_action(struct cam_sim *sim, sbp_scsi_xfer *sxfer)
 2773 {
 2774         int s;
 2775 
 2776         s = splfw();
 2777         sbp_action1(sim->softc, sxfer);
 2778         splx(s);
 2779 }
 2780 #endif
 2781 
 2782 static void
 2783 sbp_execute_ocb(void *arg,  bus_dma_segment_t *segments, int seg, int error)
 2784 {
 2785         int i;
 2786         struct sbp_ocb *ocb;
 2787         struct sbp_ocb *prev;
 2788         bus_dma_segment_t *s;
 2789 
 2790         if (error)
 2791                 printf("sbp_execute_ocb: error=%d\n", error);
 2792 
 2793         ocb = (struct sbp_ocb *)arg;
 2794 
 2795 SBP_DEBUG(2)
 2796         printf("sbp_execute_ocb: seg %d", seg);
 2797         for (i = 0; i < seg; i++)
 2798 #if defined(__DragonFly__) || \
 2799     (defined(__FreeBSD__) && __FreeBSD_version < 500000)
 2800                 printf(", %x:%d", segments[i].ds_addr, segments[i].ds_len);
 2801 #else
 2802                 printf(", %jx:%jd", (uintmax_t)segments[i].ds_addr,
 2803                                         (uintmax_t)segments[i].ds_len);
 2804 #endif
 2805         printf("\n");
 2806 END_DEBUG
 2807 
 2808         if (seg == 1) {
 2809                 /* direct pointer */
 2810                 s = &segments[0];
 2811                 if (s->ds_len > SBP_SEG_MAX)
 2812                         panic("ds_len > SBP_SEG_MAX, fix busdma code");
 2813                 ocb->orb[3] = htonl(s->ds_addr);
 2814                 ocb->orb[4] |= htonl(s->ds_len);
 2815         } else if(seg > 1) {
 2816                 /* page table */
 2817                 for (i = 0; i < seg; i++) {
 2818                         s = &segments[i];
 2819 SBP_DEBUG(0)
 2820                         /* XXX LSI Logic "< 16 byte" bug might be hit */
 2821                         if (s->ds_len < 16)
 2822                                 printf("sbp_execute_ocb: warning, "
 2823 #if defined(__DragonFly__) || \
 2824     (defined(__FreeBSD__) && __FreeBSD_version < 500000)
 2825                                         "segment length(%d) is less than 16."
 2826 #else
 2827                                         "segment length(%jd) is less than 16."
 2828 #endif
 2829                                         "(seg=%d/%d)\n", (uintmax_t)s->ds_len, i+1, seg);
 2830 END_DEBUG
 2831                         if (s->ds_len > SBP_SEG_MAX)
 2832                                 panic("ds_len > SBP_SEG_MAX, fix busdma code");
 2833                         ocb->ind_ptr[i].hi = htonl(s->ds_len << 16);
 2834                         ocb->ind_ptr[i].lo = htonl(s->ds_addr);
 2835                 }
 2836                 ocb->orb[4] |= htonl(ORB_CMD_PTBL | seg);
 2837         }
 2838         
 2839         if (seg > 0)
 2840                 fw_bus_dmamap_sync(ocb->sdev->target->sbp->dmat, ocb->dmamap,
 2841                         (ntohl(ocb->orb[4]) & ORB_CMD_IN) ?
 2842                         BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
 2843         prev = sbp_enqueue_ocb(ocb->sdev, ocb);
 2844         fwdma_sync(&ocb->sdev->dma, BUS_DMASYNC_PREWRITE);
 2845         if (use_doorbell) {
 2846                 if (prev == NULL) {
 2847                         if (ocb->sdev->last_ocb != NULL)
 2848                                 sbp_doorbell(ocb->sdev);
 2849                         else
 2850                                 sbp_orb_pointer(ocb->sdev, ocb); 
 2851                 }
 2852         } else {
 2853                 if (prev == NULL || (ocb->sdev->flags & ORB_LINK_DEAD) != 0) {
 2854                         ocb->sdev->flags &= ~ORB_LINK_DEAD;
 2855                         sbp_orb_pointer(ocb->sdev, ocb); 
 2856                 }
 2857         }
 2858 }
 2859 
 2860 #if defined(__FreeBSD__)
 2861 static void
 2862 sbp_poll(struct cam_sim *sim)
 2863 {       
 2864         struct sbp_softc *sbp;
 2865         struct firewire_comm *fc;
 2866 
 2867         sbp = (struct sbp_softc *)sim->softc;
 2868         fc = sbp->fd.fc;
 2869 
 2870         fc->poll(fc, 0, -1);
 2871 
 2872         return;
 2873 }
 2874 
 2875 #endif
 2876 static struct sbp_ocb *
 2877 sbp_dequeue_ocb(struct sbp_dev *sdev, struct sbp_status *sbp_status)
 2878 {
 2879         struct sbp_ocb *ocb;
 2880         struct sbp_ocb *next;
 2881         int s = splfw(), order = 0;
 2882         int flags;
 2883 
 2884 SBP_DEBUG(1)
 2885         sbp_show_sdev_info(sdev, 2);
 2886 #if defined(__DragonFly__) || \
 2887     (defined(__FreeBSD__) && __FreeBSD_version < 500000)
 2888         printf("%s: 0x%08lx src %d\n",
 2889 #else
 2890         printf("%s: 0x%08x src %d\n",
 2891 #endif
 2892             __func__, ntohl(sbp_status->orb_lo), sbp_status->src);
 2893 END_DEBUG
 2894         for (ocb = STAILQ_FIRST(&sdev->ocbs); ocb != NULL; ocb = next) {
 2895                 next = STAILQ_NEXT(ocb, ocb);
 2896                 flags = ocb->flags;
 2897                 if (OCB_MATCH(ocb, sbp_status)) {
 2898                         /* found */
 2899                         STAILQ_REMOVE(&sdev->ocbs, ocb, sbp_ocb, ocb);
 2900                         if (ocb->sxfer != NULL)
 2901 #if defined(__DragonFly__) || defined(__NetBSD__)
 2902                                 callout_stop(&SCSI_XFER_CALLOUT(ocb->sxfer));
 2903 #else
 2904                                 untimeout(sbp_timeout, (caddr_t)ocb,
 2905                                                 SCSI_XFER_CALLOUT(ocb->sxfer));
 2906 #endif
 2907                         if (ntohl(ocb->orb[4]) & 0xffff) {
 2908                                 fw_bus_dmamap_sync(sdev->target->sbp->dmat,
 2909                                         ocb->dmamap,
 2910                                         (ntohl(ocb->orb[4]) & ORB_CMD_IN) ?
 2911                                         BUS_DMASYNC_POSTREAD :
 2912                                         BUS_DMASYNC_POSTWRITE);
 2913                                 fw_bus_dmamap_unload(sdev->target->sbp->dmat,
 2914                                         ocb->dmamap);
 2915                         }
 2916                         if (!use_doorbell) {
 2917                                 if (sbp_status->src == SRC_NO_NEXT) {
 2918                                         if (next != NULL)
 2919                                                 sbp_orb_pointer(sdev, next); 
 2920                                         else if (order > 0) {
 2921                                                 /*
 2922                                                  * Unordered execution
 2923                                                  * We need to send pointer for
 2924                                                  * next ORB
 2925                                                  */
 2926                                                 sdev->flags |= ORB_LINK_DEAD;
 2927                                         }
 2928                                 }
 2929                         } else {
 2930                                 /*
 2931                                  * XXX this is not correct for unordered
 2932                                  * execution. 
 2933                                  */
 2934                                 if (sdev->last_ocb != NULL)
 2935                                         sbp_free_ocb(sdev, sdev->last_ocb);
 2936                                 sdev->last_ocb = ocb;
 2937                                 if (next != NULL &&
 2938                                     sbp_status->src == SRC_NO_NEXT)
 2939                                         sbp_doorbell(sdev);
 2940                         }
 2941                         break;
 2942                 } else
 2943                         order ++;
 2944         }
 2945         splx(s);
 2946 SBP_DEBUG(0)
 2947         if (ocb && order > 0) {
 2948                 sbp_show_sdev_info(sdev, 2);
 2949                 printf("unordered execution order:%d\n", order);
 2950         }
 2951 END_DEBUG
 2952         return (ocb);
 2953 }
 2954 
 2955 static struct sbp_ocb *
 2956 sbp_enqueue_ocb(struct sbp_dev *sdev, struct sbp_ocb *ocb)
 2957 {
 2958         int s = splfw();
 2959         struct sbp_ocb *prev, *prev2;
 2960 
 2961 SBP_DEBUG(1)
 2962         sbp_show_sdev_info(sdev, 2);
 2963 #if defined(__DragonFly__) || \
 2964     (defined(__FreeBSD__) && __FreeBSD_version < 500000)
 2965         printf("%s: 0x%08x\n", __func__, ocb->bus_addr);
 2966 #else
 2967         printf("%s: 0x%08jx\n", __func__, (uintmax_t)ocb->bus_addr);
 2968 #endif
 2969 END_DEBUG
 2970         prev2 = prev = STAILQ_LAST(&sdev->ocbs, sbp_ocb, ocb);
 2971         STAILQ_INSERT_TAIL(&sdev->ocbs, ocb, ocb);
 2972 
 2973         if (ocb->sxfer != NULL)
 2974 #if defined(__DragonFly__) || defined(__NetBSD__)
 2975                 callout_reset(&SCSI_XFER_CALLOUT(ocb->sxfer),
 2976                     mstohz(SCSI_XFER_TIMEOUT(ocb->sxfer)), sbp_timeout, ocb);
 2977 #else
 2978                 SCSI_XFER_CALLOUT(ocb->sxfer) = timeout(sbp_timeout,
 2979                     (caddr_t)ocb, mstohz(SCSI_XFER_TIMEOUT(ocb->sxfer)));
 2980 #endif
 2981 
 2982         if (use_doorbell && prev == NULL)
 2983                 prev2 = sdev->last_ocb;
 2984 
 2985         if (prev2 != NULL) {
 2986 SBP_DEBUG(2)
 2987 #if defined(__DragonFly__) || \
 2988     (defined(__FreeBSD__) && __FreeBSD_version < 500000)
 2989                 printf("linking chain 0x%x -> 0x%x\n",
 2990                     prev2->bus_addr, ocb->bus_addr);
 2991 #else
 2992                 printf("linking chain 0x%jx -> 0x%jx\n",
 2993                     (uintmax_t)prev2->bus_addr, (uintmax_t)ocb->bus_addr);
 2994 #endif
 2995 END_DEBUG
 2996                 prev2->orb[1] = htonl(ocb->bus_addr);
 2997                 prev2->orb[0] = 0;
 2998         }
 2999         splx(s);
 3000 
 3001         return prev;
 3002 }
 3003 
 3004 static struct sbp_ocb *
 3005 sbp_get_ocb(struct sbp_dev *sdev)
 3006 {
 3007         struct sbp_ocb *ocb;
 3008         int s = splfw();
 3009         ocb = STAILQ_FIRST(&sdev->free_ocbs);
 3010         if (ocb == NULL) {
 3011                 sdev->flags |= ORB_SHORTAGE;
 3012                 printf("ocb shortage!!!\n");
 3013                 splx(s);
 3014                 return NULL;
 3015         }
 3016         STAILQ_REMOVE_HEAD(&sdev->free_ocbs, ocb);
 3017         splx(s);
 3018         ocb->sxfer = NULL;
 3019         return (ocb);
 3020 }
 3021 
 3022 static void
 3023 sbp_free_ocb(struct sbp_dev *sdev, struct sbp_ocb *ocb)
 3024 {
 3025         ocb->flags = 0;
 3026         ocb->sxfer = NULL;
 3027         STAILQ_INSERT_TAIL(&sdev->free_ocbs, ocb, ocb);
 3028         if ((sdev->flags & ORB_SHORTAGE) != 0) {
 3029                 int count;
 3030 
 3031                 sdev->flags &= ~ORB_SHORTAGE;
 3032                 count = sdev->freeze;
 3033                 sdev->freeze = 0;
 3034                 SBP_DEVICE_THAW(sdev, count);
 3035         }
 3036 }
 3037 
 3038 static void
 3039 sbp_abort_ocb(struct sbp_ocb *ocb, int status)
 3040 {
 3041         struct sbp_dev *sdev;
 3042 
 3043         sdev = ocb->sdev;
 3044 SBP_DEBUG(0)
 3045         sbp_show_sdev_info(sdev, 2);
 3046 #if defined(__DragonFly__) || \
 3047     (defined(__FreeBSD__) && __FreeBSD_version < 500000)
 3048         printf("sbp_abort_ocb 0x%x\n", ocb->bus_addr);
 3049 #else
 3050         printf("sbp_abort_ocb 0x%jx\n", (uintmax_t)ocb->bus_addr);
 3051 #endif
 3052 END_DEBUG
 3053 SBP_DEBUG(1)
 3054         if (ocb->sxfer != NULL)
 3055                 sbp_print_scsi_cmd(ocb);
 3056 END_DEBUG
 3057         if (ntohl(ocb->orb[4]) & 0xffff) {
 3058                 fw_bus_dmamap_sync(sdev->target->sbp->dmat, ocb->dmamap,
 3059                         (ntohl(ocb->orb[4]) & ORB_CMD_IN) ?
 3060                         BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
 3061                 fw_bus_dmamap_unload(sdev->target->sbp->dmat, ocb->dmamap);
 3062         }
 3063         if (ocb->sxfer != NULL) {
 3064 #if defined(__DragonFly__ ) || defined(__NetBSD__)
 3065                 callout_stop(&SCSI_XFER_CALLOUT(ocb->sxfer));
 3066 #else
 3067                 untimeout(sbp_timeout, (caddr_t)ocb,
 3068                                         SCSI_XFER_CALLOUT(ocb->sxfer));
 3069 #endif
 3070                 SCSI_XFER_ERROR(ocb->sxfer) = status;
 3071                 SCSI_TRANSFER_DONE(ocb->sxfer);
 3072         }
 3073         sbp_free_ocb(sdev, ocb);
 3074 }
 3075 
 3076 static void
 3077 sbp_abort_all_ocbs(struct sbp_dev *sdev, int status)
 3078 {
 3079         int s;
 3080         struct sbp_ocb *ocb, *next;
 3081         STAILQ_HEAD(, sbp_ocb) temp;
 3082 
 3083         s = splfw();
 3084 
 3085         bcopy(&sdev->ocbs, &temp, sizeof(temp));
 3086         STAILQ_INIT(&sdev->ocbs);
 3087         for (ocb = STAILQ_FIRST(&temp); ocb != NULL; ocb = next) {
 3088                 next = STAILQ_NEXT(ocb, ocb);
 3089                 sbp_abort_ocb(ocb, status);
 3090         }
 3091         if (sdev->last_ocb != NULL) {
 3092                 sbp_free_ocb(sdev, sdev->last_ocb);
 3093                 sdev->last_ocb = NULL;
 3094         }
 3095 
 3096         splx(s);
 3097 }
 3098 
 3099 #if defined(__FreeBSD__)
 3100 static devclass_t sbp_devclass;
 3101 
 3102 static device_method_t sbp_methods[] = {
 3103         /* device interface */
 3104         DEVMETHOD(device_probe,         sbp_probe),
 3105         DEVMETHOD(device_attach,        sbp_attach),
 3106         DEVMETHOD(device_detach,        sbp_detach),
 3107         DEVMETHOD(device_shutdown,      sbp_shutdown),
 3108 
 3109         { 0, 0 }
 3110 };
 3111 
 3112 static driver_t sbp_driver = {
 3113         "sbp",
 3114         sbp_methods,
 3115         sizeof(struct sbp_softc),
 3116 };
 3117 #ifdef __DragonFly__
 3118 DECLARE_DUMMY_MODULE(sbp);
 3119 #endif
 3120 DRIVER_MODULE(sbp, firewire, sbp_driver, sbp_devclass, 0, 0);
 3121 MODULE_VERSION(sbp, 1);
 3122 MODULE_DEPEND(sbp, firewire, 1, 1, 1);
 3123 MODULE_DEPEND(sbp, cam, 1, 1, 1);
 3124 #elif defined(__NetBSD__)
 3125 static void
 3126 sbp_scsipi_request(
 3127     struct scsipi_channel *channel, scsipi_adapter_req_t req, void *arg)
 3128 {
 3129         int i, s;
 3130         struct sbp_softc *sbp =
 3131             (struct sbp_softc *)channel->chan_adapter->adapt_dev;
 3132         struct scsipi_xfer *xs = arg;
 3133         
 3134         if (debug > 1)
 3135                 printf("Called sbpscsi_scsipi_request\n");
 3136 
 3137         switch (req) {
 3138         case ADAPTER_REQ_RUN_XFER:
 3139                 if (debug > 1) {
 3140                         printf("Got req_run_xfer\n");
 3141                         printf("xs control: 0x%08x, timeout: %d\n", 
 3142                             xs->xs_control, xs->timeout);
 3143                         printf("opcode: 0x%02x\n", (int)xs->cmd->opcode);
 3144                         for (i = 0; i < 15; i++)
 3145                                 printf("0x%02x ",(int)xs->cmd->bytes[i]);
 3146                         printf("\n");
 3147                 }
 3148                 if (xs->xs_control & XS_CTL_RESET) {
 3149                         if (debug > 1)
 3150                                 printf("XS_CTL_RESET not support\n");
 3151                         break;
 3152                 }
 3153 #define SBPSCSI_SBP2_MAX_CDB 12
 3154                 if (xs->cmdlen > SBPSCSI_SBP2_MAX_CDB) {
 3155                         if (debug > 0)
 3156                                 printf(
 3157                                     "sbp doesn't support cdb's larger than %d "
 3158                                     "bytes\n", SBPSCSI_SBP2_MAX_CDB);
 3159                         SCSI_XFER_ERROR(xs) = XS_REQ_INVALID;
 3160                         SCSI_TRANSFER_DONE(xs);
 3161                         return;
 3162                 }
 3163                 s = splfw();
 3164                 sbp_action1(sbp, xs);
 3165                 splx(s);
 3166 
 3167                 break;
 3168         case ADAPTER_REQ_GROW_RESOURCES:
 3169                 if (debug > 1)
 3170                         printf("Got req_grow_resources\n");
 3171                 break;
 3172         case ADAPTER_REQ_SET_XFER_MODE:
 3173                 if (debug > 1)
 3174                         printf("Got set xfer mode\n");
 3175                 break;
 3176         default:
 3177                 panic("Unknown request: %d\n", (int)req);
 3178         }
 3179 }
 3180 
 3181 static void
 3182 sbp_minphys(struct buf *bp)
 3183 {
 3184         minphys(bp);
 3185 }
 3186 
 3187 CFATTACH_DECL(sbp, sizeof (struct sbp_softc),
 3188     sbpmatch, sbpattach, sbpdetach, NULL);
 3189 #endif

Cache object: cc38369c6c13c1341cfc1b5f6f714cc8


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