aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/fusion/mptsas.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/message/fusion/mptsas.c')
-rw-r--r--drivers/message/fusion/mptsas.c404
1 files changed, 346 insertions, 58 deletions
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index 17e9757e728b..5a06d8d8694e 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * Copyright (c) 1999-2005 LSI Logic Corporation 6 * Copyright (c) 1999-2005 LSI Logic Corporation
7 * (mailto:mpt_linux_developer@lsil.com) 7 * (mailto:mpt_linux_developer@lsil.com)
8 * Copyright (c) 2005 Dell 8 * Copyright (c) 2005-2006 Dell
9 */ 9 */
10/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 10/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
11/* 11/*
@@ -86,6 +86,24 @@ static int mptsasInternalCtx = -1; /* Used only for internal commands */
86static int mptsasMgmtCtx = -1; 86static int mptsasMgmtCtx = -1;
87 87
88 88
89enum mptsas_hotplug_action {
90 MPTSAS_ADD_DEVICE,
91 MPTSAS_DEL_DEVICE,
92};
93
94struct mptsas_hotplug_event {
95 struct work_struct work;
96 MPT_ADAPTER *ioc;
97 enum mptsas_hotplug_action event_type;
98 u64 sas_address;
99 u32 channel;
100 u32 id;
101 u32 device_info;
102 u16 handle;
103 u16 parent_handle;
104 u8 phy_id;
105};
106
89/* 107/*
90 * SAS topology structures 108 * SAS topology structures
91 * 109 *
@@ -99,8 +117,8 @@ struct mptsas_devinfo {
99 u8 phy_id; /* phy number of parent device */ 117 u8 phy_id; /* phy number of parent device */
100 u8 port_id; /* sas physical port this device 118 u8 port_id; /* sas physical port this device
101 is assoc'd with */ 119 is assoc'd with */
102 u8 target; /* logical target id of this device */ 120 u8 id; /* logical target id of this device */
103 u8 bus; /* logical bus number of this device */ 121 u8 channel; /* logical bus number of this device */
104 u64 sas_address; /* WWN of this device, 122 u64 sas_address; /* WWN of this device,
105 SATA is assigned by HBA,expander */ 123 SATA is assigned by HBA,expander */
106 u32 device_info; /* bitfield detailed info about this device */ 124 u32 device_info; /* bitfield detailed info about this device */
@@ -114,6 +132,7 @@ struct mptsas_phyinfo {
114 u8 programmed_link_rate; /* programmed max/min phy link rate */ 132 u8 programmed_link_rate; /* programmed max/min phy link rate */
115 struct mptsas_devinfo identify; /* point to phy device info */ 133 struct mptsas_devinfo identify; /* point to phy device info */
116 struct mptsas_devinfo attached; /* point to attached device info */ 134 struct mptsas_devinfo attached; /* point to attached device info */
135 struct sas_phy *phy;
117 struct sas_rphy *rphy; 136 struct sas_rphy *rphy;
118}; 137};
119 138
@@ -239,13 +258,12 @@ mptsas_slave_alloc(struct scsi_device *sdev)
239 struct scsi_target *starget; 258 struct scsi_target *starget;
240 int i; 259 int i;
241 260
242 vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL); 261 vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
243 if (!vdev) { 262 if (!vdev) {
244 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n", 263 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
245 hd->ioc->name, sizeof(VirtDevice)); 264 hd->ioc->name, sizeof(VirtDevice));
246 return -ENOMEM; 265 return -ENOMEM;
247 } 266 }
248 memset(vdev, 0, sizeof(VirtDevice));
249 vdev->ioc_id = hd->ioc->id; 267 vdev->ioc_id = hd->ioc->id;
250 sdev->hostdata = vdev; 268 sdev->hostdata = vdev;
251 starget = scsi_target(sdev); 269 starget = scsi_target(sdev);
@@ -256,19 +274,32 @@ mptsas_slave_alloc(struct scsi_device *sdev)
256 hd->Targets[sdev->id] = vtarget; 274 hd->Targets[sdev->id] = vtarget;
257 } 275 }
258 276
277 /*
278 RAID volumes placed beyond the last expected port.
279 */
280 if (sdev->channel == hd->ioc->num_ports) {
281 vdev->target_id = sdev->id;
282 vdev->bus_id = 0;
283 vdev->lun = 0;
284 goto out;
285 }
286
259 rphy = dev_to_rphy(sdev->sdev_target->dev.parent); 287 rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
288 mutex_lock(&hd->ioc->sas_topology_mutex);
260 list_for_each_entry(p, &hd->ioc->sas_topology, list) { 289 list_for_each_entry(p, &hd->ioc->sas_topology, list) {
261 for (i = 0; i < p->num_phys; i++) { 290 for (i = 0; i < p->num_phys; i++) {
262 if (p->phy_info[i].attached.sas_address == 291 if (p->phy_info[i].attached.sas_address ==
263 rphy->identify.sas_address) { 292 rphy->identify.sas_address) {
264 vdev->target_id = 293 vdev->target_id =
265 p->phy_info[i].attached.target; 294 p->phy_info[i].attached.id;
266 vdev->bus_id = p->phy_info[i].attached.bus; 295 vdev->bus_id = p->phy_info[i].attached.channel;
267 vdev->lun = sdev->lun; 296 vdev->lun = sdev->lun;
297 mutex_unlock(&hd->ioc->sas_topology_mutex);
268 goto out; 298 goto out;
269 } 299 }
270 } 300 }
271 } 301 }
302 mutex_unlock(&hd->ioc->sas_topology_mutex);
272 303
273 printk("No matching SAS device found!!\n"); 304 printk("No matching SAS device found!!\n");
274 kfree(vdev); 305 kfree(vdev);
@@ -282,6 +313,42 @@ mptsas_slave_alloc(struct scsi_device *sdev)
282 return 0; 313 return 0;
283} 314}
284 315
316static void
317mptsas_slave_destroy(struct scsi_device *sdev)
318{
319 struct Scsi_Host *host = sdev->host;
320 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
321 struct sas_rphy *rphy;
322 struct mptsas_portinfo *p;
323 int i;
324
325 /*
326 * Handle hotplug removal case.
327 * We need to clear out attached data structure.
328 */
329 rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
330
331 mutex_lock(&hd->ioc->sas_topology_mutex);
332 list_for_each_entry(p, &hd->ioc->sas_topology, list) {
333 for (i = 0; i < p->num_phys; i++) {
334 if (p->phy_info[i].attached.sas_address ==
335 rphy->identify.sas_address) {
336 memset(&p->phy_info[i].attached, 0,
337 sizeof(struct mptsas_devinfo));
338 p->phy_info[i].rphy = NULL;
339 goto out;
340 }
341 }
342 }
343
344 out:
345 mutex_unlock(&hd->ioc->sas_topology_mutex);
346 /*
347 * TODO: Issue target reset to flush firmware outstanding commands.
348 */
349 mptscsih_slave_destroy(sdev);
350}
351
285static struct scsi_host_template mptsas_driver_template = { 352static struct scsi_host_template mptsas_driver_template = {
286 .module = THIS_MODULE, 353 .module = THIS_MODULE,
287 .proc_name = "mptsas", 354 .proc_name = "mptsas",
@@ -293,7 +360,7 @@ static struct scsi_host_template mptsas_driver_template = {
293 .slave_alloc = mptsas_slave_alloc, 360 .slave_alloc = mptsas_slave_alloc,
294 .slave_configure = mptscsih_slave_configure, 361 .slave_configure = mptscsih_slave_configure,
295 .target_destroy = mptscsih_target_destroy, 362 .target_destroy = mptscsih_target_destroy,
296 .slave_destroy = mptscsih_slave_destroy, 363 .slave_destroy = mptsas_slave_destroy,
297 .change_queue_depth = mptscsih_change_queue_depth, 364 .change_queue_depth = mptscsih_change_queue_depth,
298 .eh_abort_handler = mptscsih_abort, 365 .eh_abort_handler = mptscsih_abort,
299 .eh_device_reset_handler = mptscsih_dev_reset, 366 .eh_device_reset_handler = mptscsih_dev_reset,
@@ -399,7 +466,7 @@ static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
399 if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP) 466 if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
400 return -ENXIO; 467 return -ENXIO;
401 468
402 if (down_interruptible(&ioc->sas_mgmt.mutex)) 469 if (mutex_lock_interruptible(&ioc->sas_mgmt.mutex))
403 goto out; 470 goto out;
404 471
405 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc); 472 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
@@ -450,7 +517,7 @@ static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
450 error = 0; 517 error = 0;
451 518
452 out_unlock: 519 out_unlock:
453 up(&ioc->sas_mgmt.mutex); 520 mutex_unlock(&ioc->sas_mgmt.mutex);
454 out: 521 out:
455 return error; 522 return error;
456} 523}
@@ -649,8 +716,8 @@ mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
649 device_info->handle = le16_to_cpu(buffer->DevHandle); 716 device_info->handle = le16_to_cpu(buffer->DevHandle);
650 device_info->phy_id = buffer->PhyNum; 717 device_info->phy_id = buffer->PhyNum;
651 device_info->port_id = buffer->PhysicalPort; 718 device_info->port_id = buffer->PhysicalPort;
652 device_info->target = buffer->TargetID; 719 device_info->id = buffer->TargetID;
653 device_info->bus = buffer->Bus; 720 device_info->channel = buffer->Bus;
654 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64)); 721 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
655 device_info->sas_address = le64_to_cpu(sas_address); 722 device_info->sas_address = le64_to_cpu(sas_address);
656 device_info->device_info = 723 device_info->device_info =
@@ -858,36 +925,36 @@ mptsas_parse_device_info(struct sas_identify *identify,
858static int mptsas_probe_one_phy(struct device *dev, 925static int mptsas_probe_one_phy(struct device *dev,
859 struct mptsas_phyinfo *phy_info, int index, int local) 926 struct mptsas_phyinfo *phy_info, int index, int local)
860{ 927{
861 struct sas_phy *port; 928 struct sas_phy *phy;
862 int error; 929 int error;
863 930
864 port = sas_phy_alloc(dev, index); 931 phy = sas_phy_alloc(dev, index);
865 if (!port) 932 if (!phy)
866 return -ENOMEM; 933 return -ENOMEM;
867 934
868 port->port_identifier = phy_info->port_id; 935 phy->port_identifier = phy_info->port_id;
869 mptsas_parse_device_info(&port->identify, &phy_info->identify); 936 mptsas_parse_device_info(&phy->identify, &phy_info->identify);
870 937
871 /* 938 /*
872 * Set Negotiated link rate. 939 * Set Negotiated link rate.
873 */ 940 */
874 switch (phy_info->negotiated_link_rate) { 941 switch (phy_info->negotiated_link_rate) {
875 case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED: 942 case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
876 port->negotiated_linkrate = SAS_PHY_DISABLED; 943 phy->negotiated_linkrate = SAS_PHY_DISABLED;
877 break; 944 break;
878 case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION: 945 case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
879 port->negotiated_linkrate = SAS_LINK_RATE_FAILED; 946 phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;
880 break; 947 break;
881 case MPI_SAS_IOUNIT0_RATE_1_5: 948 case MPI_SAS_IOUNIT0_RATE_1_5:
882 port->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS; 949 phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
883 break; 950 break;
884 case MPI_SAS_IOUNIT0_RATE_3_0: 951 case MPI_SAS_IOUNIT0_RATE_3_0:
885 port->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS; 952 phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
886 break; 953 break;
887 case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE: 954 case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
888 case MPI_SAS_IOUNIT0_RATE_UNKNOWN: 955 case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
889 default: 956 default:
890 port->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN; 957 phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
891 break; 958 break;
892 } 959 }
893 960
@@ -896,10 +963,10 @@ static int mptsas_probe_one_phy(struct device *dev,
896 */ 963 */
897 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) { 964 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
898 case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5: 965 case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
899 port->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS; 966 phy->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
900 break; 967 break;
901 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0: 968 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
902 port->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS; 969 phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
903 break; 970 break;
904 default: 971 default:
905 break; 972 break;
@@ -911,10 +978,10 @@ static int mptsas_probe_one_phy(struct device *dev,
911 switch (phy_info->programmed_link_rate & 978 switch (phy_info->programmed_link_rate &
912 MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) { 979 MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
913 case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5: 980 case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
914 port->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS; 981 phy->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
915 break; 982 break;
916 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0: 983 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
917 port->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS; 984 phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
918 break; 985 break;
919 default: 986 default:
920 break; 987 break;
@@ -925,10 +992,10 @@ static int mptsas_probe_one_phy(struct device *dev,
925 */ 992 */
926 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) { 993 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
927 case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5: 994 case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
928 port->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS; 995 phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
929 break; 996 break;
930 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0: 997 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
931 port->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS; 998 phy->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
932 break; 999 break;
933 default: 1000 default:
934 break; 1001 break;
@@ -940,28 +1007,29 @@ static int mptsas_probe_one_phy(struct device *dev,
940 switch (phy_info->programmed_link_rate & 1007 switch (phy_info->programmed_link_rate &
941 MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) { 1008 MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
942 case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5: 1009 case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
943 port->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS; 1010 phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
944 break; 1011 break;
945 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0: 1012 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
946 port->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS; 1013 phy->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
947 break; 1014 break;
948 default: 1015 default:
949 break; 1016 break;
950 } 1017 }
951 1018
952 if (local) 1019 if (local)
953 port->local_attached = 1; 1020 phy->local_attached = 1;
954 1021
955 error = sas_phy_add(port); 1022 error = sas_phy_add(phy);
956 if (error) { 1023 if (error) {
957 sas_phy_free(port); 1024 sas_phy_free(phy);
958 return error; 1025 return error;
959 } 1026 }
1027 phy_info->phy = phy;
960 1028
961 if (phy_info->attached.handle) { 1029 if (phy_info->attached.handle) {
962 struct sas_rphy *rphy; 1030 struct sas_rphy *rphy;
963 1031
964 rphy = sas_rphy_alloc(port); 1032 rphy = sas_rphy_alloc(phy);
965 if (!rphy) 1033 if (!rphy)
966 return 0; /* non-fatal: an rphy can be added later */ 1034 return 0; /* non-fatal: an rphy can be added later */
967 1035
@@ -985,16 +1053,19 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index)
985 u32 handle = 0xFFFF; 1053 u32 handle = 0xFFFF;
986 int error = -ENOMEM, i; 1054 int error = -ENOMEM, i;
987 1055
988 port_info = kmalloc(sizeof(*port_info), GFP_KERNEL); 1056 port_info = kzalloc(sizeof(*port_info), GFP_KERNEL);
989 if (!port_info) 1057 if (!port_info)
990 goto out; 1058 goto out;
991 memset(port_info, 0, sizeof(*port_info));
992 1059
993 error = mptsas_sas_io_unit_pg0(ioc, port_info); 1060 error = mptsas_sas_io_unit_pg0(ioc, port_info);
994 if (error) 1061 if (error)
995 goto out_free_port_info; 1062 goto out_free_port_info;
996 1063
1064 ioc->num_ports = port_info->num_phys;
1065 mutex_lock(&ioc->sas_topology_mutex);
997 list_add_tail(&port_info->list, &ioc->sas_topology); 1066 list_add_tail(&port_info->list, &ioc->sas_topology);
1067 mutex_unlock(&ioc->sas_topology_mutex);
1068
998 for (i = 0; i < port_info->num_phys; i++) { 1069 for (i = 0; i < port_info->num_phys; i++) {
999 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i], 1070 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
1000 (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER << 1071 (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
@@ -1034,10 +1105,9 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
1034 struct mptsas_portinfo *port_info, *p; 1105 struct mptsas_portinfo *port_info, *p;
1035 int error = -ENOMEM, i, j; 1106 int error = -ENOMEM, i, j;
1036 1107
1037 port_info = kmalloc(sizeof(*port_info), GFP_KERNEL); 1108 port_info = kzalloc(sizeof(*port_info), GFP_KERNEL);
1038 if (!port_info) 1109 if (!port_info)
1039 goto out; 1110 goto out;
1040 memset(port_info, 0, sizeof(*port_info));
1041 1111
1042 error = mptsas_sas_expander_pg0(ioc, port_info, 1112 error = mptsas_sas_expander_pg0(ioc, port_info,
1043 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE << 1113 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
@@ -1047,7 +1117,10 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
1047 1117
1048 *handle = port_info->handle; 1118 *handle = port_info->handle;
1049 1119
1120 mutex_lock(&ioc->sas_topology_mutex);
1050 list_add_tail(&port_info->list, &ioc->sas_topology); 1121 list_add_tail(&port_info->list, &ioc->sas_topology);
1122 mutex_unlock(&ioc->sas_topology_mutex);
1123
1051 for (i = 0; i < port_info->num_phys; i++) { 1124 for (i = 0; i < port_info->num_phys; i++) {
1052 struct device *parent; 1125 struct device *parent;
1053 1126
@@ -1079,6 +1152,7 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
1079 * HBA phys. 1152 * HBA phys.
1080 */ 1153 */
1081 parent = &ioc->sh->shost_gendev; 1154 parent = &ioc->sh->shost_gendev;
1155 mutex_lock(&ioc->sas_topology_mutex);
1082 list_for_each_entry(p, &ioc->sas_topology, list) { 1156 list_for_each_entry(p, &ioc->sas_topology, list) {
1083 for (j = 0; j < p->num_phys; j++) { 1157 for (j = 0; j < p->num_phys; j++) {
1084 if (port_info->phy_info[i].identify.handle == 1158 if (port_info->phy_info[i].identify.handle ==
@@ -1086,6 +1160,7 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
1086 parent = &p->phy_info[j].rphy->dev; 1160 parent = &p->phy_info[j].rphy->dev;
1087 } 1161 }
1088 } 1162 }
1163 mutex_unlock(&ioc->sas_topology_mutex);
1089 1164
1090 mptsas_probe_one_phy(parent, &port_info->phy_info[i], 1165 mptsas_probe_one_phy(parent, &port_info->phy_info[i],
1091 *index, 0); 1166 *index, 0);
@@ -1111,6 +1186,211 @@ mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
1111 ; 1186 ;
1112} 1187}
1113 1188
1189static struct mptsas_phyinfo *
1190mptsas_find_phyinfo_by_parent(MPT_ADAPTER *ioc, u16 parent_handle, u8 phy_id)
1191{
1192 struct mptsas_portinfo *port_info;
1193 struct mptsas_devinfo device_info;
1194 struct mptsas_phyinfo *phy_info = NULL;
1195 int i, error;
1196
1197 /*
1198 * Retrieve the parent sas_address
1199 */
1200 error = mptsas_sas_device_pg0(ioc, &device_info,
1201 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1202 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1203 parent_handle);
1204 if (error) {
1205 printk("mptsas: failed to retrieve device page\n");
1206 return NULL;
1207 }
1208
1209 /*
1210 * The phy_info structures are never deallocated during lifetime of
1211 * a host, so the code below is safe without additional refcounting.
1212 */
1213 mutex_lock(&ioc->sas_topology_mutex);
1214 list_for_each_entry(port_info, &ioc->sas_topology, list) {
1215 for (i = 0; i < port_info->num_phys; i++) {
1216 if (port_info->phy_info[i].identify.sas_address ==
1217 device_info.sas_address &&
1218 port_info->phy_info[i].phy_id == phy_id) {
1219 phy_info = &port_info->phy_info[i];
1220 break;
1221 }
1222 }
1223 }
1224 mutex_unlock(&ioc->sas_topology_mutex);
1225
1226 return phy_info;
1227}
1228
1229static struct mptsas_phyinfo *
1230mptsas_find_phyinfo_by_handle(MPT_ADAPTER *ioc, u16 handle)
1231{
1232 struct mptsas_portinfo *port_info;
1233 struct mptsas_phyinfo *phy_info = NULL;
1234 int i;
1235
1236 /*
1237 * The phy_info structures are never deallocated during lifetime of
1238 * a host, so the code below is safe without additional refcounting.
1239 */
1240 mutex_lock(&ioc->sas_topology_mutex);
1241 list_for_each_entry(port_info, &ioc->sas_topology, list) {
1242 for (i = 0; i < port_info->num_phys; i++) {
1243 if (port_info->phy_info[i].attached.handle == handle) {
1244 phy_info = &port_info->phy_info[i];
1245 break;
1246 }
1247 }
1248 }
1249 mutex_unlock(&ioc->sas_topology_mutex);
1250
1251 return phy_info;
1252}
1253
1254static void
1255mptsas_hotplug_work(void *arg)
1256{
1257 struct mptsas_hotplug_event *ev = arg;
1258 MPT_ADAPTER *ioc = ev->ioc;
1259 struct mptsas_phyinfo *phy_info;
1260 struct sas_rphy *rphy;
1261 char *ds = NULL;
1262
1263 if (ev->device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET)
1264 ds = "ssp";
1265 if (ev->device_info & MPI_SAS_DEVICE_INFO_STP_TARGET)
1266 ds = "stp";
1267 if (ev->device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1268 ds = "sata";
1269
1270 switch (ev->event_type) {
1271 case MPTSAS_DEL_DEVICE:
1272 printk(MYIOC_s_INFO_FMT
1273 "removing %s device, channel %d, id %d, phy %d\n",
1274 ioc->name, ds, ev->channel, ev->id, ev->phy_id);
1275
1276 phy_info = mptsas_find_phyinfo_by_handle(ioc, ev->handle);
1277 if (!phy_info) {
1278 printk("mptsas: remove event for non-existant PHY.\n");
1279 break;
1280 }
1281
1282 if (phy_info->rphy) {
1283 sas_rphy_delete(phy_info->rphy);
1284 phy_info->rphy = NULL;
1285 }
1286 break;
1287 case MPTSAS_ADD_DEVICE:
1288 printk(MYIOC_s_INFO_FMT
1289 "attaching %s device, channel %d, id %d, phy %d\n",
1290 ioc->name, ds, ev->channel, ev->id, ev->phy_id);
1291
1292 phy_info = mptsas_find_phyinfo_by_parent(ioc,
1293 ev->parent_handle, ev->phy_id);
1294 if (!phy_info) {
1295 printk("mptsas: add event for non-existant PHY.\n");
1296 break;
1297 }
1298
1299 if (phy_info->rphy) {
1300 printk("mptsas: trying to add existing device.\n");
1301 break;
1302 }
1303
1304 /* fill attached info */
1305 phy_info->attached.handle = ev->handle;
1306 phy_info->attached.phy_id = ev->phy_id;
1307 phy_info->attached.port_id = phy_info->identify.port_id;
1308 phy_info->attached.id = ev->id;
1309 phy_info->attached.channel = ev->channel;
1310 phy_info->attached.sas_address = ev->sas_address;
1311 phy_info->attached.device_info = ev->device_info;
1312
1313 rphy = sas_rphy_alloc(phy_info->phy);
1314 if (!rphy)
1315 break; /* non-fatal: an rphy can be added later */
1316
1317 mptsas_parse_device_info(&rphy->identify, &phy_info->attached);
1318 if (sas_rphy_add(rphy)) {
1319 sas_rphy_free(rphy);
1320 break;
1321 }
1322
1323 phy_info->rphy = rphy;
1324 break;
1325 }
1326
1327 kfree(ev);
1328}
1329
1330static void
1331mptscsih_send_sas_event(MPT_ADAPTER *ioc,
1332 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
1333{
1334 struct mptsas_hotplug_event *ev;
1335 u32 device_info = le32_to_cpu(sas_event_data->DeviceInfo);
1336 __le64 sas_address;
1337
1338 if ((device_info &
1339 (MPI_SAS_DEVICE_INFO_SSP_TARGET |
1340 MPI_SAS_DEVICE_INFO_STP_TARGET |
1341 MPI_SAS_DEVICE_INFO_SATA_DEVICE )) == 0)
1342 return;
1343
1344 if ((sas_event_data->ReasonCode &
1345 (MPI_EVENT_SAS_DEV_STAT_RC_ADDED |
1346 MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING)) == 0)
1347 return;
1348
1349 ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
1350 if (!ev) {
1351 printk(KERN_WARNING "mptsas: lost hotplug event\n");
1352 return;
1353 }
1354
1355
1356 INIT_WORK(&ev->work, mptsas_hotplug_work, ev);
1357 ev->ioc = ioc;
1358 ev->handle = le16_to_cpu(sas_event_data->DevHandle);
1359 ev->parent_handle = le16_to_cpu(sas_event_data->ParentDevHandle);
1360 ev->channel = sas_event_data->Bus;
1361 ev->id = sas_event_data->TargetID;
1362 ev->phy_id = sas_event_data->PhyNum;
1363 memcpy(&sas_address, &sas_event_data->SASAddress, sizeof(__le64));
1364 ev->sas_address = le64_to_cpu(sas_address);
1365 ev->device_info = device_info;
1366
1367 if (sas_event_data->ReasonCode & MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
1368 ev->event_type = MPTSAS_ADD_DEVICE;
1369 else
1370 ev->event_type = MPTSAS_DEL_DEVICE;
1371
1372 schedule_work(&ev->work);
1373}
1374
1375static int
1376mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
1377{
1378 u8 event = le32_to_cpu(reply->Event) & 0xFF;
1379
1380 if (!ioc->sh)
1381 return 1;
1382
1383 switch (event) {
1384 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
1385 mptscsih_send_sas_event(ioc,
1386 (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data);
1387 return 1; /* currently means nothing really */
1388
1389 default:
1390 return mptscsih_event_process(ioc, reply);
1391 }
1392}
1393
1114static int 1394static int
1115mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) 1395mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1116{ 1396{
@@ -1118,11 +1398,10 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1118 MPT_SCSI_HOST *hd; 1398 MPT_SCSI_HOST *hd;
1119 MPT_ADAPTER *ioc; 1399 MPT_ADAPTER *ioc;
1120 unsigned long flags; 1400 unsigned long flags;
1121 int sz, ii; 1401 int ii;
1122 int numSGE = 0; 1402 int numSGE = 0;
1123 int scale; 1403 int scale;
1124 int ioc_cap; 1404 int ioc_cap;
1125 u8 *mem;
1126 int error=0; 1405 int error=0;
1127 int r; 1406 int r;
1128 1407
@@ -1203,7 +1482,9 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1203 sh->unique_id = ioc->id; 1482 sh->unique_id = ioc->id;
1204 1483
1205 INIT_LIST_HEAD(&ioc->sas_topology); 1484 INIT_LIST_HEAD(&ioc->sas_topology);
1206 init_MUTEX(&ioc->sas_mgmt.mutex); 1485 mutex_init(&ioc->sas_topology_mutex);
1486
1487 mutex_init(&ioc->sas_mgmt.mutex);
1207 init_completion(&ioc->sas_mgmt.done); 1488 init_completion(&ioc->sas_mgmt.done);
1208 1489
1209 /* Verify that we won't exceed the maximum 1490 /* Verify that we won't exceed the maximum
@@ -1244,36 +1525,27 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1244 /* SCSI needs scsi_cmnd lookup table! 1525 /* SCSI needs scsi_cmnd lookup table!
1245 * (with size equal to req_depth*PtrSz!) 1526 * (with size equal to req_depth*PtrSz!)
1246 */ 1527 */
1247 sz = ioc->req_depth * sizeof(void *); 1528 hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
1248 mem = kmalloc(sz, GFP_ATOMIC); 1529 if (!hd->ScsiLookup) {
1249 if (mem == NULL) {
1250 error = -ENOMEM; 1530 error = -ENOMEM;
1251 goto out_mptsas_probe; 1531 goto out_mptsas_probe;
1252 } 1532 }
1253 1533
1254 memset(mem, 0, sz); 1534 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n",
1255 hd->ScsiLookup = (struct scsi_cmnd **) mem; 1535 ioc->name, hd->ScsiLookup));
1256
1257 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
1258 ioc->name, hd->ScsiLookup, sz));
1259 1536
1260 /* Allocate memory for the device structures. 1537 /* Allocate memory for the device structures.
1261 * A non-Null pointer at an offset 1538 * A non-Null pointer at an offset
1262 * indicates a device exists. 1539 * indicates a device exists.
1263 * max_id = 1 + maximum id (hosts.h) 1540 * max_id = 1 + maximum id (hosts.h)
1264 */ 1541 */
1265 sz = sh->max_id * sizeof(void *); 1542 hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC);
1266 mem = kmalloc(sz, GFP_ATOMIC); 1543 if (!hd->Targets) {
1267 if (mem == NULL) {
1268 error = -ENOMEM; 1544 error = -ENOMEM;
1269 goto out_mptsas_probe; 1545 goto out_mptsas_probe;
1270 } 1546 }
1271 1547
1272 memset(mem, 0, sz); 1548 dprintk((KERN_INFO " vtarget @ %p\n", hd->Targets));
1273 hd->Targets = (VirtTarget **) mem;
1274
1275 dprintk((KERN_INFO
1276 " vtarget @ %p, sz=%d\n", hd->Targets, sz));
1277 1549
1278 /* Clear the TM flags 1550 /* Clear the TM flags
1279 */ 1551 */
@@ -1324,6 +1596,20 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1324 1596
1325 mptsas_scan_sas_topology(ioc); 1597 mptsas_scan_sas_topology(ioc);
1326 1598
1599 /*
1600 Reporting RAID volumes.
1601 */
1602 if (!ioc->raid_data.pIocPg2)
1603 return 0;
1604 if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
1605 return 0;
1606 for (ii=0;ii<ioc->raid_data.pIocPg2->NumActiveVolumes;ii++) {
1607 scsi_add_device(sh,
1608 ioc->num_ports,
1609 ioc->raid_data.pIocPg2->RaidVolume[ii].VolumeID,
1610 0);
1611 }
1612
1327 return 0; 1613 return 0;
1328 1614
1329out_mptsas_probe: 1615out_mptsas_probe:
@@ -1339,10 +1625,12 @@ static void __devexit mptsas_remove(struct pci_dev *pdev)
1339 1625
1340 sas_remove_host(ioc->sh); 1626 sas_remove_host(ioc->sh);
1341 1627
1628 mutex_lock(&ioc->sas_topology_mutex);
1342 list_for_each_entry_safe(p, n, &ioc->sas_topology, list) { 1629 list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
1343 list_del(&p->list); 1630 list_del(&p->list);
1344 kfree(p); 1631 kfree(p);
1345 } 1632 }
1633 mutex_unlock(&ioc->sas_topology_mutex);
1346 1634
1347 mptscsih_remove(pdev); 1635 mptscsih_remove(pdev);
1348} 1636}
@@ -1393,7 +1681,7 @@ mptsas_init(void)
1393 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER); 1681 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
1394 mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER); 1682 mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
1395 1683
1396 if (mpt_event_register(mptsasDoneCtx, mptscsih_event_process) == 0) { 1684 if (mpt_event_register(mptsasDoneCtx, mptsas_event_process) == 0) {
1397 devtprintk((KERN_INFO MYNAM 1685 devtprintk((KERN_INFO MYNAM
1398 ": Registered for IOC event notifications\n")); 1686 ": Registered for IOC event notifications\n"));
1399 } 1687 }