ctl.c (268690) | ctl.c (268692) |
---|---|
1/*- 2 * Copyright (c) 2003-2009 Silicon Graphics International Corp. 3 * Copyright (c) 2012 The FreeBSD Foundation 4 * All rights reserved. 5 * 6 * Portions of this software were developed by Edward Tomasz Napierala 7 * under sponsorship from the FreeBSD Foundation. 8 * --- 28 unchanged lines hidden (view full) --- 37 * CAM Target Layer, a SCSI device emulation subsystem. 38 * 39 * Author: Ken Merry <ken@FreeBSD.org> 40 */ 41 42#define _CTL_C 43 44#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2003-2009 Silicon Graphics International Corp. 3 * Copyright (c) 2012 The FreeBSD Foundation 4 * All rights reserved. 5 * 6 * Portions of this software were developed by Edward Tomasz Napierala 7 * under sponsorship from the FreeBSD Foundation. 8 * --- 28 unchanged lines hidden (view full) --- 37 * CAM Target Layer, a SCSI device emulation subsystem. 38 * 39 * Author: Ken Merry <ken@FreeBSD.org> 40 */ 41 42#define _CTL_C 43 44#include <sys/cdefs.h> |
45__FBSDID("$FreeBSD: stable/10/sys/cam/ctl/ctl.c 268690 2014-07-15 17:12:37Z mav $"); | 45__FBSDID("$FreeBSD: stable/10/sys/cam/ctl/ctl.c 268692 2014-07-15 17:14:53Z mav $"); |
46 47#include <sys/param.h> 48#include <sys/systm.h> 49#include <sys/kernel.h> 50#include <sys/types.h> 51#include <sys/kthread.h> 52#include <sys/bio.h> 53#include <sys/fcntl.h> --- 1032 unchanged lines hidden (view full) --- 1086 ctl_pool_free(emergency_pool); 1087 ctl_pool_free(other_pool); 1088 return (error); 1089 } 1090 if (bootverbose) 1091 printf("ctl: CAM Target Layer loaded\n"); 1092 1093 /* | 46 47#include <sys/param.h> 48#include <sys/systm.h> 49#include <sys/kernel.h> 50#include <sys/types.h> 51#include <sys/kthread.h> 52#include <sys/bio.h> 53#include <sys/fcntl.h> --- 1032 unchanged lines hidden (view full) --- 1086 ctl_pool_free(emergency_pool); 1087 ctl_pool_free(other_pool); 1088 return (error); 1089 } 1090 if (bootverbose) 1091 printf("ctl: CAM Target Layer loaded\n"); 1092 1093 /* |
1094 * Initialize the initiator and portname mappings 1095 */ 1096 memset(softc->wwpn_iid, 0, sizeof(softc->wwpn_iid)); 1097 1098 /* | |
1099 * Initialize the ioctl front end. 1100 */ 1101 ctl_frontend_register(&ioctl_frontend); 1102 port = &softc->ioctl_info.port; 1103 port->frontend = &ioctl_frontend; 1104 sprintf(softc->ioctl_info.port_name, "ioctl"); 1105 port->port_type = CTL_PORT_IOCTL; 1106 port->num_requested_ctl_io = 100; --- 255 unchanged lines hidden (view full) --- 1362 1363 ioctl_info = (struct ctl_ioctl_info *)arg; 1364 1365 ioctl_info->flags &= ~CTL_IOCTL_FLAG_ENABLED; 1366} 1367 1368/* 1369 * Remove an initiator by port number and initiator ID. | 1094 * Initialize the ioctl front end. 1095 */ 1096 ctl_frontend_register(&ioctl_frontend); 1097 port = &softc->ioctl_info.port; 1098 port->frontend = &ioctl_frontend; 1099 sprintf(softc->ioctl_info.port_name, "ioctl"); 1100 port->port_type = CTL_PORT_IOCTL; 1101 port->num_requested_ctl_io = 100; --- 255 unchanged lines hidden (view full) --- 1357 1358 ioctl_info = (struct ctl_ioctl_info *)arg; 1359 1360 ioctl_info->flags &= ~CTL_IOCTL_FLAG_ENABLED; 1361} 1362 1363/* 1364 * Remove an initiator by port number and initiator ID. |
1370 * Returns 0 for success, 1 for failure. | 1365 * Returns 0 for success, -1 for failure. |
1371 */ 1372int | 1366 */ 1367int |
1373ctl_remove_initiator(int32_t targ_port, uint32_t iid) | 1368ctl_remove_initiator(struct ctl_port *port, int iid) |
1374{ | 1369{ |
1375 struct ctl_softc *softc; | 1370 struct ctl_softc *softc = control_softc; |
1376 | 1371 |
1377 softc = control_softc; 1378 | |
1379 mtx_assert(&softc->ctl_lock, MA_NOTOWNED); 1380 | 1372 mtx_assert(&softc->ctl_lock, MA_NOTOWNED); 1373 |
1381 if ((targ_port < 0) 1382 || (targ_port > CTL_MAX_PORTS)) { 1383 printf("%s: invalid port number %d\n", __func__, targ_port); 1384 return (1); 1385 } | |
1386 if (iid > CTL_MAX_INIT_PER_PORT) { 1387 printf("%s: initiator ID %u > maximun %u!\n", 1388 __func__, iid, CTL_MAX_INIT_PER_PORT); | 1374 if (iid > CTL_MAX_INIT_PER_PORT) { 1375 printf("%s: initiator ID %u > maximun %u!\n", 1376 __func__, iid, CTL_MAX_INIT_PER_PORT); |
1389 return (1); | 1377 return (-1); |
1390 } 1391 1392 mtx_lock(&softc->ctl_lock); | 1378 } 1379 1380 mtx_lock(&softc->ctl_lock); |
1393 1394 softc->wwpn_iid[targ_port][iid].in_use = 0; 1395 | 1381 port->wwpn_iid[iid].in_use--; 1382 port->wwpn_iid[iid].last_use = time_uptime; |
1396 mtx_unlock(&softc->ctl_lock); 1397 1398 return (0); 1399} 1400 1401/* 1402 * Add an initiator to the initiator map. | 1383 mtx_unlock(&softc->ctl_lock); 1384 1385 return (0); 1386} 1387 1388/* 1389 * Add an initiator to the initiator map. |
1403 * Returns 0 for success, 1 for failure. | 1390 * Returns iid for success, < 0 for failure. |
1404 */ 1405int | 1391 */ 1392int |
1406ctl_add_initiator(uint64_t wwpn, int32_t targ_port, uint32_t iid) | 1393ctl_add_initiator(struct ctl_port *port, int iid, uint64_t wwpn, char *name) |
1407{ | 1394{ |
1408 struct ctl_softc *softc; 1409 int retval; | 1395 struct ctl_softc *softc = control_softc; 1396 time_t best_time; 1397 int i, best; |
1410 | 1398 |
1411 softc = control_softc; 1412 | |
1413 mtx_assert(&softc->ctl_lock, MA_NOTOWNED); 1414 | 1399 mtx_assert(&softc->ctl_lock, MA_NOTOWNED); 1400 |
1415 retval = 0; 1416 1417 if ((targ_port < 0) 1418 || (targ_port > CTL_MAX_PORTS)) { 1419 printf("%s: invalid port number %d\n", __func__, targ_port); 1420 return (1); 1421 } 1422 if (iid > CTL_MAX_INIT_PER_PORT) { 1423 printf("%s: WWPN %#jx initiator ID %u > maximun %u!\n", | 1401 if (iid >= CTL_MAX_INIT_PER_PORT) { 1402 printf("%s: WWPN %#jx initiator ID %u > maximum %u!\n", |
1424 __func__, wwpn, iid, CTL_MAX_INIT_PER_PORT); | 1403 __func__, wwpn, iid, CTL_MAX_INIT_PER_PORT); |
1425 return (1); | 1404 free(name, M_CTL); 1405 return (-1); |
1426 } 1427 1428 mtx_lock(&softc->ctl_lock); 1429 | 1406 } 1407 1408 mtx_lock(&softc->ctl_lock); 1409 |
1430 if (softc->wwpn_iid[targ_port][iid].in_use != 0) { | 1410 if (iid < 0 && (wwpn != 0 || name != NULL)) { 1411 for (i = 0; i < CTL_MAX_INIT_PER_PORT; i++) { 1412 if (wwpn != 0 && wwpn == port->wwpn_iid[i].wwpn) { 1413 iid = i; 1414 break; 1415 } 1416 if (name != NULL && port->wwpn_iid[i].name != NULL && 1417 strcmp(name, port->wwpn_iid[i].name) == 0) { 1418 iid = i; 1419 break; 1420 } 1421 } 1422 } 1423 1424 if (iid < 0) { 1425 for (i = 0; i < CTL_MAX_INIT_PER_PORT; i++) { 1426 if (port->wwpn_iid[i].in_use == 0 && 1427 port->wwpn_iid[i].wwpn == 0 && 1428 port->wwpn_iid[i].name == NULL) { 1429 iid = i; 1430 break; 1431 } 1432 } 1433 } 1434 1435 if (iid < 0) { 1436 best = -1; 1437 best_time = INT32_MAX; 1438 for (i = 0; i < CTL_MAX_INIT_PER_PORT; i++) { 1439 if (port->wwpn_iid[i].in_use == 0) { 1440 if (port->wwpn_iid[i].last_use < best_time) { 1441 best = i; 1442 best_time = port->wwpn_iid[i].last_use; 1443 } 1444 } 1445 } 1446 iid = best; 1447 } 1448 1449 if (iid < 0) { 1450 mtx_unlock(&softc->ctl_lock); 1451 free(name, M_CTL); 1452 return (-2); 1453 } 1454 1455 if (port->wwpn_iid[iid].in_use > 0 && (wwpn != 0 || name != NULL)) { |
1431 /* | 1456 /* |
1432 * We don't treat this as an error. | 1457 * This is not an error yet. |
1433 */ | 1458 */ |
1434 if (softc->wwpn_iid[targ_port][iid].wwpn == wwpn) { 1435 printf("%s: port %d iid %u WWPN %#jx arrived again?\n", 1436 __func__, targ_port, iid, (uintmax_t)wwpn); 1437 goto bailout; | 1459 if (wwpn != 0 && wwpn == port->wwpn_iid[iid].wwpn) { 1460#if 0 1461 printf("%s: port %d iid %u WWPN %#jx arrived" 1462 " again\n", __func__, port->targ_port, 1463 iid, (uintmax_t)wwpn); 1464#endif 1465 goto take; |
1438 } | 1466 } |
1467 if (name != NULL && port->wwpn_iid[iid].name != NULL && 1468 strcmp(name, port->wwpn_iid[iid].name) == 0) { 1469#if 0 1470 printf("%s: port %d iid %u name '%s' arrived" 1471 " again\n", __func__, port->targ_port, 1472 iid, name); 1473#endif 1474 goto take; 1475 } |
|
1439 1440 /* 1441 * This is an error, but what do we do about it? The 1442 * driver is telling us we have a new WWPN for this 1443 * initiator ID, so we pretty much need to use it. 1444 */ | 1476 1477 /* 1478 * This is an error, but what do we do about it? The 1479 * driver is telling us we have a new WWPN for this 1480 * initiator ID, so we pretty much need to use it. 1481 */ |
1445 printf("%s: port %d iid %u WWPN %#jx arrived, WWPN %#jx is " 1446 "still at that address\n", __func__, targ_port, iid, 1447 (uintmax_t)wwpn, 1448 (uintmax_t)softc->wwpn_iid[targ_port][iid].wwpn); | 1482 printf("%s: port %d iid %u WWPN %#jx '%s' arrived," 1483 " but WWPN %#jx '%s' is still at that address\n", 1484 __func__, port->targ_port, iid, wwpn, name, 1485 (uintmax_t)port->wwpn_iid[iid].wwpn, 1486 port->wwpn_iid[iid].name); |
1449 1450 /* 1451 * XXX KDM clear have_ca and ua_pending on each LUN for 1452 * this initiator. 1453 */ 1454 } | 1487 1488 /* 1489 * XXX KDM clear have_ca and ua_pending on each LUN for 1490 * this initiator. 1491 */ 1492 } |
1455 softc->wwpn_iid[targ_port][iid].in_use = 1; 1456 softc->wwpn_iid[targ_port][iid].iid = iid; 1457 softc->wwpn_iid[targ_port][iid].wwpn = wwpn; 1458 softc->wwpn_iid[targ_port][iid].port = targ_port; 1459 1460bailout: 1461 | 1493take: 1494 free(port->wwpn_iid[iid].name, M_CTL); 1495 port->wwpn_iid[iid].name = name; 1496 port->wwpn_iid[iid].wwpn = wwpn; 1497 port->wwpn_iid[iid].in_use++; |
1462 mtx_unlock(&softc->ctl_lock); 1463 | 1498 mtx_unlock(&softc->ctl_lock); 1499 |
1464 return (retval); | 1500 return (iid); |
1465} 1466 1467static int 1468ctl_ioctl_lun_enable(void *arg, struct ctl_id targ_id, int lun_id) 1469{ 1470 return (0); 1471} 1472 --- 1396 unchanged lines hidden (view full) --- 2869 "error serial %ju on LUN %u\n", __func__, 2870 delete_desc->serial, delete_desc->lun_id); 2871 retval = EINVAL; 2872 break; 2873 } 2874 break; 2875 } 2876 case CTL_DUMP_STRUCTS: { | 1501} 1502 1503static int 1504ctl_ioctl_lun_enable(void *arg, struct ctl_id targ_id, int lun_id) 1505{ 1506 return (0); 1507} 1508 --- 1396 unchanged lines hidden (view full) --- 2905 "error serial %ju on LUN %u\n", __func__, 2906 delete_desc->serial, delete_desc->lun_id); 2907 retval = EINVAL; 2908 break; 2909 } 2910 break; 2911 } 2912 case CTL_DUMP_STRUCTS: { |
2877 int i, j, k; | 2913 int i, j, k, idx; |
2878 struct ctl_port *port; 2879 struct ctl_frontend *fe; 2880 | 2914 struct ctl_port *port; 2915 struct ctl_frontend *fe; 2916 |
2881 printf("CTL IID to WWPN map start:\n"); 2882 for (i = 0; i < CTL_MAX_PORTS; i++) { 2883 for (j = 0; j < CTL_MAX_INIT_PER_PORT; j++) { 2884 if (softc->wwpn_iid[i][j].in_use == 0) 2885 continue; 2886 2887 printf("port %d iid %u WWPN %#jx\n", 2888 softc->wwpn_iid[i][j].port, 2889 softc->wwpn_iid[i][j].iid, 2890 (uintmax_t)softc->wwpn_iid[i][j].wwpn); 2891 } 2892 } 2893 printf("CTL IID to WWPN map end\n"); | 2917 mtx_lock(&softc->ctl_lock); |
2894 printf("CTL Persistent Reservation information start:\n"); 2895 for (i = 0; i < CTL_MAX_LUNS; i++) { 2896 struct ctl_lun *lun; 2897 2898 lun = softc->ctl_luns[i]; 2899 2900 if ((lun == NULL) 2901 || ((lun->flags & CTL_LUN_DISABLED) != 0)) 2902 continue; 2903 2904 for (j = 0; j < (CTL_MAX_PORTS * 2); j++) { 2905 for (k = 0; k < CTL_MAX_INIT_PER_PORT; k++){ | 2918 printf("CTL Persistent Reservation information start:\n"); 2919 for (i = 0; i < CTL_MAX_LUNS; i++) { 2920 struct ctl_lun *lun; 2921 2922 lun = softc->ctl_luns[i]; 2923 2924 if ((lun == NULL) 2925 || ((lun->flags & CTL_LUN_DISABLED) != 0)) 2926 continue; 2927 2928 for (j = 0; j < (CTL_MAX_PORTS * 2); j++) { 2929 for (k = 0; k < CTL_MAX_INIT_PER_PORT; k++){ |
2906 if (lun->per_res[j+k].registered == 0) | 2930 idx = j * CTL_MAX_INIT_PER_PORT + k; 2931 if (lun->per_res[idx].registered == 0) |
2907 continue; | 2932 continue; |
2908 printf("LUN %d port %d iid %d key " | 2933 printf(" LUN %d port %d iid %d key " |
2909 "%#jx\n", i, j, k, 2910 (uintmax_t)scsi_8btou64( | 2934 "%#jx\n", i, j, k, 2935 (uintmax_t)scsi_8btou64( |
2911 lun->per_res[j+k].res_key.key)); | 2936 lun->per_res[idx].res_key.key)); |
2912 } 2913 } 2914 } 2915 printf("CTL Persistent Reservation information end\n"); 2916 printf("CTL Ports:\n"); | 2937 } 2938 } 2939 } 2940 printf("CTL Persistent Reservation information end\n"); 2941 printf("CTL Ports:\n"); |
2917 /* 2918 * XXX KDM calling this without a lock. We'd likely want 2919 * to drop the lock before calling the frontend's dump 2920 * routine anyway. 2921 */ | |
2922 STAILQ_FOREACH(port, &softc->port_list, links) { | 2942 STAILQ_FOREACH(port, &softc->port_list, links) { |
2923 printf("Port %s Frontend %s Type %u pport %d vport %d WWNN " 2924 "%#jx WWPN %#jx\n", port->port_name, | 2943 printf(" Port %d '%s' Frontend '%s' Type %u pp %d vp %d WWNN " 2944 "%#jx WWPN %#jx\n", port->targ_port, port->port_name, |
2925 port->frontend->name, port->port_type, 2926 port->physical_port, port->virtual_port, 2927 (uintmax_t)port->wwnn, (uintmax_t)port->wwpn); | 2945 port->frontend->name, port->port_type, 2946 port->physical_port, port->virtual_port, 2947 (uintmax_t)port->wwnn, (uintmax_t)port->wwpn); |
2948 for (j = 0; j < CTL_MAX_INIT_PER_PORT; j++) { 2949 if (port->wwpn_iid[j].in_use == 0 && 2950 port->wwpn_iid[j].wwpn == 0 && 2951 port->wwpn_iid[j].name == NULL) 2952 continue; 2953 2954 printf(" iid %u use %d WWPN %#jx '%s'\n", 2955 j, port->wwpn_iid[j].in_use, 2956 (uintmax_t)port->wwpn_iid[j].wwpn, 2957 port->wwpn_iid[j].name); 2958 } |
|
2928 } 2929 printf("CTL Port information end\n"); | 2959 } 2960 printf("CTL Port information end\n"); |
2961 mtx_unlock(&softc->ctl_lock); 2962 /* 2963 * XXX KDM calling this without a lock. We'd likely want 2964 * to drop the lock before calling the frontend's dump 2965 * routine anyway. 2966 */ |
|
2930 printf("CTL Frontends:\n"); 2931 STAILQ_FOREACH(fe, &softc->fe_list, links) { | 2967 printf("CTL Frontends:\n"); 2968 STAILQ_FOREACH(fe, &softc->fe_list, links) { |
2932 printf("Frontend %s\n", fe->name); | 2969 printf(" Frontend '%s'\n", fe->name); |
2933 if (fe->fe_dump != NULL) 2934 fe->fe_dump(); 2935 } 2936 printf("CTL Frontend information end\n"); 2937 break; 2938 } 2939 case CTL_LUN_REQ: { 2940 struct ctl_lun_req *lun_req; --- 10992 unchanged lines hidden --- | 2970 if (fe->fe_dump != NULL) 2971 fe->fe_dump(); 2972 } 2973 printf("CTL Frontend information end\n"); 2974 break; 2975 } 2976 case CTL_LUN_REQ: { 2977 struct ctl_lun_req *lun_req; --- 10992 unchanged lines hidden --- |