Deleted Added
sdiff udiff text old ( 266270 ) new ( 266772 )
full compact
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:

--- 17 unchanged lines hidden (view full) ---

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: head/sys/dev/firewire/sbp.c 266772 2014-05-27 19:56:02Z jhb $
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>

--- 129 unchanged lines hidden (view full) ---

172 union ccb *ccb;
173 bus_addr_t bus_addr;
174 uint32_t orb[8];
175#define IND_PTR_OFFSET (8*sizeof(uint32_t))
176 struct ind_ptr ind_ptr[SBP_IND_MAX];
177 struct sbp_dev *sdev;
178 int flags; /* XXX should be removed */
179 bus_dmamap_t dmamap;
180 struct callout timer;
181};
182
183#define OCB_ACT_MGM 0
184#define OCB_ACT_CMD 1
185#define OCB_MATCH(o,s) ((o)->bus_addr == ntohl((s)->orb_lo))
186
187struct sbp_dev{
188#define SBP_DEV_RESET 0 /* accept login */

--- 56 unchanged lines hidden (view full) ---

245 struct sbp_target targets[SBP_NUM_TARGETS];
246 struct fw_bind fwb;
247 bus_dma_tag_t dmat;
248 struct timeval last_busreset;
249#define SIMQ_FREEZED 1
250 int flags;
251 struct mtx mtx;
252};
253#define SBP_LOCK(sbp) mtx_lock(&(sbp)->mtx)
254#define SBP_UNLOCK(sbp) mtx_unlock(&(sbp)->mtx)
255#define SBP_LOCK_ASSERT(sbp) mtx_assert(&(sbp)->mtx, MA_OWNED)
256
257static void sbp_post_explore (void *);
258static void sbp_recv (struct fw_xfer *);
259static void sbp_mgm_callback (struct fw_xfer *);
260#if 0
261static void sbp_cmd_callback (struct fw_xfer *);
262#endif
263static void sbp_orb_pointer (struct sbp_dev *, struct sbp_ocb *);
264static void sbp_doorbell(struct sbp_dev *);
265static void sbp_execute_ocb (void *, bus_dma_segment_t *, int, int);
266static void sbp_free_ocb (struct sbp_dev *, struct sbp_ocb *);
267static void sbp_abort_ocb (struct sbp_ocb *, int);
268static void sbp_abort_all_ocbs (struct sbp_dev *, int);
269static struct fw_xfer * sbp_write_cmd (struct sbp_dev *, int, int);
270static struct sbp_ocb * sbp_get_ocb (struct sbp_dev *);
271static struct sbp_ocb * sbp_enqueue_ocb (struct sbp_dev *, struct sbp_ocb *);
272static struct sbp_ocb * sbp_dequeue_ocb (struct sbp_dev *, struct sbp_status *);
273static void sbp_cam_detach_sdev(struct sbp_dev *);
274static void sbp_free_sdev(struct sbp_dev *);
275static void sbp_cam_detach_target (struct sbp_target *);
276static void sbp_free_target (struct sbp_target *);

--- 55 unchanged lines hidden (view full) ---

332
333static void
334sbp_identify(driver_t *driver, device_t parent)
335{
336SBP_DEBUG(0)
337 printf("sbp_identify\n");
338END_DEBUG
339
340 if (device_find_child(parent, "sbp", -1) == NULL)
341 BUS_ADD_CHILD(parent, 0, "sbp", -1);
342}
343
344/*
345 * sbp_probe()
346 */
347static int
348sbp_probe(device_t dev)
349{
350
351SBP_DEBUG(0)
352 printf("sbp_probe\n");
353END_DEBUG
354
355 device_set_desc(dev, "SBP-2/SCSI over FireWire");
356
357#if 0
358 if (bootverbose)
359 debug = bootverbose;
360#endif
361
362 return (0);

--- 87 unchanged lines hidden (view full) ---

450{
451 struct crom_context cc;
452 struct csrreg *reg;
453 struct sbp_dev *sdev, **newluns;
454 struct sbp_softc *sbp;
455 int maxlun, lun, i;
456
457 sbp = target->sbp;
458 SBP_LOCK_ASSERT(sbp);
459 crom_init_context(&cc, target->fwdev->csrrom);
460 /* XXX shoud parse appropriate unit directories only */
461 maxlun = -1;
462 while (cc.depth >= 0) {
463 reg = crom_search_key(&cc, CROM_LUN);
464 if (reg == NULL)
465 break;
466 lun = reg->val & 0xffff;
467SBP_DEBUG(0)
468 printf("target %d lun %d found\n", target->target_id, lun);
469END_DEBUG
470 if (maxlun < lun)
471 maxlun = lun;
472 crom_next(&cc);
473 }
474 if (maxlun < 0)
475 device_printf(target->sbp->fd.dev, "%d no LUN found\n",
476 target->target_id);
477
478 maxlun ++;
479 if (maxlun >= SBP_NUM_LUNS)
480 maxlun = SBP_NUM_LUNS;
481
482 /* Invalidiate stale devices */
483 for (lun = 0; lun < target->num_lun; lun ++) {

--- 54 unchanged lines hidden (view full) ---

538 if (sdev == NULL) {
539 printf("%s: malloc failed\n", __func__);
540 goto next;
541 }
542 target->luns[lun] = sdev;
543 sdev->lun_id = lun;
544 sdev->target = target;
545 STAILQ_INIT(&sdev->ocbs);
546 callout_init_mtx(&sdev->login_callout, &sbp->mtx, 0);
547 sdev->status = SBP_DEV_RESET;
548 new = 1;
549 snprintf(sdev->bustgtlun, 32, "%s:%d:%d",
550 device_get_nameunit(sdev->target->sbp->fd.dev),
551 sdev->target->target_id,
552 sdev->lun_id);
553 }
554 sdev->flags |= VALID_LUN;

--- 27 unchanged lines hidden (view full) ---

582 + SBP_LOGIN_SIZE
583 + sizeof(struct sbp_ocb) * i
584 + offsetof(struct sbp_ocb, orb[0]);
585 if (bus_dmamap_create(sbp->dmat, 0, &ocb->dmamap)) {
586 printf("sbp_attach: cannot create dmamap\n");
587 /* XXX */
588 goto next;
589 }
590 callout_init_mtx(&ocb->timer, &sbp->mtx, 0);
591 sbp_free_ocb(sdev, ocb);
592 }
593next:
594 crom_next(&cc);
595 }
596
597 for (lun = 0; lun < target->num_lun; lun ++) {
598 sdev = target->luns[lun];

--- 39 unchanged lines hidden (view full) ---

638 target->mgm_lo = 0xf0000000 | (reg->val << 2);
639 target->mgm_ocb_cur = NULL;
640SBP_DEBUG(1)
641 printf("target:%d mgm_port: %x\n", i, target->mgm_lo);
642END_DEBUG
643 STAILQ_INIT(&target->xferlist);
644 target->n_xfer = 0;
645 STAILQ_INIT(&target->mgm_ocb_queue);
646 callout_init_mtx(&target->mgm_ocb_timeout, &sbp->mtx, 0);
647 callout_init_mtx(&target->scan_callout, &sbp->mtx, 0);
648
649 target->luns = NULL;
650 target->num_lun = 0;
651 return target;
652}
653
654static void
655sbp_probe_lun(struct sbp_dev *sdev)

--- 27 unchanged lines hidden (view full) ---

683 crom_next(cc);
684 crom_parse_text(cc, sdev->product, sizeof(sdev->product));
685}
686
687static void
688sbp_login_callout(void *arg)
689{
690 struct sbp_dev *sdev = (struct sbp_dev *)arg;
691 SBP_LOCK_ASSERT(sdev->target->sbp);
692 sbp_mgm_orb(sdev, ORB_FUN_LGI, NULL);
693}
694
695static void
696sbp_login(struct sbp_dev *sdev)
697{
698 struct timeval delta;
699 struct timeval t;

--- 28 unchanged lines hidden (view full) ---

728 alive = SBP_FWDEV_ALIVE(target->fwdev);
729SBP_DEBUG(1)
730 device_printf(sbp->fd.dev, "%s %d%salive\n",
731 __func__, target->target_id,
732 (!alive) ? " not " : "");
733END_DEBUG
734
735 sbp = target->sbp;
736 SBP_LOCK_ASSERT(sbp);
737 sbp_alloc_lun(target);
738
739 /* XXX untimeout mgm_ocb and dequeue */
740 for (i=0; i < target->num_lun; i++) {
741 sdev = target->luns[i];
742 if (sdev == NULL)
743 continue;
744 if (alive && (sdev->status != SBP_DEV_DEAD)) {
745 if (sdev->path != NULL) {
746 xpt_freeze_devq(sdev->path, 1);
747 sdev->freeze ++;
748 }
749 sbp_probe_lun(sdev);
750 sbp_show_sdev_info(sdev);
751
752 sbp_abort_all_ocbs(sdev, CAM_SCSI_BUS_RESET);
753 switch (sdev->status) {
754 case SBP_DEV_RESET:
755 /* new or revived target */

--- 12 unchanged lines hidden (view full) ---

768 switch (sdev->status) {
769 case SBP_DEV_ATTACHED:
770SBP_DEBUG(0)
771 /* the device has gone */
772 device_printf(sbp->fd.dev, "%s: lost target\n",
773 __func__);
774END_DEBUG
775 if (sdev->path) {
776 xpt_freeze_devq(sdev->path, 1);
777 sdev->freeze ++;
778 }
779 sdev->status = SBP_DEV_RETRY;
780 sbp_cam_detach_sdev(sdev);
781 sbp_free_sdev(sdev);
782 target->luns[i] = NULL;
783 break;
784 case SBP_DEV_PROBE:
785 case SBP_DEV_TOATTACH:

--- 12 unchanged lines hidden (view full) ---

798sbp_post_busreset(void *arg)
799{
800 struct sbp_softc *sbp;
801
802 sbp = (struct sbp_softc *)arg;
803SBP_DEBUG(0)
804 printf("sbp_post_busreset\n");
805END_DEBUG
806 SBP_LOCK(sbp);
807 if ((sbp->sim->flags & SIMQ_FREEZED) == 0) {
808 xpt_freeze_simq(sbp->sim, /*count*/1);
809 sbp->sim->flags |= SIMQ_FREEZED;
810 }
811 microtime(&sbp->last_busreset);
812 SBP_UNLOCK(sbp);
813}
814
815static void
816sbp_post_explore(void *arg)
817{
818 struct sbp_softc *sbp = (struct sbp_softc *)arg;
819 struct sbp_target *target;
820 struct fw_device *fwdev;

--- 4 unchanged lines hidden (view full) ---

825END_DEBUG
826 /* We need physical access */
827 if (!firewire_phydma_enable)
828 return;
829
830 if (sbp_cold > 0)
831 sbp_cold --;
832
833 SBP_LOCK(sbp);
834#if 0
835 /*
836 * XXX don't let CAM the bus rest.
837 * CAM tries to do something with freezed (DEV_RETRY) devices.
838 */
839 xpt_async(AC_BUS_RESET, sbp->path, /*arg*/ NULL);
840#endif
841

--- 34 unchanged lines hidden (view full) ---

876 } else {
877 continue;
878 }
879 }
880 sbp_probe_target((void *)target);
881 if (target->num_lun == 0)
882 sbp_free_target(target);
883 }
884 xpt_release_simq(sbp->sim, /*run queue*/TRUE);
885 sbp->sim->flags &= ~SIMQ_FREEZED;
886 SBP_UNLOCK(sbp);
887}
888
889#if NEED_RESPONSE
890static void
891sbp_loginres_callback(struct fw_xfer *xfer){
892 struct sbp_dev *sdev;
893 sdev = (struct sbp_dev *)xfer->sc;
894SBP_DEBUG(1)
895 device_printf(sdev->target->sbp->fd.dev,"%s\n", __func__);
896END_DEBUG
897 /* recycle */
898 SBP_LOCK(sdev->target->sbp);
899 STAILQ_INSERT_TAIL(&sdev->target->sbp->fwb.xferlist, xfer, link);
900 SBP_UNLOCK(sdev->target->sbp);
901 return;
902}
903#endif
904
905static __inline void
906sbp_xfer_free(struct fw_xfer *xfer)
907{
908 struct sbp_dev *sdev;
909
910 sdev = (struct sbp_dev *)xfer->sc;
911 fw_xfer_unload(xfer);
912 SBP_LOCK_ASSERT(sdev->target->sbp);
913 STAILQ_INSERT_TAIL(&sdev->target->xferlist, xfer, link);
914}
915
916static void
917sbp_reset_start_callback(struct fw_xfer *xfer)
918{
919 struct sbp_dev *tsdev, *sdev = (struct sbp_dev *)xfer->sc;
920 struct sbp_target *target = sdev->target;
921 int i;
922
923 if (xfer->resp != 0) {
924 device_printf(sdev->target->sbp->fd.dev,
925 "%s: %s failed: resp=%d\n", __func__, sdev->bustgtlun, xfer->resp);
926 }
927
928 SBP_LOCK(target->sbp);
929 for (i = 0; i < target->num_lun; i++) {
930 tsdev = target->luns[i];
931 if (tsdev != NULL && tsdev->status == SBP_DEV_LOGIN)
932 sbp_login(tsdev);
933 }
934 SBP_UNLOCK(target->sbp);
935}
936
937static void
938sbp_reset_start(struct sbp_dev *sdev)
939{
940 struct fw_xfer *xfer;
941 struct fw_pkt *fp;
942

--- 19 unchanged lines hidden (view full) ---

962
963 sdev = (struct sbp_dev *)xfer->sc;
964
965SBP_DEBUG(1)
966 device_printf(sdev->target->sbp->fd.dev,
967 "%s:%s\n", __func__, sdev->bustgtlun);
968END_DEBUG
969 resp = xfer->resp;
970 SBP_LOCK(sdev->target->sbp);
971 sbp_xfer_free(xfer);
972 SBP_UNLOCK(sdev->target->sbp);
973}
974
975static struct sbp_dev *
976sbp_next_dev(struct sbp_target *target, int lun)
977{
978 struct sbp_dev **sdevp;
979 int i;
980

--- 8 unchanged lines hidden (view full) ---

989static void
990sbp_cam_scan_lun(struct cam_periph *periph, union ccb *ccb)
991{
992 struct sbp_target *target;
993 struct sbp_dev *sdev;
994
995 sdev = (struct sbp_dev *) ccb->ccb_h.ccb_sdev_ptr;
996 target = sdev->target;
997 SBP_LOCK_ASSERT(target->sbp);
998SBP_DEBUG(0)
999 device_printf(sdev->target->sbp->fd.dev,
1000 "%s:%s\n", __func__, sdev->bustgtlun);
1001END_DEBUG
1002 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
1003 sdev->status = SBP_DEV_ATTACHED;
1004 } else {
1005 device_printf(sdev->target->sbp->fd.dev,

--- 14 unchanged lines hidden (view full) ---

1020
1021static void
1022sbp_cam_scan_target(void *arg)
1023{
1024 struct sbp_target *target = (struct sbp_target *)arg;
1025 struct sbp_dev *sdev;
1026 union ccb *ccb;
1027
1028 SBP_LOCK_ASSERT(target->sbp);
1029 sdev = sbp_next_dev(target, 0);
1030 if (sdev == NULL) {
1031 printf("sbp_cam_scan_target: nothing to do for target%d\n",
1032 target->target_id);
1033 return;
1034 }
1035SBP_DEBUG(0)
1036 device_printf(sdev->target->sbp->fd.dev,

--- 7 unchanged lines hidden (view full) ---

1044 xpt_setup_ccb(&ccb->ccb_h, sdev->path, SCAN_PRI);
1045 ccb->ccb_h.func_code = XPT_SCAN_LUN;
1046 ccb->ccb_h.cbfcnp = sbp_cam_scan_lun;
1047 ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
1048 ccb->crcn.flags = CAM_FLAG_NONE;
1049 ccb->ccb_h.ccb_sdev_ptr = sdev;
1050
1051 /* The scan is in progress now. */
1052 xpt_action(ccb);
1053 xpt_release_devq(sdev->path, sdev->freeze, TRUE);
1054 sdev->freeze = 1;
1055}
1056
1057static __inline void
1058sbp_scan_dev(struct sbp_dev *sdev)
1059{
1060 sdev->status = SBP_DEV_PROBE;
1061 callout_reset(&sdev->target->scan_callout, scan_delay * hz / 1000,
1062 sbp_cam_scan_target, (void *)sdev->target);

--- 4 unchanged lines hidden (view full) ---

1067{
1068 struct sbp_dev *sdev;
1069 struct sbp_target *target;
1070 struct sbp_softc *sbp;
1071
1072 sdev = (struct sbp_dev *)xfer->sc;
1073 target = sdev->target;
1074 sbp = target->sbp;
1075 SBP_LOCK(sbp);
1076SBP_DEBUG(0)
1077 device_printf(sdev->target->sbp->fd.dev,
1078 "%s:%s\n", __func__, sdev->bustgtlun);
1079END_DEBUG
1080 sbp_xfer_free(xfer);
1081
1082 if (sdev->path == NULL)
1083 xpt_create_path(&sdev->path, NULL,
1084 cam_sim_path(target->sbp->sim),
1085 target->target_id, sdev->lun_id);
1086
1087 /*
1088 * Let CAM scan the bus if we are in the boot process.
1089 * XXX xpt_scan_bus cannot detect LUN larger than 0
1090 * if LUN 0 doesn't exist.
1091 */
1092 if (sbp_cold > 0) {
1093 sdev->status = SBP_DEV_ATTACHED;
1094 SBP_UNLOCK(sbp);
1095 return;
1096 }
1097
1098 sbp_scan_dev(sdev);
1099 SBP_UNLOCK(sbp);
1100}
1101
1102static void
1103sbp_agent_reset_callback(struct fw_xfer *xfer)
1104{
1105 struct sbp_dev *sdev;
1106
1107 sdev = (struct sbp_dev *)xfer->sc;
1108SBP_DEBUG(1)
1109 device_printf(sdev->target->sbp->fd.dev,
1110 "%s:%s\n", __func__, sdev->bustgtlun);
1111END_DEBUG
1112 if (xfer->resp != 0) {
1113 device_printf(sdev->target->sbp->fd.dev,
1114 "%s:%s resp=%d\n", __func__, sdev->bustgtlun, xfer->resp);
1115 }
1116
1117 SBP_LOCK(sdev->target->sbp);
1118 sbp_xfer_free(xfer);
1119 if (sdev->path) {
1120 xpt_release_devq(sdev->path, sdev->freeze, TRUE);
1121 sdev->freeze = 0;
1122 }
1123 SBP_UNLOCK(sdev->target->sbp);
1124}
1125
1126static void
1127sbp_agent_reset(struct sbp_dev *sdev)
1128{
1129 struct fw_xfer *xfer;
1130 struct fw_pkt *fp;
1131
1132 SBP_LOCK_ASSERT(sdev->target->sbp);
1133SBP_DEBUG(0)
1134 device_printf(sdev->target->sbp->fd.dev,
1135 "%s:%s\n", __func__, sdev->bustgtlun);
1136END_DEBUG
1137 xfer = sbp_write_cmd(sdev, FWTCODE_WREQQ, 0x04);
1138 if (xfer == NULL)
1139 return;
1140 if (sdev->status == SBP_DEV_ATTACHED || sdev->status == SBP_DEV_PROBE)

--- 11 unchanged lines hidden (view full) ---

1152{
1153 struct sbp_dev *sdev;
1154
1155 sdev = (struct sbp_dev *)xfer->sc;
1156SBP_DEBUG(1)
1157 device_printf(sdev->target->sbp->fd.dev,
1158 "%s:%s\n", __func__, sdev->bustgtlun);
1159END_DEBUG
1160 SBP_LOCK(sdev->target->sbp);
1161 sbp_xfer_free(xfer);
1162 sbp_agent_reset(sdev);
1163 SBP_UNLOCK(sdev->target->sbp);
1164}
1165
1166static void
1167sbp_busy_timeout(struct sbp_dev *sdev)
1168{
1169 struct fw_pkt *fp;
1170 struct fw_xfer *xfer;
1171SBP_DEBUG(0)

--- 19 unchanged lines hidden (view full) ---

1191SBP_DEBUG(2)
1192 device_printf(sdev->target->sbp->fd.dev,
1193 "%s:%s\n", __func__, sdev->bustgtlun);
1194END_DEBUG
1195 if (xfer->resp != 0) {
1196 /* XXX */
1197 printf("%s: xfer->resp = %d\n", __func__, xfer->resp);
1198 }
1199 SBP_LOCK(sdev->target->sbp);
1200 sbp_xfer_free(xfer);
1201
1202 sdev->flags &= ~ORB_POINTER_ACTIVE;
1203
1204 if ((sdev->flags & ORB_POINTER_NEED) != 0) {
1205 struct sbp_ocb *ocb;
1206
1207 sdev->flags &= ~ORB_POINTER_NEED;
1208 ocb = STAILQ_FIRST(&sdev->ocbs);
1209 if (ocb != NULL)

--- 10 unchanged lines hidden (view full) ---

1220 struct fw_pkt *fp;
1221SBP_DEBUG(1)
1222 device_printf(sdev->target->sbp->fd.dev,
1223 "%s:%s 0x%08x\n",
1224 __func__, sdev->bustgtlun,
1225 (uint32_t)ocb->bus_addr);
1226END_DEBUG
1227
1228 SBP_LOCK_ASSERT(sdev->target->sbp);
1229
1230 if ((sdev->flags & ORB_POINTER_ACTIVE) != 0) {
1231SBP_DEBUG(0)
1232 printf("%s: orb pointer active\n", __func__);
1233END_DEBUG
1234 sdev->flags |= ORB_POINTER_NEED;
1235 return;
1236 }
1237
1238 sdev->flags |= ORB_POINTER_ACTIVE;
1239 xfer = sbp_write_cmd(sdev, FWTCODE_WREQB, 0x08);
1240 if (xfer == NULL)
1241 return;
1242 xfer->hand = sbp_orb_pointer_callback;
1243
1244 fp = &xfer->send.hdr;
1245 fp->mode.wreqb.len = 8;
1246 fp->mode.wreqb.extcode = 0;
1247 xfer->send.payload[0] =
1248 htonl(((sdev->target->sbp->fd.fc->nodeid | FWLOCALBUS )<< 16));
1249 xfer->send.payload[1] = htonl((uint32_t)ocb->bus_addr);
1250
1251 if (fw_asyreq(xfer->fc, -1, xfer) != 0) {
1252 sbp_xfer_free(xfer);
1253 ocb->ccb->ccb_h.status = CAM_REQ_INVALID;
1254 xpt_done(ocb->ccb);
1255 }
1256}
1257
1258static void
1259sbp_doorbell_callback(struct fw_xfer *xfer)
1260{
1261 struct sbp_dev *sdev;
1262 sdev = (struct sbp_dev *)xfer->sc;
1263
1264SBP_DEBUG(1)
1265 device_printf(sdev->target->sbp->fd.dev,
1266 "%s:%s\n", __func__, sdev->bustgtlun);
1267END_DEBUG
1268 if (xfer->resp != 0) {
1269 /* XXX */
1270 device_printf(sdev->target->sbp->fd.dev,
1271 "%s: xfer->resp = %d\n", __func__, xfer->resp);
1272 }
1273 SBP_LOCK(sdev->target->sbp);
1274 sbp_xfer_free(xfer);
1275 sdev->flags &= ~ORB_DOORBELL_ACTIVE;
1276 if ((sdev->flags & ORB_DOORBELL_NEED) != 0) {
1277 sdev->flags &= ~ORB_DOORBELL_NEED;
1278 sbp_doorbell(sdev);
1279 }
1280 SBP_UNLOCK(sdev->target->sbp);
1281}
1282
1283static void
1284sbp_doorbell(struct sbp_dev *sdev)
1285{
1286 struct fw_xfer *xfer;
1287 struct fw_pkt *fp;
1288SBP_DEBUG(1)
1289 device_printf(sdev->target->sbp->fd.dev,
1290 "%s:%s\n", __func__, sdev->bustgtlun);
1291END_DEBUG
1292
1293 if ((sdev->flags & ORB_DOORBELL_ACTIVE) != 0) {
1294 sdev->flags |= ORB_DOORBELL_NEED;
1295 return;
1296 }
1297 sdev->flags |= ORB_DOORBELL_ACTIVE;
1298 xfer = sbp_write_cmd(sdev, FWTCODE_WREQQ, 0x10);
1299 if (xfer == NULL)
1300 return;
1301 xfer->hand = sbp_doorbell_callback;
1302 fp = &xfer->send.hdr;
1303 fp->mode.wreqq.data = htonl(0xf);
1304 fw_asyreq(xfer->fc, -1, xfer);
1305}
1306
1307static struct fw_xfer *
1308sbp_write_cmd(struct sbp_dev *sdev, int tcode, int offset)
1309{
1310 struct fw_xfer *xfer;
1311 struct fw_pkt *fp;
1312 struct sbp_target *target;
1313 int new = 0;
1314
1315 SBP_LOCK_ASSERT(sdev->target->sbp);
1316
1317 target = sdev->target;
1318 xfer = STAILQ_FIRST(&target->xferlist);
1319 if (xfer == NULL) {
1320 if (target->n_xfer > 5 /* XXX */) {
1321 printf("sbp: no more xfer for this target\n");
1322 return(NULL);
1323 }
1324 xfer = fw_xfer_alloc_buf(M_SBP, 8, 0);
1325 if(xfer == NULL){
1326 printf("sbp: fw_xfer_alloc_buf failed\n");
1327 return NULL;
1328 }
1329 target->n_xfer ++;
1330 if (debug)
1331 printf("sbp: alloc %d xfer\n", target->n_xfer);
1332 new = 1;
1333 } else {
1334 STAILQ_REMOVE_HEAD(&target->xferlist, link);
1335 }
1336
1337 if (new) {
1338 xfer->recv.pay_len = 0;
1339 xfer->send.spd = min(sdev->target->fwdev->speed, max_speed);
1340 xfer->fc = sdev->target->sbp->fd.fc;
1341 }
1342
1343 if (tcode == FWTCODE_WREQB)

--- 6 unchanged lines hidden (view full) ---

1350 fp->mode.wreqq.dest_hi = sdev->login->cmd_hi;
1351 fp->mode.wreqq.dest_lo = sdev->login->cmd_lo + offset;
1352 fp->mode.wreqq.tlrt = 0;
1353 fp->mode.wreqq.tcode = tcode;
1354 fp->mode.wreqq.pri = 0;
1355 fp->mode.wreqq.dst = FWLOCALBUS | sdev->target->fwdev->dst;
1356
1357 return xfer;
1358}
1359
1360static void
1361sbp_mgm_orb(struct sbp_dev *sdev, int func, struct sbp_ocb *aocb)
1362{
1363 struct fw_xfer *xfer;
1364 struct fw_pkt *fp;
1365 struct sbp_ocb *ocb;
1366 struct sbp_target *target;
1367 int nid;
1368
1369 target = sdev->target;
1370 nid = target->sbp->fd.fc->nodeid | FWLOCALBUS;
1371
1372 SBP_LOCK_ASSERT(target->sbp);
1373 if (func == ORB_FUN_RUNQUEUE) {
1374 ocb = STAILQ_FIRST(&target->mgm_ocb_queue);
1375 if (target->mgm_ocb_cur != NULL || ocb == NULL) {
1376 return;
1377 }
1378 STAILQ_REMOVE_HEAD(&target->mgm_ocb_queue, ocb);
1379 goto start;
1380 }
1381 if ((ocb = sbp_get_ocb(sdev)) == NULL) {
1382 /* XXX */
1383 return;
1384 }
1385 ocb->flags = OCB_ACT_MGM;
1386 ocb->sdev = sdev;
1387
1388 bzero((void *)ocb->orb, sizeof(ocb->orb));
1389 ocb->orb[6] = htonl((nid << 16) | SBP_BIND_HI);
1390 ocb->orb[7] = htonl(SBP_DEV2ADDR(target->target_id, sdev->lun_id));
1391
1392SBP_DEBUG(0)

--- 23 unchanged lines hidden (view full) ---

1416 case ORB_FUN_RST:
1417 case ORB_FUN_ATS:
1418 ocb->orb[4] = htonl(ORB_NOTIFY | func | sdev->login->id);
1419 break;
1420 }
1421
1422 if (target->mgm_ocb_cur != NULL) {
1423 /* there is a standing ORB */
1424 STAILQ_INSERT_TAIL(&sdev->target->mgm_ocb_queue, ocb, ocb);
1425 return;
1426 }
1427start:
1428 target->mgm_ocb_cur = ocb;
1429
1430 callout_reset(&target->mgm_ocb_timeout, 5*hz,
1431 sbp_mgm_timeout, (caddr_t)ocb);
1432 xfer = sbp_write_cmd(sdev, FWTCODE_WREQB, 0);
1433 if(xfer == NULL){
1434 return;
1435 }
1436 xfer->hand = sbp_mgm_callback;

--- 194 unchanged lines hidden (view full) ---

1631 uint32_t *ld;
1632 ld = xfer->recv.buf;
1633printf("sbp %x %d %d %08x %08x %08x %08x\n",
1634 xfer->resp, xfer->recv.len, xfer->recv.off, ntohl(ld[0]), ntohl(ld[1]), ntohl(ld[2]), ntohl(ld[3]));
1635printf("sbp %08x %08x %08x %08x\n", ntohl(ld[4]), ntohl(ld[5]), ntohl(ld[6]), ntohl(ld[7]));
1636printf("sbp %08x %08x %08x %08x\n", ntohl(ld[8]), ntohl(ld[9]), ntohl(ld[10]), ntohl(ld[11]));
1637*/
1638 sbp = (struct sbp_softc *)xfer->sc;
1639 SBP_LOCK_ASSERT(sbp);
1640 if (xfer->resp != 0){
1641 printf("sbp_recv: xfer->resp = %d\n", xfer->resp);
1642 goto done0;
1643 }
1644 if (xfer->recv.payload == NULL){
1645 printf("sbp_recv: xfer->recv.payload == NULL\n");
1646 goto done0;
1647 }

--- 103 unchanged lines hidden (view full) ---

1751 default:
1752 printf("unknown respose code %d\n", sbp_status->resp);
1753 }
1754 }
1755
1756 /* we have to reset the fetch agent if it's dead */
1757 if (sbp_status->dead) {
1758 if (sdev->path) {
1759 xpt_freeze_devq(sdev->path, 1);
1760 sdev->freeze ++;
1761 }
1762 reset_agent = 1;
1763 }
1764
1765 if (ocb == NULL)
1766 goto done;
1767
1768 switch(ntohl(ocb->orb[4]) & ORB_FMT_MSK){

--- 88 unchanged lines hidden (view full) ---

1857 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1858 }else{
1859 ccb->ccb_h.status = CAM_REQ_CMP;
1860 }
1861 }
1862 /* fix up inq data */
1863 if (ccb->csio.cdb_io.cdb_bytes[0] == INQUIRY)
1864 sbp_fix_inq_data(ocb);
1865 xpt_done(ccb);
1866 }
1867 break;
1868 default:
1869 break;
1870 }
1871 }
1872
1873 if (!use_doorbell)

--- 22 unchanged lines hidden (view full) ---

1896 sfp->mode.wres.tlrt = rfp->mode.wreqb.tlrt;
1897 sfp->mode.wres.tcode = FWTCODE_WRES;
1898 sfp->mode.wres.rtcode = 0;
1899 sfp->mode.wres.pri = 0;
1900
1901 fw_asyreq(xfer->fc, -1, xfer);
1902#else
1903 /* recycle */
1904 STAILQ_INSERT_TAIL(&sbp->fwb.xferlist, xfer, link);
1905#endif
1906}
1907
1908static void
1909sbp_recv(struct fw_xfer *xfer)
1910{
1911 struct sbp_softc *sbp;
1912
1913 sbp = (struct sbp_softc *)xfer->sc;
1914 SBP_LOCK(sbp);
1915 sbp_recv1(xfer);
1916 SBP_UNLOCK(sbp);
1917}
1918/*
1919 * sbp_attach()
1920 */
1921static int
1922sbp_attach(device_t dev)
1923{
1924 struct sbp_softc *sbp;
1925 struct cam_devq *devq;
1926 struct firewire_comm *fc;
1927 int i, error;
1928
1929 if (DFLTPHYS > SBP_MAXPHYS)
1930 device_printf(dev, "Warning, DFLTPHYS(%dKB) is larger than "
1931 "SBP_MAXPHYS(%dKB).\n", DFLTPHYS / 1024,
1932 SBP_MAXPHYS / 1024);
1933
1934 if (!firewire_phydma_enable)
1935 device_printf(dev, "Warning, hw.firewire.phydma_enable must be 1 "
1936 "for SBP over FireWire.\n");
1937SBP_DEBUG(0)
1938 printf("sbp_attach (cold=%d)\n", cold);
1939END_DEBUG
1940
1941 if (cold)
1942 sbp_cold ++;
1943 sbp = device_get_softc(dev);
1944 sbp->fd.dev = dev;
1945 sbp->fd.fc = fc = device_get_ivars(dev);
1946 mtx_init(&sbp->mtx, "sbp", NULL, MTX_DEF);
1947
1948 if (max_speed < 0)
1949 max_speed = fc->speed;
1950
1951 error = bus_dma_tag_create(/*parent*/fc->dmat,

--- 59 unchanged lines hidden (view full) ---

2011 fc, (void *)sbp, sbp_recv);
2012
2013 fw_bindadd(fc, &sbp->fwb);
2014
2015 sbp->fd.post_busreset = sbp_post_busreset;
2016 sbp->fd.post_explore = sbp_post_explore;
2017
2018 if (fc->status != -1) {
2019 sbp_post_busreset((void *)sbp);
2020 sbp_post_explore((void *)sbp);
2021 }
2022 SBP_LOCK(sbp);
2023 xpt_async(AC_BUS_RESET, sbp->path, /*arg*/ NULL);
2024 SBP_UNLOCK(sbp);
2025
2026 return (0);
2027fail:
2028 SBP_UNLOCK(sbp);

--- 6 unchanged lines hidden (view full) ---

2035{
2036 struct sbp_target *target;
2037 struct sbp_dev *sdev;
2038 int i, j;
2039
2040SBP_DEBUG(0)
2041 printf("sbp_logout_all\n");
2042END_DEBUG
2043 SBP_LOCK_ASSERT(sbp);
2044 for (i = 0 ; i < SBP_NUM_TARGETS ; i ++) {
2045 target = &sbp->targets[i];
2046 if (target->luns == NULL)
2047 continue;
2048 for (j = 0; j < target->num_lun; j++) {
2049 sdev = target->luns[j];
2050 if (sdev == NULL)
2051 continue;

--- 7 unchanged lines hidden (view full) ---

2059 return 0;
2060}
2061
2062static int
2063sbp_shutdown(device_t dev)
2064{
2065 struct sbp_softc *sbp = ((struct sbp_softc *)device_get_softc(dev));
2066
2067 SBP_LOCK(sbp);
2068 sbp_logout_all(sbp);
2069 SBP_UNLOCK(sbp);
2070 return (0);
2071}
2072
2073static void
2074sbp_free_sdev(struct sbp_dev *sdev)
2075{
2076 struct sbp_softc *sbp;
2077 int i;
2078
2079 if (sdev == NULL)
2080 return;
2081 sbp = sdev->target->sbp;
2082 SBP_UNLOCK(sbp);
2083 callout_drain(&sdev->login_callout);
2084 for (i = 0; i < SBP_QUEUE_LEN; i++) {
2085 callout_drain(&sdev->ocb[i].timer);
2086 bus_dmamap_destroy(sbp->dmat, sdev->ocb[i].dmamap);
2087 }
2088 fwdma_free(sbp->fd.fc, &sdev->dma);
2089 free(sdev, M_SBP);
2090 SBP_LOCK(sbp);
2091}
2092
2093static void
2094sbp_free_target(struct sbp_target *target)
2095{
2096 struct sbp_softc *sbp;
2097 struct fw_xfer *xfer, *next;
2098 int i;
2099
2100 if (target->luns == NULL)
2101 return;
2102 sbp = target->sbp;
2103 SBP_LOCK_ASSERT(sbp);
2104 SBP_UNLOCK(sbp);
2105 callout_drain(&target->mgm_ocb_timeout);
2106 callout_drain(&target->scan_callout);
2107 SBP_LOCK(sbp);
2108 for (i = 0; i < target->num_lun; i++)
2109 sbp_free_sdev(target->luns[i]);
2110
2111 STAILQ_FOREACH_SAFE(xfer, &target->xferlist, link, next) {
2112 fw_xfer_free_buf(xfer);
2113 }
2114 STAILQ_INIT(&target->xferlist);
2115 free(target->luns, M_SBP);
2116 target->num_lun = 0;
2117 target->luns = NULL;
2118 target->fwdev = NULL;
2119}

--- 4 unchanged lines hidden (view full) ---

2124 struct sbp_softc *sbp = ((struct sbp_softc *)device_get_softc(dev));
2125 struct firewire_comm *fc = sbp->fd.fc;
2126 int i;
2127
2128SBP_DEBUG(0)
2129 printf("sbp_detach\n");
2130END_DEBUG
2131
2132 SBP_LOCK(sbp);
2133 for (i = 0; i < SBP_NUM_TARGETS; i ++)
2134 sbp_cam_detach_target(&sbp->targets[i]);
2135
2136 xpt_async(AC_LOST_DEVICE, sbp->path, NULL);
2137 xpt_free_path(sbp->path);
2138 xpt_bus_deregister(cam_sim_path(sbp->sim));
2139 cam_sim_free(sbp->sim, /*free_devq*/ TRUE);
2140
2141 sbp_logout_all(sbp);
2142 SBP_UNLOCK(sbp);
2143
2144 /* XXX wait for logout completion */
2145 pause("sbpdtc", hz/2);
2146
2147 SBP_LOCK(sbp);
2148 for (i = 0 ; i < SBP_NUM_TARGETS ; i ++)
2149 sbp_free_target(&sbp->targets[i]);
2150 SBP_UNLOCK(sbp);
2151
2152 fw_bindremove(fc, &sbp->fwb);
2153 fw_xferlist_remove(&sbp->fwb.xferlist);
2154
2155 bus_dma_tag_destroy(sbp->dmat);
2156 mtx_destroy(&sbp->mtx);
2157
2158 return (0);
2159}
2160
2161static void
2162sbp_cam_detach_sdev(struct sbp_dev *sdev)
2163{
2164 if (sdev == NULL)
2165 return;
2166 if (sdev->status == SBP_DEV_DEAD)
2167 return;
2168 if (sdev->status == SBP_DEV_RESET)
2169 return;
2170 SBP_LOCK_ASSERT(sdev->target->sbp);
2171 sbp_abort_all_ocbs(sdev, CAM_DEV_NOT_THERE);
2172 if (sdev->path) {
2173 xpt_release_devq(sdev->path,
2174 sdev->freeze, TRUE);
2175 sdev->freeze = 0;
2176 xpt_async(AC_LOST_DEVICE, sdev->path, NULL);
2177 xpt_free_path(sdev->path);
2178 sdev->path = NULL;
2179 }
2180}
2181
2182static void
2183sbp_cam_detach_target(struct sbp_target *target)
2184{
2185 int i;
2186
2187 SBP_LOCK_ASSERT(target->sbp);
2188 if (target->luns != NULL) {
2189SBP_DEBUG(0)
2190 printf("sbp_detach_target %d\n", target->target_id);
2191END_DEBUG
2192 callout_stop(&target->scan_callout);
2193 for (i = 0; i < target->num_lun; i++)
2194 sbp_cam_detach_sdev(target->luns[i]);
2195 }
2196}
2197
2198static void
2199sbp_target_reset(struct sbp_dev *sdev, int method)
2200{
2201 int i;
2202 struct sbp_target *target = sdev->target;
2203 struct sbp_dev *tsdev;
2204
2205 SBP_LOCK_ASSERT(target->sbp);
2206 for (i = 0; i < target->num_lun; i++) {
2207 tsdev = target->luns[i];
2208 if (tsdev == NULL)
2209 continue;
2210 if (tsdev->status == SBP_DEV_DEAD)
2211 continue;
2212 if (tsdev->status == SBP_DEV_RESET)
2213 continue;
2214 xpt_freeze_devq(tsdev->path, 1);
2215 tsdev->freeze ++;
2216 sbp_abort_all_ocbs(tsdev, CAM_CMD_TIMEOUT);
2217 if (method == 2)
2218 tsdev->status = SBP_DEV_LOGIN;
2219 }
2220 switch(method) {
2221 case 1:
2222 printf("target reset\n");
2223 sbp_mgm_orb(sdev, ORB_FUN_RST, NULL);

--- 8 unchanged lines hidden (view full) ---

2232
2233static void
2234sbp_mgm_timeout(void *arg)
2235{
2236 struct sbp_ocb *ocb = (struct sbp_ocb *)arg;
2237 struct sbp_dev *sdev = ocb->sdev;
2238 struct sbp_target *target = sdev->target;
2239
2240 SBP_LOCK_ASSERT(target->sbp);
2241 device_printf(sdev->target->sbp->fd.dev,
2242 "%s:%s request timeout(mgm orb:0x%08x)\n",
2243 __func__, sdev->bustgtlun, (uint32_t)ocb->bus_addr);
2244 target->mgm_ocb_cur = NULL;
2245 sbp_free_ocb(sdev, ocb);
2246#if 0
2247 /* XXX */
2248 printf("run next request\n");

--- 10 unchanged lines hidden (view full) ---

2259{
2260 struct sbp_ocb *ocb = (struct sbp_ocb *)arg;
2261 struct sbp_dev *sdev = ocb->sdev;
2262
2263 device_printf(sdev->target->sbp->fd.dev,
2264 "%s:%s request timeout(cmd orb:0x%08x) ... ",
2265 __func__, sdev->bustgtlun, (uint32_t)ocb->bus_addr);
2266
2267 SBP_LOCK_ASSERT(sdev->target->sbp);
2268 sdev->timeout ++;
2269 switch(sdev->timeout) {
2270 case 1:
2271 printf("agent reset\n");
2272 xpt_freeze_devq(sdev->path, 1);
2273 sdev->freeze ++;
2274 sbp_abort_all_ocbs(sdev, CAM_CMD_TIMEOUT);
2275 sbp_agent_reset(sdev);
2276 break;
2277 case 2:
2278 case 3:
2279 sbp_target_reset(sdev, sdev->timeout - 1);
2280 break;
2281#if 0

--- 5 unchanged lines hidden (view full) ---

2287 target->num_lun = 0;
2288 target->luns = NULL;
2289 target->fwdev = NULL;
2290#endif
2291 }
2292}
2293
2294static void
2295sbp_action(struct cam_sim *sim, union ccb *ccb)
2296{
2297
2298 struct sbp_softc *sbp = (struct sbp_softc *)sim->softc;
2299 struct sbp_target *target = NULL;
2300 struct sbp_dev *sdev = NULL;
2301
2302 if (sbp != NULL)
2303 SBP_LOCK_ASSERT(sbp);
2304 /* target:lun -> sdev mapping */
2305 if (sbp != NULL
2306 && ccb->ccb_h.target_id != CAM_TARGET_WILDCARD
2307 && ccb->ccb_h.target_id < SBP_NUM_TARGETS) {
2308 target = &sbp->targets[ccb->ccb_h.target_id];
2309 if (target->fwdev != NULL
2310 && ccb->ccb_h.target_lun != CAM_LUN_WILDCARD
2311 && ccb->ccb_h.target_lun < target->num_lun) {

--- 105 unchanged lines hidden (view full) ---

2417 xpt_done(ccb);
2418 return;
2419 }
2420 }
2421#endif
2422 if ((ocb = sbp_get_ocb(sdev)) == NULL) {
2423 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
2424 if (sdev->freeze == 0) {
2425 xpt_freeze_devq(sdev->path, 1);
2426 sdev->freeze ++;
2427 }
2428 xpt_done(ccb);
2429 return;
2430 }
2431
2432 ocb->flags = OCB_ACT_CMD;
2433 ocb->sdev = sdev;
2434 ocb->ccb = ccb;

--- 39 unchanged lines hidden (view full) ---

2474#if defined(__DragonFly__) || __FreeBSD_version < 501100
2475 uint32_t size_mb;
2476 uint32_t secs_per_cylinder;
2477 int extended = 1;
2478#endif
2479
2480 ccg = &ccb->ccg;
2481 if (ccg->block_size == 0) {
2482 printf("sbp_action: block_size is 0.\n");
2483 ccb->ccb_h.status = CAM_REQ_INVALID;
2484 xpt_done(ccb);
2485 break;
2486 }
2487SBP_DEBUG(1)
2488 printf("%s:%d:%d:%jx:XPT_CALC_GEOMETRY: "
2489#if defined(__DragonFly__) || __FreeBSD_version < 500000
2490 "Volume size = %d\n",

--- 108 unchanged lines hidden (view full) ---

2599 ccb->ccb_h.status = CAM_REQ_INVALID;
2600 xpt_done(ccb);
2601 break;
2602 }
2603 return;
2604}
2605
2606static void
2607sbp_execute_ocb(void *arg, bus_dma_segment_t *segments, int seg, int error)
2608{
2609 int i;
2610 struct sbp_ocb *ocb;
2611 struct sbp_ocb *prev;
2612 bus_dma_segment_t *s;
2613
2614 if (error)

--- 78 unchanged lines hidden (view full) ---

2693 return;
2694}
2695
2696static struct sbp_ocb *
2697sbp_dequeue_ocb(struct sbp_dev *sdev, struct sbp_status *sbp_status)
2698{
2699 struct sbp_ocb *ocb;
2700 struct sbp_ocb *next;
2701 int order = 0;
2702
2703SBP_DEBUG(1)
2704 device_printf(sdev->target->sbp->fd.dev,
2705#if defined(__DragonFly__) || __FreeBSD_version < 500000
2706 "%s:%s 0x%08lx src %d\n",
2707#else
2708 "%s:%s 0x%08x src %d\n",
2709#endif
2710 __func__, sdev->bustgtlun, ntohl(sbp_status->orb_lo), sbp_status->src);
2711END_DEBUG
2712 SBP_LOCK_ASSERT(sdev->target->sbp);
2713 STAILQ_FOREACH_SAFE(ocb, &sdev->ocbs, ocb, next) {
2714 if (OCB_MATCH(ocb, sbp_status)) {
2715 /* found */
2716 STAILQ_REMOVE(&sdev->ocbs, ocb, sbp_ocb, ocb);
2717 if (ocb->ccb != NULL)
2718 callout_stop(&ocb->timer);
2719 if (ntohl(ocb->orb[4]) & 0xffff) {
2720 bus_dmamap_sync(sdev->target->sbp->dmat,
2721 ocb->dmamap,
2722 (ntohl(ocb->orb[4]) & ORB_CMD_IN) ?
2723 BUS_DMASYNC_POSTREAD :
2724 BUS_DMASYNC_POSTWRITE);
2725 bus_dmamap_unload(sdev->target->sbp->dmat,
2726 ocb->dmamap);

--- 12 unchanged lines hidden (view full) ---

2739 }
2740 }
2741 } else {
2742 /*
2743 * XXX this is not correct for unordered
2744 * execution.
2745 */
2746 if (sdev->last_ocb != NULL) {
2747 sbp_free_ocb(sdev, sdev->last_ocb);
2748 }
2749 sdev->last_ocb = ocb;
2750 if (next != NULL &&
2751 sbp_status->src == SRC_NO_NEXT)
2752 sbp_doorbell(sdev);
2753 }
2754 break;
2755 } else
2756 order ++;
2757 }
2758SBP_DEBUG(0)
2759 if (ocb && order > 0) {
2760 device_printf(sdev->target->sbp->fd.dev,
2761 "%s:%s unordered execution order:%d\n",
2762 __func__, sdev->bustgtlun, order);
2763 }
2764END_DEBUG
2765 return (ocb);
2766}
2767
2768static struct sbp_ocb *
2769sbp_enqueue_ocb(struct sbp_dev *sdev, struct sbp_ocb *ocb)
2770{
2771 struct sbp_ocb *prev, *prev2;
2772
2773 SBP_LOCK_ASSERT(sdev->target->sbp);
2774SBP_DEBUG(1)
2775 device_printf(sdev->target->sbp->fd.dev,
2776#if defined(__DragonFly__) || __FreeBSD_version < 500000
2777 "%s:%s 0x%08x\n", __func__, sdev->bustgtlun, ocb->bus_addr);
2778#else
2779 "%s:%s 0x%08jx\n", __func__, sdev->bustgtlun, (uintmax_t)ocb->bus_addr);
2780#endif
2781END_DEBUG
2782 prev2 = prev = STAILQ_LAST(&sdev->ocbs, sbp_ocb, ocb);
2783 STAILQ_INSERT_TAIL(&sdev->ocbs, ocb, ocb);
2784
2785 if (ocb->ccb != NULL)
2786 callout_reset(&ocb->timer, (ocb->ccb->ccb_h.timeout * hz) / 1000,
2787 sbp_timeout, ocb);
2788
2789 if (use_doorbell && prev == NULL)
2790 prev2 = sdev->last_ocb;
2791
2792 if (prev2 != NULL && (ocb->sdev->flags & ORB_LINK_DEAD) == 0) {
2793SBP_DEBUG(1)
2794#if defined(__DragonFly__) || __FreeBSD_version < 500000
2795 printf("linking chain 0x%x -> 0x%x\n",

--- 6 unchanged lines hidden (view full) ---

2802 /*
2803 * Suppress compiler optimization so that orb[1] must be written first.
2804 * XXX We may need an explicit memory barrier for other architectures
2805 * other than i386/amd64.
2806 */
2807 *(volatile uint32_t *)&prev2->orb[1] = htonl(ocb->bus_addr);
2808 *(volatile uint32_t *)&prev2->orb[0] = 0;
2809 }
2810
2811 return prev;
2812}
2813
2814static struct sbp_ocb *
2815sbp_get_ocb(struct sbp_dev *sdev)
2816{
2817 struct sbp_ocb *ocb;
2818
2819 SBP_LOCK_ASSERT(sdev->target->sbp);
2820 ocb = STAILQ_FIRST(&sdev->free_ocbs);
2821 if (ocb == NULL) {
2822 sdev->flags |= ORB_SHORTAGE;
2823 printf("ocb shortage!!!\n");
2824 return NULL;
2825 }
2826 STAILQ_REMOVE_HEAD(&sdev->free_ocbs, ocb);
2827 ocb->ccb = NULL;
2828 return (ocb);
2829}
2830
2831static void
2832sbp_free_ocb(struct sbp_dev *sdev, struct sbp_ocb *ocb)
2833{
2834 ocb->flags = 0;
2835 ocb->ccb = NULL;
2836
2837 SBP_LOCK_ASSERT(sdev->target->sbp);
2838 STAILQ_INSERT_TAIL(&sdev->free_ocbs, ocb, ocb);
2839 if ((sdev->flags & ORB_SHORTAGE) != 0) {
2840 int count;
2841
2842 sdev->flags &= ~ORB_SHORTAGE;
2843 count = sdev->freeze;
2844 sdev->freeze = 0;
2845 xpt_release_devq(sdev->path, count, TRUE);
2846 }
2847}
2848
2849static void
2850sbp_abort_ocb(struct sbp_ocb *ocb, int status)
2851{
2852 struct sbp_dev *sdev;
2853
2854 sdev = ocb->sdev;
2855 SBP_LOCK_ASSERT(sdev->target->sbp);
2856SBP_DEBUG(0)
2857 device_printf(sdev->target->sbp->fd.dev,
2858#if defined(__DragonFly__) || __FreeBSD_version < 500000
2859 "%s:%s 0x%x\n", __func__, sdev->bustgtlun, ocb->bus_addr);
2860#else
2861 "%s:%s 0x%jx\n", __func__, sdev->bustgtlun, (uintmax_t)ocb->bus_addr);
2862#endif
2863END_DEBUG
2864SBP_DEBUG(1)
2865 if (ocb->ccb != NULL)
2866 sbp_print_scsi_cmd(ocb);
2867END_DEBUG
2868 if (ntohl(ocb->orb[4]) & 0xffff) {
2869 bus_dmamap_sync(sdev->target->sbp->dmat, ocb->dmamap,
2870 (ntohl(ocb->orb[4]) & ORB_CMD_IN) ?
2871 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
2872 bus_dmamap_unload(sdev->target->sbp->dmat, ocb->dmamap);
2873 }
2874 if (ocb->ccb != NULL) {
2875 callout_stop(&ocb->timer);
2876 ocb->ccb->ccb_h.status = status;
2877 xpt_done(ocb->ccb);
2878 }
2879 sbp_free_ocb(sdev, ocb);
2880}
2881
2882static void
2883sbp_abort_all_ocbs(struct sbp_dev *sdev, int status)
2884{
2885 struct sbp_ocb *ocb, *next;
2886 STAILQ_HEAD(, sbp_ocb) temp;
2887
2888 STAILQ_INIT(&temp);
2889 SBP_LOCK_ASSERT(sdev->target->sbp);
2890 STAILQ_CONCAT(&temp, &sdev->ocbs);
2891 STAILQ_INIT(&sdev->ocbs);
2892
2893 STAILQ_FOREACH_SAFE(ocb, &temp, ocb, next) {
2894 sbp_abort_ocb(ocb, status);
2895 }
2896 if (sdev->last_ocb != NULL) {
2897 sbp_free_ocb(sdev, sdev->last_ocb);
2898 sdev->last_ocb = NULL;
2899 }
2900}
2901
2902static devclass_t sbp_devclass;
2903
2904static device_method_t sbp_methods[] = {
2905 /* device interface */
2906 DEVMETHOD(device_identify, sbp_identify),
2907 DEVMETHOD(device_probe, sbp_probe),

--- 19 unchanged lines hidden ---