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.c818
1 files changed, 641 insertions, 177 deletions
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index 2512d0e6155e..010d4a39269b 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -104,6 +104,13 @@ struct mptsas_hotplug_event {
104 u16 handle; 104 u16 handle;
105 u16 parent_handle; 105 u16 parent_handle;
106 u8 phy_id; 106 u8 phy_id;
107 u8 phys_disk_num;
108 u8 phys_disk_num_valid;
109};
110
111struct mptsas_discovery_event {
112 struct work_struct work;
113 MPT_ADAPTER *ioc;
107}; 114};
108 115
109/* 116/*
@@ -117,6 +124,8 @@ struct mptsas_hotplug_event {
117struct mptsas_devinfo { 124struct mptsas_devinfo {
118 u16 handle; /* unique id to address this device */ 125 u16 handle; /* unique id to address this device */
119 u16 handle_parent; /* unique id to address parent device */ 126 u16 handle_parent; /* unique id to address parent device */
127 u16 handle_enclosure; /* enclosure identifier of the enclosure */
128 u16 slot; /* physical slot in enclosure */
120 u8 phy_id; /* phy number of parent device */ 129 u8 phy_id; /* phy number of parent device */
121 u8 port_id; /* sas physical port this device 130 u8 port_id; /* sas physical port this device
122 is assoc'd with */ 131 is assoc'd with */
@@ -137,6 +146,7 @@ struct mptsas_phyinfo {
137 struct mptsas_devinfo attached; /* point to attached device info */ 146 struct mptsas_devinfo attached; /* point to attached device info */
138 struct sas_phy *phy; 147 struct sas_phy *phy;
139 struct sas_rphy *rphy; 148 struct sas_rphy *rphy;
149 struct scsi_target *starget;
140}; 150};
141 151
142struct mptsas_portinfo { 152struct mptsas_portinfo {
@@ -146,6 +156,17 @@ struct mptsas_portinfo {
146 struct mptsas_phyinfo *phy_info; 156 struct mptsas_phyinfo *phy_info;
147}; 157};
148 158
159struct mptsas_enclosure {
160 u64 enclosure_logical_id; /* The WWN for the enclosure */
161 u16 enclosure_handle; /* unique id to address this */
162 u16 flags; /* details enclosure management */
163 u16 num_slot; /* num slots */
164 u16 start_slot; /* first slot */
165 u8 start_id; /* starting logical target id */
166 u8 start_channel; /* starting logical channel id */
167 u8 sep_id; /* SEP device logical target id */
168 u8 sep_channel; /* SEP channel logical channel id */
169};
149 170
150#ifdef SASDEBUG 171#ifdef SASDEBUG
151static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA *phy_data) 172static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
@@ -205,6 +226,7 @@ static void mptsas_print_device_pg0(SasDevicePage0_t *pg0)
205 226
206 printk("---- SAS DEVICE PAGE 0 ---------\n"); 227 printk("---- SAS DEVICE PAGE 0 ---------\n");
207 printk("Handle=0x%X\n" ,le16_to_cpu(pg0->DevHandle)); 228 printk("Handle=0x%X\n" ,le16_to_cpu(pg0->DevHandle));
229 printk("Parent Handle=0x%X\n" ,le16_to_cpu(pg0->ParentDevHandle));
208 printk("Enclosure Handle=0x%X\n", le16_to_cpu(pg0->EnclosureHandle)); 230 printk("Enclosure Handle=0x%X\n", le16_to_cpu(pg0->EnclosureHandle));
209 printk("Slot=0x%X\n", le16_to_cpu(pg0->Slot)); 231 printk("Slot=0x%X\n", le16_to_cpu(pg0->Slot));
210 printk("SAS Address=0x%llX\n", le64_to_cpu(sas_address)); 232 printk("SAS Address=0x%llX\n", le64_to_cpu(sas_address));
@@ -243,6 +265,111 @@ static void mptsas_print_expander_pg1(SasExpanderPage1_t *pg1)
243#define mptsas_print_expander_pg1(pg1) do { } while (0) 265#define mptsas_print_expander_pg1(pg1) do { } while (0)
244#endif 266#endif
245 267
268static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
269{
270 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
271 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
272}
273
274static inline MPT_ADAPTER *rphy_to_ioc(struct sas_rphy *rphy)
275{
276 struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
277 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
278}
279
280/*
281 * mptsas_find_portinfo_by_handle
282 *
283 * This function should be called with the sas_topology_mutex already held
284 */
285static struct mptsas_portinfo *
286mptsas_find_portinfo_by_handle(MPT_ADAPTER *ioc, u16 handle)
287{
288 struct mptsas_portinfo *port_info, *rc=NULL;
289 int i;
290
291 list_for_each_entry(port_info, &ioc->sas_topology, list)
292 for (i = 0; i < port_info->num_phys; i++)
293 if (port_info->phy_info[i].identify.handle == handle) {
294 rc = port_info;
295 goto out;
296 }
297 out:
298 return rc;
299}
300
301static int
302mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
303 u32 form, u32 form_specific)
304{
305 ConfigExtendedPageHeader_t hdr;
306 CONFIGPARMS cfg;
307 SasEnclosurePage0_t *buffer;
308 dma_addr_t dma_handle;
309 int error;
310 __le64 le_identifier;
311
312 memset(&hdr, 0, sizeof(hdr));
313 hdr.PageVersion = MPI_SASENCLOSURE0_PAGEVERSION;
314 hdr.PageNumber = 0;
315 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
316 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_ENCLOSURE;
317
318 cfg.cfghdr.ehdr = &hdr;
319 cfg.physAddr = -1;
320 cfg.pageAddr = form + form_specific;
321 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
322 cfg.dir = 0; /* read */
323 cfg.timeout = 10;
324
325 error = mpt_config(ioc, &cfg);
326 if (error)
327 goto out;
328 if (!hdr.ExtPageLength) {
329 error = -ENXIO;
330 goto out;
331 }
332
333 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
334 &dma_handle);
335 if (!buffer) {
336 error = -ENOMEM;
337 goto out;
338 }
339
340 cfg.physAddr = dma_handle;
341 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
342
343 error = mpt_config(ioc, &cfg);
344 if (error)
345 goto out_free_consistent;
346
347 /* save config data */
348 memcpy(&le_identifier, &buffer->EnclosureLogicalID, sizeof(__le64));
349 enclosure->enclosure_logical_id = le64_to_cpu(le_identifier);
350 enclosure->enclosure_handle = le16_to_cpu(buffer->EnclosureHandle);
351 enclosure->flags = le16_to_cpu(buffer->Flags);
352 enclosure->num_slot = le16_to_cpu(buffer->NumSlots);
353 enclosure->start_slot = le16_to_cpu(buffer->StartSlot);
354 enclosure->start_id = buffer->StartTargetID;
355 enclosure->start_channel = buffer->StartBus;
356 enclosure->sep_id = buffer->SEPTargetID;
357 enclosure->sep_channel = buffer->SEPBus;
358
359 out_free_consistent:
360 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
361 buffer, dma_handle);
362 out:
363 return error;
364}
365
366static int
367mptsas_slave_configure(struct scsi_device *sdev)
368{
369 sas_read_port_mode_page(sdev);
370
371 return mptscsih_slave_configure(sdev);
372}
246 373
247/* 374/*
248 * This is pretty ugly. We will be able to seriously clean it up 375 * This is pretty ugly. We will be able to seriously clean it up
@@ -259,6 +386,7 @@ mptsas_slave_alloc(struct scsi_device *sdev)
259 VirtTarget *vtarget; 386 VirtTarget *vtarget;
260 VirtDevice *vdev; 387 VirtDevice *vdev;
261 struct scsi_target *starget; 388 struct scsi_target *starget;
389 u32 target_id;
262 int i; 390 int i;
263 391
264 vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL); 392 vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
@@ -267,10 +395,10 @@ mptsas_slave_alloc(struct scsi_device *sdev)
267 hd->ioc->name, sizeof(VirtDevice)); 395 hd->ioc->name, sizeof(VirtDevice));
268 return -ENOMEM; 396 return -ENOMEM;
269 } 397 }
270 vdev->ioc_id = hd->ioc->id;
271 sdev->hostdata = vdev; 398 sdev->hostdata = vdev;
272 starget = scsi_target(sdev); 399 starget = scsi_target(sdev);
273 vtarget = starget->hostdata; 400 vtarget = starget->hostdata;
401 vtarget->ioc_id = hd->ioc->id;
274 vdev->vtarget = vtarget; 402 vdev->vtarget = vtarget;
275 if (vtarget->num_luns == 0) { 403 if (vtarget->num_luns == 0) {
276 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY; 404 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY;
@@ -281,8 +409,8 @@ mptsas_slave_alloc(struct scsi_device *sdev)
281 RAID volumes placed beyond the last expected port. 409 RAID volumes placed beyond the last expected port.
282 */ 410 */
283 if (sdev->channel == hd->ioc->num_ports) { 411 if (sdev->channel == hd->ioc->num_ports) {
284 vdev->target_id = sdev->id; 412 target_id = sdev->id;
285 vdev->bus_id = 0; 413 vtarget->bus_id = 0;
286 vdev->lun = 0; 414 vdev->lun = 0;
287 goto out; 415 goto out;
288 } 416 }
@@ -293,11 +421,21 @@ mptsas_slave_alloc(struct scsi_device *sdev)
293 for (i = 0; i < p->num_phys; i++) { 421 for (i = 0; i < p->num_phys; i++) {
294 if (p->phy_info[i].attached.sas_address == 422 if (p->phy_info[i].attached.sas_address ==
295 rphy->identify.sas_address) { 423 rphy->identify.sas_address) {
296 vdev->target_id = 424 target_id = p->phy_info[i].attached.id;
297 p->phy_info[i].attached.id; 425 vtarget->bus_id = p->phy_info[i].attached.channel;
298 vdev->bus_id = p->phy_info[i].attached.channel;
299 vdev->lun = sdev->lun; 426 vdev->lun = sdev->lun;
300 mutex_unlock(&hd->ioc->sas_topology_mutex); 427 p->phy_info[i].starget = sdev->sdev_target;
428 /*
429 * Exposing hidden disk (RAID)
430 */
431 if (mptscsih_is_phys_disk(hd->ioc, target_id)) {
432 target_id = mptscsih_raid_id_to_num(hd,
433 target_id);
434 vdev->vtarget->tflags |=
435 MPT_TARGET_FLAGS_RAID_COMPONENT;
436 sdev->no_uld_attach = 1;
437 }
438 mutex_unlock(&hd->ioc->sas_topology_mutex);
301 goto out; 439 goto out;
302 } 440 }
303 } 441 }
@@ -308,9 +446,7 @@ mptsas_slave_alloc(struct scsi_device *sdev)
308 return -ENXIO; 446 return -ENXIO;
309 447
310 out: 448 out:
311 vtarget->ioc_id = vdev->ioc_id; 449 vtarget->target_id = target_id;
312 vtarget->target_id = vdev->target_id;
313 vtarget->bus_id = vdev->bus_id;
314 vtarget->num_luns++; 450 vtarget->num_luns++;
315 return 0; 451 return 0;
316} 452}
@@ -320,41 +456,17 @@ mptsas_slave_destroy(struct scsi_device *sdev)
320{ 456{
321 struct Scsi_Host *host = sdev->host; 457 struct Scsi_Host *host = sdev->host;
322 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; 458 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
323 struct sas_rphy *rphy;
324 struct mptsas_portinfo *p;
325 int i;
326 VirtDevice *vdev; 459 VirtDevice *vdev;
327 460
328 /* 461 /*
329 * Handle hotplug removal case.
330 * We need to clear out attached data structure.
331 */
332 rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
333
334 mutex_lock(&hd->ioc->sas_topology_mutex);
335 list_for_each_entry(p, &hd->ioc->sas_topology, list) {
336 for (i = 0; i < p->num_phys; i++) {
337 if (p->phy_info[i].attached.sas_address ==
338 rphy->identify.sas_address) {
339 memset(&p->phy_info[i].attached, 0,
340 sizeof(struct mptsas_devinfo));
341 p->phy_info[i].rphy = NULL;
342 goto out;
343 }
344 }
345 }
346
347 out:
348 mutex_unlock(&hd->ioc->sas_topology_mutex);
349 /*
350 * Issue target reset to flush firmware outstanding commands. 462 * Issue target reset to flush firmware outstanding commands.
351 */ 463 */
352 vdev = sdev->hostdata; 464 vdev = sdev->hostdata;
353 if (vdev->configured_lun){ 465 if (vdev->configured_lun){
354 if (mptscsih_TMHandler(hd, 466 if (mptscsih_TMHandler(hd,
355 MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 467 MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
356 vdev->bus_id, 468 vdev->vtarget->bus_id,
357 vdev->target_id, 469 vdev->vtarget->target_id,
358 0, 0, 5 /* 5 second timeout */) 470 0, 0, 5 /* 5 second timeout */)
359 < 0){ 471 < 0){
360 472
@@ -364,7 +476,7 @@ mptsas_slave_destroy(struct scsi_device *sdev)
364 printk(MYIOC_s_WARN_FMT 476 printk(MYIOC_s_WARN_FMT
365 "Error processing TaskMgmt id=%d TARGET_RESET\n", 477 "Error processing TaskMgmt id=%d TARGET_RESET\n",
366 hd->ioc->name, 478 hd->ioc->name,
367 vdev->target_id); 479 vdev->vtarget->target_id);
368 480
369 hd->tmPending = 0; 481 hd->tmPending = 0;
370 hd->tmState = TM_STATE_NONE; 482 hd->tmState = TM_STATE_NONE;
@@ -382,7 +494,7 @@ static struct scsi_host_template mptsas_driver_template = {
382 .queuecommand = mptscsih_qcmd, 494 .queuecommand = mptscsih_qcmd,
383 .target_alloc = mptscsih_target_alloc, 495 .target_alloc = mptscsih_target_alloc,
384 .slave_alloc = mptsas_slave_alloc, 496 .slave_alloc = mptsas_slave_alloc,
385 .slave_configure = mptscsih_slave_configure, 497 .slave_configure = mptsas_slave_configure,
386 .target_destroy = mptscsih_target_destroy, 498 .target_destroy = mptscsih_target_destroy,
387 .slave_destroy = mptsas_slave_destroy, 499 .slave_destroy = mptsas_slave_destroy,
388 .change_queue_depth = mptscsih_change_queue_depth, 500 .change_queue_depth = mptscsih_change_queue_depth,
@@ -399,12 +511,6 @@ static struct scsi_host_template mptsas_driver_template = {
399 .use_clustering = ENABLE_CLUSTERING, 511 .use_clustering = ENABLE_CLUSTERING,
400}; 512};
401 513
402static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
403{
404 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
405 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
406}
407
408static int mptsas_get_linkerrors(struct sas_phy *phy) 514static int mptsas_get_linkerrors(struct sas_phy *phy)
409{ 515{
410 MPT_ADAPTER *ioc = phy_to_ioc(phy); 516 MPT_ADAPTER *ioc = phy_to_ioc(phy);
@@ -546,8 +652,67 @@ static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
546 return error; 652 return error;
547} 653}
548 654
655static int
656mptsas_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
657{
658 MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
659 int i, error;
660 struct mptsas_portinfo *p;
661 struct mptsas_enclosure enclosure_info;
662 u64 enclosure_handle;
663
664 mutex_lock(&ioc->sas_topology_mutex);
665 list_for_each_entry(p, &ioc->sas_topology, list) {
666 for (i = 0; i < p->num_phys; i++) {
667 if (p->phy_info[i].attached.sas_address ==
668 rphy->identify.sas_address) {
669 enclosure_handle = p->phy_info[i].
670 attached.handle_enclosure;
671 goto found_info;
672 }
673 }
674 }
675 mutex_unlock(&ioc->sas_topology_mutex);
676 return -ENXIO;
677
678 found_info:
679 mutex_unlock(&ioc->sas_topology_mutex);
680 memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
681 error = mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
682 (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
683 MPI_SAS_ENCLOS_PGAD_FORM_SHIFT), enclosure_handle);
684 if (!error)
685 *identifier = enclosure_info.enclosure_logical_id;
686 return error;
687}
688
689static int
690mptsas_get_bay_identifier(struct sas_rphy *rphy)
691{
692 MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
693 struct mptsas_portinfo *p;
694 int i, rc;
695
696 mutex_lock(&ioc->sas_topology_mutex);
697 list_for_each_entry(p, &ioc->sas_topology, list) {
698 for (i = 0; i < p->num_phys; i++) {
699 if (p->phy_info[i].attached.sas_address ==
700 rphy->identify.sas_address) {
701 rc = p->phy_info[i].attached.slot;
702 goto out;
703 }
704 }
705 }
706 rc = -ENXIO;
707 out:
708 mutex_unlock(&ioc->sas_topology_mutex);
709 return rc;
710}
711
549static struct sas_function_template mptsas_transport_functions = { 712static struct sas_function_template mptsas_transport_functions = {
550 .get_linkerrors = mptsas_get_linkerrors, 713 .get_linkerrors = mptsas_get_linkerrors,
714 .get_enclosure_identifier = mptsas_get_enclosure_identifier,
715 .get_bay_identifier = mptsas_get_bay_identifier,
551 .phy_reset = mptsas_phy_reset, 716 .phy_reset = mptsas_phy_reset,
552}; 717};
553 718
@@ -607,6 +772,9 @@ mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
607 goto out_free_consistent; 772 goto out_free_consistent;
608 } 773 }
609 774
775 if (port_info->num_phys)
776 port_info->handle =
777 le16_to_cpu(buffer->PhyData[0].ControllerDevHandle);
610 for (i = 0; i < port_info->num_phys; i++) { 778 for (i = 0; i < port_info->num_phys; i++) {
611 mptsas_print_phy_data(&buffer->PhyData[i]); 779 mptsas_print_phy_data(&buffer->PhyData[i]);
612 port_info->phy_info[i].phy_id = i; 780 port_info->phy_info[i].phy_id = i;
@@ -713,6 +881,7 @@ mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
713 cfg.dir = 0; /* read */ 881 cfg.dir = 0; /* read */
714 cfg.timeout = 10; 882 cfg.timeout = 10;
715 883
884 memset(device_info, 0, sizeof(struct mptsas_devinfo));
716 error = mpt_config(ioc, &cfg); 885 error = mpt_config(ioc, &cfg);
717 if (error) 886 if (error)
718 goto out; 887 goto out;
@@ -739,6 +908,9 @@ mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
739 908
740 device_info->handle = le16_to_cpu(buffer->DevHandle); 909 device_info->handle = le16_to_cpu(buffer->DevHandle);
741 device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle); 910 device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle);
911 device_info->handle_enclosure =
912 le16_to_cpu(buffer->EnclosureHandle);
913 device_info->slot = le16_to_cpu(buffer->Slot);
742 device_info->phy_id = buffer->PhyNum; 914 device_info->phy_id = buffer->PhyNum;
743 device_info->port_id = buffer->PhysicalPort; 915 device_info->port_id = buffer->PhysicalPort;
744 device_info->id = buffer->TargetID; 916 device_info->id = buffer->TargetID;
@@ -780,6 +952,7 @@ mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
780 cfg.dir = 0; /* read */ 952 cfg.dir = 0; /* read */
781 cfg.timeout = 10; 953 cfg.timeout = 10;
782 954
955 memset(port_info, 0, sizeof(struct mptsas_portinfo));
783 error = mpt_config(ioc, &cfg); 956 error = mpt_config(ioc, &cfg);
784 if (error) 957 if (error)
785 goto out; 958 goto out;
@@ -880,7 +1053,6 @@ mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
880 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle); 1053 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
881 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle); 1054 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
882 1055
883
884 out_free_consistent: 1056 out_free_consistent:
885 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4, 1057 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
886 buffer, dma_handle); 1058 buffer, dma_handle);
@@ -970,12 +1142,19 @@ mptsas_parse_device_info(struct sas_identify *identify,
970static int mptsas_probe_one_phy(struct device *dev, 1142static int mptsas_probe_one_phy(struct device *dev,
971 struct mptsas_phyinfo *phy_info, int index, int local) 1143 struct mptsas_phyinfo *phy_info, int index, int local)
972{ 1144{
1145 MPT_ADAPTER *ioc;
973 struct sas_phy *phy; 1146 struct sas_phy *phy;
974 int error; 1147 int error;
975 1148
976 phy = sas_phy_alloc(dev, index); 1149 if (!dev)
977 if (!phy) 1150 return -ENODEV;
978 return -ENOMEM; 1151
1152 if (!phy_info->phy) {
1153 phy = sas_phy_alloc(dev, index);
1154 if (!phy)
1155 return -ENOMEM;
1156 } else
1157 phy = phy_info->phy;
979 1158
980 phy->port_identifier = phy_info->port_id; 1159 phy->port_identifier = phy_info->port_id;
981 mptsas_parse_device_info(&phy->identify, &phy_info->identify); 1160 mptsas_parse_device_info(&phy->identify, &phy_info->identify);
@@ -1061,24 +1240,54 @@ static int mptsas_probe_one_phy(struct device *dev,
1061 break; 1240 break;
1062 } 1241 }
1063 1242
1064 if (local) 1243 if (!phy_info->phy) {
1065 phy->local_attached = 1;
1066 1244
1067 error = sas_phy_add(phy); 1245 if (local)
1068 if (error) { 1246 phy->local_attached = 1;
1069 sas_phy_free(phy); 1247
1070 return error; 1248 error = sas_phy_add(phy);
1249 if (error) {
1250 sas_phy_free(phy);
1251 return error;
1252 }
1253 phy_info->phy = phy;
1071 } 1254 }
1072 phy_info->phy = phy;
1073 1255
1074 if (phy_info->attached.handle) { 1256 if ((phy_info->attached.handle) &&
1257 (!phy_info->rphy)) {
1258
1075 struct sas_rphy *rphy; 1259 struct sas_rphy *rphy;
1260 struct sas_identify identify;
1261
1262 ioc = phy_to_ioc(phy_info->phy);
1076 1263
1077 rphy = sas_rphy_alloc(phy); 1264 /*
1265 * Let the hotplug_work thread handle processing
1266 * the adding/removing of devices that occur
1267 * after start of day.
1268 */
1269 if (ioc->sas_discovery_runtime &&
1270 mptsas_is_end_device(&phy_info->attached))
1271 return 0;
1272
1273 mptsas_parse_device_info(&identify, &phy_info->attached);
1274 switch (identify.device_type) {
1275 case SAS_END_DEVICE:
1276 rphy = sas_end_device_alloc(phy);
1277 break;
1278 case SAS_EDGE_EXPANDER_DEVICE:
1279 case SAS_FANOUT_EXPANDER_DEVICE:
1280 rphy = sas_expander_alloc(phy, identify.device_type);
1281 break;
1282 default:
1283 rphy = NULL;
1284 break;
1285 }
1078 if (!rphy) 1286 if (!rphy)
1079 return 0; /* non-fatal: an rphy can be added later */ 1287 return 0; /* non-fatal: an rphy can be added later */
1080 1288
1081 mptsas_parse_device_info(&rphy->identify, &phy_info->attached); 1289 rphy->identify = identify;
1290
1082 error = sas_rphy_add(rphy); 1291 error = sas_rphy_add(rphy);
1083 if (error) { 1292 if (error) {
1084 sas_rphy_free(rphy); 1293 sas_rphy_free(rphy);
@@ -1092,24 +1301,37 @@ static int mptsas_probe_one_phy(struct device *dev,
1092} 1301}
1093 1302
1094static int 1303static int
1095mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index) 1304mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
1096{ 1305{
1097 struct mptsas_portinfo *port_info; 1306 struct mptsas_portinfo *port_info, *hba;
1098 u32 handle = 0xFFFF; 1307 u32 handle = 0xFFFF;
1099 int error = -ENOMEM, i; 1308 int error = -ENOMEM, i;
1100 1309
1101 port_info = kzalloc(sizeof(*port_info), GFP_KERNEL); 1310 hba = kzalloc(sizeof(*port_info), GFP_KERNEL);
1102 if (!port_info) 1311 if (! hba)
1103 goto out; 1312 goto out;
1104 1313
1105 error = mptsas_sas_io_unit_pg0(ioc, port_info); 1314 error = mptsas_sas_io_unit_pg0(ioc, hba);
1106 if (error) 1315 if (error)
1107 goto out_free_port_info; 1316 goto out_free_port_info;
1108 1317
1109 ioc->num_ports = port_info->num_phys;
1110 mutex_lock(&ioc->sas_topology_mutex); 1318 mutex_lock(&ioc->sas_topology_mutex);
1111 list_add_tail(&port_info->list, &ioc->sas_topology); 1319 port_info = mptsas_find_portinfo_by_handle(ioc, hba->handle);
1320 if (!port_info) {
1321 port_info = hba;
1322 list_add_tail(&port_info->list, &ioc->sas_topology);
1323 } else {
1324 port_info->handle = hba->handle;
1325 for (i = 0; i < hba->num_phys; i++)
1326 port_info->phy_info[i].negotiated_link_rate =
1327 hba->phy_info[i].negotiated_link_rate;
1328 if (hba->phy_info)
1329 kfree(hba->phy_info);
1330 kfree(hba);
1331 hba = NULL;
1332 }
1112 mutex_unlock(&ioc->sas_topology_mutex); 1333 mutex_unlock(&ioc->sas_topology_mutex);
1334 ioc->num_ports = port_info->num_phys;
1113 1335
1114 for (i = 0; i < port_info->num_phys; i++) { 1336 for (i = 0; i < port_info->num_phys; i++) {
1115 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i], 1337 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
@@ -1132,38 +1354,49 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index)
1132 } 1354 }
1133 1355
1134 mptsas_probe_one_phy(&ioc->sh->shost_gendev, 1356 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
1135 &port_info->phy_info[i], *index, 1); 1357 &port_info->phy_info[i], ioc->sas_index, 1);
1136 (*index)++; 1358 ioc->sas_index++;
1137 } 1359 }
1138 1360
1139 return 0; 1361 return 0;
1140 1362
1141 out_free_port_info: 1363 out_free_port_info:
1142 kfree(port_info); 1364 if (hba)
1365 kfree(hba);
1143 out: 1366 out:
1144 return error; 1367 return error;
1145} 1368}
1146 1369
1147static int 1370static int
1148mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index) 1371mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle)
1149{ 1372{
1150 struct mptsas_portinfo *port_info, *p; 1373 struct mptsas_portinfo *port_info, *p, *ex;
1151 int error = -ENOMEM, i, j; 1374 int error = -ENOMEM, i, j;
1152 1375
1153 port_info = kzalloc(sizeof(*port_info), GFP_KERNEL); 1376 ex = kzalloc(sizeof(*port_info), GFP_KERNEL);
1154 if (!port_info) 1377 if (!ex)
1155 goto out; 1378 goto out;
1156 1379
1157 error = mptsas_sas_expander_pg0(ioc, port_info, 1380 error = mptsas_sas_expander_pg0(ioc, ex,
1158 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE << 1381 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
1159 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle); 1382 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
1160 if (error) 1383 if (error)
1161 goto out_free_port_info; 1384 goto out_free_port_info;
1162 1385
1163 *handle = port_info->handle; 1386 *handle = ex->handle;
1164 1387
1165 mutex_lock(&ioc->sas_topology_mutex); 1388 mutex_lock(&ioc->sas_topology_mutex);
1166 list_add_tail(&port_info->list, &ioc->sas_topology); 1389 port_info = mptsas_find_portinfo_by_handle(ioc, *handle);
1390 if (!port_info) {
1391 port_info = ex;
1392 list_add_tail(&port_info->list, &ioc->sas_topology);
1393 } else {
1394 port_info->handle = ex->handle;
1395 if (ex->phy_info)
1396 kfree(ex->phy_info);
1397 kfree(ex);
1398 ex = NULL;
1399 }
1167 mutex_unlock(&ioc->sas_topology_mutex); 1400 mutex_unlock(&ioc->sas_topology_mutex);
1168 1401
1169 for (i = 0; i < port_info->num_phys; i++) { 1402 for (i = 0; i < port_info->num_phys; i++) {
@@ -1189,6 +1422,8 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
1189 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE << 1422 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1190 MPI_SAS_DEVICE_PGAD_FORM_SHIFT), 1423 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1191 port_info->phy_info[i].attached.handle); 1424 port_info->phy_info[i].attached.handle);
1425 port_info->phy_info[i].attached.phy_id =
1426 port_info->phy_info[i].phy_id;
1192 } 1427 }
1193 1428
1194 /* 1429 /*
@@ -1208,27 +1443,137 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
1208 mutex_unlock(&ioc->sas_topology_mutex); 1443 mutex_unlock(&ioc->sas_topology_mutex);
1209 1444
1210 mptsas_probe_one_phy(parent, &port_info->phy_info[i], 1445 mptsas_probe_one_phy(parent, &port_info->phy_info[i],
1211 *index, 0); 1446 ioc->sas_index, 0);
1212 (*index)++; 1447 ioc->sas_index++;
1213 } 1448 }
1214 1449
1215 return 0; 1450 return 0;
1216 1451
1217 out_free_port_info: 1452 out_free_port_info:
1218 kfree(port_info); 1453 if (ex) {
1454 if (ex->phy_info)
1455 kfree(ex->phy_info);
1456 kfree(ex);
1457 }
1219 out: 1458 out:
1220 return error; 1459 return error;
1221} 1460}
1222 1461
1462/*
1463 * mptsas_delete_expander_phys
1464 *
1465 *
1466 * This will traverse topology, and remove expanders
1467 * that are no longer present
1468 */
1469static void
1470mptsas_delete_expander_phys(MPT_ADAPTER *ioc)
1471{
1472 struct mptsas_portinfo buffer;
1473 struct mptsas_portinfo *port_info, *n, *parent;
1474 int i;
1475
1476 mutex_lock(&ioc->sas_topology_mutex);
1477 list_for_each_entry_safe(port_info, n, &ioc->sas_topology, list) {
1478
1479 if (port_info->phy_info &&
1480 (!(port_info->phy_info[0].identify.device_info &
1481 MPI_SAS_DEVICE_INFO_SMP_TARGET)))
1482 continue;
1483
1484 if (mptsas_sas_expander_pg0(ioc, &buffer,
1485 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
1486 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), port_info->handle)) {
1487
1488 /*
1489 * Obtain the port_info instance to the parent port
1490 */
1491 parent = mptsas_find_portinfo_by_handle(ioc,
1492 port_info->phy_info[0].identify.handle_parent);
1493
1494 if (!parent)
1495 goto next_port;
1496
1497 /*
1498 * Delete rphys in the parent that point
1499 * to this expander. The transport layer will
1500 * cleanup all the children.
1501 */
1502 for (i = 0; i < parent->num_phys; i++) {
1503 if ((!parent->phy_info[i].rphy) ||
1504 (parent->phy_info[i].attached.sas_address !=
1505 port_info->phy_info[i].identify.sas_address))
1506 continue;
1507 sas_rphy_delete(parent->phy_info[i].rphy);
1508 memset(&parent->phy_info[i].attached, 0,
1509 sizeof(struct mptsas_devinfo));
1510 parent->phy_info[i].rphy = NULL;
1511 parent->phy_info[i].starget = NULL;
1512 }
1513 next_port:
1514 list_del(&port_info->list);
1515 if (port_info->phy_info)
1516 kfree(port_info->phy_info);
1517 kfree(port_info);
1518 }
1519 /*
1520 * Free this memory allocated from inside
1521 * mptsas_sas_expander_pg0
1522 */
1523 if (buffer.phy_info)
1524 kfree(buffer.phy_info);
1525 }
1526 mutex_unlock(&ioc->sas_topology_mutex);
1527}
1528
1529/*
1530 * Start of day discovery
1531 */
1223static void 1532static void
1224mptsas_scan_sas_topology(MPT_ADAPTER *ioc) 1533mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
1225{ 1534{
1226 u32 handle = 0xFFFF; 1535 u32 handle = 0xFFFF;
1227 int index = 0; 1536 int i;
1537
1538 mutex_lock(&ioc->sas_discovery_mutex);
1539 mptsas_probe_hba_phys(ioc);
1540 while (!mptsas_probe_expander_phys(ioc, &handle))
1541 ;
1542 /*
1543 Reporting RAID volumes.
1544 */
1545 if (!ioc->raid_data.pIocPg2)
1546 goto out;
1547 if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
1548 goto out;
1549 for (i=0; i<ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
1550 scsi_add_device(ioc->sh, ioc->num_ports,
1551 ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
1552 }
1553 out:
1554 mutex_unlock(&ioc->sas_discovery_mutex);
1555}
1556
1557/*
1558 * Work queue thread to handle Runtime discovery
1559 * Mere purpose is the hot add/delete of expanders
1560 */
1561static void
1562mptscsih_discovery_work(void * arg)
1563{
1564 struct mptsas_discovery_event *ev = arg;
1565 MPT_ADAPTER *ioc = ev->ioc;
1566 u32 handle = 0xFFFF;
1228 1567
1229 mptsas_probe_hba_phys(ioc, &index); 1568 mutex_lock(&ioc->sas_discovery_mutex);
1230 while (!mptsas_probe_expander_phys(ioc, &handle, &index)) 1569 ioc->sas_discovery_runtime=1;
1570 mptsas_delete_expander_phys(ioc);
1571 mptsas_probe_hba_phys(ioc);
1572 while (!mptsas_probe_expander_phys(ioc, &handle))
1231 ; 1573 ;
1574 kfree(ev);
1575 ioc->sas_discovery_runtime=0;
1576 mutex_unlock(&ioc->sas_discovery_mutex);
1232} 1577}
1233 1578
1234static struct mptsas_phyinfo * 1579static struct mptsas_phyinfo *
@@ -1246,10 +1591,8 @@ mptsas_find_phyinfo_by_parent(MPT_ADAPTER *ioc, u16 parent_handle, u8 phy_id)
1246 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE << 1591 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1247 MPI_SAS_DEVICE_PGAD_FORM_SHIFT), 1592 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1248 parent_handle); 1593 parent_handle);
1249 if (error) { 1594 if (error)
1250 printk("mptsas: failed to retrieve device page\n");
1251 return NULL; 1595 return NULL;
1252 }
1253 1596
1254 /* 1597 /*
1255 * The phy_info structures are never deallocated during lifetime of 1598 * The phy_info structures are never deallocated during lifetime of
@@ -1296,6 +1639,35 @@ mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u32 id)
1296 return phy_info; 1639 return phy_info;
1297} 1640}
1298 1641
1642/*
1643 * Work queue thread to clear the persitency table
1644 */
1645static void
1646mptscsih_sas_persist_clear_table(void * arg)
1647{
1648 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
1649
1650 mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
1651}
1652
1653static void
1654mptsas_reprobe_lun(struct scsi_device *sdev, void *data)
1655{
1656 sdev->no_uld_attach = data ? 1 : 0;
1657 scsi_device_reprobe(sdev);
1658}
1659
1660static void
1661mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)
1662{
1663 starget_for_each_device(starget, uld_attach ? (void *)1 : NULL,
1664 mptsas_reprobe_lun);
1665}
1666
1667
1668/*
1669 * Work queue thread to handle SAS hotplug events
1670 */
1299static void 1671static void
1300mptsas_hotplug_work(void *arg) 1672mptsas_hotplug_work(void *arg)
1301{ 1673{
@@ -1304,16 +1676,39 @@ mptsas_hotplug_work(void *arg)
1304 struct mptsas_phyinfo *phy_info; 1676 struct mptsas_phyinfo *phy_info;
1305 struct sas_rphy *rphy; 1677 struct sas_rphy *rphy;
1306 struct scsi_device *sdev; 1678 struct scsi_device *sdev;
1679 struct sas_identify identify;
1307 char *ds = NULL; 1680 char *ds = NULL;
1308 struct mptsas_devinfo sas_device; 1681 struct mptsas_devinfo sas_device;
1682 VirtTarget *vtarget;
1683
1684 mutex_lock(&ioc->sas_discovery_mutex);
1309 1685
1310 switch (ev->event_type) { 1686 switch (ev->event_type) {
1311 case MPTSAS_DEL_DEVICE: 1687 case MPTSAS_DEL_DEVICE:
1312 1688
1313 phy_info = mptsas_find_phyinfo_by_target(ioc, ev->id); 1689 phy_info = mptsas_find_phyinfo_by_target(ioc, ev->id);
1314 if (!phy_info) { 1690
1315 printk("mptsas: remove event for non-existant PHY.\n"); 1691 /*
1692 * Sanity checks, for non-existing phys and remote rphys.
1693 */
1694 if (!phy_info)
1316 break; 1695 break;
1696 if (!phy_info->rphy)
1697 break;
1698 if (phy_info->starget) {
1699 vtarget = phy_info->starget->hostdata;
1700
1701 if (!vtarget)
1702 break;
1703 /*
1704 * Handling RAID components
1705 */
1706 if (ev->phys_disk_num_valid) {
1707 vtarget->target_id = ev->phys_disk_num;
1708 vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
1709 mptsas_reprobe_target(vtarget->starget, 1);
1710 break;
1711 }
1317 } 1712 }
1318 1713
1319 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET) 1714 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET)
@@ -1327,55 +1722,74 @@ mptsas_hotplug_work(void *arg)
1327 "removing %s device, channel %d, id %d, phy %d\n", 1722 "removing %s device, channel %d, id %d, phy %d\n",
1328 ioc->name, ds, ev->channel, ev->id, phy_info->phy_id); 1723 ioc->name, ds, ev->channel, ev->id, phy_info->phy_id);
1329 1724
1330 if (phy_info->rphy) { 1725 sas_rphy_delete(phy_info->rphy);
1331 sas_rphy_delete(phy_info->rphy); 1726 memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
1332 phy_info->rphy = NULL; 1727 phy_info->rphy = NULL;
1333 } 1728 phy_info->starget = NULL;
1334 break; 1729 break;
1335 case MPTSAS_ADD_DEVICE: 1730 case MPTSAS_ADD_DEVICE:
1336 1731
1337 /* 1732 /*
1338 * When there is no sas address, 1733 * Refresh sas device pg0 data
1339 * RAID volumes are being deleted,
1340 * and hidden phy disk are being added.
1341 * We don't know the SAS data yet,
1342 * so lookup sas device page to get
1343 * pertaining info
1344 */ 1734 */
1345 if (!ev->sas_address) { 1735 if (mptsas_sas_device_pg0(ioc, &sas_device,
1346 if (mptsas_sas_device_pg0(ioc, 1736 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
1347 &sas_device, ev->id, 1737 MPI_SAS_DEVICE_PGAD_FORM_SHIFT), ev->id))
1348 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID << 1738 break;
1349 MPI_SAS_DEVICE_PGAD_FORM_SHIFT)))
1350 break;
1351 ev->handle = sas_device.handle;
1352 ev->parent_handle = sas_device.handle_parent;
1353 ev->channel = sas_device.channel;
1354 ev->phy_id = sas_device.phy_id;
1355 ev->sas_address = sas_device.sas_address;
1356 ev->device_info = sas_device.device_info;
1357 }
1358 1739
1359 phy_info = mptsas_find_phyinfo_by_parent(ioc, 1740 phy_info = mptsas_find_phyinfo_by_parent(ioc,
1360 ev->parent_handle, ev->phy_id); 1741 sas_device.handle_parent, sas_device.phy_id);
1742
1361 if (!phy_info) { 1743 if (!phy_info) {
1362 printk("mptsas: add event for non-existant PHY.\n"); 1744 u32 handle = 0xFFFF;
1363 break; 1745
1746 /*
1747 * Its possible when an expander has been hot added
1748 * containing attached devices, the sas firmware
1749 * may send a RC_ADDED event prior to the
1750 * DISCOVERY STOP event. If that occurs, our
1751 * view of the topology in the driver in respect to this
1752 * expander might of not been setup, and we hit this
1753 * condition.
1754 * Therefore, this code kicks off discovery to
1755 * refresh the data.
1756 * Then again, we check whether the parent phy has
1757 * been created.
1758 */
1759 ioc->sas_discovery_runtime=1;
1760 mptsas_delete_expander_phys(ioc);
1761 mptsas_probe_hba_phys(ioc);
1762 while (!mptsas_probe_expander_phys(ioc, &handle))
1763 ;
1764 ioc->sas_discovery_runtime=0;
1765
1766 phy_info = mptsas_find_phyinfo_by_parent(ioc,
1767 sas_device.handle_parent, sas_device.phy_id);
1768 if (!phy_info)
1769 break;
1364 } 1770 }
1365 1771
1366 if (phy_info->rphy) { 1772 if (phy_info->starget) {
1367 printk("mptsas: trying to add existing device.\n"); 1773 vtarget = phy_info->starget->hostdata;
1774
1775 if (!vtarget)
1776 break;
1777 /*
1778 * Handling RAID components
1779 */
1780 if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
1781 vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT;
1782 vtarget->target_id = ev->id;
1783 mptsas_reprobe_target(phy_info->starget, 0);
1784 }
1368 break; 1785 break;
1369 } 1786 }
1370 1787
1371 /* fill attached info */ 1788 if (phy_info->rphy)
1372 phy_info->attached.handle = ev->handle; 1789 break;
1373 phy_info->attached.phy_id = ev->phy_id; 1790
1374 phy_info->attached.port_id = phy_info->identify.port_id; 1791 memcpy(&phy_info->attached, &sas_device,
1375 phy_info->attached.id = ev->id; 1792 sizeof(struct mptsas_devinfo));
1376 phy_info->attached.channel = ev->channel;
1377 phy_info->attached.sas_address = ev->sas_address;
1378 phy_info->attached.device_info = ev->device_info;
1379 1793
1380 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET) 1794 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET)
1381 ds = "ssp"; 1795 ds = "ssp";
@@ -1388,13 +1802,23 @@ mptsas_hotplug_work(void *arg)
1388 "attaching %s device, channel %d, id %d, phy %d\n", 1802 "attaching %s device, channel %d, id %d, phy %d\n",
1389 ioc->name, ds, ev->channel, ev->id, ev->phy_id); 1803 ioc->name, ds, ev->channel, ev->id, ev->phy_id);
1390 1804
1391 1805 mptsas_parse_device_info(&identify, &phy_info->attached);
1392 rphy = sas_rphy_alloc(phy_info->phy); 1806 switch (identify.device_type) {
1807 case SAS_END_DEVICE:
1808 rphy = sas_end_device_alloc(phy_info->phy);
1809 break;
1810 case SAS_EDGE_EXPANDER_DEVICE:
1811 case SAS_FANOUT_EXPANDER_DEVICE:
1812 rphy = sas_expander_alloc(phy_info->phy, identify.device_type);
1813 break;
1814 default:
1815 rphy = NULL;
1816 break;
1817 }
1393 if (!rphy) 1818 if (!rphy)
1394 break; /* non-fatal: an rphy can be added later */ 1819 break; /* non-fatal: an rphy can be added later */
1395 1820
1396 rphy->scsi_target_id = phy_info->attached.id; 1821 rphy->identify = identify;
1397 mptsas_parse_device_info(&rphy->identify, &phy_info->attached);
1398 if (sas_rphy_add(rphy)) { 1822 if (sas_rphy_add(rphy)) {
1399 sas_rphy_free(rphy); 1823 sas_rphy_free(rphy);
1400 break; 1824 break;
@@ -1413,7 +1837,7 @@ mptsas_hotplug_work(void *arg)
1413 break; 1837 break;
1414 } 1838 }
1415 printk(MYIOC_s_INFO_FMT 1839 printk(MYIOC_s_INFO_FMT
1416 "attaching device, channel %d, id %d\n", 1840 "attaching raid volume, channel %d, id %d\n",
1417 ioc->name, ioc->num_ports, ev->id); 1841 ioc->name, ioc->num_ports, ev->id);
1418 scsi_add_device(ioc->sh, 1842 scsi_add_device(ioc->sh,
1419 ioc->num_ports, 1843 ioc->num_ports,
@@ -1430,7 +1854,7 @@ mptsas_hotplug_work(void *arg)
1430 if (!sdev) 1854 if (!sdev)
1431 break; 1855 break;
1432 printk(MYIOC_s_INFO_FMT 1856 printk(MYIOC_s_INFO_FMT
1433 "removing device, channel %d, id %d\n", 1857 "removing raid volume, channel %d, id %d\n",
1434 ioc->name, ioc->num_ports, ev->id); 1858 ioc->name, ioc->num_ports, ev->id);
1435 scsi_remove_device(sdev); 1859 scsi_remove_device(sdev);
1436 scsi_device_put(sdev); 1860 scsi_device_put(sdev);
@@ -1439,6 +1863,7 @@ mptsas_hotplug_work(void *arg)
1439 } 1863 }
1440 1864
1441 kfree(ev); 1865 kfree(ev);
1866 mutex_unlock(&ioc->sas_discovery_mutex);
1442} 1867}
1443 1868
1444static void 1869static void
@@ -1455,35 +1880,51 @@ mptscsih_send_sas_event(MPT_ADAPTER *ioc,
1455 MPI_SAS_DEVICE_INFO_SATA_DEVICE )) == 0) 1880 MPI_SAS_DEVICE_INFO_SATA_DEVICE )) == 0)
1456 return; 1881 return;
1457 1882
1458 if ((sas_event_data->ReasonCode & 1883 switch (sas_event_data->ReasonCode) {
1459 (MPI_EVENT_SAS_DEV_STAT_RC_ADDED | 1884 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
1460 MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING)) == 0) 1885 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
1461 return; 1886 ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
1887 if (!ev) {
1888 printk(KERN_WARNING "mptsas: lost hotplug event\n");
1889 break;
1890 }
1462 1891
1463 ev = kmalloc(sizeof(*ev), GFP_ATOMIC); 1892 INIT_WORK(&ev->work, mptsas_hotplug_work, ev);
1464 if (!ev) { 1893 ev->ioc = ioc;
1465 printk(KERN_WARNING "mptsas: lost hotplug event\n"); 1894 ev->handle = le16_to_cpu(sas_event_data->DevHandle);
1466 return; 1895 ev->parent_handle =
1896 le16_to_cpu(sas_event_data->ParentDevHandle);
1897 ev->channel = sas_event_data->Bus;
1898 ev->id = sas_event_data->TargetID;
1899 ev->phy_id = sas_event_data->PhyNum;
1900 memcpy(&sas_address, &sas_event_data->SASAddress,
1901 sizeof(__le64));
1902 ev->sas_address = le64_to_cpu(sas_address);
1903 ev->device_info = device_info;
1904
1905 if (sas_event_data->ReasonCode &
1906 MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
1907 ev->event_type = MPTSAS_ADD_DEVICE;
1908 else
1909 ev->event_type = MPTSAS_DEL_DEVICE;
1910 schedule_work(&ev->work);
1911 break;
1912 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
1913 /*
1914 * Persistent table is full.
1915 */
1916 INIT_WORK(&ioc->mptscsih_persistTask,
1917 mptscsih_sas_persist_clear_table,
1918 (void *)ioc);
1919 schedule_work(&ioc->mptscsih_persistTask);
1920 break;
1921 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
1922 /* TODO */
1923 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
1924 /* TODO */
1925 default:
1926 break;
1467 } 1927 }
1468
1469
1470 INIT_WORK(&ev->work, mptsas_hotplug_work, ev);
1471 ev->ioc = ioc;
1472 ev->handle = le16_to_cpu(sas_event_data->DevHandle);
1473 ev->parent_handle = le16_to_cpu(sas_event_data->ParentDevHandle);
1474 ev->channel = sas_event_data->Bus;
1475 ev->id = sas_event_data->TargetID;
1476 ev->phy_id = sas_event_data->PhyNum;
1477 memcpy(&sas_address, &sas_event_data->SASAddress, sizeof(__le64));
1478 ev->sas_address = le64_to_cpu(sas_address);
1479 ev->device_info = device_info;
1480
1481 if (sas_event_data->ReasonCode & MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
1482 ev->event_type = MPTSAS_ADD_DEVICE;
1483 else
1484 ev->event_type = MPTSAS_DEL_DEVICE;
1485
1486 schedule_work(&ev->work);
1487} 1928}
1488 1929
1489static void 1930static void
@@ -1512,6 +1953,9 @@ mptscsih_send_raid_event(MPT_ADAPTER *ioc,
1512 ev->event_type = MPTSAS_ADD_DEVICE; 1953 ev->event_type = MPTSAS_ADD_DEVICE;
1513 break; 1954 break;
1514 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED: 1955 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
1956 ioc->raid_data.isRaid = 1;
1957 ev->phys_disk_num_valid = 1;
1958 ev->phys_disk_num = raid_event_data->PhysDiskNum;
1515 ev->event_type = MPTSAS_DEL_DEVICE; 1959 ev->event_type = MPTSAS_DEL_DEVICE;
1516 break; 1960 break;
1517 case MPI_EVENT_RAID_RC_VOLUME_DELETED: 1961 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
@@ -1533,15 +1977,31 @@ mptscsih_send_raid_event(MPT_ADAPTER *ioc,
1533 schedule_work(&ev->work); 1977 schedule_work(&ev->work);
1534} 1978}
1535 1979
1536/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1537/* work queue thread to clear the persitency table */
1538static void 1980static void
1539mptscsih_sas_persist_clear_table(void * arg) 1981mptscsih_send_discovery(MPT_ADAPTER *ioc,
1982 EVENT_DATA_SAS_DISCOVERY *discovery_data)
1540{ 1983{
1541 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg; 1984 struct mptsas_discovery_event *ev;
1985
1986 /*
1987 * DiscoveryStatus
1988 *
1989 * This flag will be non-zero when firmware
1990 * kicks off discovery, and return to zero
1991 * once its completed.
1992 */
1993 if (discovery_data->DiscoveryStatus)
1994 return;
1995
1996 ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
1997 if (!ev)
1998 return;
1999 memset(ev,0,sizeof(struct mptsas_discovery_event));
2000 INIT_WORK(&ev->work, mptscsih_discovery_work, ev);
2001 ev->ioc = ioc;
2002 schedule_work(&ev->work);
2003};
1542 2004
1543 mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
1544}
1545 2005
1546static int 2006static int
1547mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply) 2007mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
@@ -1552,6 +2012,17 @@ mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
1552 if (!ioc->sh) 2012 if (!ioc->sh)
1553 goto out; 2013 goto out;
1554 2014
2015 /*
2016 * sas_discovery_ignore_events
2017 *
2018 * This flag is to prevent anymore processing of
2019 * sas events once mptsas_remove function is called.
2020 */
2021 if (ioc->sas_discovery_ignore_events) {
2022 rc = mptscsih_event_process(ioc, reply);
2023 goto out;
2024 }
2025
1555 switch (event) { 2026 switch (event) {
1556 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE: 2027 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
1557 mptscsih_send_sas_event(ioc, 2028 mptscsih_send_sas_event(ioc,
@@ -1567,6 +2038,10 @@ mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
1567 (void *)ioc); 2038 (void *)ioc);
1568 schedule_work(&ioc->mptscsih_persistTask); 2039 schedule_work(&ioc->mptscsih_persistTask);
1569 break; 2040 break;
2041 case MPI_EVENT_SAS_DISCOVERY:
2042 mptscsih_send_discovery(ioc,
2043 (EVENT_DATA_SAS_DISCOVERY *)reply->Data);
2044 break;
1570 default: 2045 default:
1571 rc = mptscsih_event_process(ioc, reply); 2046 rc = mptscsih_event_process(ioc, reply);
1572 break; 2047 break;
@@ -1668,7 +2143,7 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1668 2143
1669 INIT_LIST_HEAD(&ioc->sas_topology); 2144 INIT_LIST_HEAD(&ioc->sas_topology);
1670 mutex_init(&ioc->sas_topology_mutex); 2145 mutex_init(&ioc->sas_topology_mutex);
1671 2146 mutex_init(&ioc->sas_discovery_mutex);
1672 mutex_init(&ioc->sas_mgmt.mutex); 2147 mutex_init(&ioc->sas_mgmt.mutex);
1673 init_completion(&ioc->sas_mgmt.done); 2148 init_completion(&ioc->sas_mgmt.done);
1674 2149
@@ -1781,20 +2256,6 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1781 2256
1782 mptsas_scan_sas_topology(ioc); 2257 mptsas_scan_sas_topology(ioc);
1783 2258
1784 /*
1785 Reporting RAID volumes.
1786 */
1787 if (!ioc->raid_data.pIocPg2)
1788 return 0;
1789 if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
1790 return 0;
1791 for (ii=0;ii<ioc->raid_data.pIocPg2->NumActiveVolumes;ii++) {
1792 scsi_add_device(sh,
1793 ioc->num_ports,
1794 ioc->raid_data.pIocPg2->RaidVolume[ii].VolumeID,
1795 0);
1796 }
1797
1798 return 0; 2259 return 0;
1799 2260
1800out_mptsas_probe: 2261out_mptsas_probe:
@@ -1808,11 +2269,14 @@ static void __devexit mptsas_remove(struct pci_dev *pdev)
1808 MPT_ADAPTER *ioc = pci_get_drvdata(pdev); 2269 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1809 struct mptsas_portinfo *p, *n; 2270 struct mptsas_portinfo *p, *n;
1810 2271
2272 ioc->sas_discovery_ignore_events=1;
1811 sas_remove_host(ioc->sh); 2273 sas_remove_host(ioc->sh);
1812 2274
1813 mutex_lock(&ioc->sas_topology_mutex); 2275 mutex_lock(&ioc->sas_topology_mutex);
1814 list_for_each_entry_safe(p, n, &ioc->sas_topology, list) { 2276 list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
1815 list_del(&p->list); 2277 list_del(&p->list);
2278 if (p->phy_info)
2279 kfree(p->phy_info);
1816 kfree(p); 2280 kfree(p);
1817 } 2281 }
1818 mutex_unlock(&ioc->sas_topology_mutex); 2282 mutex_unlock(&ioc->sas_topology_mutex);
@@ -1867,7 +2331,7 @@ mptsas_init(void)
1867 mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER); 2331 mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
1868 2332
1869 if (mpt_event_register(mptsasDoneCtx, mptsas_event_process) == 0) { 2333 if (mpt_event_register(mptsasDoneCtx, mptsas_event_process) == 0) {
1870 devtprintk((KERN_INFO MYNAM 2334 devtverboseprintk((KERN_INFO MYNAM
1871 ": Registered for IOC event notifications\n")); 2335 ": Registered for IOC event notifications\n"));
1872 } 2336 }
1873 2337