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/sbp2.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: sbp2.c,v 1.18.4.1 2004/07/02 17:27:56 he Exp $ */
    2 
    3 /*
    4  * Copyright (c) 2001,2002 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by James Chacon.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *      This product includes software developed by the NetBSD
   21  *      Foundation, Inc. and its contributors.
   22  * 4. Neither the name of The NetBSD Foundation nor the names of its
   23  *    contributors may be used to endorse or promote products derived
   24  *    from this software without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36  * POSSIBILITY OF SUCH DAMAGE.
   37  */
   38 
   39 #include <sys/cdefs.h>
   40 __KERNEL_RCSID(0, "$NetBSD: sbp2.c,v 1.18.4.1 2004/07/02 17:27:56 he Exp $");
   41 
   42 #include <sys/param.h>
   43 #include <sys/kernel.h>
   44 #include <sys/device.h>
   45 #include <sys/systm.h>
   46 #include <sys/malloc.h>
   47 #include <sys/lock.h>
   48 
   49 #include <machine/bus.h>
   50 #include <machine/limits.h>
   51 
   52 #include <dev/std/ieee1212reg.h>
   53 #include <dev/std/ieee1212var.h>
   54 #include <dev/ieee1394/ieee1394reg.h>
   55 #include <dev/ieee1394/ieee1394var.h>
   56 #include <dev/ieee1394/sbp2reg.h>
   57 #include <dev/ieee1394/sbp2var.h>
   58 #include <dev/ieee1394/sbpscsireg.h>
   59 
   60 static void sbp2_print_data(struct p1212_data *);
   61 static void sbp2_print_dir(struct p1212_dir *);
   62 static void sbp2_login(struct sbp2 *, struct sbp2_lun *);
   63 static void sbp2_login_ans(struct ieee1394_abuf *, int);
   64 static void sbp2_login_resp(struct ieee1394_abuf *, int);
   65 static struct sbp2_lun *sbp2_alloc_lun(u_int32_t, u_int32_t, u_int32_t,
   66     u_int32_t, u_int32_t);
   67 static void sbp2_logout(struct sbp2 *, struct sbp2_lun *);
   68 static void sbp2_relogin(struct ieee1394_softc *, void *);
   69 static struct sbp2_orb *sbp2_alloc_orb(void);
   70 static void sbp2_free_orb(struct sbp2_orb *);
   71 static void sbp2_alloc_data_mapping(struct sbp2 *, struct sbp2_mapping *,
   72     u_char *, u_int32_t, u_int8_t);
   73 static void sbp2_free_data_mapping(struct sbp2 *, struct sbp2_mapping *);
   74 static u_int64_t sbp2_alloc_addr(struct sbp2 *);
   75 static void sbp2_free_addr(struct sbp2 *, u_int64_t);
   76 static void sbp2_orb_resp(struct ieee1394_abuf *, int);
   77 static void sbp2_data_resp(struct ieee1394_abuf *, int);
   78 static void sbp2_enable_status(struct ieee1394_abuf *, int);
   79 static void sbp2_null_resp(struct ieee1394_abuf *, int);
   80 static void sbp2_doorbell_reset(struct ieee1394_abuf *, int);
   81 static void sbp2_status_resp(struct sbp2_status *, void *);
   82 static struct sbp2_pagetable *sbp2_alloc_pt(struct uio *, u_int8_t, 
   83     struct sbp2_orb *);
   84 static void sbp2_pt_resp(struct ieee1394_abuf *, int);
   85 static void sbp2_free_pt(struct sbp2_pagetable *);
   86 
   87 #ifdef SBP2_DEBUG
   88 static void sbp2_agent_status(struct ieee1394_abuf *, int);
   89 #endif
   90 
   91 static CIRCLEQ_HEAD(, sbp2_orb) sbp2_freeorbs =
   92     CIRCLEQ_HEAD_INITIALIZER(sbp2_freeorbs);
   93 static struct simplelock sbp2_freeorbs_lock = SIMPLELOCK_INITIALIZER;
   94 static struct sbp2_orb status_orb;
   95 static TAILQ_HEAD(, sbp2_map) sbp2_maps =
   96     TAILQ_HEAD_INITIALIZER(sbp2_maps);
   97 static struct simplelock sbp2_maps_lock = SIMPLELOCK_INITIALIZER;
   98 
   99 #ifdef SBP2_DEBUG
  100 #define DPRINTF(x)      if (sbp2debug) printf x
  101 #define DPRINTFN(n,x)   if (sbp2debug>(n)) printf x
  102 int     sbp2debug = 3;
  103 #else
  104 #define DPRINTF(x)
  105 #define DPRINTFN(n,x)
  106 #endif
  107 
  108 static void
  109 sbp2_print_data(struct p1212_data *data)
  110 {
  111         switch (data->com.key.key_value) {
  112         case SBP2_KEYVALUE_Command_Set:
  113                 printf("SBP2 Command Set: ");
  114                 if (data->com.key.val == SBPSCSI_COMMAND_SET)
  115                         printf("SCSI 2\n");
  116                 else
  117                         printf("0x%08x\n", data->val);
  118                 break;
  119         case SBP2_KEYVALUE_Unit_Characteristics:
  120                 printf("SBP2 Unit Characteristics: 0x%08x\n",data->com.key.val);
  121                 break;
  122         case SBP2_KEYVALUE_Command_Set_Revision:
  123                 printf("SBP2 Command Set Revision: 0x%08x\n",data->com.key.val);
  124                 break;
  125         case SBP2_KEYVALUE_Command_Set_Spec_Id:
  126                 printf("SBP2 Command Set Spec Id: 0x%08x\n", data->com.key.val);
  127                 break;
  128         case SBP2_KEYVALUE_Firmware_Revision:
  129                 printf("SBP2 Firmware Revision: 0x%08x\n", data->com.key.val);
  130                 break;
  131         case SBP2_KEYVALUE_Reconnect_Timeout:
  132                 printf("SBP2 Reconnect Timeout: 0x%08x\n", data->com.key.val);
  133                 break;
  134         case SBP2_KEYVALUE_Unit_Unique_Id:
  135                 printf("SBP2 Unit Unique Id: 0x%08x\n", data->com.key.val);
  136                 break;
  137         case P1212_KEYVALUE_Unit_Dependent_Info:
  138                 if (data->com.key.key_type == P1212_KEYTYPE_Immediate) 
  139                         printf("SBP2 Logical Unit Number: 0x%08x\n",
  140                             data->com.key.val);
  141                 else if (data->com.key.key_type == P1212_KEYTYPE_Offset) 
  142                         printf("SBP2 Management Agent: 0x%08x\n",
  143                             data->com.key.val);
  144                 break;
  145         default:
  146                 printf("Unknown SBP2 key and value: 0x%08x 0x%08x\n",
  147                     data->com.key.key_value, data->com.key.val);
  148                 break;
  149         }
  150         return;
  151 }
  152 
  153 static void
  154 sbp2_print_dir(struct p1212_dir *dir)
  155 {
  156         switch(dir->com.key.key_type) {
  157         case SBP2_KEYVALUE_Logical_Unit_Directory:
  158                 printf("Logical Unit\n");
  159                 break;
  160         default:
  161                 printf("Unknown SBP2 key and value: 0x%08x 0x%08x\n",
  162                     dir->com.key.key_value, dir->com.key.val);
  163                 break;
  164         }
  165         return;
  166 }
  167 
  168 #define VALID_SBP2_IMM(data) { \
  169 if (data->com.key.key_type != P1212_KEYTYPE_Immediate) { \
  170         DPRINTF(("Unknown SBP2 key and value: 0x%08x 0x%08x\n", \
  171                     data->com.key.key_value, data->com.key.val)); \
  172         break; \
  173 } \
  174 } 
  175 
  176 struct sbp2 *
  177 sbp2_init(struct ieee1394_softc *sc, struct p1212_dir *udir)
  178 {
  179         struct sbp2 *sbp2;
  180         struct sbp2_map *sbp2_map;
  181         struct p1212_data *data;
  182         struct p1212_dir *dir;
  183         struct sbp2_lun *lun;
  184         u_int32_t *luns;
  185         int32_t cmd_spec_id, cmd_set, cmd_set_rev;
  186         int i, luncnt, found;
  187 
  188         sbp2 = malloc(sizeof (struct sbp2), M_1394DATA, M_WAITOK|M_ZERO);
  189         luns = NULL;
  190         luncnt = 0;
  191 
  192         sbp2->sc = sc;
  193         sc->sc1394_callback.sc1394_reset = sbp2_relogin;
  194         sc->sc1394_callback.sc1394_resetarg = sbp2;
  195         simple_lock_init(&sbp2->orblist_lock);
  196 
  197         found = 0;
  198         simple_lock(&sbp2_maps_lock);
  199         if (!TAILQ_EMPTY(&sbp2_maps)) {
  200                 TAILQ_FOREACH(sbp2_map, &sbp2_maps, map_list) {
  201                         if (sbp2_map->sc_bus ==
  202                             (struct ieee1394_softc *)sc->sc1394_dev.dv_parent) {
  203                                 sbp2_map->refcnt++;
  204                                 found = 1;
  205                                 sbp2->map = sbp2_map;
  206                                 break;
  207                         }
  208                 }
  209         }
  210         simple_unlock(&sbp2_maps_lock);
  211         if (!found) {
  212                 sbp2_map = malloc(sizeof (struct sbp2_map), M_1394DATA,
  213                     M_WAITOK|M_ZERO);
  214                 simple_lock_init(&sbp2_map->maplock);
  215                 simple_lock(&sbp2_map->maplock);
  216                 simple_lock(&sbp2_maps_lock);
  217                 TAILQ_INSERT_TAIL(&sbp2_maps, sbp2_map, map_list);
  218                 simple_unlock(&sbp2_maps_lock);
  219                 sbp2_map->sc_bus =
  220                     (struct ieee1394_softc *)sc->sc1394_dev.dv_parent;
  221                 sbp2_map->refcnt = 1;
  222                 sbp2->map = sbp2_map;
  223                 simple_unlock(&sbp2_map->maplock);
  224                 
  225                 status_orb.cmd.ab_addr = sbp2_alloc_addr(sbp2);
  226                 status_orb.cmd.ab_length = SBP2_STATUS_SIZE;
  227                 status_orb.cmd.ab_data = malloc(SBP2_STATUS_SIZE, M_1394DATA,
  228                     M_WAITOK|M_ZERO);
  229                 status_orb.cmd.ab_req = sc;
  230                 status_orb.cmd.ab_cb = sbp2_orb_resp;
  231                 status_orb.cmd.ab_cbarg = &status_orb;
  232                 status_orb.cmd.ab_tcode = IEEE1394_TCODE_WRITE_REQ_BLOCK;
  233                 status_orb.state = SBP2_ORB_STATUS_STATE;
  234                 status_orb.sbp2 = sbp2;
  235                 sc->sc1394_callback.sc1394_inreg(&status_orb.cmd, 0);
  236         } 
  237         
  238         TAILQ_INIT(&sbp2->luns);
  239         CIRCLEQ_INIT(&sbp2->orbs);
  240 
  241         TAILQ_FOREACH(data, &udir->data_root, data) {
  242                 switch (data->com.key.key_value) {
  243                 case SBP2_KEYVALUE_Command_Set_Spec_Id:
  244                         VALID_SBP2_IMM(data);
  245                         sbp2->cmd_spec_id = data->com.key.val;
  246                         data->print = sbp2_print_data;
  247                         break;
  248                 case SBP2_KEYVALUE_Command_Set:
  249                         VALID_SBP2_IMM(data);
  250                         sbp2->cmd_set = data->com.key.val;
  251                         data->print = sbp2_print_data;
  252                         break;
  253                 case SBP2_KEYVALUE_Unit_Characteristics:
  254                         VALID_SBP2_IMM(data);
  255                         sbp2->orb_size = (data->com.key.val & 0xff);
  256                         sbp2->orb_timeout = ((data->com.key.val >> 8) & 0xff);
  257                         data->print = sbp2_print_data;
  258                         break;
  259                 case SBP2_KEYVALUE_Command_Set_Revision:
  260                         VALID_SBP2_IMM(data);
  261                         sbp2->cmd_set_rev = data->com.key.val;
  262                         data->print = sbp2_print_data;
  263                         break;
  264                 case SBP2_KEYVALUE_Firmware_Revision:
  265                         VALID_SBP2_IMM(data);
  266                         sbp2->firmware_rev = data->com.key.val;
  267                         data->print = sbp2_print_data;
  268                         break;
  269                 case SBP2_KEYVALUE_Reconnect_Timeout:
  270                         VALID_SBP2_IMM(data);
  271                         sbp2->max_reconnect = (data->com.key.val & 0xffff);
  272                         data->print = sbp2_print_data;
  273                         break;
  274                 case SBP2_KEYVALUE_Logical_Unit_Number:
  275                         /*
  276                          * This is either lun or management reg offset 
  277                          * depending on type. 
  278                          */
  279 
  280                         if (data->com.key.key_type == P1212_KEYTYPE_Immediate) {
  281 
  282                                 /* Save until done with data entries. */
  283                                 luncnt++;
  284                                 luns = realloc(luns, sizeof(u_int32_t) * luncnt,
  285                                     M_1394DATA, M_WAITOK);
  286                                 luns[luncnt - 1] = data->com.key.val;
  287                                 data->print = sbp2_print_data;
  288                         }
  289                         if (data->com.key.key_type == P1212_KEYTYPE_Offset) {
  290                                 if (data->com.key.val < SBP2_MIN_MGMT_OFFSET) {
  291                                         DPRINTF(("Management reg offset too "
  292                                             "small: 0x%08x\n", 
  293                                             data->com.key.val));
  294                                         break;
  295                                 }
  296                                 sbp2->mgmtreg = (data->com.key.val * 4) + 
  297                                     CSR_BASE;
  298                                 data->print = sbp2_print_data;
  299                         }
  300                         break;
  301                 case SBP2_KEYVALUE_Unit_Unique_Id:
  302                         if (data->com.key.key_type != P1212_KEYTYPE_Leaf) {
  303                                 DPRINTF(("Unknown SBP2 key and value: "
  304                                             "0x%08x 0x%08x\n", \
  305                                             data->com.key.key_value,
  306                                             data->com.key.val)); \
  307                                 break;
  308                         }
  309 #ifdef DIAGNOSTIC
  310                         if (data->leafdata == NULL) {
  311                                 printf ("sbp2: No leaf data?\n");
  312                                 break;
  313                         }
  314                         if (data->leafdata->len != 2) {
  315                                 printf ("sbp2: Unique ID must be length 2\n");
  316                                 break;
  317                         }
  318 #endif
  319                         memcpy (&sbp2->uniq_id, &data->leafdata->data[0], 4);
  320                         memcpy (&sbp2->uniq_id+4, &data->leafdata->data[1], 4);
  321                         data->print = sbp2_print_data;
  322                         break;
  323                 default:
  324                         break;
  325                 }
  326         }
  327 
  328         for (i = 0; i < luncnt; i++) {
  329                 lun = sbp2_alloc_lun(luns[i], sbp2->orb_size,
  330                     sbp2->cmd_spec_id, sbp2->cmd_set, sbp2->cmd_set_rev);
  331                 sbp2->luncnt++;
  332                 TAILQ_INSERT_TAIL(&sbp2->luns, lun, lun_list);
  333         }
  334         free(luns, M_1394DATA);
  335 
  336         /*
  337          * A little complicated since entries can come in any order in a ROM
  338          * directory.
  339          *
  340          * For each logical unit directory, scan it for overriding command set
  341          * values. Then go back and for each logical unit found setup a lun
  342          * with the appropriate default or overriden cmd_set values.
  343          */
  344 
  345         TAILQ_FOREACH(dir, &udir->subdir_root, dir) {
  346                 if (dir->com.key.key_value ==
  347                     SBP2_KEYVALUE_Logical_Unit_Directory) {
  348                         dir->print = sbp2_print_dir;
  349                         cmd_spec_id = -1;
  350                         cmd_set = -1;
  351                         cmd_set_rev = -1;
  352                         TAILQ_FOREACH(data, &dir->data_root, data) {
  353                                 switch(data->com.key.key_value) {
  354                                 case SBP2_KEYVALUE_Command_Set_Spec_Id:
  355                                         cmd_spec_id = data->com.key.val;
  356                                         data->print = sbp2_print_data;
  357                                         break;
  358                                 case SBP2_KEYVALUE_Command_Set:
  359                                         cmd_set = data->com.key.val;
  360                                         data->print = sbp2_print_data;
  361                                         break;
  362                                 case SBP2_KEYVALUE_Command_Set_Revision:
  363                                         cmd_set_rev = data->com.key.val;
  364                                         data->print = sbp2_print_data;
  365                                         break;
  366                                 default:
  367                                         break;
  368                                 }
  369                         }
  370                         if (cmd_spec_id == -1)
  371                                 cmd_spec_id = sbp2->cmd_spec_id;
  372                         if (cmd_set == -1)
  373                                 cmd_set = sbp2->cmd_set;
  374                         if (cmd_set_rev == -1)
  375                                 cmd_set_rev = sbp2->cmd_set_rev;
  376 
  377                         TAILQ_FOREACH(data, &dir->data_root, data) {
  378                                 if (data->com.key.key_value ==
  379                                     SBP2_KEYVALUE_Logical_Unit_Number) {
  380                                         lun = sbp2_alloc_lun(data->com.key.val,
  381                                             sbp2->orb_size, cmd_spec_id,
  382                                             cmd_set, cmd_set_rev);
  383                                         TAILQ_INSERT_TAIL(&sbp2->luns, lun,
  384                                             lun_list);
  385                                         sbp2->luncnt++;
  386                                         data->print = sbp2_print_data;
  387                                 }
  388                         }
  389                 }
  390         }
  391         return sbp2;
  392 }
  393 
  394 #undef VALID_SBP2_IMM
  395 
  396 static struct sbp2_lun *
  397 sbp2_alloc_lun(u_int32_t luninfo, u_int32_t orb_size, u_int32_t cmd_spec_id,
  398     u_int32_t cmd_set, u_int32_t cmd_set_rev)
  399 {
  400         struct sbp2_lun *lun;
  401 
  402         lun = malloc(sizeof(struct sbp2_lun), M_1394DATA, M_WAITOK|M_ZERO);
  403 
  404         lun->cmd_spec_id = cmd_spec_id;
  405         lun->cmd_set = cmd_set;
  406         lun->cmd_set_rev = cmd_set_rev;
  407 
  408         lun->lun = luninfo & 0xffff;
  409         lun->ordered = ((luninfo >> 22) & 0x1);
  410         lun->dev_type = ((luninfo >> 16) & 0x1f);
  411         lun->command.ab_data = malloc(orb_size, M_1394DATA, M_WAITOK|M_ZERO);
  412         lun->doorbell.ab_data = malloc(orb_size, M_1394DATA, M_WAITOK|M_ZERO);
  413         lun->status.ab_data = malloc(orb_size, M_1394DATA, M_WAITOK|M_ZERO);
  414         return lun;
  415 }
  416 
  417 static void
  418 sbp2_login(struct sbp2 *sbp2, struct sbp2_lun *lun)
  419 {
  420         struct sbp2_orb *orb;
  421         u_int64_t respaddr, orbaddr;
  422 
  423         orb = sbp2_alloc_orb();
  424 
  425         lun->command.ab_length = 8;
  426         lun->command.ab_req = sbp2->sc;
  427         lun->command.ab_cb = sbp2_null_resp;
  428         lun->command.ab_cbarg = sbp2;
  429 
  430         orbaddr = sbp2_alloc_addr(sbp2);
  431         lun->command.ab_addr = sbp2->mgmtreg;
  432         lun->command.ab_data[0] = IEEE1394_CREATE_ADDR_HIGH(orbaddr);
  433         lun->command.ab_data[1] = IEEE1394_CREATE_ADDR_LOW(orbaddr);
  434         lun->command.ab_tcode = IEEE1394_TCODE_WRITE_REQ_BLOCK;
  435 
  436         respaddr = sbp2_alloc_addr(sbp2);
  437         orb->cmd.ab_req = sbp2->sc;
  438         orb->cmd.ab_length = SBP2_LOGIN_SIZE;
  439         orb->cmd.ab_tcode = IEEE1394_TCODE_READ_REQ_BLOCK;
  440         orb->cmd.ab_data[0] = 0;
  441         orb->cmd.ab_data[1] = 0;
  442         orb->cmd.ab_data[2] = IEEE1394_CREATE_ADDR_HIGH(respaddr);
  443         orb->cmd.ab_data[3] = IEEE1394_CREATE_ADDR_LOW(respaddr);
  444         orb->cmd.ab_data[4] |= SBP2_LOGIN_SET_EXCLUSIVE;
  445         orb->cmd.ab_data[4] |= SBP2_ORB_NOTIFY_MASK;
  446 
  447         /* Ask for reasonable reconnect time. */
  448         orb->cmd.ab_data[4] |= SBP2_LOGIN_SET_RECONNECT(SBP2_RECONNECT);
  449         orb->cmd.ab_data[4] |= lun->loginid;
  450         orb->cmd.ab_data[4] = htonl(orb->cmd.ab_data[4]);
  451 
  452         /* Allow max login response. */
  453         orb->cmd.ab_data[5] = htonl(SBP2_LOGIN_MAX_RESP);
  454         orb->cmd.ab_data[6] = IEEE1394_CREATE_ADDR_HIGH(status_orb.cmd.ab_addr);
  455         orb->cmd.ab_data[7] = IEEE1394_CREATE_ADDR_LOW(status_orb.cmd.ab_addr);
  456 
  457         orb->cmd.ab_addr = orbaddr;
  458         orb->cmd.ab_cb = sbp2_login_ans;
  459         orb->cmd.ab_cbarg = orb;
  460         orb->sbp2 = sbp2;
  461 
  462         lun->doorbell.ab_addr = respaddr;
  463         lun->doorbell.ab_length = SBP2_LOGIN_MAX_RESP;
  464         lun->doorbell.ab_data = malloc (SBP2_LOGIN_MAX_RESP, M_1394DATA,
  465             M_WAITOK|M_ZERO);
  466         lun->doorbell.ab_req = sbp2->sc;
  467         lun->doorbell.ab_cb = sbp2_login_resp;
  468         lun->doorbell.ab_cbarg = lun;
  469         lun->doorbell.ab_tcode = IEEE1394_TCODE_WRITE_REQ_BLOCK;
  470 
  471         sbp2->sc->sc1394_callback.sc1394_inreg(&orb->cmd, 0);
  472         sbp2->sc->sc1394_callback.sc1394_inreg(&lun->doorbell, 0);
  473         sbp2->sc->sc1394_callback.sc1394_write(&lun->command);
  474 
  475         simple_lock(&sbp2->orblist_lock);
  476         orb = sbp2_alloc_orb();
  477         orb->cmd.ab_addr = sbp2_alloc_addr(sbp2);
  478         orb->cmd.ab_req = sbp2->sc;
  479         orb->cmd.ab_tcode = IEEE1394_TCODE_READ_REQ_BLOCK;
  480         orb->cmd.ab_length = (sbp2->orb_size * 4);
  481         orb->cmd.ab_data[0] = htonl(SBP2_ORB_NULL_POINTER);
  482         orb->cmd.ab_data[4] = htonl(SBP2_ORB_FMT_DUMMY_MASK);
  483 
  484         /*
  485          * Go ahead and set the notify bit. Some SBP2 devices always
  486          * seem to return status on a dummy orb regardless so don't 2nd guess.
  487          */
  488 
  489         orb->cmd.ab_data[4] |= htonl(SBP2_ORB_NOTIFY_MASK);
  490         orb->cmd.ab_subok = 1;
  491         orb->cmd.ab_cb = sbp2_orb_resp;
  492         orb->cmd.ab_cbarg = orb;
  493         orb->sbp2 = sbp2;
  494 
  495         orb->cb = sbp2_status_resp;
  496         CIRCLEQ_INSERT_HEAD(&sbp2->orbs, orb, orb_list);
  497         simple_unlock(&sbp2->orblist_lock);
  498         sbp2->sc->sc1394_callback.sc1394_inreg(&orb->cmd, 0);
  499 
  500         return;
  501 }
  502 
  503 static void
  504 sbp2_login_ans(struct ieee1394_abuf *ab, int rcode)
  505 {
  506         struct ieee1394_softc *sc = ab->ab_req;
  507         struct sbp2_orb *orb = ab->ab_cbarg;
  508 
  509         /* Got a read so allocate the buffer and write out the response. */
  510 
  511         if (orb->state != SBP2_ORB_INIT_STATE) {
  512                 orb->cmd.ab_tcode = IEEE1394_TCODE_READ_REQ_BLOCK;
  513                 sbp2_free_orb(orb);
  514                 return;
  515         }
  516 
  517         if (rcode) {
  518                 DPRINTF(("sbp2_login: Bad return code: %d\n", rcode));
  519                 orb->cmd.ab_tcode = IEEE1394_TCODE_READ_REQ_BLOCK;
  520                 sbp2_free_orb(orb);
  521                 return;
  522         }
  523 
  524         orb->cmd.ab_tcode = IEEE1394_TCODE_READ_RESP_BLOCK;
  525         orb->state = SBP2_ORB_SENT_STATE;
  526         sc->sc1394_callback.sc1394_write(&orb->cmd);
  527         return;
  528 }
  529 
  530 static void
  531 sbp2_login_resp(struct ieee1394_abuf *ab, int rcode)
  532 {
  533         struct ieee1394_softc *sc = ab->ab_req;
  534         struct sbp2_lun *lun = ab->ab_cbarg;
  535         struct sbp2_orb *orb;
  536         struct sbp2 *sbp2 = lun->command.ab_cbarg;
  537 
  538 #ifdef SBP2_DEBUG
  539         int i;
  540 #endif
  541 
  542         sc->sc1394_callback.sc1394_unreg(&lun->doorbell, 1);
  543 
  544         if (rcode) {
  545                 DPRINTF(("Bad return code: %d\n", rcode));
  546                 return;
  547         }
  548 
  549         DPRINTF(("csr: 0x%016qx\n", (quad_t)ab->ab_addr));
  550 #ifdef SBP2_DEBUG
  551         if (sbp2debug > 2) 
  552                 for (i = 0; i < (ab->ab_retlen / 4); i++) 
  553                         DPRINTF(("%d: 0x%08x\n", i, ntohl(ab->ab_data[i])));
  554 #endif
  555 
  556         lun->cmdreg = SBP2_LOGINRESP_CREATE_CMDREG(ntohl(ab->ab_data[1]),
  557             ntohl(ab->ab_data[2]));
  558         if (SBP2_LOGINRESP_GET_LENGTH(ntohl(ab->ab_data[0])) ==
  559             SBP2_LOGIN_MAX_RESP)
  560                 lun->reconnect =
  561                     SBP2_LOGINRESP_GET_RECONNECT(ntohl(ab->ab_data[3]));
  562         lun->loginid = SBP2_LOGINRESP_GET_LOGINID(ntohl(ab->ab_data[0]));
  563         lun->login_flag = SBP2_LOGGED_IN;
  564 
  565         lun->doorbell.ab_addr = lun->cmdreg + SBP2_CMDREG_AGENT_RESET;
  566         lun->doorbell.ab_length = 4;
  567         lun->doorbell.ab_req = sc;
  568         lun->doorbell.ab_cb = sbp2_enable_status;
  569         lun->doorbell.ab_cbarg = lun;
  570         lun->doorbell.ab_tcode = IEEE1394_TCODE_WRITE_REQ_QUAD;
  571         lun->doorbell.ab_data[0] = 0xffffffff;
  572 
  573         /*
  574          * Reset the state engine, plug the address of the first orb into
  575          * the orb pointer and off we go.
  576          */
  577 
  578         lun->command.ab_addr = lun->cmdreg + SBP2_CMDREG_ORB_POINTER;
  579         lun->command.ab_length = 8;
  580         lun->command.ab_req = sc;
  581         lun->command.ab_cb = sbp2_doorbell_reset;
  582         lun->command.ab_cbarg = lun;
  583         lun->command.ab_tcode = IEEE1394_TCODE_WRITE_REQ_BLOCK;
  584         simple_lock(&sbp2->orblist_lock);
  585         orb = CIRCLEQ_LAST(&sbp2->orbs);
  586         simple_lock(&orb->orb_lock);
  587         lun->command.ab_data[0] = IEEE1394_CREATE_ADDR_HIGH(orb->cmd.ab_addr);
  588         lun->command.ab_data[1] = IEEE1394_CREATE_ADDR_LOW(orb->cmd.ab_addr);
  589         simple_unlock(&orb->orb_lock);
  590         simple_unlock(&sbp2->orblist_lock);
  591         sc->sc1394_callback.sc1394_write(&lun->doorbell);
  592         sc->sc1394_callback.sc1394_write(&lun->command);
  593         lun->state = SBP2_STATE_ACTIVE;
  594 
  595         return;
  596 }
  597 
  598 static void
  599 sbp2_enable_status(struct ieee1394_abuf *ab, int rcode)
  600 {
  601         struct sbp2_lun *lun = ab->ab_cbarg;
  602 
  603         lun->doorbell.ab_cb = sbp2_doorbell_reset;
  604         lun->doorbell.ab_addr = lun->cmdreg +
  605             SBP2_CMDREG_UNSOLICITED_STATUS_ENABLE;
  606         ab->ab_req->sc1394_callback.sc1394_write(&lun->doorbell);
  607         return;
  608 }
  609 
  610 static void
  611 sbp2_doorbell_reset(struct ieee1394_abuf *ab, int rcode)
  612 {
  613         struct sbp2_lun *lun = ab->ab_cbarg;
  614 
  615         if (lun->cmdreg)
  616                 lun->doorbell.ab_addr = lun->cmdreg + SBP2_CMDREG_DOORBELL;
  617         return;
  618 }
  619 
  620 static void
  621 sbp2_null_resp(struct ieee1394_abuf *ab, int rcode)
  622 {
  623         return;
  624 }
  625 
  626 static void
  627 sbp2_status_resp(struct sbp2_status *status, void *arg)
  628 {
  629         DPRINTFN(1, ("Got a status response in sbp2_status_resp\n"));
  630         DPRINTFN(1, ("status: resp 0x%04x, sbp_status 0x%04x\n", status->resp,
  631                      status->sbp_status));
  632 }
  633 
  634 int
  635 sbp2_match(struct p1212_dir *udir)
  636 {
  637         struct p1212_key **keys;
  638 
  639         keys = p1212_find(udir, P1212_KEYTYPE_Immediate,
  640                           P1212_KEYVALUE_Unit_Spec_Id, 0);
  641         if (keys && keys[0]->val == SBP2_UNIT_SPEC_ID) {
  642                 keys = p1212_find(udir, P1212_KEYTYPE_Immediate,
  643                                   P1212_KEYVALUE_Unit_Sw_Version, 0);
  644                 if (keys && keys[0]->val == SBP2_UNIT_SW_VERSION)
  645                         return 1;
  646         }
  647         return 0;
  648 }
  649 
  650 static void
  651 sbp2_logout(struct sbp2 *sbp2, struct sbp2_lun *lun)
  652 {
  653         DPRINTF(("Called sbp2_logout\n"));
  654         return;
  655 }
  656 
  657 void
  658 sbp2_free(struct sbp2 *sbp2)
  659 {
  660         struct sbp2_orb *orb;
  661         struct sbp2_lun *lun;
  662 
  663         while (!CIRCLEQ_EMPTY(&sbp2->orbs)) {
  664                 orb = CIRCLEQ_FIRST(&sbp2->orbs);
  665                 (void)sbp2_abort(orb);
  666         }
  667         while (TAILQ_FIRST(&sbp2->luns) != NULL) {
  668                 lun = TAILQ_FIRST(&sbp2->luns);
  669                 TAILQ_REMOVE(&sbp2->luns, lun, lun_list);
  670                 if (lun->login_flag)
  671                         sbp2_logout(sbp2, lun);
  672                 free(lun, M_1394DATA);
  673         }
  674         simple_lock(&sbp2_maps_lock);
  675         if (!--sbp2->map->refcnt) {
  676                 TAILQ_REMOVE(&sbp2_maps, sbp2->map, map_list);
  677                 free(sbp2->map, M_1394DATA);
  678         }
  679         simple_unlock(&sbp2_maps_lock);
  680         sbp2->sc->sc1394_callback.sc1394_unreg(&status_orb.cmd, 1);
  681         free(status_orb.cmd.ab_data, M_1394DATA);
  682 }
  683 
  684 #ifdef FW_DEBUG
  685 extern int fwdebug;
  686 #endif
  687 
  688 void *
  689 sbp2_runcmd(struct sbp2 *sbp2, struct sbp2_cmd *cmd)
  690 {
  691 #ifdef DIAGNOSTIC
  692         int found = 0;
  693 #endif
  694         struct sbp2_orb *orb, *toporb;
  695         struct ieee1394_softc *psc =
  696             (struct ieee1394_softc *) sbp2->sc->sc1394_dev.dv_parent;
  697         struct sbp2_lun *lun;
  698         struct uio io;
  699         struct iovec iov;
  700         u_int32_t t;
  701         u_int64_t addr;
  702 
  703 #if defined(FW_DEBUG) && defined(SBP2_DEBUG)
  704         if (sbp2debug > 2)
  705                 fwdebug = 3;
  706 #endif
  707         TAILQ_FOREACH(lun, &sbp2->luns, lun_list)
  708                 if (lun->lun == cmd->lun) {
  709 #ifdef DIAGNOSTIC
  710                         found = 1;
  711 #endif
  712                         break;
  713                 }
  714 
  715 #ifdef DIAGNOSTIC
  716         if (!found) {
  717                 DPRINTF(("Got a request for an invalid lun: %d\n", cmd->lun));
  718                 return NULL;
  719         }
  720         if (cmd->cmdlen % 4) {
  721                 DPRINTF(("cmdlen is not 4 byte aligned: %d\n", cmd->cmdlen));
  722                 return NULL;
  723         }
  724         if ((cmd->cmdlen / 4) > (sbp2->orb_size - 5)) {
  725                 DPRINTF(("cmdlen too large: len - %d max - %d\n",
  726                             cmd->cmdlen / 4, sbp2->orb_size - 5));
  727                 return NULL;
  728         }
  729 #endif
  730         if (lun->login_flag != SBP2_LOGGED_IN)
  731                 sbp2_login(sbp2, lun);
  732 
  733         orb = sbp2_alloc_orb();
  734 
  735         orb->cmd.ab_addr = sbp2_alloc_addr(sbp2);
  736         orb->cb = cmd->cb;
  737         orb->cb_arg = cmd->cb_arg;
  738         orb->cmd.ab_subok = 1;
  739 
  740         orb->cmd.ab_req = sbp2->sc;
  741         orb->cmd.ab_tcode = IEEE1394_TCODE_READ_REQ_BLOCK;
  742         orb->cmd.ab_length = (sbp2->orb_size * 4);
  743         orb->cmd.ab_data[0] = htonl(SBP2_ORB_NULL_POINTER);
  744         orb->cmd.ab_data[4] |= SBP2_ORB_NOTIFY_MASK;
  745 
  746         if (cmd->rw == SBP_WRITE)
  747                 orb->cmd.ab_data[4] |= SBP2_ORB_RW_MASK;
  748         orb->cmd.ab_data[4] |= SBP2_ORB_SET_SPEED(sbp2->sc->sc1394_link_speed);
  749         orb->cmd.ab_data[4] = htonl(orb->cmd.ab_data[4]);
  750 
  751         memcpy(&orb->cmd.ab_data[5], cmd->cmd, cmd->cmdlen);
  752 
  753         orb->cmd.ab_cb = sbp2_orb_resp;
  754         orb->cmd.ab_cbarg = orb;
  755         orb->lun = lun;
  756         orb->sbp2 = sbp2;
  757 
  758         if (cmd->data) {
  759                 if ((cmd->datalen == 0) || (cmd->datalen > SBP2_MAXPHYS)) {
  760                         /* Handle uio and large data chunks via page tables. */
  761                         if (cmd->datalen) {
  762                                 io.uio_iov = &iov;
  763                                 io.uio_iovcnt = 1;
  764                                 io.uio_offset = 0;
  765                                 io.uio_resid = cmd->datalen;
  766                                 io.uio_segflg = UIO_SYSSPACE;
  767                                 if (cmd->rw == SBP_WRITE)
  768                                         io.uio_rw = UIO_WRITE;
  769                                 else
  770                                         io.uio_rw = UIO_READ;
  771                                 io.uio_procp = NULL;
  772                                 iov.iov_base = cmd->data;
  773                                 iov.iov_len = cmd->datalen;
  774                                 orb->pt = sbp2_alloc_pt(&io, cmd->rw, orb);
  775                         } else 
  776                                 orb->pt = 
  777                                     sbp2_alloc_pt((struct uio *)cmd->data, 
  778                                         cmd->rw, orb);
  779                         if (orb->pt == NULL) {
  780                                 sbp2_free_orb (orb);
  781                                 return NULL;
  782                         }
  783                         orb->cmd.ab_data[2] =
  784                             IEEE1394_CREATE_ADDR_HIGH(orb->pt->pt_ent.ab_addr);
  785                         orb->cmd.ab_data[2] |=
  786                             htonl((0xffc0 | psc->sc1394_node_id) << 16);
  787                         orb->cmd.ab_data[3] =
  788                             IEEE1394_CREATE_ADDR_LOW(orb->pt->pt_ent.ab_addr);
  789                         t = SBP2_ORB_SET_MAXTRANS(sbp2->sc->sc1394_link_speed);
  790                         orb->cmd.ab_data[4] |= htonl(t);
  791                         orb->cmd.ab_data[4] |= htonl(SBP2_ORB_PAGETABLE_MASK);
  792                         orb->cmd.ab_data[4] |= htonl(orb->pt->pt_cnt);
  793                 } else {
  794                         sbp2_alloc_data_mapping(sbp2, &orb->data_map, cmd->data,
  795                             cmd->datalen, cmd->rw);
  796                         orb->data_map.orb = orb;
  797                         orb->data.ab_length = cmd->datalen;
  798                         orb->data.ab_addr = orb->data_map.fwaddr;
  799                         orb->data.ab_cb = sbp2_data_resp;
  800                         orb->data.ab_cbarg = &orb->data_map;
  801                         orb->data.ab_data = (u_int32_t *)cmd->data;
  802                         orb->data.ab_req = sbp2->sc;
  803                         if (cmd->rw == SBP_WRITE)
  804                                 orb->data.ab_tcode = 
  805                                     IEEE1394_TCODE_WRITE_REQ_BLOCK;
  806                         else
  807                                 orb->data.ab_tcode = 
  808                                     IEEE1394_TCODE_READ_REQ_BLOCK;
  809                         orb->cmd.ab_data[2] =
  810                             IEEE1394_CREATE_ADDR_HIGH(orb->data.ab_addr);
  811                         orb->cmd.ab_data[2] |=
  812                             htonl((0xffc0 | psc->sc1394_node_id) << 16);
  813                         orb->cmd.ab_data[3] =
  814                             IEEE1394_CREATE_ADDR_LOW(orb->data.ab_addr);
  815                         t = SBP2_ORB_SET_MAXTRANS(sbp2->sc->sc1394_link_speed);
  816                         orb->cmd.ab_data[4] |= htonl(t);
  817                         orb->cmd.ab_data[4] |= htonl(cmd->datalen);
  818                         sbp2->sc->sc1394_callback.sc1394_inreg(&orb->data, 1);
  819                 }
  820         }
  821 
  822         simple_lock(&sbp2->orblist_lock);
  823         toporb = CIRCLEQ_FIRST(&sbp2->orbs);
  824         simple_lock(&toporb->orb_lock);
  825         addr = orb->cmd.ab_addr;
  826         toporb->cmd.ab_data[0] = IEEE1394_CREATE_ADDR_HIGH(addr);
  827         toporb->cmd.ab_data[1] = IEEE1394_CREATE_ADDR_LOW(addr);
  828         sbp2->sc->sc1394_callback.sc1394_inreg(&orb->cmd, 0);
  829         if ((lun->state == SBP2_STATE_SUSPENDED) || 
  830             ((lun->state == SBP2_STATE_ACTIVE) && 
  831              (toporb->state != SBP2_ORB_INIT_STATE))) {
  832                 DPRINTFN(1, ("Ringing doorbell\n"));
  833                 toporb->state = SBP2_ORB_INIT_STATE;
  834                 toporb->db = 1;
  835                 toporb->dback = 0;
  836                 sbp2->sc->sc1394_callback.sc1394_write(&lun->doorbell);
  837         } else if (lun->state == SBP2_STATE_DEAD) {
  838                 CIRCLEQ_FOREACH(toporb, &orb->sbp2->orbs, orb_list) {
  839                         toporb->ack = 0;
  840                         toporb->status_rec = 0;
  841                         toporb->db = 0;
  842                         toporb->dback = 0;
  843                 }
  844                 toporb = CIRCLEQ_LAST(&sbp2->orbs);
  845                 lun->doorbell.ab_addr = lun->cmdreg + SBP2_CMDREG_AGENT_RESET;
  846                 lun->doorbell.ab_cb = sbp2_enable_status;
  847                 lun->command.ab_data[0] =
  848                     IEEE1394_CREATE_ADDR_HIGH(toporb->cmd.ab_addr);
  849                 lun->command.ab_data[1] =
  850                     IEEE1394_CREATE_ADDR_LOW(toporb->cmd.ab_addr);
  851                 toporb->state = SBP2_ORB_INIT_STATE;
  852                 sbp2->sc->sc1394_callback.sc1394_write(&lun->doorbell);
  853                 sbp2->sc->sc1394_callback.sc1394_write(&lun->command);
  854         }
  855         lun->state = SBP2_STATE_ACTIVE;
  856 
  857         CIRCLEQ_INSERT_HEAD(&sbp2->orbs, orb, orb_list);
  858         simple_unlock(&toporb->orb_lock);
  859         simple_unlock(&sbp2->orblist_lock);
  860 
  861         return orb;
  862 }
  863 
  864 #ifdef SBP2_DEBUG
  865 static void
  866 sbp2_agent_status(struct ieee1394_abuf *abuf, int status)
  867 {
  868         DPRINTF(("sbp2_agent_status: 0x%08x\n", ntohl(abuf->ab_data[0])));
  869         return;
  870 }
  871 #endif
  872 
  873 static void
  874 sbp2_orb_resp(struct ieee1394_abuf *abuf, int status)
  875 {
  876         struct sbp2_orb *statorb, *orb;
  877         u_int64_t addr;
  878         int found = 0;
  879         u_int32_t t;
  880 
  881         orb = abuf->ab_cbarg;
  882 
  883         DPRINTFN(1, ("orb addr: 0x%016qx\n", orb->cmd.ab_addr));
  884         DPRINTFN(1, ("orb next ptr: 0x%08x%08x\n", ntohl(orb->cmd.ab_data[0]), ntohl(orb->cmd.ab_data[1])));
  885         DPRINTFN(1, ("retlen: %d, length: %d\n", abuf->ab_retlen,
  886                      abuf->ab_length));
  887 
  888 #ifdef SBP2_DEBUG
  889         if ((sbp2debug > 3) && orb->lun) {
  890                 orb->lun->status.ab_addr = 
  891                     orb->lun->cmdreg + SBP2_CMDREG_AGENT_STATE;
  892                 orb->lun->status.ab_cb = sbp2_agent_status;
  893                 orb->lun->status.ab_cbarg = orb->lun;
  894                 orb->lun->status.ab_length = 4;
  895                 orb->lun->status.ab_req = orb->sbp2->sc;
  896                 orb->lun->status.ab_tcode = IEEE1394_TCODE_READ_REQ_QUAD;
  897                 orb->sbp2->sc->sc1394_callback.sc1394_read(&orb->lun->status);
  898         }
  899 #endif
  900         simple_lock(&orb->orb_lock);
  901 
  902         switch (orb->state) {
  903         case SBP2_ORB_INIT_STATE:
  904                 if (abuf->ab_tcode == IEEE1394_TCODE_READ_REQ_BLOCK) {
  905                         orb->state = SBP2_ORB_STATUS_STATE;
  906                         abuf->ab_tcode = IEEE1394_TCODE_READ_RESP_BLOCK;
  907                         abuf->ab_length = abuf->ab_retlen;
  908                         abuf->ab_req->sc1394_callback.sc1394_write(&orb->cmd);
  909                         break;
  910                 }
  911 
  912                 /* FALL THRU */
  913 
  914         case SBP2_ORB_STATUS_STATE:
  915 
  916                 /*
  917                  * If it's not the fifo addr then just resend the orb out as
  918                  * the doorbell was rung to reread.
  919                  */
  920 
  921                 if (orb->cmd.ab_addr != status_orb.cmd.ab_addr) {
  922                         /* An ack from a write */
  923 
  924                         /*
  925                          * Change engine state once this has been processed 
  926                          * and it's next pointer is the null pointer. 
  927                          */
  928 
  929                         if ((orb->cmd.ab_data[0] == 
  930                             ntohl(SBP2_ORB_NULL_POINTER)) &&
  931                             (orb->lun->state == SBP2_STATE_ACTIVE))
  932                                 orb->lun->state = SBP2_STATE_SUSPENDED;
  933                         if (orb->ack == 0) 
  934                                 orb->ack = 1;
  935                         else if ((orb->db == 1) && (orb->dback == 0)) 
  936                                 orb->dback = 1;
  937                         else
  938                                 panic ("Unknown packet received!");
  939                 } else {
  940 
  941                         /*
  942                          * The orb passed in is the generic status. Find the 
  943                          * one it goes with so status can be filled in and 
  944                          * passed back up.
  945                          */
  946 
  947                         addr = ntohl(abuf->ab_data[0]);
  948                         addr &= 0x0000ffff;
  949                         addr = (addr << 32);
  950                         addr |= ntohl(abuf->ab_data[1]);
  951                         simple_lock(&orb->sbp2->orblist_lock);
  952                         CIRCLEQ_FOREACH(statorb, &orb->sbp2->orbs, orb_list) {
  953                                 if (addr == statorb->cmd.ab_addr) {
  954                                         found = 1;
  955                                         break;
  956                                 }
  957                         }
  958                         simple_unlock(&orb->sbp2->orblist_lock);
  959                         simple_lock(&statorb->orb_lock);
  960 
  961                         /* XXX: Need to handle unsolicited correctly. */
  962                         if (SBP2_STATUS_GET_DEAD(ntohl(abuf->ab_data[0]))) {
  963                                 DPRINTFN(1, ("Transitioning to dead state\n"));
  964                                 statorb->lun->state = SBP2_STATE_DEAD;
  965                         }
  966                         if (!found) {
  967 #ifdef SBP2_DEBUG
  968                                 u_int32_t i = ntohl(abuf->ab_data[0]);
  969 #endif
  970                                 DPRINTF(("Got a status block for an unknown "
  971                                     "orb addr: 0x%016qx\n", addr));
  972                                 DPRINTF(("resp: 0x%x status: 0x%x len: 0x%x\n",
  973                                     SBP2_STATUS_GET_RESP(i),
  974                                     SBP2_STATUS_GET_STATUS(i),
  975                                     SBP2_STATUS_GET_LEN(i) - 1));
  976                                 return;
  977                         }
  978 
  979                         /*
  980                          * After it's been sent turn this into a dummy orb. 
  981                          * That way if the engine stalls and has to be 
  982                          * restarted this orb getting reread won't cause 
  983                          * duplicate work.
  984                          */
  985 
  986                         statorb->cmd.ab_data[4] |= 
  987                                 htonl(SBP2_ORB_FMT_DUMMY_MASK);
  988                         statorb->status.resp =
  989                             SBP2_STATUS_GET_RESP(ntohl(abuf->ab_data[0]));
  990                         statorb->status.sbp_status =
  991                             SBP2_STATUS_GET_STATUS(ntohl(abuf->ab_data[0]));
  992                         statorb->status.datalen =
  993                             SBP2_STATUS_GET_LEN(ntohl(abuf->ab_data[0])) - 1;
  994                         if (statorb->status.datalen)
  995                                 statorb->status.data = &abuf->ab_data[2];
  996                         if ((statorb->status.resp == 
  997                             SBP2_STATUS_TRANSPORT_FAIL) &&
  998                             (statorb->status.sbp_status == 
  999                             SBP2_STATUS_UNSPEC_ERROR)) {
 1000                                 t = statorb->status.sbp_status;
 1001                                 statorb->status.object = 
 1002                                     SBP2_STATUS_GET_OBJECT(t);
 1003                                 statorb->status.bus_error =
 1004                                     SBP2_STATUS_GET_BUS_ERROR(t);
 1005                         }
 1006                         statorb->status_rec = 1;
 1007                         simple_unlock(&statorb->orb_lock);
 1008                         statorb->cb(&statorb->status, statorb->cb_arg);
 1009                         statorb->cb = sbp2_status_resp;
 1010                         orb = statorb;
 1011                 }
 1012 
 1013                 /* If it's not the null pointer orb, free it. */
 1014                 simple_lock(&orb->orb_lock);
 1015                 if ((orb->cmd.ab_data[0] == ntohl(SBP2_ORB_NULL_POINTER)))
 1016                         break;
 1017                 /* Check conditions for free'ing an orb */
 1018                 if ((orb->status_rec == 0) || (orb->ack == 0) || 
 1019                     ((orb->db == 1) && (orb->dback == 0)))
 1020                         break;
 1021                 simple_lock(&orb->sbp2->orblist_lock);
 1022 
 1023                 /*
 1024                  * Always leave the last orb on the list so the doorbell can
 1025                  * be rang.
 1026                  */
 1027 
 1028                 if (orb != CIRCLEQ_FIRST(&orb->sbp2->orbs)) {
 1029                         orb->cmd.ab_tcode = IEEE1394_TCODE_READ_REQ_BLOCK;
 1030 
 1031                         CIRCLEQ_REMOVE(&orb->sbp2->orbs, orb, orb_list);
 1032                         simple_unlock(&orb->sbp2->orblist_lock);
 1033                         simple_unlock(&orb->orb_lock);
 1034                         sbp2_free_orb(orb);
 1035                         return;
 1036                 }
 1037                 simple_unlock(&orb->sbp2->orblist_lock);
 1038                 break;
 1039         case SBP2_ORB_FREE_STATE:
 1040                 break;
 1041         default:
 1042                 panic("Invalid orb state: %d\n", orb->state);
 1043                 break;
 1044         }
 1045         simple_unlock(&orb->orb_lock);
 1046 }
 1047 
 1048 static void
 1049 sbp2_data_resp(struct ieee1394_abuf *abuf, int rcode)
 1050 {
 1051         struct sbp2_orb *orb;
 1052         struct sbp2_mapping *data_map;
 1053         u_int32_t offset;
 1054         unsigned char *addr;
 1055 
 1056         switch (abuf->ab_tcode) {
 1057 
 1058         case IEEE1394_TCODE_WRITE_REQ_BLOCK:
 1059                 return;
 1060                 break;
 1061         case IEEE1394_TCODE_READ_REQ_BLOCK:
 1062                 data_map = abuf->ab_cbarg;
 1063                 orb = data_map->orb;
 1064 
 1065                 simple_lock(&orb->orb_lock);
 1066 
 1067                 addr = data_map->laddr;
 1068                 offset = abuf->ab_retaddr - data_map->fwaddr;
 1069 
 1070                 orb->resp.ab_addr = abuf->ab_retaddr;
 1071                 orb->resp.ab_tcode = IEEE1394_TCODE_READ_RESP_BLOCK;
 1072                 orb->resp.ab_tlabel = abuf->ab_tlabel;
 1073                 orb->resp.ab_length = abuf->ab_retlen;
 1074                 orb->resp.ab_req = abuf->ab_req;
 1075                 orb->resp.ab_data = (u_int32_t *)(addr + offset);
 1076                 orb->resp.ab_cb = sbp2_null_resp;
 1077                 orb->resp.ab_cbarg = data_map;
 1078                 orb->sbp2->sc->sc1394_callback.sc1394_write(&orb->resp);
 1079                 simple_unlock(&orb->orb_lock);
 1080                 break;
 1081         default:
 1082                 panic("Invalid tcode: 0x%0x\n", abuf->ab_tcode);
 1083         }
 1084 }
 1085 
 1086 void *
 1087 sbp2_abort(void *handle)
 1088 {
 1089         struct sbp2_orb *orb = handle;
 1090         void *arg;
 1091 
 1092         DPRINTF(("Called sbp2_abort\n"));
 1093 
 1094         simple_lock(&orb->sbp2->orblist_lock);
 1095         simple_lock(&orb->orb_lock);
 1096 
 1097         arg = orb->cb_arg;
 1098         CIRCLEQ_REMOVE(&orb->sbp2->orbs, orb, orb_list);
 1099 
 1100         simple_unlock(&orb->orb_lock);
 1101         simple_unlock(&orb->sbp2->orblist_lock);
 1102 
 1103         sbp2_free_orb(orb);
 1104 
 1105         return arg;
 1106 }
 1107 
 1108 static void
 1109 sbp2_relogin(struct ieee1394_softc *sc, void *arg)
 1110 {
 1111         struct sbp2 *sbp2 = arg;
 1112 
 1113         DPRINTF(("Called sbp2_relogin\n"));
 1114         if (sbp2)
 1115                 return;
 1116 }
 1117 
 1118 void
 1119 sbp2_reset_lun(struct sbp2 *sbp2, u_int16_t lun)
 1120 {
 1121         DPRINTF(("Called sbp2_reset_lun\n"));
 1122         return;
 1123 }
 1124 
 1125 static struct sbp2_orb *
 1126 sbp2_alloc_orb(void)
 1127 {
 1128         struct sbp2_orb *orb = NULL;
 1129         int i;
 1130 
 1131         simple_lock(&sbp2_freeorbs_lock);
 1132         if (CIRCLEQ_EMPTY(&sbp2_freeorbs)) {
 1133                 DPRINTFN(2, ("Alloc'ing more orbs\n"));
 1134                 for (i = 0; i < SBP2_NUM_ALLOC; i++) {
 1135                         simple_unlock(&sbp2_freeorbs_lock);
 1136                         orb = malloc(sizeof(struct sbp2_orb), M_1394DATA,
 1137                             M_WAITOK|M_ZERO);
 1138                         orb->cmd.ab_data = malloc(SBP2_MAX_ORB, M_1394DATA,
 1139                             M_WAITOK|M_ZERO);
 1140                         simple_lock_init(&orb->orb_lock);
 1141                         simple_lock(&sbp2_freeorbs_lock);
 1142                         CIRCLEQ_INSERT_TAIL(&sbp2_freeorbs, orb, orb_list);
 1143                 }
 1144                 simple_unlock(&sbp2_freeorbs_lock);
 1145                 orb = malloc(sizeof(struct sbp2_orb), M_DEVBUF,
 1146                     M_WAITOK|M_ZERO);
 1147                 orb->cmd.ab_data = malloc(SBP2_MAX_ORB, M_1394DATA,
 1148                     M_WAITOK|M_ZERO);
 1149                 simple_lock_init(&orb->orb_lock);
 1150                 return orb;
 1151         } else {
 1152                 orb = CIRCLEQ_FIRST(&sbp2_freeorbs);
 1153                 CIRCLEQ_REMOVE(&sbp2_freeorbs, orb, orb_list);
 1154         }
 1155         simple_unlock(&sbp2_freeorbs_lock);
 1156         orb->state = SBP2_ORB_INIT_STATE;
 1157         return orb;
 1158 }
 1159 
 1160 static void
 1161 sbp2_free_orb(struct sbp2_orb *orb)
 1162 {
 1163 
 1164         simple_lock(&orb->orb_lock);
 1165         DPRINTFN(2, ("Freeing orb at addr: 0x%016qx status_rec: 0x%0x\n", 
 1166             orb->cmd.ab_addr, orb->status_rec));
 1167         orb->sbp2->sc->sc1394_callback.sc1394_unreg(&orb->cmd, 0);
 1168         if (orb->data_map.laddr) {
 1169                 orb->sbp2->sc->sc1394_callback.sc1394_unreg(&orb->data, 1);
 1170                 sbp2_free_data_mapping(orb->sbp2, &orb->data_map);
 1171         }
 1172         if (orb->pt)
 1173                 sbp2_free_pt(orb->pt);
 1174 
 1175         sbp2_free_addr(orb->sbp2, orb->cmd.ab_addr);
 1176 
 1177         simple_lock(&sbp2_freeorbs_lock);
 1178         memset(orb->cmd.ab_data, 0, SBP2_MAX_ORB);
 1179         memset(&orb->status, 0, sizeof(struct sbp2_status));
 1180         memset(&orb->data_map, 0, sizeof(struct sbp2_mapping));
 1181         orb->sbp2 = NULL;
 1182         orb->pt = NULL;
 1183         orb->lun = NULL;
 1184         orb->cb = NULL;
 1185         orb->cb_arg = NULL;
 1186         orb->status_rec = 0;
 1187         orb->db = 0;
 1188         orb->dback = 0;
 1189         orb->ack = 0;
 1190         orb->state = SBP2_ORB_FREE_STATE;
 1191         CIRCLEQ_INSERT_TAIL(&sbp2_freeorbs, orb, orb_list);
 1192         simple_unlock(&sbp2_freeorbs_lock);
 1193         simple_unlock(&orb->orb_lock);
 1194 }
 1195 
 1196 static void
 1197 sbp2_alloc_data_mapping(struct sbp2 *sbp2, struct sbp2_mapping *map,
 1198     u_char *data, u_int32_t datalen, u_int8_t rw)
 1199 {
 1200         int byte, bitpos, found;
 1201         u_int32_t size, count, startbyte, startbit;
 1202         unsigned char bit;
 1203 
 1204         size = datalen / SBP_DATA_BLOCK_SIZE;
 1205         if (datalen % SBP_DATA_BLOCK_SIZE)
 1206                 size++;
 1207 
 1208         map->laddr = data;
 1209         map->size = datalen;
 1210         map->rw = rw;
 1211 
 1212         simple_lock(&sbp2->map->maplock);
 1213         count = found = 0;
 1214         startbyte = 0;
 1215         startbit = 0;
 1216         for (byte = 0; byte < sizeof(sbp2->map->datamap); byte++) {
 1217                 for (bitpos = 0; bitpos < CHAR_BIT; bitpos++) {
 1218                         bit = 0x1 << bitpos;
 1219                         if ((sbp2->map->datamap[byte] & bit) == 0) {
 1220                                 if (++count == size) {
 1221                                         found = 1;
 1222                                         break;
 1223                                 }
 1224                         } else {
 1225                                 count = 0;
 1226                                 if (bitpos != (CHAR_BIT - 1)) {
 1227                                         startbyte = byte;
 1228                                         startbit = bitpos + 1;
 1229                                 } else {
 1230                                         startbyte = byte + 1;
 1231                                         startbit = 0;
 1232                                 }
 1233                         }
 1234                 }
 1235                 if (found)
 1236                         break;
 1237         }
 1238 
 1239         /* Gets a little complicated to handle crossing bytes on the ends. */
 1240 
 1241         /* Handle the bits on the front end if they start in the middle */
 1242         if (startbit) {
 1243                 count = CHAR_BIT - startbit;
 1244                 if (size < count)
 1245                         count = size;
 1246                 for (bitpos = 0; bitpos < count; bitpos++) {
 1247                         bit = 0x1 << (bitpos + startbit);
 1248                         size--;
 1249                         sbp2->map->datamap[startbyte] |= bit;
 1250                 }
 1251                 startbyte++;
 1252         }
 1253 
 1254         /* Allocate bytes at a time */
 1255         if (size) {
 1256                 count = startbyte + (size / CHAR_BIT);
 1257                 for (byte = startbyte; byte < count; byte++) {
 1258                         sbp2->map->datamap[byte] = 0xff;
 1259                         size -= CHAR_BIT;
 1260                 }
 1261                 /* If any bits are left allocate them out of the next byte */
 1262                 if (size) {
 1263 #ifdef DEBUG
 1264                         if (size >= CHAR_BIT)
 1265                                 panic ("Too many bits left to allocate: %d",
 1266                                     size);
 1267 #endif
 1268                         for (bitpos = 0; bitpos < size; bitpos++) {
 1269                                 bit = 0x1 << bitpos;
 1270                                 sbp2->map->datamap[byte] |= bit;
 1271                         }
 1272                 }
 1273         }
 1274 
 1275         /* Adjust back one if the bits started 1 byte back */
 1276         if (startbit)
 1277                 startbyte--;
 1278         map->fwaddr = SBP_DATA_BEG +
 1279             (((startbyte * CHAR_BIT) + startbit) * SBP_DATA_BLOCK_SIZE);
 1280 
 1281         simple_unlock(&sbp2->map->maplock);
 1282 }
 1283 
 1284 static u_int64_t
 1285 sbp2_alloc_addr(struct sbp2 *sbp2)
 1286 {
 1287         u_int64_t addr;
 1288         int byte, bitpos, found;
 1289         unsigned char bit;
 1290 
 1291         found = 0;
 1292         simple_lock(&sbp2->map->maplock);
 1293 
 1294         addr = SBP_ADDR_BEG + (sbp2->map->next_addr * SBP_ADDR_BLOCK_SIZE);
 1295         byte = sbp2->map->next_addr / CHAR_BIT;
 1296         bitpos = sbp2->map->next_addr % CHAR_BIT;
 1297         bit = 0x1 << bitpos;
 1298 
 1299 #ifdef DIAGNOSTIC
 1300         if (sbp2->map->addrmap[byte] & bit)
 1301                 panic("Already allocated address 0x%016" PRIx64, addr);
 1302 #endif
 1303         sbp2->map->addrmap[byte] |= bit;
 1304 
 1305         for (; byte < (sizeof(sbp2->map->addrmap) - byte); byte++) {
 1306                 for (bitpos = 0; bitpos < CHAR_BIT; bitpos++) {
 1307                         bit = 0x1 << bitpos;
 1308                         if ((sbp2->map->addrmap[byte] & bit) == 0) {
 1309                                 found = 1;
 1310                                 break;
 1311                         }
 1312                 }
 1313                 if (found)
 1314                         break;
 1315         }
 1316         sbp2->map->next_addr = (byte * CHAR_BIT) + bitpos;
 1317 
 1318         simple_unlock(&sbp2->map->maplock);
 1319 
 1320 #ifdef DIAGNOSTIC
 1321         if (sbp2->map->next_addr >= SBP_ADDR_MAX)
 1322                 panic("XXX: Used 64k of sbp addr's.\n");
 1323 #endif
 1324         return addr;
 1325 }
 1326 
 1327 static void
 1328 sbp2_free_data_mapping(struct sbp2 *sbp2, struct sbp2_mapping *map)
 1329 {
 1330         int byte, bitpos;
 1331         u_int32_t size, count, startbyte, off, startbit;
 1332         unsigned char bit;
 1333 
 1334         simple_lock(&sbp2->map->maplock);
 1335 
 1336         size = map->size / SBP_DATA_BLOCK_SIZE;
 1337         if (map->size % SBP_DATA_BLOCK_SIZE)
 1338                 size++;
 1339         off = ((int)(map->fwaddr - SBP_DATA_BEG) / SBP_DATA_BLOCK_SIZE);
 1340 
 1341         startbyte = off / CHAR_BIT;
 1342         startbit = off % CHAR_BIT;
 1343 
 1344         /*
 1345          * 3 parts. Any bits in the middle of the first byte.
 1346          * Then bytes until whole bytes are done.
 1347          * Finally, any left over remaining bits.
 1348          */
 1349 
 1350         if (startbit) {
 1351                 count = CHAR_BIT - startbit;
 1352                 if (size < count)
 1353                         count = size;
 1354                 for (bitpos = 0; bitpos < count; bitpos++) {
 1355                         bit = 0x1 << (bitpos + startbit);
 1356 #ifdef DIAGNOSTIC
 1357                         if (!(sbp2->map->datamap[startbyte] & bit))
 1358                                 panic("Freeing addr not allocated: 0x%016"
 1359                                     PRIx64, map->fwaddr);
 1360 #endif
 1361                         bit = ~bit;
 1362                         size--;
 1363                         sbp2->map->datamap[startbyte] &= bit;
 1364                 }
 1365                 startbyte++;
 1366         }
 1367 
 1368         if (size) {
 1369                 count = startbyte + (size / CHAR_BIT);
 1370                 for (byte = startbyte; byte < count; byte++) {
 1371 #ifdef DIAGNOSTIC
 1372                         if (!(sbp2->map->datamap[byte]))
 1373                                 panic("Freeing addr not allocated: 0x%016"
 1374                                     PRIx64, map->fwaddr);
 1375 #endif
 1376                         size -= CHAR_BIT;
 1377                         sbp2->map->datamap[byte] = 0;
 1378                 }
 1379                 /* If any bits are left free them out of the next byte */
 1380                 if (size) {
 1381 #ifdef DEBUG
 1382                         if (size >= CHAR_BIT)
 1383                                 panic ("Too many bits left to free: %d", size);
 1384 #endif
 1385                         for (bitpos = 0; bitpos < size; bitpos++) {
 1386                                 bit = 0x1 << bitpos;
 1387 #ifdef DIAGNOSTIC
 1388                                 if (!(sbp2->map->datamap[byte] & bit))
 1389                                         panic("Freeing addr not allocated: "
 1390                                             "0x%016" PRIx64, map->fwaddr);
 1391 #endif
 1392                                 bit = ~bit;
 1393                                 sbp2->map->datamap[byte] &= bit;
 1394                         }
 1395                 }
 1396         }
 1397         if (startbit)
 1398                 startbyte--;
 1399 
 1400         simple_unlock(&sbp2->map->maplock);
 1401 
 1402         return;
 1403 }
 1404 
 1405 static void
 1406 sbp2_free_addr(struct sbp2 *sbp2, u_int64_t addr)
 1407 {
 1408         int off, byte, bitpos;
 1409         unsigned char bit;
 1410 
 1411         off = ((int)(addr - SBP_ADDR_BEG) / SBP_ADDR_BLOCK_SIZE);
 1412 
 1413         byte = off / CHAR_BIT;
 1414         bitpos = off % CHAR_BIT;
 1415         bit = 0x1 << bitpos;
 1416 
 1417         simple_lock(&sbp2->map->maplock);
 1418 #ifdef DIAGNOSTIC
 1419         if (!(sbp2->map->addrmap[byte] & bit))
 1420                 panic("Freeing addr not allocated: 0x%016" PRIx64, addr);
 1421 #endif
 1422         bit = ~bit;
 1423         sbp2->map->addrmap[byte] &= bit;
 1424         if (sbp2->map->next_addr > off)
 1425                 sbp2->map->next_addr = off;
 1426         simple_unlock(&sbp2->map->maplock);
 1427 }
 1428 
 1429 static struct sbp2_pagetable *
 1430 sbp2_alloc_pt(struct uio *io, u_int8_t rw, struct sbp2_orb *orb)
 1431 {
 1432         struct sbp2_pagetable *pt;
 1433         struct sbp2_mapping *map;
 1434         struct ieee1394_softc *sc;
 1435         ssize_t len;
 1436         char *addr;
 1437         int i, j, k, cnt;
 1438 
 1439         pt = malloc (sizeof (*pt), M_1394DATA, M_ZERO | M_WAITOK);
 1440 
 1441         /* Compute number of entries. */
 1442 
 1443         for (i = 0; i < io->uio_iovcnt; i++) {
 1444                 if (io->uio_iov[i].iov_len <= SBP2_PHYS_SEGMENT)
 1445                         pt->pt_cnt++;
 1446                 else {
 1447                         pt->pt_cnt += 
 1448                             io->uio_iov[i].iov_len / SBP2_PHYS_SEGMENT;
 1449                         if (io->uio_iov[i].iov_len % SBP2_PHYS_SEGMENT)
 1450                                 pt->pt_cnt++;
 1451                 }
 1452 #ifdef DEBUG
 1453                 /* Overflow'd 16 bits. */
 1454                 if (pt->pt_cnt == 0) {
 1455                         DPRINTFN(1, ("pt_cnt overflow\n"));
 1456                         free (pt, M_1394DATA);
 1457                         return NULL;
 1458                 }
 1459 #endif
 1460         }
 1461 
 1462         sc = orb->sbp2->sc;
 1463 
 1464         pt->pt_ent.ab_data = malloc (SBP2_PTENT_SIZE * pt->pt_cnt, M_1394DATA, 
 1465             M_ZERO | M_WAITOK);
 1466         sbp2_alloc_data_mapping(orb->sbp2, &pt->pt_map, 
 1467             (char *)pt->pt_ent.ab_data, SBP2_PTENT_SIZE * pt->pt_cnt, SBP_READ);
 1468 
 1469         pt->pt_ent.ab_addr = pt->pt_map.fwaddr;
 1470 
 1471         pt->pt_ent.ab_length = SBP2_PTENT_SIZE * pt->pt_cnt;
 1472         pt->pt_ent.ab_tcode = IEEE1394_TCODE_READ_REQ_BLOCK;
 1473         pt->pt_ent.ab_req = sc;
 1474         pt->pt_ent.ab_cb = sbp2_pt_resp;
 1475         pt->pt_ent.ab_cbarg = orb;
 1476         pt->pt_data = malloc (sizeof (struct ieee1394_abuf) * pt->pt_cnt,
 1477             M_1394DATA, M_ZERO | M_WAITOK);
 1478 
 1479         j = 0;
 1480         for (i = 0; i < io->uio_iovcnt; i++) {
 1481                 if (io->uio_iov[i].iov_len <= SBP2_PHYS_SEGMENT) {
 1482                         cnt = 1;
 1483                 } else {
 1484                         cnt = io->uio_iov[i].iov_len / SBP2_PHYS_SEGMENT;
 1485                         if (io->uio_iov[i].iov_len % SBP2_PHYS_SEGMENT)
 1486                                 cnt++;
 1487                 }
 1488                 len = io->uio_iov[i].iov_len;
 1489                 for (k = 0; k < cnt; k++) {
 1490 #ifdef DIAGNOSTIC
 1491                         if (len == 0)
 1492                                 panic ("len is zero");
 1493 #endif
 1494                         map = malloc (sizeof (struct sbp2_mapping), M_1394DATA, 
 1495                             M_ZERO | M_WAITOK);
 1496                         pt->pt_data[j].ab_cbarg = map;
 1497                         addr = (char *)io->uio_iov[i].iov_base + 
 1498                             (k * SBP2_PHYS_SEGMENT);
 1499                         if (len > SBP2_PHYS_SEGMENT) {
 1500                                 len -= SBP2_PHYS_SEGMENT;
 1501                                 sbp2_alloc_data_mapping(orb->sbp2, map, addr,
 1502                                     SBP2_PHYS_SEGMENT, rw);
 1503                                 pt->pt_data[j].ab_length = SBP2_PHYS_SEGMENT;
 1504                                 pt->pt_ent.ab_data[j * SBP2_PTENT_SIZEQ] =
 1505                                     SBP2_PT_MAKELEN(SBP2_PHYS_SEGMENT);
 1506                         } else {
 1507                                 sbp2_alloc_data_mapping(orb->sbp2, map, addr,
 1508                                     len, rw);
 1509                                 pt->pt_data[j].ab_length = len;
 1510                                 pt->pt_ent.ab_data[j * SBP2_PTENT_SIZEQ] =
 1511                                     SBP2_PT_MAKELEN(len);
 1512                                 len -= len;
 1513                         }
 1514                         pt->pt_data[j].ab_addr = map->fwaddr;
 1515                         pt->pt_data[j].ab_req = sc;
 1516                         if (rw == SBP_WRITE)
 1517                                 pt->pt_data[j].ab_tcode = 
 1518                                     IEEE1394_TCODE_WRITE_REQ_BLOCK;
 1519                         else
 1520                                 pt->pt_data[j].ab_tcode = 
 1521                                     IEEE1394_TCODE_READ_REQ_BLOCK;
 1522                         map->orb = orb;
 1523                         pt->pt_data[j].ab_cb = sbp2_data_resp;
 1524                         pt->pt_data[j].ab_data = (u_int32_t *)addr;
 1525                         pt->pt_ent.ab_data[j * SBP2_PTENT_SIZEQ] |=
 1526                             IEEE1394_CREATE_ADDR_HIGH(map->fwaddr);
 1527                         pt->pt_ent.ab_data[(j * SBP2_PTENT_SIZEQ) + 1] =
 1528                             IEEE1394_CREATE_ADDR_LOW(map->fwaddr);
 1529                         sc->sc1394_callback.sc1394_inreg(&pt->pt_data[j], 1);
 1530                         j++;
 1531                 } 
 1532         }
 1533         sc->sc1394_callback.sc1394_inreg(&pt->pt_ent, 1);
 1534         return pt;
 1535 }
 1536 
 1537 static void 
 1538 sbp2_pt_resp(struct ieee1394_abuf *abuf, int rcode)
 1539 {
 1540         struct sbp2_orb *orb = abuf->ab_cbarg;
 1541         struct sbp2_pagetable *pt = orb->pt;
 1542         u_int32_t offset;
 1543 
 1544         if (rcode) {
 1545                 DPRINTF(("sbp2_pt_resp: Bad return code: %d\n", rcode));
 1546                 return;
 1547         }
 1548 
 1549         simple_lock(&orb->orb_lock);
 1550 
 1551         /*
 1552          * The target is allowed to read these 1 entry at a time so construct
 1553          * responses in a different abuf to allow for this.
 1554          */
 1555 
 1556         offset = abuf->ab_retaddr - abuf->ab_addr;
 1557         pt->pt_resp.ab_addr = abuf->ab_retaddr;
 1558         pt->pt_resp.ab_tcode = IEEE1394_TCODE_READ_RESP_BLOCK;
 1559         pt->pt_resp.ab_tlabel = abuf->ab_tlabel;
 1560         pt->pt_resp.ab_length = abuf->ab_retlen;
 1561         pt->pt_resp.ab_req = abuf->ab_req;
 1562         pt->pt_resp.ab_data = (u_int32_t *)((u_int8_t *)abuf->ab_data + offset);
 1563         pt->pt_resp.ab_cb = sbp2_null_resp;
 1564         pt->pt_resp.ab_cbarg = orb;
 1565         abuf->ab_req->sc1394_callback.sc1394_write(&pt->pt_resp);
 1566         simple_unlock(&orb->orb_lock);
 1567         return;
 1568 }
 1569 
 1570 static void
 1571 sbp2_free_pt(struct sbp2_pagetable *pt)
 1572 {
 1573         struct sbp2_orb *orb = pt->pt_ent.ab_cbarg;
 1574         struct ieee1394_softc *sc = orb->sbp2->sc;
 1575         int i;
 1576 
 1577         sc->sc1394_callback.sc1394_unreg(&pt->pt_ent, 1);
 1578         sbp2_free_data_mapping(orb->sbp2, &pt->pt_map);
 1579 
 1580         for (i = 0; i < pt->pt_cnt; i++) {
 1581                 sc->sc1394_callback.sc1394_unreg(&pt->pt_data[i], 1);
 1582                 sbp2_free_data_mapping(orb->sbp2, pt->pt_data[i].ab_cbarg);
 1583                 free (pt->pt_data[i].ab_cbarg, M_1394DATA);
 1584         }
 1585         free (pt->pt_data, M_1394DATA);
 1586         free (pt->pt_ent.ab_data, M_1394DATA);
 1587         free (pt, M_1394DATA);
 1588 }

Cache object: f3495a31d769a89ff435584c968e2a70


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