3 * Hidetoshi Shimokawa. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
16 * This product includes software developed by Hidetoshi Shimokawa.
18 * 4. Neither the name of the author nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 #include <sys/param.h>
38 #include <sys/kernel.h>
39 #include <sys/systm.h>
40 #include <sys/sysctl.h>
41 #include <sys/types.h>
43 #include <sys/malloc.h>
44 #include <sys/endian.h>
45 #if __FreeBSD_version < 500000
46 #include <sys/devicestat.h>
50 #include <machine/bus.h>
52 #include <dev/firewire/firewire.h>
53 #include <dev/firewire/firewirereg.h>
54 #include <dev/firewire/iec13213.h>
55 #include <dev/firewire/sbp.h>
56 #include <dev/firewire/fwmem.h>
59 #include <cam/cam_ccb.h>
60 #include <cam/cam_sim.h>
61 #include <cam/cam_xpt_sim.h>
62 #include <cam/cam_debug.h>
63 #include <cam/cam_periph.h>
64 #include <cam/scsi/scsi_all.h>
65 #include <cam/scsi/scsi_message.h>
67 #define SBP_TARG_RECV_LEN 8
68 #define MAX_INITIATORS 8
73 * management/command block agent registers
75 * BASE 0xffff f001 0000 management port
76 * BASE 0xffff f001 0020 command port for login id 0
77 * BASE 0xffff f001 0040 command port for login id 1
80 #define SBP_TARG_MGM 0x10000 /* offset from 0xffff f000 000 */
81 #define SBP_TARG_BIND_HI 0xffff
82 #define SBP_TARG_BIND_LO(l) (0xf0000000 + SBP_TARG_MGM + 0x20 * ((l) + 1))
83 #define SBP_TARG_BIND_START (((u_int64_t)SBP_TARG_BIND_HI << 32) | \
85 #define SBP_TARG_BIND_END (((u_int64_t)SBP_TARG_BIND_HI << 32) | \
86 SBP_TARG_BIND_LO(MAX_LOGINS))
87 #define SBP_TARG_LOGIN_ID(lo) (((lo) - SBP_TARG_BIND_LO(0))/0x20)
91 #define FETCH_POINTER 2
93 #define F_LINK_ACTIVE (1 << 0)
94 #define F_ATIO_STARVED (1 << 1)
95 #define F_LOGIN (1 << 2)
96 #define F_HOLD (1 << 3)
97 #define F_FREEZED (1 << 4)
99 static MALLOC_DEFINE(M_SBP_TARG, "sbp_targ", "SBP-II/FireWire target mode");
101 static int debug = 0;
103 SYSCTL_INT(_debug, OID_AUTO, sbp_targ_debug, CTLFLAG_RW, &debug, 0,
104 "SBP target mode debug flag");
106 struct sbp_targ_login {
107 struct sbp_targ_lstate *lstate;
108 struct fw_device *fwdev;
109 struct sbp_login_res loginres;
114 STAILQ_HEAD(, orb_info) orbs;
115 STAILQ_ENTRY(sbp_targ_login) link;
120 struct callout hold_callout;
123 struct sbp_targ_lstate {
125 struct sbp_targ_softc *sc;
126 struct cam_path *path;
127 struct ccb_hdr_slist accept_tios;
128 struct ccb_hdr_slist immed_notifies;
129 struct crom_chunk model;
131 STAILQ_HEAD(, sbp_targ_login) logins;
134 struct sbp_targ_softc {
135 struct firewire_dev_comm fd;
137 struct cam_path *path;
141 struct crom_chunk unit;
142 struct sbp_targ_lstate *lstate[MAX_LUN];
143 struct sbp_targ_lstate *black_hole;
144 struct sbp_targ_login *logins[MAX_LOGINS];
147 #define SBP_LOCK(sc) mtx_lock(&(sc)->mtx)
148 #define SBP_UNLOCK(sc) mtx_unlock(&(sc)->mtx)
151 #if BYTE_ORDER == BIG_ENDIAN
158 page_table_present:1,
162 uint32_t data_size:16,
164 page_table_present:1,
175 #if BYTE_ORDER == BIG_ENDIAN
192 * Urestricted page table format
193 * states that the segment length
194 * and high base addr are in the first
195 * 32 bits and the base low is in
198 struct unrestricted_page_table_fmt {
199 uint16_t segment_len;
200 uint16_t segment_base_high;
201 uint32_t segment_base_low;
206 struct sbp_targ_softc *sc;
207 struct fw_device *fwdev;
208 struct sbp_targ_login *login;
210 struct ccb_accept_tio *atio;
212 #define ORBI_STATUS_NONE 0
213 #define ORBI_STATUS_FETCH 1
214 #define ORBI_STATUS_ATIO 2
215 #define ORBI_STATUS_CTIO 3
216 #define ORBI_STATUS_STATUS 4
217 #define ORBI_STATUS_POINTER 5
218 #define ORBI_STATUS_ABORTED 7
225 STAILQ_ENTRY(orb_info) link;
227 struct unrestricted_page_table_fmt *page_table;
228 struct unrestricted_page_table_fmt *cur_pte;
229 struct unrestricted_page_table_fmt *last_pte;
230 uint32_t last_block_read;
231 struct sbp_status status;
234 static char *orb_fun_name[] = {
238 static void sbp_targ_recv(struct fw_xfer *);
239 static void sbp_targ_fetch_orb(struct sbp_targ_softc *, struct fw_device *,
240 uint16_t, uint32_t, struct sbp_targ_login *, int);
241 static void sbp_targ_xfer_pt(struct orb_info *);
242 static void sbp_targ_abort(struct sbp_targ_softc *, struct orb_info *);
245 sbp_targ_identify(driver_t *driver, device_t parent)
247 BUS_ADD_CHILD(parent, 0, "sbp_targ", device_get_unit(parent));
251 sbp_targ_probe(device_t dev)
255 pa = device_get_parent(dev);
256 if(device_get_unit(dev) != device_get_unit(pa)){
260 device_set_desc(dev, "SBP-2/SCSI over FireWire target mode");
265 sbp_targ_dealloc_login(struct sbp_targ_login *login)
267 struct orb_info *orbi, *next;
270 printf("%s: login = NULL\n", __func__);
273 for (orbi = STAILQ_FIRST(&login->orbs); orbi != NULL; orbi = next) {
274 next = STAILQ_NEXT(orbi, link);
276 printf("%s: free orbi %p\n", __func__, orbi);
277 free(orbi, M_SBP_TARG);
280 callout_stop(&login->hold_callout);
282 STAILQ_REMOVE(&login->lstate->logins, login, sbp_targ_login, link);
283 login->lstate->sc->logins[login->id] = NULL;
285 printf("%s: free login %p\n", __func__, login);
286 free((void *)login, M_SBP_TARG);
291 sbp_targ_hold_expire(void *arg)
293 struct sbp_targ_login *login;
295 login = (struct sbp_targ_login *)arg;
297 if (login->flags & F_HOLD) {
298 printf("%s: login_id=%d expired\n", __func__, login->id);
299 sbp_targ_dealloc_login(login);
301 printf("%s: login_id=%d not hold\n", __func__, login->id);
306 sbp_targ_post_busreset(void *arg)
308 struct sbp_targ_softc *sc;
309 struct crom_src *src;
310 struct crom_chunk *root;
311 struct crom_chunk *unit;
312 struct sbp_targ_lstate *lstate;
313 struct sbp_targ_login *login;
316 sc = (struct sbp_targ_softc *)arg;
317 src = sc->fd.fc->crom_src;
318 root = sc->fd.fc->crom_root;
322 if ((sc->flags & F_FREEZED) == 0) {
324 sc->flags |= F_FREEZED;
325 xpt_freeze_simq(sc->sim, /*count*/1);
328 printf("%s: already freezed\n", __func__);
331 bzero(unit, sizeof(struct crom_chunk));
333 crom_add_chunk(src, root, unit, CROM_UDIR);
334 crom_add_entry(unit, CSRKEY_SPEC, CSRVAL_ANSIT10);
335 crom_add_entry(unit, CSRKEY_VER, CSRVAL_T10SBP2);
336 crom_add_entry(unit, CSRKEY_COM_SPEC, CSRVAL_ANSIT10);
337 crom_add_entry(unit, CSRKEY_COM_SET, CSRVAL_SCSI);
339 crom_add_entry(unit, CROM_MGM, SBP_TARG_MGM >> 2);
340 crom_add_entry(unit, CSRKEY_UNIT_CH, (10<<8) | 8);
342 for (i = 0; i < MAX_LUN; i ++) {
343 lstate = sc->lstate[i];
346 crom_add_entry(unit, CSRKEY_FIRM_VER, 1);
347 crom_add_entry(unit, CROM_LUN, i);
348 crom_add_entry(unit, CSRKEY_MODEL, 1);
349 crom_add_simple_text(src, unit, &lstate->model, "TargetMode");
352 /* Process for reconnection hold time */
353 for (i = 0; i < MAX_LOGINS; i ++) {
354 login = sc->logins[i];
357 sbp_targ_abort(sc, STAILQ_FIRST(&login->orbs));
358 if (login->flags & F_LOGIN) {
359 login->flags |= F_HOLD;
360 callout_reset(&login->hold_callout,
361 hz * login->hold_sec,
362 sbp_targ_hold_expire, (void *)login);
368 sbp_targ_post_explore(void *arg)
370 struct sbp_targ_softc *sc;
372 sc = (struct sbp_targ_softc *)arg;
374 sc->flags &= ~F_FREEZED;
375 xpt_release_simq(sc->sim, /*run queue*/TRUE);
381 sbp_targ_find_devs(struct sbp_targ_softc *sc, union ccb *ccb,
382 struct sbp_targ_lstate **lstate, int notfound_failure)
386 /* XXX 0 is the only vaild target_id */
387 if (ccb->ccb_h.target_id == CAM_TARGET_WILDCARD &&
388 ccb->ccb_h.target_lun == CAM_LUN_WILDCARD) {
389 *lstate = sc->black_hole;
391 printf("setting black hole for this target id(%d)\n", ccb->ccb_h.target_id);
392 return (CAM_REQ_CMP);
395 lun = ccb->ccb_h.target_lun;
397 return (CAM_LUN_INVALID);
399 *lstate = sc->lstate[lun];
401 if (notfound_failure != 0 && *lstate == NULL) {
403 printf("%s: lstate for lun is invalid, target(%d), lun(%d)\n",
404 __func__, ccb->ccb_h.target_id, lun);
405 return (CAM_PATH_INVALID);
408 printf("%s: setting lstate for tgt(%d) lun(%d)\n",
409 __func__,ccb->ccb_h.target_id, lun);
411 return (CAM_REQ_CMP);
415 sbp_targ_en_lun(struct sbp_targ_softc *sc, union ccb *ccb)
417 struct ccb_en_lun *cel = &ccb->cel;
418 struct sbp_targ_lstate *lstate;
421 status = sbp_targ_find_devs(sc, ccb, &lstate, 0);
422 if (status != CAM_REQ_CMP) {
423 ccb->ccb_h.status = status;
427 if (cel->enable != 0) {
428 if (lstate != NULL) {
429 xpt_print_path(ccb->ccb_h.path);
430 printf("Lun already enabled\n");
431 ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
434 if (cel->grp6_len != 0 || cel->grp7_len != 0) {
435 ccb->ccb_h.status = CAM_REQ_INVALID;
436 printf("Non-zero Group Codes\n");
439 lstate = (struct sbp_targ_lstate *)
440 malloc(sizeof(*lstate), M_SBP_TARG, M_NOWAIT | M_ZERO);
441 if (lstate == NULL) {
442 xpt_print_path(ccb->ccb_h.path);
443 printf("Couldn't allocate lstate\n");
444 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
448 printf("%s: malloc'd lstate %p\n",__func__, lstate);
450 if (ccb->ccb_h.target_id == CAM_TARGET_WILDCARD) {
451 sc->black_hole = lstate;
453 printf("Blackhole set due to target id == %d\n",
454 ccb->ccb_h.target_id);
456 sc->lstate[ccb->ccb_h.target_lun] = lstate;
458 memset(lstate, 0, sizeof(*lstate));
460 status = xpt_create_path(&lstate->path, /*periph*/NULL,
461 xpt_path_path_id(ccb->ccb_h.path),
462 xpt_path_target_id(ccb->ccb_h.path),
463 xpt_path_lun_id(ccb->ccb_h.path));
464 if (status != CAM_REQ_CMP) {
465 free(lstate, M_SBP_TARG);
467 xpt_print_path(ccb->ccb_h.path);
468 printf("Couldn't allocate path\n");
469 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
472 SLIST_INIT(&lstate->accept_tios);
473 SLIST_INIT(&lstate->immed_notifies);
474 STAILQ_INIT(&lstate->logins);
476 ccb->ccb_h.status = CAM_REQ_CMP;
477 xpt_print_path(ccb->ccb_h.path);
478 printf("Lun now enabled for target mode\n");
480 sc->fd.fc->ibr(sc->fd.fc);
482 struct sbp_targ_login *login, *next;
484 if (lstate == NULL) {
485 ccb->ccb_h.status = CAM_LUN_INVALID;
486 printf("Invalid lstate for this target\n");
489 ccb->ccb_h.status = CAM_REQ_CMP;
491 if (SLIST_FIRST(&lstate->accept_tios) != NULL) {
492 printf("ATIOs pending\n");
493 ccb->ccb_h.status = CAM_REQ_INVALID;
496 if (SLIST_FIRST(&lstate->immed_notifies) != NULL) {
497 printf("INOTs pending\n");
498 ccb->ccb_h.status = CAM_REQ_INVALID;
501 if (ccb->ccb_h.status != CAM_REQ_CMP) {
502 printf("status != CAM_REQ_CMP\n");
506 xpt_print_path(ccb->ccb_h.path);
507 printf("Target mode disabled\n");
508 xpt_free_path(lstate->path);
510 for (login = STAILQ_FIRST(&lstate->logins); login != NULL;
512 next = STAILQ_NEXT(login, link);
513 sbp_targ_dealloc_login(login);
516 if (ccb->ccb_h.target_id == CAM_TARGET_WILDCARD)
517 sc->black_hole = NULL;
519 sc->lstate[ccb->ccb_h.target_lun] = NULL;
521 printf("%s: free lstate %p\n", __func__, lstate);
522 free(lstate, M_SBP_TARG);
526 sc->fd.fc->ibr(sc->fd.fc);
531 sbp_targ_send_lstate_events(struct sbp_targ_softc *sc,
532 struct sbp_targ_lstate *lstate)
535 struct ccb_hdr *ccbh;
536 struct ccb_immediate_notify *inot;
538 printf("%s: not implemented yet\n", __func__);
544 sbp_targ_remove_orb_info_locked(struct sbp_targ_login *login, struct orb_info *orbi)
546 STAILQ_REMOVE(&login->orbs, orbi, orb_info, link);
550 sbp_targ_remove_orb_info(struct sbp_targ_login *login, struct orb_info *orbi)
553 STAILQ_REMOVE(&login->orbs, orbi, orb_info, link);
554 SBP_UNLOCK(orbi->sc);
558 * tag_id/init_id encoding
560 * tag_id and init_id has only 32bit for each.
561 * scsi_target can handle very limited number(up to 15) of init_id.
562 * we have to encode 48bit orb and 64bit EUI64 into these
565 * tag_id represents lower 32bit of ORB address.
566 * init_id represents login_id.
570 static struct orb_info *
571 sbp_targ_get_orb_info(struct sbp_targ_lstate *lstate,
572 u_int tag_id, u_int init_id)
574 struct sbp_targ_login *login;
575 struct orb_info *orbi;
577 login = lstate->sc->logins[init_id];
579 printf("%s: no such login\n", __func__);
582 STAILQ_FOREACH(orbi, &login->orbs, link)
583 if (orbi->orb_lo == tag_id)
585 printf("%s: orb not found tag_id=0x%08x init_id=%d\n",
586 __func__, tag_id, init_id);
593 sbp_targ_abort(struct sbp_targ_softc *sc, struct orb_info *orbi)
595 struct orb_info *norbi;
598 for (; orbi != NULL; orbi = norbi) {
599 printf("%s: status=%d ccb=%p\n", __func__, orbi->state, orbi->ccb);
600 norbi = STAILQ_NEXT(orbi, link);
601 if (orbi->state != ORBI_STATUS_ABORTED) {
602 if (orbi->ccb != NULL) {
603 orbi->ccb->ccb_h.status = CAM_REQ_ABORTED;
607 if (orbi->state <= ORBI_STATUS_ATIO) {
608 sbp_targ_remove_orb_info_locked(orbi->login, orbi);
610 printf("%s: free orbi %p\n", __func__, orbi);
611 free(orbi, M_SBP_TARG);
614 orbi->state = ORBI_STATUS_ABORTED;
621 sbp_targ_free_orbi(struct fw_xfer *xfer)
623 struct orb_info *orbi;
625 if (xfer->resp != 0) {
627 printf("%s: xfer->resp = %d\n", __func__, xfer->resp);
629 orbi = (struct orb_info *)xfer->sc;
630 if ( orbi->page_table != NULL ) {
632 printf("%s: free orbi->page_table %p\n", __func__, orbi->page_table);
633 free(orbi->page_table, M_SBP_TARG);
634 orbi->page_table = NULL;
637 printf("%s: free orbi %p\n", __func__, orbi);
638 free(orbi, M_SBP_TARG);
644 sbp_targ_status_FIFO(struct orb_info *orbi,
645 uint32_t fifo_hi, uint32_t fifo_lo, int dequeue)
647 struct fw_xfer *xfer;
650 sbp_targ_remove_orb_info(orbi->login, orbi);
652 xfer = fwmem_write_block(orbi->fwdev, (void *)orbi,
653 /*spd*/FWSPD_S400, fifo_hi, fifo_lo,
654 sizeof(uint32_t) * (orbi->status.len + 1), (char *)&orbi->status,
659 printf("%s: xfer == NULL\n", __func__);
664 * Generate the appropriate CAM status for the
668 sbp_targ_send_status(struct orb_info *orbi, union ccb *ccb)
670 struct sbp_status *sbp_status;
672 struct orb_info *norbi;
675 sbp_status = &orbi->status;
677 orbi->state = ORBI_STATUS_STATUS;
679 sbp_status->resp = 0; /* XXX */
680 sbp_status->status = 0; /* XXX */
681 sbp_status->dead = 0; /* XXX */
683 ccb->ccb_h.status= CAM_REQ_CMP;
685 switch (ccb->csio.scsi_status) {
688 printf("%s: STATUS_OK\n", __func__);
691 case SCSI_STATUS_CHECK_COND:
693 printf("%s: STATUS SCSI_STATUS_CHECK_COND\n", __func__);
694 goto process_scsi_status;
695 case SCSI_STATUS_BUSY:
697 printf("%s: STATUS SCSI_STATUS_BUSY\n", __func__);
698 goto process_scsi_status;
699 case SCSI_STATUS_CMD_TERMINATED:
702 struct sbp_cmd_status *sbp_cmd_status;
703 struct scsi_sense_data *sense;
704 int error_code, sense_key, asc, ascq;
711 sbp_cmd_status = (struct sbp_cmd_status *)&sbp_status->data[0];
712 sbp_cmd_status->status = ccb->csio.scsi_status;
713 sense = &ccb->csio.sense_data;
715 #if 0 /* XXX What we should do? */
717 sbp_targ_abort(orbi->sc, STAILQ_NEXT(orbi, link));
719 norbi = STAILQ_NEXT(orbi, link);
721 printf("%s: status=%d\n", __func__, norbi->state);
722 if (norbi->ccb != NULL) {
723 norbi->ccb->ccb_h.status = CAM_REQ_ABORTED;
724 xpt_done(norbi->ccb);
727 sbp_targ_remove_orb_info_locked(orbi->login, norbi);
728 norbi = STAILQ_NEXT(norbi, link);
729 free(norbi, M_SBP_TARG);
734 sense_len = ccb->csio.sense_len - ccb->csio.sense_resid;
735 scsi_extract_sense_len(sense, sense_len, &error_code,
736 &sense_key, &asc, &ascq, /*show_errors*/ 0);
738 switch (error_code) {
739 case SSD_CURRENT_ERROR:
740 case SSD_DESC_CURRENT_ERROR:
741 sbp_cmd_status->sfmt = SBP_SFMT_CURR;
744 sbp_cmd_status->sfmt = SBP_SFMT_DEFER;
748 if (scsi_get_sense_info(sense, sense_len, SSD_DESC_INFO, &info,
751 sbp_cmd_status->valid = 1;
754 sbp_cmd_status->info = htobe32(info_trunc);
756 sbp_cmd_status->valid = 0;
759 sbp_cmd_status->s_key = sense_key;
761 if (scsi_get_stream_info(sense, sense_len, NULL,
762 &stream_bits) == 0) {
763 sbp_cmd_status->mark =
764 (stream_bits & SSD_FILEMARK) ? 1 : 0;
765 sbp_cmd_status->eom =
766 (stream_bits & SSD_EOM) ? 1 : 0;
767 sbp_cmd_status->ill_len =
768 (stream_bits & SSD_ILI) ? 1 : 0;
770 sbp_cmd_status->mark = 0;
771 sbp_cmd_status->eom = 0;
772 sbp_cmd_status->ill_len = 0;
776 /* add_sense_code(_qual), info, cmd_spec_info */
779 if (scsi_get_sense_info(sense, sense_len, SSD_DESC_COMMAND,
780 &info, &sinfo) == 0) {
781 uint32_t cmdspec_trunc;
783 cmdspec_trunc = info;
785 sbp_cmd_status->cdb = htobe32(cmdspec_trunc);
788 sbp_cmd_status->s_code = asc;
789 sbp_cmd_status->s_qlfr = ascq;
791 if (scsi_get_sense_info(sense, sense_len, SSD_DESC_FRU, &info,
793 sbp_cmd_status->fru = (uint8_t)info;
796 sbp_cmd_status->fru = 0;
799 if (scsi_get_sks(sense, sense_len, sks) == 0) {
800 bcopy(sks, &sbp_cmd_status->s_keydep[0], sizeof(sks));
802 ccb->ccb_h.status |= CAM_SENT_SENSE;
808 printf("%s: unknown scsi status 0x%x\n", __func__,
813 sbp_targ_status_FIFO(orbi,
814 orbi->login->fifo_hi, orbi->login->fifo_lo, /*dequeue*/1);
818 * Invoked as a callback handler from fwmem_read/write_block
820 * Process read/write of initiator address space
821 * completion and pass status onto the backend target.
822 * If this is a partial read/write for a CCB then
823 * we decrement the orbi's refcount to indicate
824 * the status of the read/write is complete
827 sbp_targ_cam_done(struct fw_xfer *xfer)
829 struct orb_info *orbi;
832 orbi = (struct orb_info *)xfer->sc;
835 printf("%s: resp=%d refcount=%d\n", __func__,
836 xfer->resp, orbi->refcount);
838 if (xfer->resp != 0) {
839 printf("%s: xfer->resp = %d\n", __func__, xfer->resp);
840 orbi->status.resp = SBP_TRANS_FAIL;
841 orbi->status.status = OBJ_DATA | SBE_TIMEOUT/*XXX*/;
842 orbi->status.dead = 1;
843 sbp_targ_abort(orbi->sc, STAILQ_NEXT(orbi, link));
849 if (orbi->refcount == 0) {
851 if (orbi->state == ORBI_STATUS_ABORTED) {
853 printf("%s: orbi aborted\n", __func__);
854 sbp_targ_remove_orb_info(orbi->login, orbi);
855 if (orbi->page_table != NULL) {
857 printf("%s: free orbi->page_table %p\n",
858 __func__, orbi->page_table);
859 free(orbi->page_table, M_SBP_TARG);
862 printf("%s: free orbi %p\n", __func__, orbi);
863 free(orbi, M_SBP_TARG);
865 } else if (orbi->status.resp == ORBI_STATUS_NONE) {
866 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) {
868 printf("%s: CAM_SEND_STATUS set %0x\n", __func__, ccb->ccb_h.flags);
869 sbp_targ_send_status(orbi, ccb);
872 printf("%s: CAM_SEND_STATUS not set %0x\n", __func__, ccb->ccb_h.flags);
873 ccb->ccb_h.status = CAM_REQ_CMP;
877 SBP_UNLOCK(orbi->sc);
879 orbi->status.len = 1;
880 sbp_targ_status_FIFO(orbi,
881 orbi->login->fifo_hi, orbi->login->fifo_lo,
883 ccb->ccb_h.status = CAM_REQ_ABORTED;
886 SBP_UNLOCK(orbi->sc);
894 sbp_targ_abort_ccb(struct sbp_targ_softc *sc, union ccb *ccb)
897 struct sbp_targ_lstate *lstate;
898 struct ccb_hdr_slist *list;
899 struct ccb_hdr *curelm;
903 status = sbp_targ_find_devs(sc, ccb, &lstate, 0);
904 if (status != CAM_REQ_CMP)
907 accb = ccb->cab.abort_ccb;
909 if (accb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO)
910 list = &lstate->accept_tios;
911 else if (accb->ccb_h.func_code == XPT_IMMEDIATE_NOTIFY)
912 list = &lstate->immed_notifies;
914 return (CAM_UA_ABORT);
916 curelm = SLIST_FIRST(list);
918 if (curelm == &accb->ccb_h) {
920 SLIST_REMOVE_HEAD(list, sim_links.sle);
922 while(curelm != NULL) {
923 struct ccb_hdr *nextelm;
925 nextelm = SLIST_NEXT(curelm, sim_links.sle);
926 if (nextelm == &accb->ccb_h) {
928 SLIST_NEXT(curelm, sim_links.sle) =
929 SLIST_NEXT(nextelm, sim_links.sle);
936 accb->ccb_h.status = CAM_REQ_ABORTED;
938 return (CAM_REQ_CMP);
940 printf("%s: not found\n", __func__);
941 return (CAM_PATH_INVALID);
945 * directly execute a read or write to the initiator
946 * address space and set hand(sbp_targ_cam_done) to
947 * process the completion from the SIM to the target.
948 * set orbi->refcount to inidicate that a read/write
949 * is inflight to/from the initiator.
952 sbp_targ_xfer_buf(struct orb_info *orbi, u_int offset,
953 uint16_t dst_hi, uint32_t dst_lo, u_int size,
954 void (*hand)(struct fw_xfer *))
956 struct fw_xfer *xfer;
957 u_int len, ccb_dir, off = 0;
961 printf("%s: offset=%d size=%d\n", __func__, offset, size);
962 ccb_dir = orbi->ccb->ccb_h.flags & CAM_DIR_MASK;
963 ptr = (char *)orbi->ccb->csio.data_ptr + offset;
966 /* XXX assume dst_lo + off doesn't overflow */
967 len = MIN(size, 2048 /* XXX */);
970 if (ccb_dir == CAM_DIR_OUT) {
972 printf("%s: CAM_DIR_OUT --> read block in?\n",__func__);
973 xfer = fwmem_read_block(orbi->fwdev,
974 (void *)orbi, /*spd*/FWSPD_S400,
975 dst_hi, dst_lo + off, len,
979 printf("%s: CAM_DIR_IN --> write block out?\n",__func__);
980 xfer = fwmem_write_block(orbi->fwdev,
981 (void *)orbi, /*spd*/FWSPD_S400,
982 dst_hi, dst_lo + off, len,
986 printf("%s: xfer == NULL", __func__);
987 /* XXX what should we do?? */
995 sbp_targ_pt_done(struct fw_xfer *xfer)
997 struct orb_info *orbi;
998 struct unrestricted_page_table_fmt *pt;
1001 orbi = (struct orb_info *)xfer->sc;
1003 if (orbi->state == ORBI_STATUS_ABORTED) {
1005 printf("%s: orbi aborted\n", __func__);
1006 sbp_targ_remove_orb_info(orbi->login, orbi);
1008 printf("%s: free orbi->page_table %p\n", __func__, orbi->page_table);
1009 printf("%s: free orbi %p\n", __func__, orbi);
1011 free(orbi->page_table, M_SBP_TARG);
1012 free(orbi, M_SBP_TARG);
1017 if (xfer->resp != 0) {
1018 printf("%s: xfer->resp = %d\n", __func__, xfer->resp);
1019 orbi->status.resp = SBP_TRANS_FAIL;
1020 orbi->status.status = OBJ_PT | SBE_TIMEOUT/*XXX*/;
1021 orbi->status.dead = 1;
1022 orbi->status.len = 1;
1023 sbp_targ_abort(orbi->sc, STAILQ_NEXT(orbi, link));
1026 printf("%s: free orbi->page_table %p\n", __func__, orbi->page_table);
1028 sbp_targ_status_FIFO(orbi,
1029 orbi->login->fifo_hi, orbi->login->fifo_lo, /*dequeue*/1);
1030 free(orbi->page_table, M_SBP_TARG);
1031 orbi->page_table = NULL;
1037 * Set endianess here so we don't have
1038 * to deal with is later
1040 for (i = 0, pt = orbi->page_table; i < orbi->orb4.data_size; i++, pt++) {
1041 pt->segment_len = ntohs(pt->segment_len);
1043 printf("%s:segment_len = %u\n", __func__,pt->segment_len);
1044 pt->segment_base_high = ntohs(pt->segment_base_high);
1045 pt->segment_base_low = ntohl(pt->segment_base_low);
1048 sbp_targ_xfer_pt(orbi);
1051 if (orbi->refcount == 0)
1052 printf("%s: refcount == 0\n", __func__);
1058 static void sbp_targ_xfer_pt(struct orb_info *orbi)
1061 uint32_t res, offset, len;
1065 printf("%s: dxfer_len=%d\n", __func__, ccb->csio.dxfer_len);
1066 res = ccb->csio.dxfer_len;
1068 * If the page table required multiple CTIO's to
1069 * complete, then cur_pte is non NULL
1070 * and we need to start from the last position
1071 * If this is the first pass over a page table
1072 * then we just start at the beginning of the page
1075 * Parse the unrestricted page table and figure out where we need
1076 * to shove the data from this read request.
1078 for (offset = 0, len = 0; (res != 0) && (orbi->cur_pte < orbi->last_pte); offset += len) {
1079 len = MIN(orbi->cur_pte->segment_len, res);
1082 printf("%s:page_table: %04x:%08x segment_len(%u) res(%u) len(%u)\n",
1083 __func__, orbi->cur_pte->segment_base_high,
1084 orbi->cur_pte->segment_base_low,
1085 orbi->cur_pte->segment_len,
1087 sbp_targ_xfer_buf(orbi, offset,
1088 orbi->cur_pte->segment_base_high,
1089 orbi->cur_pte->segment_base_low,
1090 len, sbp_targ_cam_done);
1092 * If we have only written partially to
1093 * this page table, then we need to save
1094 * our position for the next CTIO. If we
1095 * have completed the page table, then we
1096 * are safe to move on to the next entry.
1098 if (len == orbi->cur_pte->segment_len) {
1101 uint32_t saved_base_low;
1103 /* Handle transfers that cross a 4GB boundary. */
1104 saved_base_low = orbi->cur_pte->segment_base_low;
1105 orbi->cur_pte->segment_base_low += len;
1106 if (orbi->cur_pte->segment_base_low < saved_base_low)
1107 orbi->cur_pte->segment_base_high++;
1109 orbi->cur_pte->segment_len -= len;
1113 printf("%s: base_low(%08x) page_table_off(%p) last_block(%u)\n",
1114 __func__, orbi->cur_pte->segment_base_low,
1115 orbi->cur_pte, orbi->last_block_read);
1118 printf("Warning - short pt encountered. "
1119 "Could not transfer all data.\n");
1124 * Create page table in local memory
1125 * and transfer it from the initiator
1126 * in order to know where we are supposed
1131 sbp_targ_fetch_pt(struct orb_info *orbi)
1133 struct fw_xfer *xfer;
1136 * Pull in page table from initiator
1137 * and setup for data from our
1140 if (orbi->page_table == NULL) {
1141 orbi->page_table = malloc(orbi->orb4.data_size*
1142 sizeof(struct unrestricted_page_table_fmt),
1143 M_SBP_TARG, M_NOWAIT|M_ZERO);
1144 if (orbi->page_table == NULL)
1146 orbi->cur_pte = orbi->page_table;
1147 orbi->last_pte = orbi->page_table + orbi->orb4.data_size;
1148 orbi->last_block_read = orbi->orb4.data_size;
1149 if (debug && orbi->page_table != NULL)
1150 printf("%s: malloc'd orbi->page_table(%p), orb4.data_size(%u)\n",
1151 __func__, orbi->page_table, orbi->orb4.data_size);
1153 xfer = fwmem_read_block(orbi->fwdev, (void *)orbi, /*spd*/FWSPD_S400,
1154 orbi->data_hi, orbi->data_lo, orbi->orb4.data_size*
1155 sizeof(struct unrestricted_page_table_fmt),
1156 (void *)orbi->page_table, sbp_targ_pt_done);
1162 * This is a CTIO for a page table we have
1163 * already malloc'd, so just directly invoke
1164 * the xfer function on the orbi.
1166 sbp_targ_xfer_pt(orbi);
1170 orbi->ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
1172 printf("%s: free orbi->page_table %p due to xfer == NULL\n", __func__, orbi->page_table);
1173 if (orbi->page_table != NULL) {
1174 free(orbi->page_table, M_SBP_TARG);
1175 orbi->page_table = NULL;
1177 xpt_done(orbi->ccb);
1182 sbp_targ_action1(struct cam_sim *sim, union ccb *ccb)
1184 struct sbp_targ_softc *sc;
1185 struct sbp_targ_lstate *lstate;
1189 sc = (struct sbp_targ_softc *)cam_sim_softc(sim);
1191 status = sbp_targ_find_devs(sc, ccb, &lstate, TRUE);
1193 switch (ccb->ccb_h.func_code) {
1194 case XPT_CONT_TARGET_IO:
1196 struct orb_info *orbi;
1199 printf("%s: XPT_CONT_TARGET_IO (0x%08x)\n",
1200 __func__, ccb->csio.tag_id);
1202 if (status != CAM_REQ_CMP) {
1203 ccb->ccb_h.status = status;
1207 /* XXX transfer from/to initiator */
1208 orbi = sbp_targ_get_orb_info(lstate,
1209 ccb->csio.tag_id, ccb->csio.init_id);
1211 ccb->ccb_h.status = CAM_REQ_ABORTED; /* XXX */
1215 if (orbi->state == ORBI_STATUS_ABORTED) {
1217 printf("%s: ctio aborted\n", __func__);
1218 sbp_targ_remove_orb_info_locked(orbi->login, orbi);
1220 printf("%s: free orbi %p\n", __func__, orbi);
1221 free(orbi, M_SBP_TARG);
1222 ccb->ccb_h.status = CAM_REQ_ABORTED;
1226 orbi->state = ORBI_STATUS_CTIO;
1229 ccb_dir = ccb->ccb_h.flags & CAM_DIR_MASK;
1232 if (ccb->csio.dxfer_len == 0)
1233 ccb_dir = CAM_DIR_NONE;
1236 if (ccb_dir == CAM_DIR_IN && orbi->orb4.dir == 0)
1237 printf("%s: direction mismatch\n", __func__);
1239 /* check page table */
1240 if (ccb_dir != CAM_DIR_NONE && orbi->orb4.page_table_present) {
1242 printf("%s: page_table_present\n",
1244 if (orbi->orb4.page_size != 0) {
1245 printf("%s: unsupported pagesize %d != 0\n",
1246 __func__, orbi->orb4.page_size);
1247 ccb->ccb_h.status = CAM_REQ_INVALID;
1251 sbp_targ_fetch_pt(orbi);
1256 if (ccb_dir != CAM_DIR_NONE) {
1257 sbp_targ_xfer_buf(orbi, 0, orbi->data_hi,
1259 MIN(orbi->orb4.data_size, ccb->csio.dxfer_len),
1261 if ( orbi->orb4.data_size > ccb->csio.dxfer_len ) {
1262 orbi->data_lo += ccb->csio.dxfer_len;
1263 orbi->orb4.data_size -= ccb->csio.dxfer_len;
1267 if (ccb_dir == CAM_DIR_NONE) {
1268 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) {
1271 sbp_targ_send_status(orbi, ccb);
1274 ccb->ccb_h.status = CAM_REQ_CMP;
1279 case XPT_ACCEPT_TARGET_IO: /* Add Accept Target IO Resource */
1280 if (status != CAM_REQ_CMP) {
1281 ccb->ccb_h.status = status;
1285 SLIST_INSERT_HEAD(&lstate->accept_tios, &ccb->ccb_h,
1287 ccb->ccb_h.status = CAM_REQ_INPROG;
1288 if ((lstate->flags & F_ATIO_STARVED) != 0) {
1289 struct sbp_targ_login *login;
1292 printf("%s: new atio arrived\n", __func__);
1293 lstate->flags &= ~F_ATIO_STARVED;
1294 STAILQ_FOREACH(login, &lstate->logins, link)
1295 if ((login->flags & F_ATIO_STARVED) != 0) {
1296 login->flags &= ~F_ATIO_STARVED;
1297 sbp_targ_fetch_orb(lstate->sc,
1299 login->last_hi, login->last_lo,
1304 case XPT_NOTIFY_ACKNOWLEDGE: /* recycle notify ack */
1305 case XPT_IMMEDIATE_NOTIFY: /* Add Immediate Notify Resource */
1306 if (status != CAM_REQ_CMP) {
1307 ccb->ccb_h.status = status;
1311 SLIST_INSERT_HEAD(&lstate->immed_notifies, &ccb->ccb_h,
1313 ccb->ccb_h.status = CAM_REQ_INPROG;
1314 sbp_targ_send_lstate_events(sc, lstate);
1317 sbp_targ_en_lun(sc, ccb);
1322 struct ccb_pathinq *cpi = &ccb->cpi;
1324 cpi->version_num = 1; /* XXX??? */
1325 cpi->hba_inquiry = PI_TAG_ABLE;
1326 cpi->target_sprt = PIT_PROCESSOR
1329 cpi->transport = XPORT_SPI; /* FIXME add XPORT_FW type to cam */
1330 cpi->hba_misc = PIM_NOBUSRESET | PIM_NOBUSRESET;
1331 cpi->hba_eng_cnt = 0;
1332 cpi->max_target = 7; /* XXX */
1333 cpi->max_lun = MAX_LUN - 1;
1334 cpi->initiator_id = 7; /* XXX */
1335 cpi->bus_id = sim->bus_id;
1336 cpi->base_transfer_speed = 400 * 1000 / 8;
1337 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
1338 strncpy(cpi->hba_vid, "SBP_TARG", HBA_IDLEN);
1339 strncpy(cpi->dev_name, sim->sim_name, DEV_IDLEN);
1340 cpi->unit_number = sim->unit_number;
1342 cpi->ccb_h.status = CAM_REQ_CMP;
1348 union ccb *accb = ccb->cab.abort_ccb;
1350 switch (accb->ccb_h.func_code) {
1351 case XPT_ACCEPT_TARGET_IO:
1352 case XPT_IMMEDIATE_NOTIFY:
1353 ccb->ccb_h.status = sbp_targ_abort_ccb(sc, ccb);
1355 case XPT_CONT_TARGET_IO:
1357 ccb->ccb_h.status = CAM_UA_ABORT;
1360 printf("%s: aborting unknown function %d\n",
1361 __func__, accb->ccb_h.func_code);
1362 ccb->ccb_h.status = CAM_REQ_INVALID;
1368 #ifdef CAM_NEW_TRAN_CODE
1369 case XPT_SET_TRAN_SETTINGS:
1370 ccb->ccb_h.status = CAM_REQ_INVALID;
1373 case XPT_GET_TRAN_SETTINGS:
1375 struct ccb_trans_settings *cts = &ccb->cts;
1376 struct ccb_trans_settings_scsi *scsi =
1377 &cts->proto_specific.scsi;
1378 struct ccb_trans_settings_spi *spi =
1379 &cts->xport_specific.spi;
1381 cts->protocol = PROTO_SCSI;
1382 cts->protocol_version = SCSI_REV_2;
1383 cts->transport = XPORT_FW; /* should have a FireWire */
1384 cts->transport_version = 2;
1385 spi->valid = CTS_SPI_VALID_DISC;
1386 spi->flags = CTS_SPI_FLAGS_DISC_ENB;
1387 scsi->valid = CTS_SCSI_VALID_TQ;
1388 scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
1390 printf("%s:%d:%d XPT_GET_TRAN_SETTINGS:\n",
1391 device_get_nameunit(sc->fd.dev),
1392 ccb->ccb_h.target_id, ccb->ccb_h.target_lun);
1394 cts->ccb_h.status = CAM_REQ_CMP;
1401 printf("%s: unknown function 0x%x\n",
1402 __func__, ccb->ccb_h.func_code);
1403 ccb->ccb_h.status = CAM_PROVIDE_FAIL;
1411 sbp_targ_action(struct cam_sim *sim, union ccb *ccb)
1416 sbp_targ_action1(sim, ccb);
1421 sbp_targ_poll(struct cam_sim *sim)
1428 sbp_targ_cmd_handler(struct fw_xfer *xfer)
1433 struct orb_info *orbi;
1434 struct ccb_accept_tio *atio;
1438 orbi = (struct orb_info *)xfer->sc;
1439 if (xfer->resp != 0) {
1440 printf("%s: xfer->resp = %d\n", __func__, xfer->resp);
1441 orbi->status.resp = SBP_TRANS_FAIL;
1442 orbi->status.status = OBJ_ORB | SBE_TIMEOUT/*XXX*/;
1443 orbi->status.dead = 1;
1444 orbi->status.len = 1;
1445 sbp_targ_abort(orbi->sc, STAILQ_NEXT(orbi, link));
1447 sbp_targ_status_FIFO(orbi,
1448 orbi->login->fifo_hi, orbi->login->fifo_lo, /*dequeue*/1);
1452 fp = &xfer->recv.hdr;
1456 if (orbi->state == ORBI_STATUS_ABORTED) {
1457 printf("%s: aborted\n", __func__);
1458 sbp_targ_remove_orb_info(orbi->login, orbi);
1459 free(orbi, M_SBP_TARG);
1460 atio->ccb_h.status = CAM_REQ_ABORTED;
1462 xpt_done((union ccb*)atio);
1463 SBP_UNLOCK(orbi->sc);
1466 orbi->state = ORBI_STATUS_ATIO;
1469 /* swap payload except SCSI command */
1470 for (i = 0; i < 5; i ++)
1471 orb[i] = ntohl(orb[i]);
1473 orb4 = (struct corb4 *)&orb[4];
1474 if (orb4->rq_fmt != 0) {
1476 printf("%s: rq_fmt(%d) != 0\n", __func__, orb4->rq_fmt);
1479 atio->ccb_h.target_id = 0; /* XXX */
1480 atio->ccb_h.target_lun = orbi->login->lstate->lun;
1481 atio->sense_len = 0;
1482 atio->tag_action = MSG_SIMPLE_TASK;
1483 atio->tag_id = orbi->orb_lo;
1484 atio->init_id = orbi->login->id;
1486 atio->ccb_h.flags = CAM_TAG_ACTION_VALID;
1487 bytes = (u_char *)&orb[5];
1489 printf("%s: %p %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
1490 __func__, (void *)atio,
1491 bytes[0], bytes[1], bytes[2], bytes[3], bytes[4],
1492 bytes[5], bytes[6], bytes[7], bytes[8], bytes[9]);
1493 switch (bytes[0] >> 5) {
1509 /* Only copy the opcode. */
1511 printf("Reserved or VU command code type encountered\n");
1515 memcpy(atio->cdb_io.cdb_bytes, bytes, atio->cdb_len);
1517 atio->ccb_h.status |= CAM_CDB_RECVD;
1520 if ((orb[0] & (1<<31)) == 0) {
1522 printf("%s: fetch next orb\n", __func__);
1523 orbi->status.src = SRC_NEXT_EXISTS;
1524 sbp_targ_fetch_orb(orbi->sc, orbi->fwdev,
1525 orb[0], orb[1], orbi->login, FETCH_CMD);
1527 orbi->status.src = SRC_NO_NEXT;
1528 orbi->login->flags &= ~F_LINK_ACTIVE;
1531 orbi->data_hi = orb[2];
1532 orbi->data_lo = orb[3];
1536 xpt_done((union ccb*)atio);
1537 SBP_UNLOCK(orbi->sc);
1543 static struct sbp_targ_login *
1544 sbp_targ_get_login(struct sbp_targ_softc *sc, struct fw_device *fwdev, int lun)
1546 struct sbp_targ_lstate *lstate;
1547 struct sbp_targ_login *login;
1550 lstate = sc->lstate[lun];
1552 STAILQ_FOREACH(login, &lstate->logins, link)
1553 if (login->fwdev == fwdev)
1556 for (i = 0; i < MAX_LOGINS; i ++)
1557 if (sc->logins[i] == NULL)
1560 printf("%s: increase MAX_LOGIN\n", __func__);
1564 login = (struct sbp_targ_login *)malloc(
1565 sizeof(struct sbp_targ_login), M_SBP_TARG, M_NOWAIT | M_ZERO);
1567 if (login == NULL) {
1568 printf("%s: malloc failed\n", __func__);
1573 login->fwdev = fwdev;
1574 login->lstate = lstate;
1575 login->last_hi = 0xffff;
1576 login->last_lo = 0xffffffff;
1577 login->hold_sec = 1;
1578 STAILQ_INIT(&login->orbs);
1579 CALLOUT_INIT(&login->hold_callout);
1580 sc->logins[i] = login;
1585 sbp_targ_mgm_handler(struct fw_xfer *xfer)
1587 struct sbp_targ_lstate *lstate;
1588 struct sbp_targ_login *login;
1592 struct orb_info *orbi;
1595 orbi = (struct orb_info *)xfer->sc;
1596 if (xfer->resp != 0) {
1597 printf("%s: xfer->resp = %d\n", __func__, xfer->resp);
1598 orbi->status.resp = SBP_TRANS_FAIL;
1599 orbi->status.status = OBJ_ORB | SBE_TIMEOUT/*XXX*/;
1600 orbi->status.dead = 1;
1601 orbi->status.len = 1;
1602 sbp_targ_abort(orbi->sc, STAILQ_NEXT(orbi, link));
1604 sbp_targ_status_FIFO(orbi,
1605 orbi->login->fifo_hi, orbi->login->fifo_lo, /*dequeue*/0);
1609 fp = &xfer->recv.hdr;
1613 for (i = 0; i < 8; i ++) {
1614 orb[i] = ntohl(orb[i]);
1616 orb4 = (struct morb4 *)&orb[4];
1618 printf("%s: %s\n", __func__, orb_fun_name[orb4->fun]);
1620 orbi->status.src = SRC_NO_NEXT;
1622 switch (orb4->fun << 16) {
1625 int exclusive = 0, lun;
1627 if (orb[4] & ORB_EXV)
1631 lstate = orbi->sc->lstate[lun];
1633 if (lun >= MAX_LUN || lstate == NULL ||
1635 STAILQ_FIRST(&lstate->logins) != NULL &&
1636 STAILQ_FIRST(&lstate->logins)->fwdev != orbi->fwdev)
1639 orbi->status.dead = 1;
1640 orbi->status.status = STATUS_ACCESS_DENY;
1641 orbi->status.len = 1;
1645 /* allocate login */
1646 login = sbp_targ_get_login(orbi->sc, orbi->fwdev, lun);
1647 if (login == NULL) {
1648 printf("%s: sbp_targ_get_login failed\n",
1650 orbi->status.dead = 1;
1651 orbi->status.status = STATUS_RES_UNAVAIL;
1652 orbi->status.len = 1;
1655 printf("%s: login id=%d\n", __func__, login->id);
1657 login->fifo_hi = orb[6];
1658 login->fifo_lo = orb[7];
1659 login->loginres.len = htons(sizeof(uint32_t) * 4);
1660 login->loginres.id = htons(login->id);
1661 login->loginres.cmd_hi = htons(SBP_TARG_BIND_HI);
1662 login->loginres.cmd_lo = htonl(SBP_TARG_BIND_LO(login->id));
1663 login->loginres.recon_hold = htons(login->hold_sec);
1665 STAILQ_INSERT_TAIL(&lstate->logins, login, link);
1666 fwmem_write_block(orbi->fwdev, NULL, /*spd*/FWSPD_S400, orb[2], orb[3],
1667 sizeof(struct sbp_login_res), (void *)&login->loginres,
1668 fw_asy_callback_free);
1669 /* XXX return status after loginres is successfully written */
1673 login = orbi->sc->logins[orb4->id];
1674 if (login != NULL && login->fwdev == orbi->fwdev) {
1675 login->flags &= ~F_HOLD;
1676 callout_stop(&login->hold_callout);
1677 printf("%s: reconnected id=%d\n",
1678 __func__, login->id);
1680 orbi->status.dead = 1;
1681 orbi->status.status = STATUS_ACCESS_DENY;
1682 printf("%s: reconnection faild id=%d\n",
1683 __func__, orb4->id);
1687 login = orbi->sc->logins[orb4->id];
1688 if (login->fwdev != orbi->fwdev) {
1689 printf("%s: wrong initiator\n", __func__);
1692 sbp_targ_dealloc_login(login);
1695 printf("%s: %s not implemented yet\n",
1696 __func__, orb_fun_name[orb4->fun]);
1699 orbi->status.len = 1;
1700 sbp_targ_status_FIFO(orbi, orb[6], orb[7], /*dequeue*/0);
1706 sbp_targ_pointer_handler(struct fw_xfer *xfer)
1708 struct orb_info *orbi;
1709 uint32_t orb0, orb1;
1711 orbi = (struct orb_info *)xfer->sc;
1712 if (xfer->resp != 0) {
1713 printf("%s: xfer->resp = %d\n", __func__, xfer->resp);
1717 orb0 = ntohl(orbi->orb[0]);
1718 orb1 = ntohl(orbi->orb[1]);
1719 if ((orb0 & (1 << 31)) != 0) {
1720 printf("%s: invalid pointer\n", __func__);
1723 sbp_targ_fetch_orb(orbi->login->lstate->sc, orbi->fwdev,
1724 (uint16_t)orb0, orb1, orbi->login, FETCH_CMD);
1726 free(orbi, M_SBP_TARG);
1732 sbp_targ_fetch_orb(struct sbp_targ_softc *sc, struct fw_device *fwdev,
1733 uint16_t orb_hi, uint32_t orb_lo, struct sbp_targ_login *login,
1736 struct orb_info *orbi;
1739 printf("%s: fetch orb %04x:%08x\n", __func__, orb_hi, orb_lo);
1740 orbi = malloc(sizeof(struct orb_info), M_SBP_TARG, M_NOWAIT | M_ZERO);
1742 printf("%s: malloc failed\n", __func__);
1746 orbi->fwdev = fwdev;
1747 orbi->login = login;
1748 orbi->orb_hi = orb_hi;
1749 orbi->orb_lo = orb_lo;
1750 orbi->status.orb_hi = htons(orb_hi);
1751 orbi->status.orb_lo = htonl(orb_lo);
1752 orbi->page_table = NULL;
1756 fwmem_read_block(fwdev, (void *)orbi, /*spd*/FWSPD_S400, orb_hi, orb_lo,
1757 sizeof(uint32_t) * 8, &orbi->orb[0],
1758 sbp_targ_mgm_handler);
1761 orbi->state = ORBI_STATUS_FETCH;
1762 login->last_hi = orb_hi;
1763 login->last_lo = orb_lo;
1764 login->flags |= F_LINK_ACTIVE;
1767 orbi->atio = (struct ccb_accept_tio *)
1768 SLIST_FIRST(&login->lstate->accept_tios);
1769 if (orbi->atio == NULL) {
1771 printf("%s: no free atio\n", __func__);
1772 login->lstate->flags |= F_ATIO_STARVED;
1773 login->flags |= F_ATIO_STARVED;
1776 login->fwdev = fwdev;
1780 SLIST_REMOVE_HEAD(&login->lstate->accept_tios, sim_links.sle);
1781 STAILQ_INSERT_TAIL(&login->orbs, orbi, link);
1783 fwmem_read_block(fwdev, (void *)orbi, /*spd*/FWSPD_S400, orb_hi, orb_lo,
1784 sizeof(uint32_t) * 8, &orbi->orb[0],
1785 sbp_targ_cmd_handler);
1788 orbi->state = ORBI_STATUS_POINTER;
1789 login->flags |= F_LINK_ACTIVE;
1790 fwmem_read_block(fwdev, (void *)orbi, /*spd*/FWSPD_S400, orb_hi, orb_lo,
1791 sizeof(uint32_t) * 2, &orbi->orb[0],
1792 sbp_targ_pointer_handler);
1795 printf("%s: invalid mode %d\n", __func__, mode);
1800 sbp_targ_resp_callback(struct fw_xfer *xfer)
1802 struct sbp_targ_softc *sc;
1806 printf("%s: xfer=%p\n", __func__, xfer);
1807 sc = (struct sbp_targ_softc *)xfer->sc;
1808 fw_xfer_unload(xfer);
1809 xfer->recv.pay_len = SBP_TARG_RECV_LEN;
1810 xfer->hand = sbp_targ_recv;
1812 STAILQ_INSERT_TAIL(&sc->fwb.xferlist, xfer, link);
1817 sbp_targ_cmd(struct fw_xfer *xfer, struct fw_device *fwdev, int login_id,
1820 struct sbp_targ_login *login;
1821 struct sbp_targ_softc *sc;
1824 if (login_id < 0 || login_id >= MAX_LOGINS)
1825 return(RESP_ADDRESS_ERROR);
1827 sc = (struct sbp_targ_softc *)xfer->sc;
1828 login = sc->logins[login_id];
1830 return(RESP_ADDRESS_ERROR);
1832 if (login->fwdev != fwdev) {
1834 return(RESP_ADDRESS_ERROR);
1838 case 0x08: /* ORB_POINTER */
1840 printf("%s: ORB_POINTER(%d)\n", __func__, login_id);
1841 if ((login->flags & F_LINK_ACTIVE) != 0) {
1843 printf("link active (ORB_POINTER)\n");
1846 sbp_targ_fetch_orb(sc, fwdev,
1847 ntohl(xfer->recv.payload[0]),
1848 ntohl(xfer->recv.payload[1]),
1851 case 0x04: /* AGENT_RESET */
1853 printf("%s: AGENT RESET(%d)\n", __func__, login_id);
1854 login->last_hi = 0xffff;
1855 login->last_lo = 0xffffffff;
1856 sbp_targ_abort(sc, STAILQ_FIRST(&login->orbs));
1858 case 0x10: /* DOORBELL */
1860 printf("%s: DOORBELL(%d)\n", __func__, login_id);
1861 if (login->last_hi == 0xffff &&
1862 login->last_lo == 0xffffffff) {
1863 printf("%s: no previous pointer(DOORBELL)\n",
1867 if ((login->flags & F_LINK_ACTIVE) != 0) {
1869 printf("link active (DOORBELL)\n");
1872 sbp_targ_fetch_orb(sc, fwdev,
1873 login->last_hi, login->last_lo,
1874 login, FETCH_POINTER);
1876 case 0x00: /* AGENT_STATE */
1877 printf("%s: AGENT_STATE (%d:ignore)\n", __func__, login_id);
1879 case 0x14: /* UNSOLICITED_STATE_ENABLE */
1880 printf("%s: UNSOLICITED_STATE_ENABLE (%d:ignore)\n",
1881 __func__, login_id);
1884 printf("%s: invalid register %d(%d)\n",
1885 __func__, reg, login_id);
1886 rtcode = RESP_ADDRESS_ERROR;
1893 sbp_targ_mgm(struct fw_xfer *xfer, struct fw_device *fwdev)
1895 struct sbp_targ_softc *sc;
1898 sc = (struct sbp_targ_softc *)xfer->sc;
1900 fp = &xfer->recv.hdr;
1901 if (fp->mode.wreqb.tcode != FWTCODE_WREQB){
1902 printf("%s: tcode = %d\n", __func__, fp->mode.wreqb.tcode);
1903 return(RESP_TYPE_ERROR);
1906 sbp_targ_fetch_orb(sc, fwdev,
1907 ntohl(xfer->recv.payload[0]),
1908 ntohl(xfer->recv.payload[1]),
1915 sbp_targ_recv(struct fw_xfer *xfer)
1917 struct fw_pkt *fp, *sfp;
1918 struct fw_device *fwdev;
1921 struct sbp_targ_softc *sc;
1924 sc = (struct sbp_targ_softc *)xfer->sc;
1925 fp = &xfer->recv.hdr;
1926 fwdev = fw_noderesolve_nodeid(sc->fd.fc, fp->mode.wreqb.src & 0x3f);
1927 if (fwdev == NULL) {
1928 printf("%s: cannot resolve nodeid=%d\n",
1929 __func__, fp->mode.wreqb.src & 0x3f);
1930 rtcode = RESP_TYPE_ERROR; /* XXX */
1933 lo = fp->mode.wreqb.dest_lo;
1935 if (lo == SBP_TARG_BIND_LO(-1))
1936 rtcode = sbp_targ_mgm(xfer, fwdev);
1937 else if (lo >= SBP_TARG_BIND_LO(0))
1938 rtcode = sbp_targ_cmd(xfer, fwdev, SBP_TARG_LOGIN_ID(lo),
1941 rtcode = RESP_ADDRESS_ERROR;
1945 printf("%s: rtcode = %d\n", __func__, rtcode);
1946 sfp = &xfer->send.hdr;
1947 xfer->send.spd = FWSPD_S400;
1948 xfer->hand = sbp_targ_resp_callback;
1949 sfp->mode.wres.dst = fp->mode.wreqb.src;
1950 sfp->mode.wres.tlrt = fp->mode.wreqb.tlrt;
1951 sfp->mode.wres.tcode = FWTCODE_WRES;
1952 sfp->mode.wres.rtcode = rtcode;
1953 sfp->mode.wres.pri = 0;
1955 fw_asyreq(xfer->fc, -1, xfer);
1960 sbp_targ_attach(device_t dev)
1962 struct sbp_targ_softc *sc;
1963 struct cam_devq *devq;
1964 struct firewire_comm *fc;
1966 sc = (struct sbp_targ_softc *) device_get_softc(dev);
1967 bzero((void *)sc, sizeof(struct sbp_targ_softc));
1969 mtx_init(&sc->mtx, "sbp_targ", NULL, MTX_DEF);
1970 sc->fd.fc = fc = device_get_ivars(dev);
1972 sc->fd.post_explore = (void *) sbp_targ_post_explore;
1973 sc->fd.post_busreset = (void *) sbp_targ_post_busreset;
1975 devq = cam_simq_alloc(/*maxopenings*/MAX_LUN*MAX_INITIATORS);
1979 sc->sim = cam_sim_alloc(sbp_targ_action, sbp_targ_poll,
1980 "sbp_targ", sc, device_get_unit(dev), &sc->mtx,
1981 /*untagged*/ 1, /*tagged*/ 1, devq);
1982 if (sc->sim == NULL) {
1983 cam_simq_free(devq);
1988 if (xpt_bus_register(sc->sim, dev, /*bus*/0) != CAM_SUCCESS)
1991 if (xpt_create_path(&sc->path, /*periph*/ NULL, cam_sim_path(sc->sim),
1992 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
1993 xpt_bus_deregister(cam_sim_path(sc->sim));
1998 sc->fwb.start = SBP_TARG_BIND_START;
1999 sc->fwb.end = SBP_TARG_BIND_END;
2001 /* pre-allocate xfer */
2002 STAILQ_INIT(&sc->fwb.xferlist);
2003 fw_xferlist_add(&sc->fwb.xferlist, M_SBP_TARG,
2004 /*send*/ 0, /*recv*/ SBP_TARG_RECV_LEN, MAX_LUN /* XXX */,
2005 fc, (void *)sc, sbp_targ_recv);
2006 fw_bindadd(fc, &sc->fwb);
2011 cam_sim_free(sc->sim, /*free_devq*/TRUE);
2016 sbp_targ_detach(device_t dev)
2018 struct sbp_targ_softc *sc;
2019 struct sbp_targ_lstate *lstate;
2022 sc = (struct sbp_targ_softc *)device_get_softc(dev);
2023 sc->fd.post_busreset = NULL;
2026 xpt_free_path(sc->path);
2027 xpt_bus_deregister(cam_sim_path(sc->sim));
2029 cam_sim_free(sc->sim, /*free_devq*/TRUE);
2031 for (i = 0; i < MAX_LUN; i ++) {
2032 lstate = sc->lstate[i];
2033 if (lstate != NULL) {
2034 xpt_free_path(lstate->path);
2035 free(lstate, M_SBP_TARG);
2038 if (sc->black_hole != NULL) {
2039 xpt_free_path(sc->black_hole->path);
2040 free(sc->black_hole, M_SBP_TARG);
2043 fw_bindremove(sc->fd.fc, &sc->fwb);
2044 fw_xferlist_remove(&sc->fwb.xferlist);
2046 mtx_destroy(&sc->mtx);
2051 static devclass_t sbp_targ_devclass;
2053 static device_method_t sbp_targ_methods[] = {
2054 /* device interface */
2055 DEVMETHOD(device_identify, sbp_targ_identify),
2056 DEVMETHOD(device_probe, sbp_targ_probe),
2057 DEVMETHOD(device_attach, sbp_targ_attach),
2058 DEVMETHOD(device_detach, sbp_targ_detach),
2062 static driver_t sbp_targ_driver = {
2065 sizeof(struct sbp_targ_softc),
2068 DRIVER_MODULE(sbp_targ, firewire, sbp_targ_driver, sbp_targ_devclass, 0, 0);
2069 MODULE_VERSION(sbp_targ, 1);
2070 MODULE_DEPEND(sbp_targ, firewire, 1, 1, 1);
2071 MODULE_DEPEND(sbp_targ, cam, 1, 1, 1);