Deleted Added
full compact
isp_freebsd.c (228914) isp_freebsd.c (236427)
1/*-
2 * Copyright (c) 1997-2009 by Matthew Jacob
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

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

23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27/*
28 * Platform (FreeBSD) dependent common attachment code for Qlogic adapters.
29 */
30#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 1997-2009 by Matthew Jacob
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

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

23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27/*
28 * Platform (FreeBSD) dependent common attachment code for Qlogic adapters.
29 */
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/sys/dev/isp/isp_freebsd.c 228914 2011-12-27 14:59:24Z mjacob $");
31__FBSDID("$FreeBSD: head/sys/dev/isp/isp_freebsd.c 236427 2012-06-01 23:29:48Z mjacob $");
32#include <dev/isp/isp_freebsd.h>
33#include <sys/unistd.h>
34#include <sys/kthread.h>
35#include <sys/conf.h>
36#include <sys/module.h>
37#include <sys/ioccom.h>
38#include <dev/isp/isp_ioctl.h>
39#include <sys/devicestat.h>

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

776 isp->isp_osinfo.pcmd_free = ISP_PCMD(ccb);
777 ISP_PCMD(ccb) = NULL;
778}
779/*
780 * Put the target mode functions here, because some are inlines
781 */
782
783#ifdef ISP_TARGET_MODE
32#include <dev/isp/isp_freebsd.h>
33#include <sys/unistd.h>
34#include <sys/kthread.h>
35#include <sys/conf.h>
36#include <sys/module.h>
37#include <sys/ioccom.h>
38#include <dev/isp/isp_ioctl.h>
39#include <sys/devicestat.h>

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

776 isp->isp_osinfo.pcmd_free = ISP_PCMD(ccb);
777 ISP_PCMD(ccb) = NULL;
778}
779/*
780 * Put the target mode functions here, because some are inlines
781 */
782
783#ifdef ISP_TARGET_MODE
784static ISP_INLINE void isp_tmlock(ispsoftc_t *, const char *);
785static ISP_INLINE void isp_tmunlk(ispsoftc_t *);
786static ISP_INLINE int is_any_lun_enabled(ispsoftc_t *, int);
784static ISP_INLINE int is_lun_enabled(ispsoftc_t *, int, lun_id_t);
785static ISP_INLINE tstate_t *get_lun_statep(ispsoftc_t *, int, lun_id_t);
786static ISP_INLINE tstate_t *get_lun_statep_from_tag(ispsoftc_t *, int, uint32_t);
787static ISP_INLINE void rls_lun_statep(ispsoftc_t *, tstate_t *);
788static ISP_INLINE inot_private_data_t *get_ntp_from_tagdata(ispsoftc_t *, uint32_t, uint32_t, tstate_t **);
789static ISP_INLINE atio_private_data_t *isp_get_atpd(ispsoftc_t *, tstate_t *, uint32_t);
790static ISP_INLINE void isp_put_atpd(ispsoftc_t *, tstate_t *, atio_private_data_t *);
791static ISP_INLINE inot_private_data_t *isp_get_ntpd(ispsoftc_t *, tstate_t *);
792static ISP_INLINE inot_private_data_t *isp_find_ntpd(ispsoftc_t *, tstate_t *, uint32_t, uint32_t);
793static ISP_INLINE void isp_put_ntpd(ispsoftc_t *, tstate_t *, inot_private_data_t *);
794static cam_status create_lun_state(ispsoftc_t *, int, struct cam_path *, tstate_t **);
795static void destroy_lun_state(ispsoftc_t *, tstate_t *);
796static void isp_enable_lun(ispsoftc_t *, union ccb *);
787static ISP_INLINE int is_lun_enabled(ispsoftc_t *, int, lun_id_t);
788static ISP_INLINE tstate_t *get_lun_statep(ispsoftc_t *, int, lun_id_t);
789static ISP_INLINE tstate_t *get_lun_statep_from_tag(ispsoftc_t *, int, uint32_t);
790static ISP_INLINE void rls_lun_statep(ispsoftc_t *, tstate_t *);
791static ISP_INLINE inot_private_data_t *get_ntp_from_tagdata(ispsoftc_t *, uint32_t, uint32_t, tstate_t **);
792static ISP_INLINE atio_private_data_t *isp_get_atpd(ispsoftc_t *, tstate_t *, uint32_t);
793static ISP_INLINE void isp_put_atpd(ispsoftc_t *, tstate_t *, atio_private_data_t *);
794static ISP_INLINE inot_private_data_t *isp_get_ntpd(ispsoftc_t *, tstate_t *);
795static ISP_INLINE inot_private_data_t *isp_find_ntpd(ispsoftc_t *, tstate_t *, uint32_t, uint32_t);
796static ISP_INLINE void isp_put_ntpd(ispsoftc_t *, tstate_t *, inot_private_data_t *);
797static cam_status create_lun_state(ispsoftc_t *, int, struct cam_path *, tstate_t **);
798static void destroy_lun_state(ispsoftc_t *, tstate_t *);
799static void isp_enable_lun(ispsoftc_t *, union ccb *);
797static void isp_enable_deferred_luns(ispsoftc_t *, int);
800static cam_status isp_enable_deferred_luns(ispsoftc_t *, int);
798static cam_status isp_enable_deferred(ispsoftc_t *, int, lun_id_t);
799static void isp_disable_lun(ispsoftc_t *, union ccb *);
800static int isp_enable_target_mode(ispsoftc_t *, int);
801static cam_status isp_enable_deferred(ispsoftc_t *, int, lun_id_t);
802static void isp_disable_lun(ispsoftc_t *, union ccb *);
803static int isp_enable_target_mode(ispsoftc_t *, int);
804static int isp_disable_target_mode(ispsoftc_t *, int);
801static void isp_ledone(ispsoftc_t *, lun_entry_t *);
802static timeout_t isp_refire_putback_atio;
803static void isp_complete_ctio(union ccb *);
804static void isp_target_putback_atio(union ccb *);
805static void isp_target_start_ctio(ispsoftc_t *, union ccb *);
806static void isp_handle_platform_atio(ispsoftc_t *, at_entry_t *);
807static void isp_handle_platform_atio2(ispsoftc_t *, at2_entry_t *);
808static void isp_handle_platform_atio7(ispsoftc_t *, at7_entry_t *);
809static void isp_handle_platform_ctio(ispsoftc_t *, void *);
810static void isp_handle_platform_notify_scsi(ispsoftc_t *, in_entry_t *);
811static void isp_handle_platform_notify_fc(ispsoftc_t *, in_fcentry_t *);
812static void isp_handle_platform_notify_24xx(ispsoftc_t *, in_fcentry_24xx_t *);
813static int isp_handle_platform_target_notify_ack(ispsoftc_t *, isp_notify_t *);
814static void isp_handle_platform_target_tmf(ispsoftc_t *, isp_notify_t *);
815static void isp_target_mark_aborted(ispsoftc_t *, union ccb *);
816static void isp_target_mark_aborted_early(ispsoftc_t *, tstate_t *, uint32_t);
817
805static void isp_ledone(ispsoftc_t *, lun_entry_t *);
806static timeout_t isp_refire_putback_atio;
807static void isp_complete_ctio(union ccb *);
808static void isp_target_putback_atio(union ccb *);
809static void isp_target_start_ctio(ispsoftc_t *, union ccb *);
810static void isp_handle_platform_atio(ispsoftc_t *, at_entry_t *);
811static void isp_handle_platform_atio2(ispsoftc_t *, at2_entry_t *);
812static void isp_handle_platform_atio7(ispsoftc_t *, at7_entry_t *);
813static void isp_handle_platform_ctio(ispsoftc_t *, void *);
814static void isp_handle_platform_notify_scsi(ispsoftc_t *, in_entry_t *);
815static void isp_handle_platform_notify_fc(ispsoftc_t *, in_fcentry_t *);
816static void isp_handle_platform_notify_24xx(ispsoftc_t *, in_fcentry_24xx_t *);
817static int isp_handle_platform_target_notify_ack(ispsoftc_t *, isp_notify_t *);
818static void isp_handle_platform_target_tmf(ispsoftc_t *, isp_notify_t *);
819static void isp_target_mark_aborted(ispsoftc_t *, union ccb *);
820static void isp_target_mark_aborted_early(ispsoftc_t *, tstate_t *, uint32_t);
821
822static ISP_INLINE void
823isp_tmlock(ispsoftc_t *isp, const char *msg)
824{
825 while (isp->isp_osinfo.tmbusy) {
826 isp->isp_osinfo.tmwanted = 1;
827 mtx_sleep(isp, &isp->isp_lock, PRIBIO, msg, 0);
828 }
829 isp->isp_osinfo.tmbusy = 1;
830}
831
832static ISP_INLINE void
833isp_tmunlk(ispsoftc_t *isp)
834{
835 isp->isp_osinfo.tmbusy = 0;
836 if (isp->isp_osinfo.tmwanted) {
837 isp->isp_osinfo.tmwanted = 0;
838 wakeup(isp);
839 }
840}
841
818static ISP_INLINE int
842static ISP_INLINE int
843is_any_lun_enabled(ispsoftc_t *isp, int bus)
844{
845 struct tslist *lhp;
846 int i;
847
848 for (i = 0; i < LUN_HASH_SIZE; i++) {
849 ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp);
850 if (SLIST_FIRST(lhp))
851 return (1);
852 }
853 return (0);
854}
855
856static ISP_INLINE int
819is_lun_enabled(ispsoftc_t *isp, int bus, lun_id_t lun)
820{
821 tstate_t *tptr;
822 struct tslist *lhp;
823
824 ISP_GET_PC_ADDR(isp, bus, lun_hash[LUN_HASH_FUNC(lun)], lhp);
825 SLIST_FOREACH(tptr, lhp, next) {
826 if (xpt_path_lun_id(tptr->owner) == lun) {

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

912 tptr->hold++;
913 return (ntp);
914 }
915 }
916 }
917 }
918 return (NULL);
919}
857is_lun_enabled(ispsoftc_t *isp, int bus, lun_id_t lun)
858{
859 tstate_t *tptr;
860 struct tslist *lhp;
861
862 ISP_GET_PC_ADDR(isp, bus, lun_hash[LUN_HASH_FUNC(lun)], lhp);
863 SLIST_FOREACH(tptr, lhp, next) {
864 if (xpt_path_lun_id(tptr->owner) == lun) {

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

950 tptr->hold++;
951 return (ntp);
952 }
953 }
954 }
955 }
956 return (NULL);
957}
958
920static ISP_INLINE void
921rls_lun_statep(ispsoftc_t *isp, tstate_t *tptr)
922{
923 KASSERT((tptr->hold), ("tptr not held"));
924 tptr->hold--;
925}
926
927static void

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

1053 if (lun != CAM_LUN_WILDCARD) {
1054 if (lun >= ISP_MAX_LUNS(isp)) {
1055 return (CAM_LUN_INVALID);
1056 }
1057 }
1058 if (is_lun_enabled(isp, bus, lun)) {
1059 return (CAM_LUN_ALRDY_ENA);
1060 }
959static ISP_INLINE void
960rls_lun_statep(ispsoftc_t *isp, tstate_t *tptr)
961{
962 KASSERT((tptr->hold), ("tptr not held"));
963 tptr->hold--;
964}
965
966static void

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

1092 if (lun != CAM_LUN_WILDCARD) {
1093 if (lun >= ISP_MAX_LUNS(isp)) {
1094 return (CAM_LUN_INVALID);
1095 }
1096 }
1097 if (is_lun_enabled(isp, bus, lun)) {
1098 return (CAM_LUN_ALRDY_ENA);
1099 }
1061 tptr = (tstate_t *) malloc(sizeof (tstate_t), M_DEVBUF, M_NOWAIT|M_ZERO);
1100 tptr = malloc(sizeof (tstate_t), M_DEVBUF, M_NOWAIT|M_ZERO);
1062 if (tptr == NULL) {
1063 return (CAM_RESRC_UNAVAIL);
1064 }
1065 status = xpt_create_path(&tptr->owner, NULL, xpt_path_path_id(path), xpt_path_target_id(path), lun);
1066 if (status != CAM_REQ_CMP) {
1067 free(tptr, M_DEVBUF);
1068 return (status);
1069 }

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

1082 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, path, "created tstate\n");
1083 return (CAM_REQ_CMP);
1084}
1085
1086static ISP_INLINE void
1087destroy_lun_state(ispsoftc_t *isp, tstate_t *tptr)
1088{
1089 struct tslist *lhp;
1101 if (tptr == NULL) {
1102 return (CAM_RESRC_UNAVAIL);
1103 }
1104 status = xpt_create_path(&tptr->owner, NULL, xpt_path_path_id(path), xpt_path_target_id(path), lun);
1105 if (status != CAM_REQ_CMP) {
1106 free(tptr, M_DEVBUF);
1107 return (status);
1108 }

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

1121 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, path, "created tstate\n");
1122 return (CAM_REQ_CMP);
1123}
1124
1125static ISP_INLINE void
1126destroy_lun_state(ispsoftc_t *isp, tstate_t *tptr)
1127{
1128 struct tslist *lhp;
1129
1090 KASSERT((tptr->hold != 0), ("tptr is not held"));
1091 KASSERT((tptr->hold == 1), ("tptr still held (%d)", tptr->hold));
1092 ISP_GET_PC_ADDR(isp, cam_sim_bus(xpt_path_sim(tptr->owner)), lun_hash[LUN_HASH_FUNC(xpt_path_lun_id(tptr->owner))], lhp);
1093 SLIST_REMOVE(lhp, tptr, tstate, next);
1130 KASSERT((tptr->hold != 0), ("tptr is not held"));
1131 KASSERT((tptr->hold == 1), ("tptr still held (%d)", tptr->hold));
1132 ISP_GET_PC_ADDR(isp, cam_sim_bus(xpt_path_sim(tptr->owner)), lun_hash[LUN_HASH_FUNC(xpt_path_lun_id(tptr->owner))], lhp);
1133 SLIST_REMOVE(lhp, tptr, tstate, next);
1134 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, tptr->owner, "destroyed tstate\n");
1094 xpt_free_path(tptr->owner);
1095 free(tptr, M_DEVBUF);
1096}
1097
1098/*
1099 * Enable a lun.
1100 */
1101static void
1102isp_enable_lun(ispsoftc_t *isp, union ccb *ccb)
1103{
1104 tstate_t *tptr = NULL;
1105 int bus, tm_enabled, target_role;
1106 target_id_t target;
1107 lun_id_t lun;
1108
1135 xpt_free_path(tptr->owner);
1136 free(tptr, M_DEVBUF);
1137}
1138
1139/*
1140 * Enable a lun.
1141 */
1142static void
1143isp_enable_lun(ispsoftc_t *isp, union ccb *ccb)
1144{
1145 tstate_t *tptr = NULL;
1146 int bus, tm_enabled, target_role;
1147 target_id_t target;
1148 lun_id_t lun;
1149
1150
1109 /*
1110 * We only support either a wildcard target/lun or a target ID of zero and a non-wildcard lun
1111 */
1112 bus = XS_CHANNEL(ccb);
1113 target = ccb->ccb_h.target_id;
1114 lun = ccb->ccb_h.target_lun;
1151 /*
1152 * We only support either a wildcard target/lun or a target ID of zero and a non-wildcard lun
1153 */
1154 bus = XS_CHANNEL(ccb);
1155 target = ccb->ccb_h.target_id;
1156 lun = ccb->ccb_h.target_lun;
1157 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0|ISP_LOGCONFIG, ccb->ccb_h.path, "enabling lun %u\n", lun);
1115 if (target != CAM_TARGET_WILDCARD && target != 0) {
1116 ccb->ccb_h.status = CAM_TID_INVALID;
1117 xpt_done(ccb);
1118 return;
1119 }
1120 if (target == CAM_TARGET_WILDCARD && lun != CAM_LUN_WILDCARD) {
1121 ccb->ccb_h.status = CAM_LUN_INVALID;
1122 xpt_done(ccb);

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

1130 }
1131 if (isp->isp_dblev & ISP_LOGTDEBUG0) {
1132 xpt_print(ccb->ccb_h.path, "enabling lun 0x%x on channel %d\n", lun, bus);
1133 }
1134
1135 /*
1136 * Wait until we're not busy with the lun enables subsystem
1137 */
1158 if (target != CAM_TARGET_WILDCARD && target != 0) {
1159 ccb->ccb_h.status = CAM_TID_INVALID;
1160 xpt_done(ccb);
1161 return;
1162 }
1163 if (target == CAM_TARGET_WILDCARD && lun != CAM_LUN_WILDCARD) {
1164 ccb->ccb_h.status = CAM_LUN_INVALID;
1165 xpt_done(ccb);

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

1173 }
1174 if (isp->isp_dblev & ISP_LOGTDEBUG0) {
1175 xpt_print(ccb->ccb_h.path, "enabling lun 0x%x on channel %d\n", lun, bus);
1176 }
1177
1178 /*
1179 * Wait until we're not busy with the lun enables subsystem
1180 */
1138 while (isp->isp_osinfo.tmbusy) {
1139 isp->isp_osinfo.tmwanted = 1;
1140 mtx_sleep(isp, &isp->isp_lock, PRIBIO, "want_isp_enable_lun", 0);
1141 }
1142 isp->isp_osinfo.tmbusy = 1;
1181 isp_tmlock(isp, "isp_enable_lun");
1143
1144 /*
1145 * This is as a good a place as any to check f/w capabilities.
1146 */
1147
1148 if (IS_FC(isp)) {
1149 if (ISP_CAP_TMODE(isp) == 0) {
1150 xpt_print(ccb->ccb_h.path, "firmware does not support target mode\n");

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

1203 /*
1204 * Now check to see whether this bus is in target mode already.
1205 *
1206 * If not, a later role change into target mode will finish the job.
1207 */
1208 if (tm_enabled == 0) {
1209 ISP_SET_PC(isp, bus, tm_enable_defer, 1);
1210 ccb->ccb_h.status = CAM_REQ_CMP;
1182
1183 /*
1184 * This is as a good a place as any to check f/w capabilities.
1185 */
1186
1187 if (IS_FC(isp)) {
1188 if (ISP_CAP_TMODE(isp) == 0) {
1189 xpt_print(ccb->ccb_h.path, "firmware does not support target mode\n");

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

1242 /*
1243 * Now check to see whether this bus is in target mode already.
1244 *
1245 * If not, a later role change into target mode will finish the job.
1246 */
1247 if (tm_enabled == 0) {
1248 ISP_SET_PC(isp, bus, tm_enable_defer, 1);
1249 ccb->ccb_h.status = CAM_REQ_CMP;
1211 xpt_print(ccb->ccb_h.path, "Target Mode Not Enabled Yet- Lun Enables Deferred\n");
1250 xpt_print(ccb->ccb_h.path, "Target Mode not enabled yet- lun enable deferred\n");
1212 goto done;
1213 }
1214
1215 /*
1216 * Enable the lun.
1217 */
1218 ccb->ccb_h.status = isp_enable_deferred(isp, bus, lun);
1219
1220done:
1251 goto done;
1252 }
1253
1254 /*
1255 * Enable the lun.
1256 */
1257 ccb->ccb_h.status = isp_enable_deferred(isp, bus, lun);
1258
1259done:
1221 if (ccb->ccb_h.status != CAM_REQ_CMP && tptr) {
1222 destroy_lun_state(isp, tptr);
1223 tptr = NULL;
1260 if (ccb->ccb_h.status != CAM_REQ_CMP) {
1261 if (tptr) {
1262 destroy_lun_state(isp, tptr);
1263 tptr = NULL;
1264 }
1265 } else {
1266 tptr->enabled = 1;
1224 }
1225 if (tptr) {
1226 rls_lun_statep(isp, tptr);
1227 }
1267 }
1268 if (tptr) {
1269 rls_lun_statep(isp, tptr);
1270 }
1228 isp->isp_osinfo.tmbusy = 0;
1229 if (isp->isp_osinfo.tmwanted) {
1230 isp->isp_osinfo.tmwanted = 0;
1231 wakeup(isp);
1232 }
1271
1272 /*
1273 * And we're outta here....
1274 */
1275 isp_tmunlk(isp);
1233 xpt_done(ccb);
1234}
1235
1276 xpt_done(ccb);
1277}
1278
1236static void
1279static cam_status
1237isp_enable_deferred_luns(ispsoftc_t *isp, int bus)
1238{
1280isp_enable_deferred_luns(ispsoftc_t *isp, int bus)
1281{
1282 tstate_t *tptr = NULL;
1283 struct tslist *lhp;
1284 int i, n;
1285
1286 ISP_GET_PC(isp, bus, tm_enabled, i);
1287 if (i == 1) {
1288 return (CAM_REQ_CMP);
1289 }
1290 ISP_GET_PC(isp, bus, tm_enable_defer, i);
1291 if (i == 0) {
1292 return (CAM_REQ_CMP);
1293 }
1239 /*
1294 /*
1240 * XXX: not entirely implemented yet
1295 * If this succeeds, it will set tm_enable
1241 */
1296 */
1242 (void) isp_enable_deferred(isp, bus, 0);
1297 if (isp_enable_target_mode(isp, bus)) {
1298 return (CAM_REQ_CMP_ERR);
1299 }
1300 isp_tmlock(isp, "isp_enable_deferred_luns");
1301 for (n = i = 0; i < LUN_HASH_SIZE; i++) {
1302 ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp);
1303 SLIST_FOREACH(tptr, lhp, next) {
1304 tptr->hold++;
1305 if (tptr->enabled == 0) {
1306 if (isp_enable_deferred(isp, bus, xpt_path_lun_id(tptr->owner)) == 0) {
1307 tptr->enabled = 1;
1308 n++;
1309 }
1310 } else {
1311 n++;
1312 }
1313 tptr->hold--;
1314 }
1315 }
1316 isp_tmunlk(isp);
1317 if (n == 0) {
1318 return (CAM_REQ_CMP_ERR);
1319 }
1320 ISP_SET_PC(isp, bus, tm_enable_defer, 0);
1321 return (CAM_REQ_CMP);
1243}
1244
1322}
1323
1245static uint32_t
1324static cam_status
1246isp_enable_deferred(ispsoftc_t *isp, int bus, lun_id_t lun)
1247{
1248 cam_status status;
1325isp_enable_deferred(ispsoftc_t *isp, int bus, lun_id_t lun)
1326{
1327 cam_status status;
1328 int luns_already_enabled = ISP_FC_PC(isp, bus)->tm_luns_enabled;
1249
1250 isp_prt(isp, ISP_LOGTINFO, "%s: bus %d lun %u", __func__, bus, lun);
1329
1330 isp_prt(isp, ISP_LOGTINFO, "%s: bus %d lun %u", __func__, bus, lun);
1251 if (IS_24XX(isp) || (IS_FC(isp) && ISP_FC_PC(isp, bus)->tm_luns_enabled)) {
1331 if (IS_24XX(isp) || (IS_FC(isp) && luns_already_enabled)) {
1252 status = CAM_REQ_CMP;
1253 } else {
1254 int cmd_cnt, not_cnt;
1255
1256 if (IS_23XX(isp)) {
1257 cmd_cnt = DFLT_CMND_CNT;
1258 not_cnt = DFLT_INOT_CNT;
1259 } else {

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

1264 isp->isp_osinfo.rptr = &status;
1265 if (isp_lun_cmd(isp, RQSTYPE_ENABLE_LUN, bus, lun, DFLT_CMND_CNT, DFLT_INOT_CNT)) {
1266 status = CAM_RESRC_UNAVAIL;
1267 } else {
1268 mtx_sleep(&status, &isp->isp_lock, PRIBIO, "isp_enable_deferred", 0);
1269 }
1270 isp->isp_osinfo.rptr = NULL;
1271 }
1332 status = CAM_REQ_CMP;
1333 } else {
1334 int cmd_cnt, not_cnt;
1335
1336 if (IS_23XX(isp)) {
1337 cmd_cnt = DFLT_CMND_CNT;
1338 not_cnt = DFLT_INOT_CNT;
1339 } else {

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

1344 isp->isp_osinfo.rptr = &status;
1345 if (isp_lun_cmd(isp, RQSTYPE_ENABLE_LUN, bus, lun, DFLT_CMND_CNT, DFLT_INOT_CNT)) {
1346 status = CAM_RESRC_UNAVAIL;
1347 } else {
1348 mtx_sleep(&status, &isp->isp_lock, PRIBIO, "isp_enable_deferred", 0);
1349 }
1350 isp->isp_osinfo.rptr = NULL;
1351 }
1272
1273 if (status == CAM_REQ_CMP) {
1274 ISP_SET_PC(isp, bus, tm_luns_enabled, 1);
1352 if (status == CAM_REQ_CMP) {
1353 ISP_SET_PC(isp, bus, tm_luns_enabled, 1);
1275 isp_prt(isp, ISP_LOGTINFO, "bus %d lun %u now enabled for target mode", bus, lun);
1354 isp_prt(isp, ISP_LOGCONFIG|ISP_LOGTINFO, "bus %d lun %u now enabled for target mode", bus, lun);
1276 }
1277 return (status);
1278}
1279
1280static void
1281isp_disable_lun(ispsoftc_t *isp, union ccb *ccb)
1282{
1283 tstate_t *tptr = NULL;
1284 int bus;
1285 cam_status status;
1286 target_id_t target;
1287 lun_id_t lun;
1288
1289 bus = XS_CHANNEL(ccb);
1290 target = ccb->ccb_h.target_id;
1291 lun = ccb->ccb_h.target_lun;
1355 }
1356 return (status);
1357}
1358
1359static void
1360isp_disable_lun(ispsoftc_t *isp, union ccb *ccb)
1361{
1362 tstate_t *tptr = NULL;
1363 int bus;
1364 cam_status status;
1365 target_id_t target;
1366 lun_id_t lun;
1367
1368 bus = XS_CHANNEL(ccb);
1369 target = ccb->ccb_h.target_id;
1370 lun = ccb->ccb_h.target_lun;
1371 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0|ISP_LOGCONFIG, ccb->ccb_h.path, "disabling lun %u\n", lun);
1292 if (target != CAM_TARGET_WILDCARD && target != 0) {
1293 ccb->ccb_h.status = CAM_TID_INVALID;
1294 xpt_done(ccb);
1295 return;
1296 }
1372 if (target != CAM_TARGET_WILDCARD && target != 0) {
1373 ccb->ccb_h.status = CAM_TID_INVALID;
1374 xpt_done(ccb);
1375 return;
1376 }
1377
1297 if (target == CAM_TARGET_WILDCARD && lun != CAM_LUN_WILDCARD) {
1298 ccb->ccb_h.status = CAM_LUN_INVALID;
1299 xpt_done(ccb);
1300 return;
1301 }
1302
1303 if (target != CAM_TARGET_WILDCARD && lun == CAM_LUN_WILDCARD) {
1304 ccb->ccb_h.status = CAM_LUN_INVALID;
1305 xpt_done(ccb);
1306 return;
1307 }
1378 if (target == CAM_TARGET_WILDCARD && lun != CAM_LUN_WILDCARD) {
1379 ccb->ccb_h.status = CAM_LUN_INVALID;
1380 xpt_done(ccb);
1381 return;
1382 }
1383
1384 if (target != CAM_TARGET_WILDCARD && lun == CAM_LUN_WILDCARD) {
1385 ccb->ccb_h.status = CAM_LUN_INVALID;
1386 xpt_done(ccb);
1387 return;
1388 }
1308 if (isp->isp_dblev & ISP_LOGTDEBUG0) {
1309 xpt_print(ccb->ccb_h.path, "enabling lun 0x%x on channel %d\n", lun, bus);
1310 }
1311
1312 /*
1313 * See if we're busy disabling a lun now.
1314 */
1389
1390 /*
1391 * See if we're busy disabling a lun now.
1392 */
1315 while (isp->isp_osinfo.tmbusy) {
1316 isp->isp_osinfo.tmwanted = 1;
1317 mtx_sleep(isp, &isp->isp_lock, PRIBIO, "want_isp_disable_lun", 0);
1318 }
1319 isp->isp_osinfo.tmbusy = 1;
1393 isp_tmlock(isp, "isp_disable_lun");
1320 status = CAM_REQ_INPROG;
1321
1322 /*
1323 * Find the state pointer.
1324 */
1325 if ((tptr = get_lun_statep(isp, bus, lun)) == NULL) {
1326 status = CAM_PATH_INVALID;
1327 goto done;

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

1336 }
1337
1338 /*
1339 * For SCC FW, we only deal with lun zero.
1340 */
1341 if (IS_FC(isp)) {
1342 lun = 0;
1343 }
1394 status = CAM_REQ_INPROG;
1395
1396 /*
1397 * Find the state pointer.
1398 */
1399 if ((tptr = get_lun_statep(isp, bus, lun)) == NULL) {
1400 status = CAM_PATH_INVALID;
1401 goto done;

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

1410 }
1411
1412 /*
1413 * For SCC FW, we only deal with lun zero.
1414 */
1415 if (IS_FC(isp)) {
1416 lun = 0;
1417 }
1344
1345 isp->isp_osinfo.rptr = &status;
1346 if (isp_lun_cmd(isp, RQSTYPE_ENABLE_LUN, bus, lun, 0, 0)) {
1347 status = CAM_RESRC_UNAVAIL;
1348 } else {
1349 mtx_sleep(ccb, &isp->isp_lock, PRIBIO, "isp_disable_lun", 0);
1350 }
1418 isp->isp_osinfo.rptr = &status;
1419 if (isp_lun_cmd(isp, RQSTYPE_ENABLE_LUN, bus, lun, 0, 0)) {
1420 status = CAM_RESRC_UNAVAIL;
1421 } else {
1422 mtx_sleep(ccb, &isp->isp_lock, PRIBIO, "isp_disable_lun", 0);
1423 }
1424 isp->isp_osinfo.rptr = NULL;
1351done:
1425done:
1352 ccb->ccb_h.status = status;
1353 if (status == CAM_REQ_CMP) {
1426 if (status == CAM_REQ_CMP) {
1354 xpt_print(ccb->ccb_h.path, "now disabled for target mode\n");
1427 tptr->enabled = 0;
1428 /*
1429 * If we have no more luns enabled for this bus, delete all tracked wwns for it (if we are FC)
1430 * and disable target mode.
1431 */
1432 if (is_any_lun_enabled(isp, bus) == 0) {
1433 isp_del_all_wwn_entries(isp, bus);
1434 if (isp_disable_target_mode(isp, bus)) {
1435 status = CAM_REQ_CMP_ERR;
1436 }
1437 }
1355 }
1438 }
1356 if (tptr) {
1439 ccb->ccb_h.status = status;
1440 if (status == CAM_REQ_CMP) {
1441 xpt_print(ccb->ccb_h.path, "lun now disabled for target mode\n");
1357 destroy_lun_state(isp, tptr);
1442 destroy_lun_state(isp, tptr);
1443 } else {
1444 if (tptr)
1445 rls_lun_statep(isp, tptr);
1358 }
1446 }
1359 isp->isp_osinfo.rptr = NULL;
1360 isp->isp_osinfo.tmbusy = 0;
1361 if (isp->isp_osinfo.tmwanted) {
1362 isp->isp_osinfo.tmwanted = 0;
1363 wakeup(isp);
1364 }
1447 isp_tmunlk(isp);
1365 xpt_done(ccb);
1366}
1367
1368static int
1369isp_enable_target_mode(ispsoftc_t *isp, int bus)
1370{
1448 xpt_done(ccb);
1449}
1450
1451static int
1452isp_enable_target_mode(ispsoftc_t *isp, int bus)
1453{
1371 int ct;
1454 int tm_enabled;
1372
1455
1373 ISP_GET_PC(isp, bus, tm_enabled, ct);
1374 if (ct != 0) {
1456 ISP_GET_PC(isp, bus, tm_enabled, tm_enabled);
1457 if (tm_enabled != 0) {
1375 return (0);
1376 }
1458 return (0);
1459 }
1377
1378 if (IS_SCSI(isp)) {
1379 mbreg_t mbs;
1460 if (IS_SCSI(isp)) {
1461 mbreg_t mbs;
1380
1381 MBSINIT(&mbs, MBOX_ENABLE_TARGET_MODE, MBLOGALL, 0);
1382 mbs.param[0] = MBOX_ENABLE_TARGET_MODE;
1383 mbs.param[1] = ENABLE_TARGET_FLAG|ENABLE_TQING_FLAG;
1384 mbs.param[2] = bus << 7;
1385 if (isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs) < 0 || mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1462 MBSINIT(&mbs, MBOX_ENABLE_TARGET_MODE, MBLOGALL, 0);
1463 mbs.param[0] = MBOX_ENABLE_TARGET_MODE;
1464 mbs.param[1] = ENABLE_TARGET_FLAG|ENABLE_TQING_FLAG;
1465 mbs.param[2] = bus << 7;
1466 if (isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs) < 0 || mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1386 isp_prt(isp, ISP_LOGERR, "Unable to add Target Role to Bus %d", bus);
1467 isp_prt(isp, ISP_LOGERR, "Unable to enable Target Role on Bus %d", bus);
1387 return (EIO);
1388 }
1468 return (EIO);
1469 }
1389 SDPARAM(isp, bus)->role |= ISP_ROLE_TARGET;
1390 }
1391 ISP_SET_PC(isp, bus, tm_enabled, 1);
1470 }
1471 ISP_SET_PC(isp, bus, tm_enabled, 1);
1392 isp_prt(isp, ISP_LOGINFO, "Target Role added to Bus %d", bus);
1472 isp_prt(isp, ISP_LOGINFO, "Target Role enabled on Bus %d", bus);
1393 return (0);
1394}
1395
1473 return (0);
1474}
1475
1396#ifdef NEEDED
1397static int
1398isp_disable_target_mode(ispsoftc_t *isp, int bus)
1399{
1476static int
1477isp_disable_target_mode(ispsoftc_t *isp, int bus)
1478{
1400 int ct;
1479 int tm_enabled;
1401
1480
1402 ISP_GET_PC(isp, bus, tm_enabled, ct);
1403 if (ct == 0) {
1481 ISP_GET_PC(isp, bus, tm_enabled, tm_enabled);
1482 if (tm_enabled == 0) {
1404 return (0);
1405 }
1483 return (0);
1484 }
1406
1407 if (IS_SCSI(isp)) {
1408 mbreg_t mbs;
1485 if (IS_SCSI(isp)) {
1486 mbreg_t mbs;
1409
1410 MBSINIT(&mbs, MBOX_ENABLE_TARGET_MODE, MBLOGALL, 0);
1411 mbs.param[2] = bus << 7;
1412 if (isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs) < 0 || mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1487 MBSINIT(&mbs, MBOX_ENABLE_TARGET_MODE, MBLOGALL, 0);
1488 mbs.param[2] = bus << 7;
1489 if (isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs) < 0 || mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1413 isp_prt(isp, ISP_LOGERR, "Unable to subtract Target Role to Bus %d", bus);
1490 isp_prt(isp, ISP_LOGERR, "Unable to disable Target Role on Bus %d", bus);
1414 return (EIO);
1415 }
1491 return (EIO);
1492 }
1416 SDPARAM(isp, bus)->role &= ~ISP_ROLE_TARGET;
1417 }
1418 ISP_SET_PC(isp, bus, tm_enabled, 0);
1493 }
1494 ISP_SET_PC(isp, bus, tm_enabled, 0);
1419 isp_prt(isp, ISP_LOGINFO, "Target Role subtracted from Bus %d", bus);
1495 isp_prt(isp, ISP_LOGINFO, "Target Role disabled onon Bus %d", bus);
1420 return (0);
1421}
1496 return (0);
1497}
1422#endif
1423
1424static void
1425isp_ledone(ispsoftc_t *isp, lun_entry_t *lep)
1426{
1427 uint32_t *rptr;
1428
1429 rptr = isp->isp_osinfo.rptr;
1430 if (lep->le_status != LUN_OK) {

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

4434 atio_private_data_t *atp = isp_get_atpd(isp, tptr, ccb->atio.tag_id);
4435 if (atp) {
4436 isp_put_atpd(isp, tptr, atp);
4437 }
4438 }
4439 tptr->atio_count++;
4440 SLIST_INSERT_HEAD(&tptr->atios, &ccb->ccb_h, sim_links.sle);
4441 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "Put FREE ATIO (tag id 0x%x), count now %d\n",
1498
1499static void
1500isp_ledone(ispsoftc_t *isp, lun_entry_t *lep)
1501{
1502 uint32_t *rptr;
1503
1504 rptr = isp->isp_osinfo.rptr;
1505 if (lep->le_status != LUN_OK) {

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

4509 atio_private_data_t *atp = isp_get_atpd(isp, tptr, ccb->atio.tag_id);
4510 if (atp) {
4511 isp_put_atpd(isp, tptr, atp);
4512 }
4513 }
4514 tptr->atio_count++;
4515 SLIST_INSERT_HEAD(&tptr->atios, &ccb->ccb_h, sim_links.sle);
4516 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "Put FREE ATIO (tag id 0x%x), count now %d\n",
4442 ((struct ccb_accept_tio *)ccb)->tag_id, tptr->atio_count);
4517 ccb->atio.tag_id, tptr->atio_count);
4443 } else if (ccb->ccb_h.func_code == XPT_IMMEDIATE_NOTIFY) {
4444 if (ccb->cin1.tag_id) {
4445 inot_private_data_t *ntp = isp_find_ntpd(isp, tptr, ccb->cin1.tag_id, ccb->cin1.seq_id);
4446 if (ntp) {
4447 isp_put_ntpd(isp, tptr, ntp);
4448 }
4449 }
4450 tptr->inot_count++;
4451 SLIST_INSERT_HEAD(&tptr->inots, &ccb->ccb_h, sim_links.sle);
4452 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "Put FREE INOT, (seq id 0x%x) count now %d\n",
4518 } else if (ccb->ccb_h.func_code == XPT_IMMEDIATE_NOTIFY) {
4519 if (ccb->cin1.tag_id) {
4520 inot_private_data_t *ntp = isp_find_ntpd(isp, tptr, ccb->cin1.tag_id, ccb->cin1.seq_id);
4521 if (ntp) {
4522 isp_put_ntpd(isp, tptr, ntp);
4523 }
4524 }
4525 tptr->inot_count++;
4526 SLIST_INSERT_HEAD(&tptr->inots, &ccb->ccb_h, sim_links.sle);
4527 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "Put FREE INOT, (seq id 0x%x) count now %d\n",
4453 ((struct ccb_immediate_notify *)ccb)->seq_id, tptr->inot_count);
4528 ccb->cin1.seq_id, tptr->inot_count);
4454 } else if (ccb->ccb_h.func_code == XPT_IMMED_NOTIFY) {
4455 tptr->inot_count++;
4456 SLIST_INSERT_HEAD(&tptr->inots, &ccb->ccb_h, sim_links.sle);
4457 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "Put FREE INOT, (seq id 0x%x) count now %d\n",
4529 } else if (ccb->ccb_h.func_code == XPT_IMMED_NOTIFY) {
4530 tptr->inot_count++;
4531 SLIST_INSERT_HEAD(&tptr->inots, &ccb->ccb_h, sim_links.sle);
4532 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "Put FREE INOT, (seq id 0x%x) count now %d\n",
4458 ((struct ccb_immediate_notify *)ccb)->seq_id, tptr->inot_count);
4533 ccb->cin1.seq_id, tptr->inot_count);
4459 }
4460 rls_lun_statep(isp, tptr);
4461 ccb->ccb_h.status = CAM_REQ_INPROG;
4462 break;
4463 }
4464 case XPT_NOTIFY_ACK:
4465 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4466 break;

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

4733 xpt_done(ccb);
4734 break;
4735
4736 case XPT_SET_SIM_KNOB: /* Set SIM knobs */
4737 {
4738 struct ccb_sim_knob *kp = &ccb->knob;
4739 fcparam *fcp;
4740
4534 }
4535 rls_lun_statep(isp, tptr);
4536 ccb->ccb_h.status = CAM_REQ_INPROG;
4537 break;
4538 }
4539 case XPT_NOTIFY_ACK:
4540 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4541 break;

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

4808 xpt_done(ccb);
4809 break;
4810
4811 case XPT_SET_SIM_KNOB: /* Set SIM knobs */
4812 {
4813 struct ccb_sim_knob *kp = &ccb->knob;
4814 fcparam *fcp;
4815
4741
4742 if (!IS_FC(isp)) {
4743 ccb->ccb_h.status = CAM_REQ_INVALID;
4744 xpt_done(ccb);
4745 break;
4746 }
4747
4748 bus = cam_sim_bus(xpt_path_sim(kp->ccb_h.path));
4749 fcp = FCPARAM(isp, bus);

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

4791 * so don't allow it.
4792 */
4793 isp_prt(isp, ISP_LOGERR, "cannot support dual role at present");
4794 ccb->ccb_h.status = CAM_REQ_INVALID;
4795#endif
4796 break;
4797 }
4798 if (rchange) {
4816 if (!IS_FC(isp)) {
4817 ccb->ccb_h.status = CAM_REQ_INVALID;
4818 xpt_done(ccb);
4819 break;
4820 }
4821
4822 bus = cam_sim_bus(xpt_path_sim(kp->ccb_h.path));
4823 fcp = FCPARAM(isp, bus);

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

4865 * so don't allow it.
4866 */
4867 isp_prt(isp, ISP_LOGERR, "cannot support dual role at present");
4868 ccb->ccb_h.status = CAM_REQ_INVALID;
4869#endif
4870 break;
4871 }
4872 if (rchange) {
4873 ISP_PATH_PRT(isp, ISP_LOGCONFIG, ccb->ccb_h.path, "changing role on from %d to %d\n", fcp->role, newrole);
4799 if (isp_fc_change_role(isp, bus, newrole) != 0) {
4800 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4801#ifdef ISP_TARGET_MODE
4802 } else if (newrole == ISP_ROLE_TARGET || newrole == ISP_ROLE_BOTH) {
4874 if (isp_fc_change_role(isp, bus, newrole) != 0) {
4875 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4876#ifdef ISP_TARGET_MODE
4877 } else if (newrole == ISP_ROLE_TARGET || newrole == ISP_ROLE_BOTH) {
4803 isp_enable_deferred_luns(isp, bus);
4878 ccb->ccb_h.status = isp_enable_deferred_luns(isp, bus);
4804#endif
4805 }
4806 }
4807 }
4808 xpt_done(ccb);
4809 break;
4810 }
4879#endif
4880 }
4881 }
4882 }
4883 xpt_done(ccb);
4884 break;
4885 }
4811 case XPT_GET_SIM_KNOB: /* Set SIM knobs */
4886 case XPT_GET_SIM_KNOB: /* Get SIM knobs */
4812 {
4813 struct ccb_sim_knob *kp = &ccb->knob;
4814
4815 if (IS_FC(isp)) {
4816 fcparam *fcp;
4817
4818 bus = cam_sim_bus(xpt_path_sim(kp->ccb_h.path));
4819 fcp = FCPARAM(isp, bus);

--- 919 unchanged lines hidden ---
4887 {
4888 struct ccb_sim_knob *kp = &ccb->knob;
4889
4890 if (IS_FC(isp)) {
4891 fcparam *fcp;
4892
4893 bus = cam_sim_bus(xpt_path_sim(kp->ccb_h.path));
4894 fcp = FCPARAM(isp, bus);

--- 919 unchanged lines hidden ---