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

Cache object: 639ab41683968e1114d317a74912a876


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