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 --- |