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