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 266270 2014-05-16 21:19:17Z brueffer $
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_handle timeout_ch;
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
256static void sbp_post_explore (void *);
257static void sbp_recv (struct fw_xfer *);
258static void sbp_mgm_callback (struct fw_xfer *);
259#if 0
260static void sbp_cmd_callback (struct fw_xfer *);
261#endif
262static void sbp_orb_pointer (struct sbp_dev *, struct sbp_ocb *);
263static void sbp_doorbell(struct sbp_dev *);
264static void sbp_execute_ocb (void *, bus_dma_segment_t *, int, int);
265static void sbp_free_ocb (struct sbp_dev *, struct sbp_ocb *);
266static void sbp_abort_ocb (struct sbp_ocb *, int);
267static void sbp_abort_all_ocbs (struct sbp_dev *, int);
268static struct fw_xfer * sbp_write_cmd_locked (struct sbp_dev *, int, 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 BUS_ADD_CHILD(parent, 0, "sbp", device_get_unit(parent));
341}
342
343/*
344 * sbp_probe()
345 */
346static int
347sbp_probe(device_t dev)
348{
349 device_t pa;
350
351SBP_DEBUG(0)
352 printf("sbp_probe\n");
353END_DEBUG
354
355 pa = device_get_parent(dev);
356 if(device_get_unit(dev) != device_get_unit(pa)){
357 return(ENXIO);
358 }
359
360 device_set_desc(dev, "SBP-2/SCSI over FireWire");
361
362#if 0
363 if (bootverbose)
364 debug = bootverbose;
365#endif
366
367 return (0);

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

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

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

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

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

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

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

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

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

688 crom_next(cc);
689 crom_parse_text(cc, sdev->product, sizeof(sdev->product));
690}
691
692static void
693sbp_login_callout(void *arg)
694{
695 struct sbp_dev *sdev = (struct sbp_dev *)arg;
696 sbp_mgm_orb(sdev, ORB_FUN_LGI, NULL);
697}
698
699static void
700sbp_login(struct sbp_dev *sdev)
701{
702 struct timeval delta;
703 struct timeval t;

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

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

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

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

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

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

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

832END_DEBUG
833 /* We need physical access */
834 if (!firewire_phydma_enable)
835 return;
836
837 if (sbp_cold > 0)
838 sbp_cold --;
839
840#if 0
841 /*
842 * XXX don't let CAM the bus rest.
843 * CAM tries to do something with freezed (DEV_RETRY) devices.
844 */
845 xpt_async(AC_BUS_RESET, sbp->path, /*arg*/ NULL);
846#endif
847

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

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

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

972
973 sdev = (struct sbp_dev *)xfer->sc;
974
975SBP_DEBUG(1)
976 device_printf(sdev->target->sbp->fd.dev,
977 "%s:%s\n", __func__, sdev->bustgtlun);
978END_DEBUG
979 resp = xfer->resp;
980 sbp_xfer_free(xfer);
981 return;
982}
983
984static struct sbp_dev *
985sbp_next_dev(struct sbp_target *target, int lun)
986{
987 struct sbp_dev **sdevp;
988 int i;
989

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

998static void
999sbp_cam_scan_lun(struct cam_periph *periph, union ccb *ccb)
1000{
1001 struct sbp_target *target;
1002 struct sbp_dev *sdev;
1003
1004 sdev = (struct sbp_dev *) ccb->ccb_h.ccb_sdev_ptr;
1005 target = sdev->target;
1006SBP_DEBUG(0)
1007 device_printf(sdev->target->sbp->fd.dev,
1008 "%s:%s\n", __func__, sdev->bustgtlun);
1009END_DEBUG
1010 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
1011 sdev->status = SBP_DEV_ATTACHED;
1012 } else {
1013 device_printf(sdev->target->sbp->fd.dev,

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

1028
1029static void
1030sbp_cam_scan_target(void *arg)
1031{
1032 struct sbp_target *target = (struct sbp_target *)arg;
1033 struct sbp_dev *sdev;
1034 union ccb *ccb;
1035
1036 sdev = sbp_next_dev(target, 0);
1037 if (sdev == NULL) {
1038 printf("sbp_cam_scan_target: nothing to do for target%d\n",
1039 target->target_id);
1040 return;
1041 }
1042SBP_DEBUG(0)
1043 device_printf(sdev->target->sbp->fd.dev,

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

1051 xpt_setup_ccb(&ccb->ccb_h, sdev->path, SCAN_PRI);
1052 ccb->ccb_h.func_code = XPT_SCAN_LUN;
1053 ccb->ccb_h.cbfcnp = sbp_cam_scan_lun;
1054 ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
1055 ccb->crcn.flags = CAM_FLAG_NONE;
1056 ccb->ccb_h.ccb_sdev_ptr = sdev;
1057
1058 /* The scan is in progress now. */
1059 SBP_LOCK(target->sbp);
1060 xpt_action(ccb);
1061 xpt_release_devq(sdev->path, sdev->freeze, TRUE);
1062 sdev->freeze = 1;
1063 SBP_UNLOCK(target->sbp);
1064}
1065
1066static __inline void
1067sbp_scan_dev(struct sbp_dev *sdev)
1068{
1069 sdev->status = SBP_DEV_PROBE;
1070 callout_reset(&sdev->target->scan_callout, scan_delay * hz / 1000,
1071 sbp_cam_scan_target, (void *)sdev->target);

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

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

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

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

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

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

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

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

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

1366 fp->mode.wreqq.dest_hi = sdev->login->cmd_hi;
1367 fp->mode.wreqq.dest_lo = sdev->login->cmd_lo + offset;
1368 fp->mode.wreqq.tlrt = 0;
1369 fp->mode.wreqq.tcode = tcode;
1370 fp->mode.wreqq.pri = 0;
1371 fp->mode.wreqq.dst = FWLOCALBUS | sdev->target->fwdev->dst;
1372
1373 return xfer;
1374
1375}
1376
1377static struct fw_xfer *
1378sbp_write_cmd(struct sbp_dev *sdev, int tcode, int offset)
1379{
1380 struct sbp_softc *sbp = sdev->target->sbp;
1381 struct fw_xfer *xfer;
1382
1383 SBP_LOCK(sbp);
1384 xfer = sbp_write_cmd_locked(sdev, tcode, offset);
1385 SBP_UNLOCK(sbp);
1386
1387 return (xfer);
1388}
1389
1390static void
1391sbp_mgm_orb(struct sbp_dev *sdev, int func, struct sbp_ocb *aocb)
1392{
1393 struct fw_xfer *xfer;
1394 struct fw_pkt *fp;
1395 struct sbp_ocb *ocb;
1396 struct sbp_target *target;
1397 int s, nid;
1398
1399 target = sdev->target;
1400 nid = target->sbp->fd.fc->nodeid | FWLOCALBUS;
1401
1402 s = splfw();
1403 SBP_LOCK(target->sbp);
1404 if (func == ORB_FUN_RUNQUEUE) {
1405 ocb = STAILQ_FIRST(&target->mgm_ocb_queue);
1406 if (target->mgm_ocb_cur != NULL || ocb == NULL) {
1407 SBP_UNLOCK(target->sbp);
1408 splx(s);
1409 return;
1410 }
1411 STAILQ_REMOVE_HEAD(&target->mgm_ocb_queue, ocb);
1412 SBP_UNLOCK(target->sbp);
1413 goto start;
1414 }
1415 if ((ocb = sbp_get_ocb(sdev)) == NULL) {
1416 SBP_UNLOCK(target->sbp);
1417 splx(s);
1418 /* XXX */
1419 return;
1420 }
1421 SBP_UNLOCK(target->sbp);
1422 ocb->flags = OCB_ACT_MGM;
1423 ocb->sdev = sdev;
1424
1425 bzero((void *)ocb->orb, sizeof(ocb->orb));
1426 ocb->orb[6] = htonl((nid << 16) | SBP_BIND_HI);
1427 ocb->orb[7] = htonl(SBP_DEV2ADDR(target->target_id, sdev->lun_id));
1428
1429SBP_DEBUG(0)

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

1453 case ORB_FUN_RST:
1454 case ORB_FUN_ATS:
1455 ocb->orb[4] = htonl(ORB_NOTIFY | func | sdev->login->id);
1456 break;
1457 }
1458
1459 if (target->mgm_ocb_cur != NULL) {
1460 /* there is a standing ORB */
1461 SBP_LOCK(target->sbp);
1462 STAILQ_INSERT_TAIL(&sdev->target->mgm_ocb_queue, ocb, ocb);
1463 SBP_UNLOCK(target->sbp);
1464 splx(s);
1465 return;
1466 }
1467start:
1468 target->mgm_ocb_cur = ocb;
1469 splx(s);
1470
1471 callout_reset(&target->mgm_ocb_timeout, 5*hz,
1472 sbp_mgm_timeout, (caddr_t)ocb);
1473 xfer = sbp_write_cmd(sdev, FWTCODE_WREQB, 0);
1474 if(xfer == NULL){
1475 return;
1476 }
1477 xfer->hand = sbp_mgm_callback;

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

1672 uint32_t *ld;
1673 ld = xfer->recv.buf;
1674printf("sbp %x %d %d %08x %08x %08x %08x\n",
1675 xfer->resp, xfer->recv.len, xfer->recv.off, ntohl(ld[0]), ntohl(ld[1]), ntohl(ld[2]), ntohl(ld[3]));
1676printf("sbp %08x %08x %08x %08x\n", ntohl(ld[4]), ntohl(ld[5]), ntohl(ld[6]), ntohl(ld[7]));
1677printf("sbp %08x %08x %08x %08x\n", ntohl(ld[8]), ntohl(ld[9]), ntohl(ld[10]), ntohl(ld[11]));
1678*/
1679 sbp = (struct sbp_softc *)xfer->sc;
1680 if (xfer->resp != 0){
1681 printf("sbp_recv: xfer->resp = %d\n", xfer->resp);
1682 goto done0;
1683 }
1684 if (xfer->recv.payload == NULL){
1685 printf("sbp_recv: xfer->recv.payload == NULL\n");
1686 goto done0;
1687 }

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

1791 default:
1792 printf("unknown respose code %d\n", sbp_status->resp);
1793 }
1794 }
1795
1796 /* we have to reset the fetch agent if it's dead */
1797 if (sbp_status->dead) {
1798 if (sdev->path) {
1799 SBP_LOCK(sbp);
1800 xpt_freeze_devq(sdev->path, 1);
1801 sdev->freeze ++;
1802 SBP_UNLOCK(sbp);
1803 }
1804 reset_agent = 1;
1805 }
1806
1807 if (ocb == NULL)
1808 goto done;
1809
1810 switch(ntohl(ocb->orb[4]) & ORB_FMT_MSK){

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

1899 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1900 }else{
1901 ccb->ccb_h.status = CAM_REQ_CMP;
1902 }
1903 }
1904 /* fix up inq data */
1905 if (ccb->csio.cdb_io.cdb_bytes[0] == INQUIRY)
1906 sbp_fix_inq_data(ocb);
1907 SBP_LOCK(sbp);
1908 xpt_done(ccb);
1909 SBP_UNLOCK(sbp);
1910 }
1911 break;
1912 default:
1913 break;
1914 }
1915 }
1916
1917 if (!use_doorbell)

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

1940 sfp->mode.wres.tlrt = rfp->mode.wreqb.tlrt;
1941 sfp->mode.wres.tcode = FWTCODE_WRES;
1942 sfp->mode.wres.rtcode = 0;
1943 sfp->mode.wres.pri = 0;
1944
1945 fw_asyreq(xfer->fc, -1, xfer);
1946#else
1947 /* recycle */
1948 /* we don't need a lock here because bottom half is serialized */
1949 STAILQ_INSERT_TAIL(&sbp->fwb.xferlist, xfer, link);
1950#endif
1951
1952 return;
1953
1954}
1955
1956static void
1957sbp_recv(struct fw_xfer *xfer)
1958{
1959 int s;
1960
1961 s = splcam();
1962 sbp_recv1(xfer);
1963 splx(s);
1964}
1965/*
1966 * sbp_attach()
1967 */
1968static int
1969sbp_attach(device_t dev)
1970{
1971 struct sbp_softc *sbp;
1972 struct cam_devq *devq;
1973 struct firewire_comm *fc;
1974 int i, s, error;
1975
1976 if (DFLTPHYS > SBP_MAXPHYS)
1977 device_printf(dev, "Warning, DFLTPHYS(%dKB) is larger than "
1978 "SBP_MAXPHYS(%dKB).\n", DFLTPHYS / 1024,
1979 SBP_MAXPHYS / 1024);
1980
1981 if (!firewire_phydma_enable)
1982 device_printf(dev, "Warning, hw.firewire.phydma_enable must be 1 "
1983 "for SBP over FireWire.\n");
1984SBP_DEBUG(0)
1985 printf("sbp_attach (cold=%d)\n", cold);
1986END_DEBUG
1987
1988 if (cold)
1989 sbp_cold ++;
1990 sbp = ((struct sbp_softc *)device_get_softc(dev));
1991 bzero(sbp, sizeof(struct sbp_softc));
1992 sbp->fd.dev = dev;
1993 sbp->fd.fc = fc = device_get_ivars(dev);
1994 mtx_init(&sbp->mtx, "sbp", NULL, MTX_DEF);
1995
1996 if (max_speed < 0)
1997 max_speed = fc->speed;
1998
1999 error = bus_dma_tag_create(/*parent*/fc->dmat,

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

2059 fc, (void *)sbp, sbp_recv);
2060
2061 fw_bindadd(fc, &sbp->fwb);
2062
2063 sbp->fd.post_busreset = sbp_post_busreset;
2064 sbp->fd.post_explore = sbp_post_explore;
2065
2066 if (fc->status != -1) {
2067 s = splfw();
2068 sbp_post_busreset((void *)sbp);
2069 sbp_post_explore((void *)sbp);
2070 splx(s);
2071 }
2072 SBP_LOCK(sbp);
2073 xpt_async(AC_BUS_RESET, sbp->path, /*arg*/ NULL);
2074 SBP_UNLOCK(sbp);
2075
2076 return (0);
2077fail:
2078 SBP_UNLOCK(sbp);

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

2085{
2086 struct sbp_target *target;
2087 struct sbp_dev *sdev;
2088 int i, j;
2089
2090SBP_DEBUG(0)
2091 printf("sbp_logout_all\n");
2092END_DEBUG
2093 for (i = 0 ; i < SBP_NUM_TARGETS ; i ++) {
2094 target = &sbp->targets[i];
2095 if (target->luns == NULL)
2096 continue;
2097 for (j = 0; j < target->num_lun; j++) {
2098 sdev = target->luns[j];
2099 if (sdev == NULL)
2100 continue;

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

2108 return 0;
2109}
2110
2111static int
2112sbp_shutdown(device_t dev)
2113{
2114 struct sbp_softc *sbp = ((struct sbp_softc *)device_get_softc(dev));
2115
2116 sbp_logout_all(sbp);
2117 return (0);
2118}
2119
2120static void
2121sbp_free_sdev(struct sbp_dev *sdev)
2122{
2123 int i;
2124
2125 if (sdev == NULL)
2126 return;
2127 for (i = 0; i < SBP_QUEUE_LEN; i++)
2128 bus_dmamap_destroy(sdev->target->sbp->dmat,
2129 sdev->ocb[i].dmamap);
2130 fwdma_free(sdev->target->sbp->fd.fc, &sdev->dma);
2131 free(sdev, M_SBP);
2132 sdev = NULL;
2133}
2134
2135static void
2136sbp_free_target(struct sbp_target *target)
2137{
2138 struct sbp_softc *sbp;
2139 struct fw_xfer *xfer, *next;
2140 int i;
2141
2142 if (target->luns == NULL)
2143 return;
2144 callout_stop(&target->mgm_ocb_timeout);
2145 sbp = target->sbp;
2146 for (i = 0; i < target->num_lun; i++)
2147 sbp_free_sdev(target->luns[i]);
2148
2149 for (xfer = STAILQ_FIRST(&target->xferlist);
2150 xfer != NULL; xfer = next) {
2151 next = STAILQ_NEXT(xfer, link);
2152 fw_xfer_free_buf(xfer);
2153 }
2154 STAILQ_INIT(&target->xferlist);
2155 free(target->luns, M_SBP);
2156 target->num_lun = 0;
2157 target->luns = NULL;
2158 target->fwdev = NULL;
2159}

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

2164 struct sbp_softc *sbp = ((struct sbp_softc *)device_get_softc(dev));
2165 struct firewire_comm *fc = sbp->fd.fc;
2166 int i;
2167
2168SBP_DEBUG(0)
2169 printf("sbp_detach\n");
2170END_DEBUG
2171
2172 for (i = 0; i < SBP_NUM_TARGETS; i ++)
2173 sbp_cam_detach_target(&sbp->targets[i]);
2174
2175 SBP_LOCK(sbp);
2176 xpt_async(AC_LOST_DEVICE, sbp->path, NULL);
2177 xpt_free_path(sbp->path);
2178 xpt_bus_deregister(cam_sim_path(sbp->sim));
2179 cam_sim_free(sbp->sim, /*free_devq*/ TRUE);
2180 SBP_UNLOCK(sbp);
2181
2182 sbp_logout_all(sbp);
2183
2184 /* XXX wait for logout completion */
2185 pause("sbpdtc", hz/2);
2186
2187 for (i = 0 ; i < SBP_NUM_TARGETS ; i ++)
2188 sbp_free_target(&sbp->targets[i]);
2189
2190 fw_bindremove(fc, &sbp->fwb);
2191 fw_xferlist_remove(&sbp->fwb.xferlist);
2192
2193 bus_dma_tag_destroy(sbp->dmat);
2194 mtx_destroy(&sbp->mtx);
2195
2196 return (0);
2197}
2198
2199static void
2200sbp_cam_detach_sdev(struct sbp_dev *sdev)
2201{
2202 if (sdev == NULL)
2203 return;
2204 if (sdev->status == SBP_DEV_DEAD)
2205 return;
2206 if (sdev->status == SBP_DEV_RESET)
2207 return;
2208 sbp_abort_all_ocbs(sdev, CAM_DEV_NOT_THERE);
2209 if (sdev->path) {
2210 SBP_LOCK(sdev->target->sbp);
2211 xpt_release_devq(sdev->path,
2212 sdev->freeze, TRUE);
2213 sdev->freeze = 0;
2214 xpt_async(AC_LOST_DEVICE, sdev->path, NULL);
2215 xpt_free_path(sdev->path);
2216 sdev->path = NULL;
2217 SBP_UNLOCK(sdev->target->sbp);
2218 }
2219}
2220
2221static void
2222sbp_cam_detach_target(struct sbp_target *target)
2223{
2224 int i;
2225
2226 if (target->luns != NULL) {
2227SBP_DEBUG(0)
2228 printf("sbp_detach_target %d\n", target->target_id);
2229END_DEBUG
2230 callout_stop(&target->scan_callout);
2231 for (i = 0; i < target->num_lun; i++)
2232 sbp_cam_detach_sdev(target->luns[i]);
2233 }
2234}
2235
2236static void
2237sbp_target_reset(struct sbp_dev *sdev, int method)
2238{
2239 int i;
2240 struct sbp_target *target = sdev->target;
2241 struct sbp_dev *tsdev;
2242
2243 for (i = 0; i < target->num_lun; i++) {
2244 tsdev = target->luns[i];
2245 if (tsdev == NULL)
2246 continue;
2247 if (tsdev->status == SBP_DEV_DEAD)
2248 continue;
2249 if (tsdev->status == SBP_DEV_RESET)
2250 continue;
2251 SBP_LOCK(target->sbp);
2252 xpt_freeze_devq(tsdev->path, 1);
2253 tsdev->freeze ++;
2254 SBP_UNLOCK(target->sbp);
2255 sbp_abort_all_ocbs(tsdev, CAM_CMD_TIMEOUT);
2256 if (method == 2)
2257 tsdev->status = SBP_DEV_LOGIN;
2258 }
2259 switch(method) {
2260 case 1:
2261 printf("target reset\n");
2262 sbp_mgm_orb(sdev, ORB_FUN_RST, NULL);

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

2271
2272static void
2273sbp_mgm_timeout(void *arg)
2274{
2275 struct sbp_ocb *ocb = (struct sbp_ocb *)arg;
2276 struct sbp_dev *sdev = ocb->sdev;
2277 struct sbp_target *target = sdev->target;
2278
2279 device_printf(sdev->target->sbp->fd.dev,
2280 "%s:%s request timeout(mgm orb:0x%08x)\n",
2281 __func__, sdev->bustgtlun, (uint32_t)ocb->bus_addr);
2282 target->mgm_ocb_cur = NULL;
2283 sbp_free_ocb(sdev, ocb);
2284#if 0
2285 /* XXX */
2286 printf("run next request\n");

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

2297{
2298 struct sbp_ocb *ocb = (struct sbp_ocb *)arg;
2299 struct sbp_dev *sdev = ocb->sdev;
2300
2301 device_printf(sdev->target->sbp->fd.dev,
2302 "%s:%s request timeout(cmd orb:0x%08x) ... ",
2303 __func__, sdev->bustgtlun, (uint32_t)ocb->bus_addr);
2304
2305 sdev->timeout ++;
2306 switch(sdev->timeout) {
2307 case 1:
2308 printf("agent reset\n");
2309 SBP_LOCK(sdev->target->sbp);
2310 xpt_freeze_devq(sdev->path, 1);
2311 sdev->freeze ++;
2312 SBP_UNLOCK(sdev->target->sbp);
2313 sbp_abort_all_ocbs(sdev, CAM_CMD_TIMEOUT);
2314 sbp_agent_reset(sdev);
2315 break;
2316 case 2:
2317 case 3:
2318 sbp_target_reset(sdev, sdev->timeout - 1);
2319 break;
2320#if 0

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

2326 target->num_lun = 0;
2327 target->luns = NULL;
2328 target->fwdev = NULL;
2329#endif
2330 }
2331}
2332
2333static void
2334sbp_action1(struct cam_sim *sim, union ccb *ccb)
2335{
2336
2337 struct sbp_softc *sbp = (struct sbp_softc *)sim->softc;
2338 struct sbp_target *target = NULL;
2339 struct sbp_dev *sdev = NULL;
2340
2341 /* target:lun -> sdev mapping */
2342 if (sbp != NULL
2343 && ccb->ccb_h.target_id != CAM_TARGET_WILDCARD
2344 && ccb->ccb_h.target_id < SBP_NUM_TARGETS) {
2345 target = &sbp->targets[ccb->ccb_h.target_id];
2346 if (target->fwdev != NULL
2347 && ccb->ccb_h.target_lun != CAM_LUN_WILDCARD
2348 && ccb->ccb_h.target_lun < target->num_lun) {

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

2454 xpt_done(ccb);
2455 return;
2456 }
2457 }
2458#endif
2459 if ((ocb = sbp_get_ocb(sdev)) == NULL) {
2460 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
2461 if (sdev->freeze == 0) {
2462 SBP_LOCK(sdev->target->sbp);
2463 xpt_freeze_devq(sdev->path, 1);
2464 sdev->freeze ++;
2465 SBP_UNLOCK(sdev->target->sbp);
2466 }
2467 xpt_done(ccb);
2468 return;
2469 }
2470
2471 ocb->flags = OCB_ACT_CMD;
2472 ocb->sdev = sdev;
2473 ocb->ccb = ccb;

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

2513#if defined(__DragonFly__) || __FreeBSD_version < 501100
2514 uint32_t size_mb;
2515 uint32_t secs_per_cylinder;
2516 int extended = 1;
2517#endif
2518
2519 ccg = &ccb->ccg;
2520 if (ccg->block_size == 0) {
2521 printf("sbp_action1: block_size is 0.\n");
2522 ccb->ccb_h.status = CAM_REQ_INVALID;
2523 xpt_done(ccb);
2524 break;
2525 }
2526SBP_DEBUG(1)
2527 printf("%s:%d:%d:%jx:XPT_CALC_GEOMETRY: "
2528#if defined(__DragonFly__) || __FreeBSD_version < 500000
2529 "Volume size = %d\n",

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

2638 ccb->ccb_h.status = CAM_REQ_INVALID;
2639 xpt_done(ccb);
2640 break;
2641 }
2642 return;
2643}
2644
2645static void
2646sbp_action(struct cam_sim *sim, union ccb *ccb)
2647{
2648 int s;
2649
2650 s = splfw();
2651 sbp_action1(sim, ccb);
2652 splx(s);
2653}
2654
2655static void
2656sbp_execute_ocb(void *arg, bus_dma_segment_t *segments, int seg, int error)
2657{
2658 int i;
2659 struct sbp_ocb *ocb;
2660 struct sbp_ocb *prev;
2661 bus_dma_segment_t *s;
2662
2663 if (error)

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

2742 return;
2743}
2744
2745static struct sbp_ocb *
2746sbp_dequeue_ocb(struct sbp_dev *sdev, struct sbp_status *sbp_status)
2747{
2748 struct sbp_ocb *ocb;
2749 struct sbp_ocb *next;
2750 int s = splfw(), order = 0;
2751
2752SBP_DEBUG(1)
2753 device_printf(sdev->target->sbp->fd.dev,
2754#if defined(__DragonFly__) || __FreeBSD_version < 500000
2755 "%s:%s 0x%08lx src %d\n",
2756#else
2757 "%s:%s 0x%08x src %d\n",
2758#endif
2759 __func__, sdev->bustgtlun, ntohl(sbp_status->orb_lo), sbp_status->src);
2760END_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 if (OCB_MATCH(ocb, sbp_status)) {
2765 /* found */
2766 STAILQ_REMOVE(&sdev->ocbs, ocb, sbp_ocb, ocb);
2767 if (ocb->ccb != NULL)
2768 untimeout(sbp_timeout, (caddr_t)ocb,
2769 ocb->timeout_ch);
2770 if (ntohl(ocb->orb[4]) & 0xffff) {
2771 bus_dmamap_sync(sdev->target->sbp->dmat,
2772 ocb->dmamap,
2773 (ntohl(ocb->orb[4]) & ORB_CMD_IN) ?
2774 BUS_DMASYNC_POSTREAD :
2775 BUS_DMASYNC_POSTWRITE);
2776 bus_dmamap_unload(sdev->target->sbp->dmat,
2777 ocb->dmamap);

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

2790 }
2791 }
2792 } else {
2793 /*
2794 * XXX this is not correct for unordered
2795 * execution.
2796 */
2797 if (sdev->last_ocb != NULL) {
2798 SBP_UNLOCK(sdev->target->sbp);
2799 sbp_free_ocb(sdev, sdev->last_ocb);
2800 SBP_LOCK(sdev->target->sbp);
2801 }
2802 sdev->last_ocb = ocb;
2803 if (next != NULL &&
2804 sbp_status->src == SRC_NO_NEXT)
2805 sbp_doorbell(sdev);
2806 }
2807 break;
2808 } else
2809 order ++;
2810 }
2811 SBP_UNLOCK(sdev->target->sbp);
2812 splx(s);
2813SBP_DEBUG(0)
2814 if (ocb && order > 0) {
2815 device_printf(sdev->target->sbp->fd.dev,
2816 "%s:%s unordered execution order:%d\n",
2817 __func__, sdev->bustgtlun, order);
2818 }
2819END_DEBUG
2820 return (ocb);
2821}
2822
2823static struct sbp_ocb *
2824sbp_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);
2830SBP_DEBUG(1)
2831 device_printf(sdev->target->sbp->fd.dev,
2832#if defined(__DragonFly__) || __FreeBSD_version < 500000
2833 "%s:%s 0x%08x\n", __func__, sdev->bustgtlun, ocb->bus_addr);
2834#else
2835 "%s:%s 0x%08jx\n", __func__, sdev->bustgtlun, (uintmax_t)ocb->bus_addr);
2836#endif
2837END_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->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) {
2849SBP_DEBUG(1)
2850#if defined(__DragonFly__) || __FreeBSD_version < 500000
2851 printf("linking chain 0x%x -> 0x%x\n",

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

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
2871static struct sbp_ocb *
2872sbp_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
2891static void
2892sbp_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
2910static void
2911sbp_abort_ocb(struct sbp_ocb *ocb, int status)
2912{
2913 struct sbp_dev *sdev;
2914
2915 sdev = ocb->sdev;
2916SBP_DEBUG(0)
2917 device_printf(sdev->target->sbp->fd.dev,
2918#if defined(__DragonFly__) || __FreeBSD_version < 500000
2919 "%s:%s 0x%x\n", __func__, sdev->bustgtlun, ocb->bus_addr);
2920#else
2921 "%s:%s 0x%jx\n", __func__, sdev->bustgtlun, (uintmax_t)ocb->bus_addr);
2922#endif
2923END_DEBUG
2924SBP_DEBUG(1)
2925 if (ocb->ccb != NULL)
2926 sbp_print_scsi_cmd(ocb);
2927END_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->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
2945static void
2946sbp_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
2972static devclass_t sbp_devclass;
2973
2974static device_method_t sbp_methods[] = {
2975 /* device interface */
2976 DEVMETHOD(device_identify, sbp_identify),
2977 DEVMETHOD(device_probe, sbp_probe),

--- 19 unchanged lines hidden ---