Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1/*
2 * linux/drivers/message/fusion/mptsas.c
3 * For use with LSI Logic PCI chip/adapter(s)
4 * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
5 *
6 * Copyright (c) 1999-2007 LSI Logic Corporation
7 * (mailto:DL-MPTFusionLinux@lsi.com)
8 * Copyright (c) 2005-2007 Dell
9 */
10/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
11/*
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; version 2 of the License.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 NO WARRANTY
22 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
23 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
24 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
25 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
26 solely responsible for determining the appropriateness of using and
27 distributing the Program and assumes all risks associated with its
28 exercise of rights under this Agreement, including but not limited to
29 the risks and costs of program errors, damage to or loss of data,
30 programs or equipment, and unavailability or interruption of operations.
31
32 DISCLAIMER OF LIABILITY
33 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
34 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
36 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
37 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
38 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
39 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
40
41 You should have received a copy of the GNU General Public License
42 along with this program; if not, write to the Free Software
43 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
44*/
45/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
46
47#include <linux/module.h>
48#include <linux/kernel.h>
49#include <linux/init.h>
50#include <linux/errno.h>
51#include <linux/jiffies.h>
52#include <linux/workqueue.h>
53#include <linux/delay.h> /* for mdelay */
54
55#include <scsi/scsi.h>
56#include <scsi/scsi_cmnd.h>
57#include <scsi/scsi_device.h>
58#include <scsi/scsi_host.h>
59#include <scsi/scsi_transport_sas.h>
60#include <scsi/scsi_dbg.h>
61
62#include "mptbase.h"
63#include "mptscsih.h"
64
65
66#define my_NAME "Fusion MPT SAS Host driver"
67#define my_VERSION MPT_LINUX_VERSION_COMMON
68#define MYNAM "mptsas"
69
70/*
71 * Reserved channel for integrated raid
72 */
73#define MPTSAS_RAID_CHANNEL 1
74
75MODULE_AUTHOR(MODULEAUTHOR);
76MODULE_DESCRIPTION(my_NAME);
77MODULE_LICENSE("GPL");
78MODULE_VERSION(my_VERSION);
79
80static int mpt_pt_clear;
81module_param(mpt_pt_clear, int, 0);
82MODULE_PARM_DESC(mpt_pt_clear,
83 " Clear persistency table: enable=1 "
84 "(default=MPTSCSIH_PT_CLEAR=0)");
85
86/* scsi-mid layer global parmeter is max_report_luns, which is 511 */
87#define MPTSAS_MAX_LUN (16895)
88static int max_lun = MPTSAS_MAX_LUN;
89module_param(max_lun, int, 0);
90MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
91
92static int mptsasDoneCtx = -1;
93static int mptsasTaskCtx = -1;
94static int mptsasInternalCtx = -1; /* Used only for internal commands */
95static int mptsasMgmtCtx = -1;
96
97static void mptsas_hotplug_work(struct work_struct *work);
98
99struct mptsas_target_reset_event {
100 struct list_head list;
101 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE sas_event_data;
102 u8 target_reset_issued;
103};
104
105enum mptsas_hotplug_action {
106 MPTSAS_ADD_DEVICE,
107 MPTSAS_DEL_DEVICE,
108 MPTSAS_ADD_RAID,
109 MPTSAS_DEL_RAID,
110 MPTSAS_ADD_INACTIVE_VOLUME,
111 MPTSAS_IGNORE_EVENT,
112};
113
114struct mptsas_hotplug_event {
115 struct work_struct work;
116 MPT_ADAPTER *ioc;
117 enum mptsas_hotplug_action event_type;
118 u64 sas_address;
119 u8 channel;
120 u8 id;
121 u32 device_info;
122 u16 handle;
123 u16 parent_handle;
124 u8 phy_id;
125 u8 phys_disk_num_valid; /* hrc (hidden raid component) */
126 u8 phys_disk_num; /* hrc - unique index*/
127 u8 hidden_raid_component; /* hrc - don't expose*/
128};
129
130struct mptsas_discovery_event {
131 struct work_struct work;
132 MPT_ADAPTER *ioc;
133};
134
135/*
136 * SAS topology structures
137 *
138 * The MPT Fusion firmware interface spreads information about the
139 * SAS topology over many manufacture pages, thus we need some data
140 * structure to collect it and process it for the SAS transport class.
141 */
142
143struct mptsas_devinfo {
144 u16 handle; /* unique id to address this device */
145 u16 handle_parent; /* unique id to address parent device */
146 u16 handle_enclosure; /* enclosure identifier of the enclosure */
147 u16 slot; /* physical slot in enclosure */
148 u8 phy_id; /* phy number of parent device */
149 u8 port_id; /* sas physical port this device
150 is assoc'd with */
151 u8 id; /* logical target id of this device */
152 u32 phys_disk_num; /* phys disk id, for csmi-ioctls */
153 u8 channel; /* logical bus number of this device */
154 u64 sas_address; /* WWN of this device,
155 SATA is assigned by HBA,expander */
156 u32 device_info; /* bitfield detailed info about this device */
157};
158
159/*
160 * Specific details on ports, wide/narrow
161 */
162struct mptsas_portinfo_details{
163 u16 num_phys; /* number of phys belong to this port */
164 u64 phy_bitmask; /* TODO, extend support for 255 phys */
165 struct sas_rphy *rphy; /* transport layer rphy object */
166 struct sas_port *port; /* transport layer port object */
167 struct scsi_target *starget;
168 struct mptsas_portinfo *port_info;
169};
170
171struct mptsas_phyinfo {
172 u16 handle; /* unique id to address this */
173 u8 phy_id; /* phy index */
174 u8 port_id; /* firmware port identifier */
175 u8 negotiated_link_rate; /* nego'd link rate for this phy */
176 u8 hw_link_rate; /* hardware max/min phys link rate */
177 u8 programmed_link_rate; /* programmed max/min phy link rate */
178 u8 sas_port_add_phy; /* flag to request sas_port_add_phy*/
179 struct mptsas_devinfo identify; /* point to phy device info */
180 struct mptsas_devinfo attached; /* point to attached device info */
181 struct sas_phy *phy; /* transport layer phy object */
182 struct mptsas_portinfo *portinfo;
183 struct mptsas_portinfo_details * port_details;
184};
185
186struct mptsas_portinfo {
187 struct list_head list;
188 u16 num_phys; /* number of phys */
189 struct mptsas_phyinfo *phy_info;
190};
191
192struct mptsas_enclosure {
193 u64 enclosure_logical_id; /* The WWN for the enclosure */
194 u16 enclosure_handle; /* unique id to address this */
195 u16 flags; /* details enclosure management */
196 u16 num_slot; /* num slots */
197 u16 start_slot; /* first slot */
198 u8 start_id; /* starting logical target id */
199 u8 start_channel; /* starting logical channel id */
200 u8 sep_id; /* SEP device logical target id */
201 u8 sep_channel; /* SEP channel logical channel id */
202};
203
204static void mptsas_print_phy_data(MPT_ADAPTER *ioc,
205 MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
206{
207 dsasprintk(ioc, printk(KERN_DEBUG "---- IO UNIT PAGE 0 ------------\n"));
208 dsasprintk(ioc, printk(KERN_DEBUG "Handle=0x%X\n",
209 le16_to_cpu(phy_data->AttachedDeviceHandle)));
210 dsasprintk(ioc, printk(KERN_DEBUG "Controller Handle=0x%X\n",
211 le16_to_cpu(phy_data->ControllerDevHandle)));
212 dsasprintk(ioc, printk(KERN_DEBUG "Port=0x%X\n", phy_data->Port));
213 dsasprintk(ioc, printk(KERN_DEBUG "Port Flags=0x%X\n", phy_data->PortFlags));
214 dsasprintk(ioc, printk(KERN_DEBUG "PHY Flags=0x%X\n", phy_data->PhyFlags));
215 dsasprintk(ioc, printk(KERN_DEBUG "Negotiated Link Rate=0x%X\n", phy_data->NegotiatedLinkRate));
216 dsasprintk(ioc, printk(KERN_DEBUG "Controller PHY Device Info=0x%X\n",
217 le32_to_cpu(phy_data->ControllerPhyDeviceInfo)));
218 dsasprintk(ioc, printk(KERN_DEBUG "DiscoveryStatus=0x%X\n\n",
219 le32_to_cpu(phy_data->DiscoveryStatus)));
220}
221
222static void mptsas_print_phy_pg0(MPT_ADAPTER *ioc, SasPhyPage0_t *pg0)
223{
224 __le64 sas_address;
225
226 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
227
228 dsasprintk(ioc, printk(KERN_DEBUG "---- SAS PHY PAGE 0 ------------\n"));
229 dsasprintk(ioc, printk(KERN_DEBUG "Attached Device Handle=0x%X\n",
230 le16_to_cpu(pg0->AttachedDevHandle)));
231 dsasprintk(ioc, printk(KERN_DEBUG "SAS Address=0x%llX\n",
232 (unsigned long long)le64_to_cpu(sas_address)));
233 dsasprintk(ioc, printk(KERN_DEBUG "Attached PHY Identifier=0x%X\n", pg0->AttachedPhyIdentifier));
234 dsasprintk(ioc, printk(KERN_DEBUG "Attached Device Info=0x%X\n",
235 le32_to_cpu(pg0->AttachedDeviceInfo)));
236 dsasprintk(ioc, printk(KERN_DEBUG "Programmed Link Rate=0x%X\n", pg0->ProgrammedLinkRate));
237 dsasprintk(ioc, printk(KERN_DEBUG "Change Count=0x%X\n", pg0->ChangeCount));
238 dsasprintk(ioc, printk(KERN_DEBUG "PHY Info=0x%X\n\n", le32_to_cpu(pg0->PhyInfo)));
239}
240
241static void mptsas_print_phy_pg1(MPT_ADAPTER *ioc, SasPhyPage1_t *pg1)
242{
243 dsasprintk(ioc, printk(KERN_DEBUG "---- SAS PHY PAGE 1 ------------\n"));
244 dsasprintk(ioc, printk(KERN_DEBUG "Invalid Dword Count=0x%x\n", pg1->InvalidDwordCount));
245 dsasprintk(ioc, printk(KERN_DEBUG "Running Disparity Error Count=0x%x\n",
246 pg1->RunningDisparityErrorCount));
247 dsasprintk(ioc, printk(KERN_DEBUG "Loss Dword Synch Count=0x%x\n", pg1->LossDwordSynchCount));
248 dsasprintk(ioc, printk(KERN_DEBUG "PHY Reset Problem Count=0x%x\n\n", pg1->PhyResetProblemCount));
249}
250
251static void mptsas_print_device_pg0(MPT_ADAPTER *ioc, SasDevicePage0_t *pg0)
252{
253 __le64 sas_address;
254
255 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
256
257 dsasprintk(ioc, printk(KERN_DEBUG "---- SAS DEVICE PAGE 0 ---------\n"));
258 dsasprintk(ioc, printk(KERN_DEBUG "Handle=0x%X\n" ,le16_to_cpu(pg0->DevHandle)));
259 dsasprintk(ioc, printk(KERN_DEBUG "Parent Handle=0x%X\n" ,le16_to_cpu(pg0->ParentDevHandle)));
260 dsasprintk(ioc, printk(KERN_DEBUG "Enclosure Handle=0x%X\n", le16_to_cpu(pg0->EnclosureHandle)));
261 dsasprintk(ioc, printk(KERN_DEBUG "Slot=0x%X\n", le16_to_cpu(pg0->Slot)));
262 dsasprintk(ioc, printk(KERN_DEBUG "SAS Address=0x%llX\n", (unsigned long long)
263 le64_to_cpu(sas_address)));
264 dsasprintk(ioc, printk(KERN_DEBUG "Target ID=0x%X\n", pg0->TargetID));
265 dsasprintk(ioc, printk(KERN_DEBUG "Bus=0x%X\n", pg0->Bus));
266 /* The PhyNum field specifies the PHY number of the parent
267 * device this device is linked to
268 */
269 dsasprintk(ioc, printk(KERN_DEBUG "Parent Phy Num=0x%X\n", pg0->PhyNum));
270 dsasprintk(ioc, printk(KERN_DEBUG "Access Status=0x%X\n", le16_to_cpu(pg0->AccessStatus)));
271 dsasprintk(ioc, printk(KERN_DEBUG "Device Info=0x%X\n", le32_to_cpu(pg0->DeviceInfo)));
272 dsasprintk(ioc, printk(KERN_DEBUG "Flags=0x%X\n", le16_to_cpu(pg0->Flags)));
273 dsasprintk(ioc, printk(KERN_DEBUG "Physical Port=0x%X\n\n", pg0->PhysicalPort));
274}
275
276static void mptsas_print_expander_pg1(MPT_ADAPTER *ioc, SasExpanderPage1_t *pg1)
277{
278 dsasprintk(ioc, printk(KERN_DEBUG "---- SAS EXPANDER PAGE 1 ------------\n"));
279 dsasprintk(ioc, printk(KERN_DEBUG "Physical Port=0x%X\n", pg1->PhysicalPort));
280 dsasprintk(ioc, printk(KERN_DEBUG "PHY Identifier=0x%X\n", pg1->PhyIdentifier));
281 dsasprintk(ioc, printk(KERN_DEBUG "Negotiated Link Rate=0x%X\n", pg1->NegotiatedLinkRate));
282 dsasprintk(ioc, printk(KERN_DEBUG "Programmed Link Rate=0x%X\n", pg1->ProgrammedLinkRate));
283 dsasprintk(ioc, printk(KERN_DEBUG "Hardware Link Rate=0x%X\n", pg1->HwLinkRate));
284 dsasprintk(ioc, printk(KERN_DEBUG "Owner Device Handle=0x%X\n",
285 le16_to_cpu(pg1->OwnerDevHandle)));
286 dsasprintk(ioc, printk(KERN_DEBUG "Attached Device Handle=0x%X\n\n",
287 le16_to_cpu(pg1->AttachedDevHandle)));
288}
289
290static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
291{
292 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
293 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
294}
295
296static inline MPT_ADAPTER *rphy_to_ioc(struct sas_rphy *rphy)
297{
298 struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
299 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
300}
301
302/*
303 * mptsas_find_portinfo_by_handle
304 *
305 * This function should be called with the sas_topology_mutex already held
306 */
307static struct mptsas_portinfo *
308mptsas_find_portinfo_by_handle(MPT_ADAPTER *ioc, u16 handle)
309{
310 struct mptsas_portinfo *port_info, *rc=NULL;
311 int i;
312
313 list_for_each_entry(port_info, &ioc->sas_topology, list)
314 for (i = 0; i < port_info->num_phys; i++)
315 if (port_info->phy_info[i].identify.handle == handle) {
316 rc = port_info;
317 goto out;
318 }
319 out:
320 return rc;
321}
322
323/*
324 * Returns true if there is a scsi end device
325 */
326static inline int
327mptsas_is_end_device(struct mptsas_devinfo * attached)
328{
329 if ((attached->sas_address) &&
330 (attached->device_info &
331 MPI_SAS_DEVICE_INFO_END_DEVICE) &&
332 ((attached->device_info &
333 MPI_SAS_DEVICE_INFO_SSP_TARGET) |
334 (attached->device_info &
335 MPI_SAS_DEVICE_INFO_STP_TARGET) |
336 (attached->device_info &
337 MPI_SAS_DEVICE_INFO_SATA_DEVICE)))
338 return 1;
339 else
340 return 0;
341}
342
343/* no mutex */
344static void
345mptsas_port_delete(MPT_ADAPTER *ioc, struct mptsas_portinfo_details * port_details)
346{
347 struct mptsas_portinfo *port_info;
348 struct mptsas_phyinfo *phy_info;
349 u8 i;
350
351 if (!port_details)
352 return;
353
354 port_info = port_details->port_info;
355 phy_info = port_info->phy_info;
356
357 dsaswideprintk(ioc, printk(KERN_DEBUG "%s: [%p]: num_phys=%02d "
358 "bitmask=0x%016llX\n", __FUNCTION__, port_details,
359 port_details->num_phys, (unsigned long long)
360 port_details->phy_bitmask));
361
362 for (i = 0; i < port_info->num_phys; i++, phy_info++) {
363 if(phy_info->port_details != port_details)
364 continue;
365 memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
366 phy_info->port_details = NULL;
367 }
368 kfree(port_details);
369}
370
371static inline struct sas_rphy *
372mptsas_get_rphy(struct mptsas_phyinfo *phy_info)
373{
374 if (phy_info->port_details)
375 return phy_info->port_details->rphy;
376 else
377 return NULL;
378}
379
380static inline void
381mptsas_set_rphy(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy)
382{
383 if (phy_info->port_details) {
384 phy_info->port_details->rphy = rphy;
385 dsaswideprintk(ioc, printk(KERN_DEBUG "sas_rphy_add: rphy=%p\n", rphy));
386 }
387
388 if (rphy) {
389 dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
390 &rphy->dev, "add:"));
391 dsaswideprintk(ioc, printk(KERN_DEBUG "rphy=%p release=%p\n",
392 rphy, rphy->dev.release));
393 }
394}
395
396static inline struct sas_port *
397mptsas_get_port(struct mptsas_phyinfo *phy_info)
398{
399 if (phy_info->port_details)
400 return phy_info->port_details->port;
401 else
402 return NULL;
403}
404
405static inline void
406mptsas_set_port(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_port *port)
407{
408 if (phy_info->port_details)
409 phy_info->port_details->port = port;
410
411 if (port) {
412 dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
413 &port->dev, "add:"));
414 dsaswideprintk(ioc, printk(KERN_DEBUG "port=%p release=%p\n",
415 port, port->dev.release));
416 }
417}
418
419static inline struct scsi_target *
420mptsas_get_starget(struct mptsas_phyinfo *phy_info)
421{
422 if (phy_info->port_details)
423 return phy_info->port_details->starget;
424 else
425 return NULL;
426}
427
428static inline void
429mptsas_set_starget(struct mptsas_phyinfo *phy_info, struct scsi_target *
430starget)
431{
432 if (phy_info->port_details)
433 phy_info->port_details->starget = starget;
434}
435
436
437/*
438 * mptsas_setup_wide_ports
439 *
440 * Updates for new and existing narrow/wide port configuration
441 * in the sas_topology
442 */
443static void
444mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
445{
446 struct mptsas_portinfo_details * port_details;
447 struct mptsas_phyinfo *phy_info, *phy_info_cmp;
448 u64 sas_address;
449 int i, j;
450
451 mutex_lock(&ioc->sas_topology_mutex);
452
453 phy_info = port_info->phy_info;
454 for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
455 if (phy_info->attached.handle)
456 continue;
457 port_details = phy_info->port_details;
458 if (!port_details)
459 continue;
460 if (port_details->num_phys < 2)
461 continue;
462 /*
463 * Removing a phy from a port, letting the last
464 * phy be removed by firmware events.
465 */
466 dsaswideprintk(ioc, printk(KERN_DEBUG
467 "%s: [%p]: deleting phy = %d\n",
468 __FUNCTION__, port_details, i));
469 port_details->num_phys--;
470 port_details->phy_bitmask &= ~ (1 << phy_info->phy_id);
471 memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
472 sas_port_delete_phy(port_details->port, phy_info->phy);
473 phy_info->port_details = NULL;
474 }
475
476 /*
477 * Populate and refresh the tree
478 */
479 phy_info = port_info->phy_info;
480 for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
481 sas_address = phy_info->attached.sas_address;
482 dsaswideprintk(ioc, printk(KERN_DEBUG "phy_id=%d sas_address=0x%018llX\n",
483 i, (unsigned long long)sas_address));
484 if (!sas_address)
485 continue;
486 port_details = phy_info->port_details;
487 /*
488 * Forming a port
489 */
490 if (!port_details) {
491 port_details = kzalloc(sizeof(*port_details),
492 GFP_KERNEL);
493 if (!port_details)
494 goto out;
495 port_details->num_phys = 1;
496 port_details->port_info = port_info;
497 if (phy_info->phy_id < 64 )
498 port_details->phy_bitmask |=
499 (1 << phy_info->phy_id);
500 phy_info->sas_port_add_phy=1;
501 dsaswideprintk(ioc, printk(KERN_DEBUG "\t\tForming port\n\t\t"
502 "phy_id=%d sas_address=0x%018llX\n",
503 i, (unsigned long long)sas_address));
504 phy_info->port_details = port_details;
505 }
506
507 if (i == port_info->num_phys - 1)
508 continue;
509 phy_info_cmp = &port_info->phy_info[i + 1];
510 for (j = i + 1 ; j < port_info->num_phys ; j++,
511 phy_info_cmp++) {
512 if (!phy_info_cmp->attached.sas_address)
513 continue;
514 if (sas_address != phy_info_cmp->attached.sas_address)
515 continue;
516 if (phy_info_cmp->port_details == port_details )
517 continue;
518 dsaswideprintk(ioc, printk(KERN_DEBUG
519 "\t\tphy_id=%d sas_address=0x%018llX\n",
520 j, (unsigned long long)
521 phy_info_cmp->attached.sas_address));
522 if (phy_info_cmp->port_details) {
523 port_details->rphy =
524 mptsas_get_rphy(phy_info_cmp);
525 port_details->port =
526 mptsas_get_port(phy_info_cmp);
527 port_details->starget =
528 mptsas_get_starget(phy_info_cmp);
529 port_details->num_phys =
530 phy_info_cmp->port_details->num_phys;
531 if (!phy_info_cmp->port_details->num_phys)
532 kfree(phy_info_cmp->port_details);
533 } else
534 phy_info_cmp->sas_port_add_phy=1;
535 /*
536 * Adding a phy to a port
537 */
538 phy_info_cmp->port_details = port_details;
539 if (phy_info_cmp->phy_id < 64 )
540 port_details->phy_bitmask |=
541 (1 << phy_info_cmp->phy_id);
542 port_details->num_phys++;
543 }
544 }
545
546 out:
547
548 for (i = 0; i < port_info->num_phys; i++) {
549 port_details = port_info->phy_info[i].port_details;
550 if (!port_details)
551 continue;
552 dsaswideprintk(ioc, printk(KERN_DEBUG
553 "%s: [%p]: phy_id=%02d num_phys=%02d "
554 "bitmask=0x%016llX\n", __FUNCTION__,
555 port_details, i, port_details->num_phys,
556 (unsigned long long)port_details->phy_bitmask));
557 dsaswideprintk(ioc, printk(KERN_DEBUG"\t\tport = %p rphy=%p\n",
558 port_details->port, port_details->rphy));
559 }
560 dsaswideprintk(ioc, printk(KERN_DEBUG"\n"));
561 mutex_unlock(&ioc->sas_topology_mutex);
562}
563
564/**
565 * csmisas_find_vtarget
566 *
567 * @ioc
568 * @volume_id
569 * @volume_bus
570 *
571 **/
572static VirtTarget *
573mptsas_find_vtarget(MPT_ADAPTER *ioc, u8 channel, u8 id)
574{
575 struct scsi_device *sdev;
576 VirtDevice *vdev;
577 VirtTarget *vtarget = NULL;
578
579 shost_for_each_device(sdev, ioc->sh) {
580 if ((vdev = sdev->hostdata) == NULL)
581 continue;
582 if (vdev->vtarget->id == id &&
583 vdev->vtarget->channel == channel)
584 vtarget = vdev->vtarget;
585 }
586 return vtarget;
587}
588
589/**
590 * mptsas_target_reset
591 *
592 * Issues TARGET_RESET to end device using handshaking method
593 *
594 * @ioc
595 * @channel
596 * @id
597 *
598 * Returns (1) success
599 * (0) failure
600 *
601 **/
602static int
603mptsas_target_reset(MPT_ADAPTER *ioc, u8 channel, u8 id)
604{
605 MPT_FRAME_HDR *mf;
606 SCSITaskMgmt_t *pScsiTm;
607
608 if ((mf = mpt_get_msg_frame(ioc->TaskCtx, ioc)) == NULL) {
609 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames @%d!!\n",
610 ioc->name,__FUNCTION__, __LINE__));
611 return 0;
612 }
613
614 /* Format the Request
615 */
616 pScsiTm = (SCSITaskMgmt_t *) mf;
617 memset (pScsiTm, 0, sizeof(SCSITaskMgmt_t));
618 pScsiTm->TargetID = id;
619 pScsiTm->Bus = channel;
620 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
621 pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
622 pScsiTm->MsgFlags = MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION;
623
624 DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)mf);
625
626 if (mpt_send_handshake_request(ioc->TaskCtx, ioc,
627 sizeof(SCSITaskMgmt_t), (u32 *)mf, NO_SLEEP)) {
628 mpt_free_msg_frame(ioc, mf);
629 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, tm handshake failed @%d!!\n",
630 ioc->name,__FUNCTION__, __LINE__));
631 return 0;
632 }
633
634 return 1;
635}
636
637/**
638 * mptsas_target_reset_queue
639 *
640 * Receive request for TARGET_RESET after recieving an firmware
641 * event NOT_RESPONDING_EVENT, then put command in link list
642 * and queue if task_queue already in use.
643 *
644 * @ioc
645 * @sas_event_data
646 *
647 **/
648static void
649mptsas_target_reset_queue(MPT_ADAPTER *ioc,
650 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
651{
652 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
653 VirtTarget *vtarget = NULL;
654 struct mptsas_target_reset_event *target_reset_list;
655 u8 id, channel;
656
657 id = sas_event_data->TargetID;
658 channel = sas_event_data->Bus;
659
660 if (!(vtarget = mptsas_find_vtarget(ioc, channel, id)))
661 return;
662
663 vtarget->deleted = 1; /* block IO */
664
665 target_reset_list = kzalloc(sizeof(*target_reset_list),
666 GFP_ATOMIC);
667 if (!target_reset_list) {
668 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, failed to allocate mem @%d..!!\n",
669 ioc->name,__FUNCTION__, __LINE__));
670 return;
671 }
672
673 memcpy(&target_reset_list->sas_event_data, sas_event_data,
674 sizeof(*sas_event_data));
675 list_add_tail(&target_reset_list->list, &hd->target_reset_list);
676
677 if (hd->resetPending)
678 return;
679
680 if (mptsas_target_reset(ioc, channel, id)) {
681 target_reset_list->target_reset_issued = 1;
682 hd->resetPending = 1;
683 }
684}
685
686/**
687 * mptsas_dev_reset_complete
688 *
689 * Completion for TARGET_RESET after NOT_RESPONDING_EVENT,
690 * enable work queue to finish off removing device from upper layers.
691 * then send next TARGET_RESET in the queue.
692 *
693 * @ioc
694 *
695 **/
696static void
697mptsas_dev_reset_complete(MPT_ADAPTER *ioc)
698{
699 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
700 struct list_head *head = &hd->target_reset_list;
701 struct mptsas_target_reset_event *target_reset_list;
702 struct mptsas_hotplug_event *ev;
703 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data;
704 u8 id, channel;
705 __le64 sas_address;
706
707 if (list_empty(head))
708 return;
709
710 target_reset_list = list_entry(head->next, struct mptsas_target_reset_event, list);
711
712 sas_event_data = &target_reset_list->sas_event_data;
713 id = sas_event_data->TargetID;
714 channel = sas_event_data->Bus;
715 hd->resetPending = 0;
716
717 /*
718 * retry target reset
719 */
720 if (!target_reset_list->target_reset_issued) {
721 if (mptsas_target_reset(ioc, channel, id)) {
722 target_reset_list->target_reset_issued = 1;
723 hd->resetPending = 1;
724 }
725 return;
726 }
727
728 /*
729 * enable work queue to remove device from upper layers
730 */
731 list_del(&target_reset_list->list);
732
733 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
734 if (!ev) {
735 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, failed to allocate mem @%d..!!\n",
736 ioc->name,__FUNCTION__, __LINE__));
737 return;
738 }
739
740 INIT_WORK(&ev->work, mptsas_hotplug_work);
741 ev->ioc = ioc;
742 ev->handle = le16_to_cpu(sas_event_data->DevHandle);
743 ev->parent_handle =
744 le16_to_cpu(sas_event_data->ParentDevHandle);
745 ev->channel = channel;
746 ev->id =id;
747 ev->phy_id = sas_event_data->PhyNum;
748 memcpy(&sas_address, &sas_event_data->SASAddress,
749 sizeof(__le64));
750 ev->sas_address = le64_to_cpu(sas_address);
751 ev->device_info = le32_to_cpu(sas_event_data->DeviceInfo);
752 ev->event_type = MPTSAS_DEL_DEVICE;
753 schedule_work(&ev->work);
754 kfree(target_reset_list);
755
756 /*
757 * issue target reset to next device in the queue
758 */
759
760 head = &hd->target_reset_list;
761 if (list_empty(head))
762 return;
763
764 target_reset_list = list_entry(head->next, struct mptsas_target_reset_event,
765 list);
766
767 sas_event_data = &target_reset_list->sas_event_data;
768 id = sas_event_data->TargetID;
769 channel = sas_event_data->Bus;
770
771 if (mptsas_target_reset(ioc, channel, id)) {
772 target_reset_list->target_reset_issued = 1;
773 hd->resetPending = 1;
774 }
775}
776
777/**
778 * mptsas_taskmgmt_complete
779 *
780 * @ioc
781 * @mf
782 * @mr
783 *
784 **/
785static int
786mptsas_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
787{
788 mptsas_dev_reset_complete(ioc);
789 return mptscsih_taskmgmt_complete(ioc, mf, mr);
790}
791
792/**
793 * mptscsih_ioc_reset
794 *
795 * @ioc
796 * @reset_phase
797 *
798 **/
799static int
800mptsas_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
801{
802 MPT_SCSI_HOST *hd;
803 struct mptsas_target_reset_event *target_reset_list, *n;
804 int rc;
805
806 rc = mptscsih_ioc_reset(ioc, reset_phase);
807
808 if (ioc->bus_type != SAS)
809 goto out;
810
811 if (reset_phase != MPT_IOC_POST_RESET)
812 goto out;
813
814 if (!ioc->sh || !ioc->sh->hostdata)
815 goto out;
816 hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
817 if (!hd->ioc)
818 goto out;
819
820 if (list_empty(&hd->target_reset_list))
821 goto out;
822
823 /* flush the target_reset_list */
824 list_for_each_entry_safe(target_reset_list, n,
825 &hd->target_reset_list, list) {
826 list_del(&target_reset_list->list);
827 kfree(target_reset_list);
828 }
829
830 out:
831 return rc;
832}
833
834static int
835mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
836 u32 form, u32 form_specific)
837{
838 ConfigExtendedPageHeader_t hdr;
839 CONFIGPARMS cfg;
840 SasEnclosurePage0_t *buffer;
841 dma_addr_t dma_handle;
842 int error;
843 __le64 le_identifier;
844
845 memset(&hdr, 0, sizeof(hdr));
846 hdr.PageVersion = MPI_SASENCLOSURE0_PAGEVERSION;
847 hdr.PageNumber = 0;
848 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
849 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_ENCLOSURE;
850
851 cfg.cfghdr.ehdr = &hdr;
852 cfg.physAddr = -1;
853 cfg.pageAddr = form + form_specific;
854 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
855 cfg.dir = 0; /* read */
856 cfg.timeout = 10;
857
858 error = mpt_config(ioc, &cfg);
859 if (error)
860 goto out;
861 if (!hdr.ExtPageLength) {
862 error = -ENXIO;
863 goto out;
864 }
865
866 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
867 &dma_handle);
868 if (!buffer) {
869 error = -ENOMEM;
870 goto out;
871 }
872
873 cfg.physAddr = dma_handle;
874 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
875
876 error = mpt_config(ioc, &cfg);
877 if (error)
878 goto out_free_consistent;
879
880 /* save config data */
881 memcpy(&le_identifier, &buffer->EnclosureLogicalID, sizeof(__le64));
882 enclosure->enclosure_logical_id = le64_to_cpu(le_identifier);
883 enclosure->enclosure_handle = le16_to_cpu(buffer->EnclosureHandle);
884 enclosure->flags = le16_to_cpu(buffer->Flags);
885 enclosure->num_slot = le16_to_cpu(buffer->NumSlots);
886 enclosure->start_slot = le16_to_cpu(buffer->StartSlot);
887 enclosure->start_id = buffer->StartTargetID;
888 enclosure->start_channel = buffer->StartBus;
889 enclosure->sep_id = buffer->SEPTargetID;
890 enclosure->sep_channel = buffer->SEPBus;
891
892 out_free_consistent:
893 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
894 buffer, dma_handle);
895 out:
896 return error;
897}
898
899static int
900mptsas_slave_configure(struct scsi_device *sdev)
901{
902
903 if (sdev->channel == MPTSAS_RAID_CHANNEL)
904 goto out;
905
906 sas_read_port_mode_page(sdev);
907
908 out:
909 return mptscsih_slave_configure(sdev);
910}
911
912static int
913mptsas_target_alloc(struct scsi_target *starget)
914{
915 struct Scsi_Host *host = dev_to_shost(&starget->dev);
916 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
917 VirtTarget *vtarget;
918 u8 id, channel;
919 struct sas_rphy *rphy;
920 struct mptsas_portinfo *p;
921 int i;
922
923 vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
924 if (!vtarget)
925 return -ENOMEM;
926
927 vtarget->starget = starget;
928 vtarget->ioc_id = hd->ioc->id;
929 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
930 id = starget->id;
931 channel = 0;
932
933 /*
934 * RAID volumes placed beyond the last expected port.
935 */
936 if (starget->channel == MPTSAS_RAID_CHANNEL) {
937 for (i=0; i < hd->ioc->raid_data.pIocPg2->NumActiveVolumes; i++)
938 if (id == hd->ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID)
939 channel = hd->ioc->raid_data.pIocPg2->RaidVolume[i].VolumeBus;
940 goto out;
941 }
942
943 rphy = dev_to_rphy(starget->dev.parent);
944 mutex_lock(&hd->ioc->sas_topology_mutex);
945 list_for_each_entry(p, &hd->ioc->sas_topology, list) {
946 for (i = 0; i < p->num_phys; i++) {
947 if (p->phy_info[i].attached.sas_address !=
948 rphy->identify.sas_address)
949 continue;
950 id = p->phy_info[i].attached.id;
951 channel = p->phy_info[i].attached.channel;
952 mptsas_set_starget(&p->phy_info[i], starget);
953
954 /*
955 * Exposing hidden raid components
956 */
957 if (mptscsih_is_phys_disk(hd->ioc, channel, id)) {
958 id = mptscsih_raid_id_to_num(hd->ioc,
959 channel, id);
960 vtarget->tflags |=
961 MPT_TARGET_FLAGS_RAID_COMPONENT;
962 p->phy_info[i].attached.phys_disk_num = id;
963 }
964 mutex_unlock(&hd->ioc->sas_topology_mutex);
965 goto out;
966 }
967 }
968 mutex_unlock(&hd->ioc->sas_topology_mutex);
969
970 kfree(vtarget);
971 return -ENXIO;
972
973 out:
974 vtarget->id = id;
975 vtarget->channel = channel;
976 starget->hostdata = vtarget;
977 return 0;
978}
979
980static void
981mptsas_target_destroy(struct scsi_target *starget)
982{
983 struct Scsi_Host *host = dev_to_shost(&starget->dev);
984 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
985 struct sas_rphy *rphy;
986 struct mptsas_portinfo *p;
987 int i;
988
989 if (!starget->hostdata)
990 return;
991
992 if (starget->channel == MPTSAS_RAID_CHANNEL)
993 goto out;
994
995 rphy = dev_to_rphy(starget->dev.parent);
996 list_for_each_entry(p, &hd->ioc->sas_topology, list) {
997 for (i = 0; i < p->num_phys; i++) {
998 if (p->phy_info[i].attached.sas_address !=
999 rphy->identify.sas_address)
1000 continue;
1001 mptsas_set_starget(&p->phy_info[i], NULL);
1002 goto out;
1003 }
1004 }
1005
1006 out:
1007 kfree(starget->hostdata);
1008 starget->hostdata = NULL;
1009}
1010
1011
1012static int
1013mptsas_slave_alloc(struct scsi_device *sdev)
1014{
1015 struct Scsi_Host *host = sdev->host;
1016 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
1017 struct sas_rphy *rphy;
1018 struct mptsas_portinfo *p;
1019 VirtDevice *vdev;
1020 struct scsi_target *starget;
1021 int i;
1022
1023 vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
1024 if (!vdev) {
1025 printk(MYIOC_s_ERR_FMT "slave_alloc kzalloc(%zd) FAILED!\n",
1026 hd->ioc->name, sizeof(VirtDevice));
1027 return -ENOMEM;
1028 }
1029 starget = scsi_target(sdev);
1030 vdev->vtarget = starget->hostdata;
1031
1032 if (sdev->channel == MPTSAS_RAID_CHANNEL)
1033 goto out;
1034
1035 rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
1036 mutex_lock(&hd->ioc->sas_topology_mutex);
1037 list_for_each_entry(p, &hd->ioc->sas_topology, list) {
1038 for (i = 0; i < p->num_phys; i++) {
1039 if (p->phy_info[i].attached.sas_address !=
1040 rphy->identify.sas_address)
1041 continue;
1042 vdev->lun = sdev->lun;
1043 /*
1044 * Exposing hidden raid components
1045 */
1046 if (mptscsih_is_phys_disk(hd->ioc,
1047 p->phy_info[i].attached.channel,
1048 p->phy_info[i].attached.id))
1049 sdev->no_uld_attach = 1;
1050 mutex_unlock(&hd->ioc->sas_topology_mutex);
1051 goto out;
1052 }
1053 }
1054 mutex_unlock(&hd->ioc->sas_topology_mutex);
1055
1056 kfree(vdev);
1057 return -ENXIO;
1058
1059 out:
1060 vdev->vtarget->num_luns++;
1061 sdev->hostdata = vdev;
1062 return 0;
1063}
1064
1065static int
1066mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1067{
1068 VirtDevice *vdev = SCpnt->device->hostdata;
1069
1070 if (!vdev || !vdev->vtarget || vdev->vtarget->deleted) {
1071 SCpnt->result = DID_NO_CONNECT << 16;
1072 done(SCpnt);
1073 return 0;
1074 }
1075
1076// scsi_print_command(SCpnt);
1077
1078 return mptscsih_qcmd(SCpnt,done);
1079}
1080
1081
1082static struct scsi_host_template mptsas_driver_template = {
1083 .module = THIS_MODULE,
1084 .proc_name = "mptsas",
1085 .proc_info = mptscsih_proc_info,
1086 .name = "MPT SPI Host",
1087 .info = mptscsih_info,
1088 .queuecommand = mptsas_qcmd,
1089 .target_alloc = mptsas_target_alloc,
1090 .slave_alloc = mptsas_slave_alloc,
1091 .slave_configure = mptsas_slave_configure,
1092 .target_destroy = mptsas_target_destroy,
1093 .slave_destroy = mptscsih_slave_destroy,
1094 .change_queue_depth = mptscsih_change_queue_depth,
1095 .eh_abort_handler = mptscsih_abort,
1096 .eh_device_reset_handler = mptscsih_dev_reset,
1097 .eh_bus_reset_handler = mptscsih_bus_reset,
1098 .eh_host_reset_handler = mptscsih_host_reset,
1099 .bios_param = mptscsih_bios_param,
1100 .can_queue = MPT_FC_CAN_QUEUE,
1101 .this_id = -1,
1102 .sg_tablesize = MPT_SCSI_SG_DEPTH,
1103 .max_sectors = 8192,
1104 .cmd_per_lun = 7,
1105 .use_clustering = ENABLE_CLUSTERING,
1106 .shost_attrs = mptscsih_host_attrs,
1107};
1108
1109static int mptsas_get_linkerrors(struct sas_phy *phy)
1110{
1111 MPT_ADAPTER *ioc = phy_to_ioc(phy);
1112 ConfigExtendedPageHeader_t hdr;
1113 CONFIGPARMS cfg;
1114 SasPhyPage1_t *buffer;
1115 dma_addr_t dma_handle;
1116 int error;
1117
1118 /* FIXME: only have link errors on local phys */
1119 if (!scsi_is_sas_phy_local(phy))
1120 return -EINVAL;
1121
1122 hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
1123 hdr.ExtPageLength = 0;
1124 hdr.PageNumber = 1 /* page number 1*/;
1125 hdr.Reserved1 = 0;
1126 hdr.Reserved2 = 0;
1127 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1128 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
1129
1130 cfg.cfghdr.ehdr = &hdr;
1131 cfg.physAddr = -1;
1132 cfg.pageAddr = phy->identify.phy_identifier;
1133 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1134 cfg.dir = 0; /* read */
1135 cfg.timeout = 10;
1136
1137 error = mpt_config(ioc, &cfg);
1138 if (error)
1139 return error;
1140 if (!hdr.ExtPageLength)
1141 return -ENXIO;
1142
1143 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1144 &dma_handle);
1145 if (!buffer)
1146 return -ENOMEM;
1147
1148 cfg.physAddr = dma_handle;
1149 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1150
1151 error = mpt_config(ioc, &cfg);
1152 if (error)
1153 goto out_free_consistent;
1154
1155 mptsas_print_phy_pg1(ioc, buffer);
1156
1157 phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
1158 phy->running_disparity_error_count =
1159 le32_to_cpu(buffer->RunningDisparityErrorCount);
1160 phy->loss_of_dword_sync_count =
1161 le32_to_cpu(buffer->LossDwordSynchCount);
1162 phy->phy_reset_problem_count =
1163 le32_to_cpu(buffer->PhyResetProblemCount);
1164
1165 out_free_consistent:
1166 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1167 buffer, dma_handle);
1168 return error;
1169}
1170
1171static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
1172 MPT_FRAME_HDR *reply)
1173{
1174 ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_COMMAND_GOOD;
1175 if (reply != NULL) {
1176 ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_RF_VALID;
1177 memcpy(ioc->sas_mgmt.reply, reply,
1178 min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
1179 }
1180 complete(&ioc->sas_mgmt.done);
1181 return 1;
1182}
1183
1184static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
1185{
1186 MPT_ADAPTER *ioc = phy_to_ioc(phy);
1187 SasIoUnitControlRequest_t *req;
1188 SasIoUnitControlReply_t *reply;
1189 MPT_FRAME_HDR *mf;
1190 MPIHeader_t *hdr;
1191 unsigned long timeleft;
1192 int error = -ERESTARTSYS;
1193
1194 /* FIXME: fusion doesn't allow non-local phy reset */
1195 if (!scsi_is_sas_phy_local(phy))
1196 return -EINVAL;
1197
1198 /* not implemented for expanders */
1199 if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
1200 return -ENXIO;
1201
1202 if (mutex_lock_interruptible(&ioc->sas_mgmt.mutex))
1203 goto out;
1204
1205 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
1206 if (!mf) {
1207 error = -ENOMEM;
1208 goto out_unlock;
1209 }
1210
1211 hdr = (MPIHeader_t *) mf;
1212 req = (SasIoUnitControlRequest_t *)mf;
1213 memset(req, 0, sizeof(SasIoUnitControlRequest_t));
1214 req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
1215 req->MsgContext = hdr->MsgContext;
1216 req->Operation = hard_reset ?
1217 MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
1218 req->PhyNum = phy->identify.phy_identifier;
1219
1220 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
1221
1222 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
1223 10 * HZ);
1224 if (!timeleft) {
1225 /* On timeout reset the board */
1226 mpt_free_msg_frame(ioc, mf);
1227 mpt_HardResetHandler(ioc, CAN_SLEEP);
1228 error = -ETIMEDOUT;
1229 goto out_unlock;
1230 }
1231
1232 /* a reply frame is expected */
1233 if ((ioc->sas_mgmt.status &
1234 MPT_IOCTL_STATUS_RF_VALID) == 0) {
1235 error = -ENXIO;
1236 goto out_unlock;
1237 }
1238
1239 /* process the completed Reply Message Frame */
1240 reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
1241 if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
1242 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
1243 __FUNCTION__,
1244 reply->IOCStatus,
1245 reply->IOCLogInfo);
1246 error = -ENXIO;
1247 goto out_unlock;
1248 }
1249
1250 error = 0;
1251
1252 out_unlock:
1253 mutex_unlock(&ioc->sas_mgmt.mutex);
1254 out:
1255 return error;
1256}
1257
1258static int
1259mptsas_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
1260{
1261 MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
1262 int i, error;
1263 struct mptsas_portinfo *p;
1264 struct mptsas_enclosure enclosure_info;
1265 u64 enclosure_handle;
1266
1267 mutex_lock(&ioc->sas_topology_mutex);
1268 list_for_each_entry(p, &ioc->sas_topology, list) {
1269 for (i = 0; i < p->num_phys; i++) {
1270 if (p->phy_info[i].attached.sas_address ==
1271 rphy->identify.sas_address) {
1272 enclosure_handle = p->phy_info[i].
1273 attached.handle_enclosure;
1274 goto found_info;
1275 }
1276 }
1277 }
1278 mutex_unlock(&ioc->sas_topology_mutex);
1279 return -ENXIO;
1280
1281 found_info:
1282 mutex_unlock(&ioc->sas_topology_mutex);
1283 memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
1284 error = mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
1285 (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
1286 MPI_SAS_ENCLOS_PGAD_FORM_SHIFT), enclosure_handle);
1287 if (!error)
1288 *identifier = enclosure_info.enclosure_logical_id;
1289 return error;
1290}
1291
1292static int
1293mptsas_get_bay_identifier(struct sas_rphy *rphy)
1294{
1295 MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
1296 struct mptsas_portinfo *p;
1297 int i, rc;
1298
1299 mutex_lock(&ioc->sas_topology_mutex);
1300 list_for_each_entry(p, &ioc->sas_topology, list) {
1301 for (i = 0; i < p->num_phys; i++) {
1302 if (p->phy_info[i].attached.sas_address ==
1303 rphy->identify.sas_address) {
1304 rc = p->phy_info[i].attached.slot;
1305 goto out;
1306 }
1307 }
1308 }
1309 rc = -ENXIO;
1310 out:
1311 mutex_unlock(&ioc->sas_topology_mutex);
1312 return rc;
1313}
1314
1315static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
1316 struct request *req)
1317{
1318 MPT_ADAPTER *ioc = ((MPT_SCSI_HOST *) shost->hostdata)->ioc;
1319 MPT_FRAME_HDR *mf;
1320 SmpPassthroughRequest_t *smpreq;
1321 struct request *rsp = req->next_rq;
1322 int ret;
1323 int flagsLength;
1324 unsigned long timeleft;
1325 char *psge;
1326 dma_addr_t dma_addr_in = 0;
1327 dma_addr_t dma_addr_out = 0;
1328 u64 sas_address = 0;
1329
1330 if (!rsp) {
1331 printk(KERN_ERR "%s: the smp response space is missing\n",
1332 __FUNCTION__);
1333 return -EINVAL;
1334 }
1335
1336 /* do we need to support multiple segments? */
1337 if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) {
1338 printk(KERN_ERR "%s: multiple segments req %u %u, rsp %u %u\n",
1339 __FUNCTION__, req->bio->bi_vcnt, req->data_len,
1340 rsp->bio->bi_vcnt, rsp->data_len);
1341 return -EINVAL;
1342 }
1343
1344 ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
1345 if (ret)
1346 goto out;
1347
1348 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
1349 if (!mf) {
1350 ret = -ENOMEM;
1351 goto out_unlock;
1352 }
1353
1354 smpreq = (SmpPassthroughRequest_t *)mf;
1355 memset(smpreq, 0, sizeof(*smpreq));
1356
1357 smpreq->RequestDataLength = cpu_to_le16(req->data_len - 4);
1358 smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
1359
1360 if (rphy)
1361 sas_address = rphy->identify.sas_address;
1362 else {
1363 struct mptsas_portinfo *port_info;
1364
1365 mutex_lock(&ioc->sas_topology_mutex);
1366 port_info = mptsas_find_portinfo_by_handle(ioc, ioc->handle);
1367 if (port_info && port_info->phy_info)
1368 sas_address =
1369 port_info->phy_info[0].phy->identify.sas_address;
1370 mutex_unlock(&ioc->sas_topology_mutex);
1371 }
1372
1373 *((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
1374
1375 psge = (char *)
1376 (((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
1377
1378 /* request */
1379 flagsLength = (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1380 MPI_SGE_FLAGS_END_OF_BUFFER |
1381 MPI_SGE_FLAGS_DIRECTION |
1382 mpt_addr_size()) << MPI_SGE_FLAGS_SHIFT;
1383 flagsLength |= (req->data_len - 4);
1384
1385 dma_addr_out = pci_map_single(ioc->pcidev, bio_data(req->bio),
1386 req->data_len, PCI_DMA_BIDIRECTIONAL);
1387 if (!dma_addr_out)
1388 goto put_mf;
1389 mpt_add_sge(psge, flagsLength, dma_addr_out);
1390 psge += (sizeof(u32) + sizeof(dma_addr_t));
1391
1392 /* response */
1393 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
1394 flagsLength |= rsp->data_len + 4;
1395 dma_addr_in = pci_map_single(ioc->pcidev, bio_data(rsp->bio),
1396 rsp->data_len, PCI_DMA_BIDIRECTIONAL);
1397 if (!dma_addr_in)
1398 goto unmap;
1399 mpt_add_sge(psge, flagsLength, dma_addr_in);
1400
1401 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
1402
1403 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
1404 if (!timeleft) {
1405 printk(KERN_ERR "%s: smp timeout!\n", __FUNCTION__);
1406 /* On timeout reset the board */
1407 mpt_HardResetHandler(ioc, CAN_SLEEP);
1408 ret = -ETIMEDOUT;
1409 goto unmap;
1410 }
1411 mf = NULL;
1412
1413 if (ioc->sas_mgmt.status & MPT_IOCTL_STATUS_RF_VALID) {
1414 SmpPassthroughReply_t *smprep;
1415
1416 smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
1417 memcpy(req->sense, smprep, sizeof(*smprep));
1418 req->sense_len = sizeof(*smprep);
1419 } else {
1420 printk(KERN_ERR "%s: smp passthru reply failed to be returned\n",
1421 __FUNCTION__);
1422 ret = -ENXIO;
1423 }
1424unmap:
1425 if (dma_addr_out)
1426 pci_unmap_single(ioc->pcidev, dma_addr_out, req->data_len,
1427 PCI_DMA_BIDIRECTIONAL);
1428 if (dma_addr_in)
1429 pci_unmap_single(ioc->pcidev, dma_addr_in, rsp->data_len,
1430 PCI_DMA_BIDIRECTIONAL);
1431put_mf:
1432 if (mf)
1433 mpt_free_msg_frame(ioc, mf);
1434out_unlock:
1435 mutex_unlock(&ioc->sas_mgmt.mutex);
1436out:
1437 return ret;
1438}
1439
1440static struct sas_function_template mptsas_transport_functions = {
1441 .get_linkerrors = mptsas_get_linkerrors,
1442 .get_enclosure_identifier = mptsas_get_enclosure_identifier,
1443 .get_bay_identifier = mptsas_get_bay_identifier,
1444 .phy_reset = mptsas_phy_reset,
1445 .smp_handler = mptsas_smp_handler,
1446};
1447
1448static struct scsi_transport_template *mptsas_transport_template;
1449
1450static int
1451mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
1452{
1453 ConfigExtendedPageHeader_t hdr;
1454 CONFIGPARMS cfg;
1455 SasIOUnitPage0_t *buffer;
1456 dma_addr_t dma_handle;
1457 int error, i;
1458
1459 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
1460 hdr.ExtPageLength = 0;
1461 hdr.PageNumber = 0;
1462 hdr.Reserved1 = 0;
1463 hdr.Reserved2 = 0;
1464 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1465 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1466
1467 cfg.cfghdr.ehdr = &hdr;
1468 cfg.physAddr = -1;
1469 cfg.pageAddr = 0;
1470 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1471 cfg.dir = 0; /* read */
1472 cfg.timeout = 10;
1473
1474 error = mpt_config(ioc, &cfg);
1475 if (error)
1476 goto out;
1477 if (!hdr.ExtPageLength) {
1478 error = -ENXIO;
1479 goto out;
1480 }
1481
1482 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1483 &dma_handle);
1484 if (!buffer) {
1485 error = -ENOMEM;
1486 goto out;
1487 }
1488
1489 cfg.physAddr = dma_handle;
1490 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1491
1492 error = mpt_config(ioc, &cfg);
1493 if (error)
1494 goto out_free_consistent;
1495
1496 port_info->num_phys = buffer->NumPhys;
1497 port_info->phy_info = kcalloc(port_info->num_phys,
1498 sizeof(*port_info->phy_info),GFP_KERNEL);
1499 if (!port_info->phy_info) {
1500 error = -ENOMEM;
1501 goto out_free_consistent;
1502 }
1503
1504 ioc->nvdata_version_persistent =
1505 le16_to_cpu(buffer->NvdataVersionPersistent);
1506 ioc->nvdata_version_default =
1507 le16_to_cpu(buffer->NvdataVersionDefault);
1508
1509 for (i = 0; i < port_info->num_phys; i++) {
1510 mptsas_print_phy_data(ioc, &buffer->PhyData[i]);
1511 port_info->phy_info[i].phy_id = i;
1512 port_info->phy_info[i].port_id =
1513 buffer->PhyData[i].Port;
1514 port_info->phy_info[i].negotiated_link_rate =
1515 buffer->PhyData[i].NegotiatedLinkRate;
1516 port_info->phy_info[i].portinfo = port_info;
1517 port_info->phy_info[i].handle =
1518 le16_to_cpu(buffer->PhyData[i].ControllerDevHandle);
1519 }
1520
1521 out_free_consistent:
1522 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1523 buffer, dma_handle);
1524 out:
1525 return error;
1526}
1527
1528static int
1529mptsas_sas_io_unit_pg1(MPT_ADAPTER *ioc)
1530{
1531 ConfigExtendedPageHeader_t hdr;
1532 CONFIGPARMS cfg;
1533 SasIOUnitPage1_t *buffer;
1534 dma_addr_t dma_handle;
1535 int error;
1536 u16 device_missing_delay;
1537
1538 memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
1539 memset(&cfg, 0, sizeof(CONFIGPARMS));
1540
1541 cfg.cfghdr.ehdr = &hdr;
1542 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1543 cfg.timeout = 10;
1544 cfg.cfghdr.ehdr->PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1545 cfg.cfghdr.ehdr->ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1546 cfg.cfghdr.ehdr->PageVersion = MPI_SASIOUNITPAGE1_PAGEVERSION;
1547 cfg.cfghdr.ehdr->PageNumber = 1;
1548
1549 error = mpt_config(ioc, &cfg);
1550 if (error)
1551 goto out;
1552 if (!hdr.ExtPageLength) {
1553 error = -ENXIO;
1554 goto out;
1555 }
1556
1557 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1558 &dma_handle);
1559 if (!buffer) {
1560 error = -ENOMEM;
1561 goto out;
1562 }
1563
1564 cfg.physAddr = dma_handle;
1565 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1566
1567 error = mpt_config(ioc, &cfg);
1568 if (error)
1569 goto out_free_consistent;
1570
1571 ioc->io_missing_delay =
1572 le16_to_cpu(buffer->IODeviceMissingDelay);
1573 device_missing_delay = le16_to_cpu(buffer->ReportDeviceMissingDelay);
1574 ioc->device_missing_delay = (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_UNIT_16) ?
1575 (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16 :
1576 device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
1577
1578 out_free_consistent:
1579 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1580 buffer, dma_handle);
1581 out:
1582 return error;
1583}
1584
1585static int
1586mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
1587 u32 form, u32 form_specific)
1588{
1589 ConfigExtendedPageHeader_t hdr;
1590 CONFIGPARMS cfg;
1591 SasPhyPage0_t *buffer;
1592 dma_addr_t dma_handle;
1593 int error;
1594
1595 hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
1596 hdr.ExtPageLength = 0;
1597 hdr.PageNumber = 0;
1598 hdr.Reserved1 = 0;
1599 hdr.Reserved2 = 0;
1600 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1601 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
1602
1603 cfg.cfghdr.ehdr = &hdr;
1604 cfg.dir = 0; /* read */
1605 cfg.timeout = 10;
1606
1607 /* Get Phy Pg 0 for each Phy. */
1608 cfg.physAddr = -1;
1609 cfg.pageAddr = form + form_specific;
1610 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1611
1612 error = mpt_config(ioc, &cfg);
1613 if (error)
1614 goto out;
1615
1616 if (!hdr.ExtPageLength) {
1617 error = -ENXIO;
1618 goto out;
1619 }
1620
1621 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1622 &dma_handle);
1623 if (!buffer) {
1624 error = -ENOMEM;
1625 goto out;
1626 }
1627
1628 cfg.physAddr = dma_handle;
1629 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1630
1631 error = mpt_config(ioc, &cfg);
1632 if (error)
1633 goto out_free_consistent;
1634
1635 mptsas_print_phy_pg0(ioc, buffer);
1636
1637 phy_info->hw_link_rate = buffer->HwLinkRate;
1638 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
1639 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
1640 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
1641
1642 out_free_consistent:
1643 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1644 buffer, dma_handle);
1645 out:
1646 return error;
1647}
1648
1649static int
1650mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
1651 u32 form, u32 form_specific)
1652{
1653 ConfigExtendedPageHeader_t hdr;
1654 CONFIGPARMS cfg;
1655 SasDevicePage0_t *buffer;
1656 dma_addr_t dma_handle;
1657 __le64 sas_address;
1658 int error=0;
1659
1660 if (ioc->sas_discovery_runtime &&
1661 mptsas_is_end_device(device_info))
1662 goto out;
1663
1664 hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
1665 hdr.ExtPageLength = 0;
1666 hdr.PageNumber = 0;
1667 hdr.Reserved1 = 0;
1668 hdr.Reserved2 = 0;
1669 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1670 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
1671
1672 cfg.cfghdr.ehdr = &hdr;
1673 cfg.pageAddr = form + form_specific;
1674 cfg.physAddr = -1;
1675 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1676 cfg.dir = 0; /* read */
1677 cfg.timeout = 10;
1678
1679 memset(device_info, 0, sizeof(struct mptsas_devinfo));
1680 error = mpt_config(ioc, &cfg);
1681 if (error)
1682 goto out;
1683 if (!hdr.ExtPageLength) {
1684 error = -ENXIO;
1685 goto out;
1686 }
1687
1688 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1689 &dma_handle);
1690 if (!buffer) {
1691 error = -ENOMEM;
1692 goto out;
1693 }
1694
1695 cfg.physAddr = dma_handle;
1696 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1697
1698 error = mpt_config(ioc, &cfg);
1699 if (error)
1700 goto out_free_consistent;
1701
1702 mptsas_print_device_pg0(ioc, buffer);
1703
1704 device_info->handle = le16_to_cpu(buffer->DevHandle);
1705 device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle);
1706 device_info->handle_enclosure =
1707 le16_to_cpu(buffer->EnclosureHandle);
1708 device_info->slot = le16_to_cpu(buffer->Slot);
1709 device_info->phy_id = buffer->PhyNum;
1710 device_info->port_id = buffer->PhysicalPort;
1711 device_info->id = buffer->TargetID;
1712 device_info->phys_disk_num = ~0;
1713 device_info->channel = buffer->Bus;
1714 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
1715 device_info->sas_address = le64_to_cpu(sas_address);
1716 device_info->device_info =
1717 le32_to_cpu(buffer->DeviceInfo);
1718
1719 out_free_consistent:
1720 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1721 buffer, dma_handle);
1722 out:
1723 return error;
1724}
1725
1726static int
1727mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
1728 u32 form, u32 form_specific)
1729{
1730 ConfigExtendedPageHeader_t hdr;
1731 CONFIGPARMS cfg;
1732 SasExpanderPage0_t *buffer;
1733 dma_addr_t dma_handle;
1734 int i, error;
1735
1736 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
1737 hdr.ExtPageLength = 0;
1738 hdr.PageNumber = 0;
1739 hdr.Reserved1 = 0;
1740 hdr.Reserved2 = 0;
1741 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1742 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1743
1744 cfg.cfghdr.ehdr = &hdr;
1745 cfg.physAddr = -1;
1746 cfg.pageAddr = form + form_specific;
1747 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1748 cfg.dir = 0; /* read */
1749 cfg.timeout = 10;
1750
1751 memset(port_info, 0, sizeof(struct mptsas_portinfo));
1752 error = mpt_config(ioc, &cfg);
1753 if (error)
1754 goto out;
1755
1756 if (!hdr.ExtPageLength) {
1757 error = -ENXIO;
1758 goto out;
1759 }
1760
1761 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1762 &dma_handle);
1763 if (!buffer) {
1764 error = -ENOMEM;
1765 goto out;
1766 }
1767
1768 cfg.physAddr = dma_handle;
1769 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1770
1771 error = mpt_config(ioc, &cfg);
1772 if (error)
1773 goto out_free_consistent;
1774
1775 /* save config data */
1776 port_info->num_phys = buffer->NumPhys;
1777 port_info->phy_info = kcalloc(port_info->num_phys,
1778 sizeof(*port_info->phy_info),GFP_KERNEL);
1779 if (!port_info->phy_info) {
1780 error = -ENOMEM;
1781 goto out_free_consistent;
1782 }
1783
1784 for (i = 0; i < port_info->num_phys; i++) {
1785 port_info->phy_info[i].portinfo = port_info;
1786 port_info->phy_info[i].handle =
1787 le16_to_cpu(buffer->DevHandle);
1788 }
1789
1790 out_free_consistent:
1791 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1792 buffer, dma_handle);
1793 out:
1794 return error;
1795}
1796
1797static int
1798mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
1799 u32 form, u32 form_specific)
1800{
1801 ConfigExtendedPageHeader_t hdr;
1802 CONFIGPARMS cfg;
1803 SasExpanderPage1_t *buffer;
1804 dma_addr_t dma_handle;
1805 int error=0;
1806
1807 if (ioc->sas_discovery_runtime &&
1808 mptsas_is_end_device(&phy_info->attached))
1809 goto out;
1810
1811 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
1812 hdr.ExtPageLength = 0;
1813 hdr.PageNumber = 1;
1814 hdr.Reserved1 = 0;
1815 hdr.Reserved2 = 0;
1816 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1817 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1818
1819 cfg.cfghdr.ehdr = &hdr;
1820 cfg.physAddr = -1;
1821 cfg.pageAddr = form + form_specific;
1822 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1823 cfg.dir = 0; /* read */
1824 cfg.timeout = 10;
1825
1826 error = mpt_config(ioc, &cfg);
1827 if (error)
1828 goto out;
1829
1830 if (!hdr.ExtPageLength) {
1831 error = -ENXIO;
1832 goto out;
1833 }
1834
1835 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1836 &dma_handle);
1837 if (!buffer) {
1838 error = -ENOMEM;
1839 goto out;
1840 }
1841
1842 cfg.physAddr = dma_handle;
1843 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1844
1845 error = mpt_config(ioc, &cfg);
1846 if (error)
1847 goto out_free_consistent;
1848
1849
1850 mptsas_print_expander_pg1(ioc, buffer);
1851
1852 /* save config data */
1853 phy_info->phy_id = buffer->PhyIdentifier;
1854 phy_info->port_id = buffer->PhysicalPort;
1855 phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
1856 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
1857 phy_info->hw_link_rate = buffer->HwLinkRate;
1858 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
1859 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
1860
1861 out_free_consistent:
1862 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1863 buffer, dma_handle);
1864 out:
1865 return error;
1866}
1867
1868static void
1869mptsas_parse_device_info(struct sas_identify *identify,
1870 struct mptsas_devinfo *device_info)
1871{
1872 u16 protocols;
1873
1874 identify->sas_address = device_info->sas_address;
1875 identify->phy_identifier = device_info->phy_id;
1876
1877 /*
1878 * Fill in Phy Initiator Port Protocol.
1879 * Bits 6:3, more than one bit can be set, fall through cases.
1880 */
1881 protocols = device_info->device_info & 0x78;
1882 identify->initiator_port_protocols = 0;
1883 if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
1884 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
1885 if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
1886 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
1887 if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
1888 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
1889 if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
1890 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
1891
1892 /*
1893 * Fill in Phy Target Port Protocol.
1894 * Bits 10:7, more than one bit can be set, fall through cases.
1895 */
1896 protocols = device_info->device_info & 0x780;
1897 identify->target_port_protocols = 0;
1898 if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
1899 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
1900 if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
1901 identify->target_port_protocols |= SAS_PROTOCOL_STP;
1902 if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
1903 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
1904 if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1905 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
1906
1907 /*
1908 * Fill in Attached device type.
1909 */
1910 switch (device_info->device_info &
1911 MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
1912 case MPI_SAS_DEVICE_INFO_NO_DEVICE:
1913 identify->device_type = SAS_PHY_UNUSED;
1914 break;
1915 case MPI_SAS_DEVICE_INFO_END_DEVICE:
1916 identify->device_type = SAS_END_DEVICE;
1917 break;
1918 case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
1919 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
1920 break;
1921 case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
1922 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
1923 break;
1924 }
1925}
1926
1927static int mptsas_probe_one_phy(struct device *dev,
1928 struct mptsas_phyinfo *phy_info, int index, int local)
1929{
1930 MPT_ADAPTER *ioc;
1931 struct sas_phy *phy;
1932 struct sas_port *port;
1933 int error = 0;
1934
1935 if (!dev) {
1936 error = -ENODEV;
1937 goto out;
1938 }
1939
1940 if (!phy_info->phy) {
1941 phy = sas_phy_alloc(dev, index);
1942 if (!phy) {
1943 error = -ENOMEM;
1944 goto out;
1945 }
1946 } else
1947 phy = phy_info->phy;
1948
1949 mptsas_parse_device_info(&phy->identify, &phy_info->identify);
1950
1951 /*
1952 * Set Negotiated link rate.
1953 */
1954 switch (phy_info->negotiated_link_rate) {
1955 case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
1956 phy->negotiated_linkrate = SAS_PHY_DISABLED;
1957 break;
1958 case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
1959 phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;
1960 break;
1961 case MPI_SAS_IOUNIT0_RATE_1_5:
1962 phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
1963 break;
1964 case MPI_SAS_IOUNIT0_RATE_3_0:
1965 phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
1966 break;
1967 case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
1968 case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
1969 default:
1970 phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
1971 break;
1972 }
1973
1974 /*
1975 * Set Max hardware link rate.
1976 */
1977 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
1978 case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
1979 phy->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
1980 break;
1981 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
1982 phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
1983 break;
1984 default:
1985 break;
1986 }
1987
1988 /*
1989 * Set Max programmed link rate.
1990 */
1991 switch (phy_info->programmed_link_rate &
1992 MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
1993 case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
1994 phy->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
1995 break;
1996 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
1997 phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
1998 break;
1999 default:
2000 break;
2001 }
2002
2003 /*
2004 * Set Min hardware link rate.
2005 */
2006 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
2007 case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
2008 phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
2009 break;
2010 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
2011 phy->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
2012 break;
2013 default:
2014 break;
2015 }
2016
2017 /*
2018 * Set Min programmed link rate.
2019 */
2020 switch (phy_info->programmed_link_rate &
2021 MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
2022 case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
2023 phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
2024 break;
2025 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
2026 phy->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
2027 break;
2028 default:
2029 break;
2030 }
2031
2032 if (!phy_info->phy) {
2033
2034 error = sas_phy_add(phy);
2035 if (error) {
2036 sas_phy_free(phy);
2037 goto out;
2038 }
2039 phy_info->phy = phy;
2040 }
2041
2042 if (!phy_info->attached.handle ||
2043 !phy_info->port_details)
2044 goto out;
2045
2046 port = mptsas_get_port(phy_info);
2047 ioc = phy_to_ioc(phy_info->phy);
2048
2049 if (phy_info->sas_port_add_phy) {
2050
2051 if (!port) {
2052 port = sas_port_alloc_num(dev);
2053 if (!port) {
2054 error = -ENOMEM;
2055 goto out;
2056 }
2057 error = sas_port_add(port);
2058 if (error) {
2059 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2060 "%s: exit at line=%d\n", ioc->name,
2061 __FUNCTION__, __LINE__));
2062 goto out;
2063 }
2064 mptsas_set_port(ioc, phy_info, port);
2065 dsaswideprintk(ioc, printk(KERN_DEBUG
2066 "sas_port_alloc: port=%p dev=%p port_id=%d\n",
2067 port, dev, port->port_identifier));
2068 }
2069 dsaswideprintk(ioc, printk(KERN_DEBUG "sas_port_add_phy: phy_id=%d\n",
2070 phy_info->phy_id));
2071 sas_port_add_phy(port, phy_info->phy);
2072 phy_info->sas_port_add_phy = 0;
2073 }
2074
2075 if (!mptsas_get_rphy(phy_info) && port && !port->rphy) {
2076
2077 struct sas_rphy *rphy;
2078 struct device *parent;
2079 struct sas_identify identify;
2080
2081 parent = dev->parent->parent;
2082 /*
2083 * Let the hotplug_work thread handle processing
2084 * the adding/removing of devices that occur
2085 * after start of day.
2086 */
2087 if (ioc->sas_discovery_runtime &&
2088 mptsas_is_end_device(&phy_info->attached))
2089 goto out;
2090
2091 mptsas_parse_device_info(&identify, &phy_info->attached);
2092 if (scsi_is_host_device(parent)) {
2093 struct mptsas_portinfo *port_info;
2094 int i;
2095
2096 mutex_lock(&ioc->sas_topology_mutex);
2097 port_info = mptsas_find_portinfo_by_handle(ioc,
2098 ioc->handle);
2099 mutex_unlock(&ioc->sas_topology_mutex);
2100
2101 for (i = 0; i < port_info->num_phys; i++)
2102 if (port_info->phy_info[i].identify.sas_address ==
2103 identify.sas_address) {
2104 sas_port_mark_backlink(port);
2105 goto out;
2106 }
2107
2108 } else if (scsi_is_sas_rphy(parent)) {
2109 struct sas_rphy *parent_rphy = dev_to_rphy(parent);
2110 if (identify.sas_address ==
2111 parent_rphy->identify.sas_address) {
2112 sas_port_mark_backlink(port);
2113 goto out;
2114 }
2115 }
2116
2117 switch (identify.device_type) {
2118 case SAS_END_DEVICE:
2119 rphy = sas_end_device_alloc(port);
2120 break;
2121 case SAS_EDGE_EXPANDER_DEVICE:
2122 case SAS_FANOUT_EXPANDER_DEVICE:
2123 rphy = sas_expander_alloc(port, identify.device_type);
2124 break;
2125 default:
2126 rphy = NULL;
2127 break;
2128 }
2129 if (!rphy) {
2130 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2131 "%s: exit at line=%d\n", ioc->name,
2132 __FUNCTION__, __LINE__));
2133 goto out;
2134 }
2135
2136 rphy->identify = identify;
2137 error = sas_rphy_add(rphy);
2138 if (error) {
2139 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2140 "%s: exit at line=%d\n", ioc->name,
2141 __FUNCTION__, __LINE__));
2142 sas_rphy_free(rphy);
2143 goto out;
2144 }
2145 mptsas_set_rphy(ioc, phy_info, rphy);
2146 }
2147
2148 out:
2149 return error;
2150}
2151
2152static int
2153mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
2154{
2155 struct mptsas_portinfo *port_info, *hba;
2156 int error = -ENOMEM, i;
2157
2158 hba = kzalloc(sizeof(*port_info), GFP_KERNEL);
2159 if (! hba)
2160 goto out;
2161
2162 error = mptsas_sas_io_unit_pg0(ioc, hba);
2163 if (error)
2164 goto out_free_port_info;
2165
2166 mptsas_sas_io_unit_pg1(ioc);
2167 mutex_lock(&ioc->sas_topology_mutex);
2168 ioc->handle = hba->phy_info[0].handle;
2169 port_info = mptsas_find_portinfo_by_handle(ioc, ioc->handle);
2170 if (!port_info) {
2171 port_info = hba;
2172 list_add_tail(&port_info->list, &ioc->sas_topology);
2173 } else {
2174 for (i = 0; i < hba->num_phys; i++) {
2175 port_info->phy_info[i].negotiated_link_rate =
2176 hba->phy_info[i].negotiated_link_rate;
2177 port_info->phy_info[i].handle =
2178 hba->phy_info[i].handle;
2179 port_info->phy_info[i].port_id =
2180 hba->phy_info[i].port_id;
2181 }
2182 kfree(hba->phy_info);
2183 kfree(hba);
2184 hba = NULL;
2185 }
2186 mutex_unlock(&ioc->sas_topology_mutex);
2187 for (i = 0; i < port_info->num_phys; i++) {
2188 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
2189 (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
2190 MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
2191
2192 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
2193 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2194 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2195 port_info->phy_info[i].handle);
2196 port_info->phy_info[i].identify.phy_id =
2197 port_info->phy_info[i].phy_id = i;
2198 if (port_info->phy_info[i].attached.handle)
2199 mptsas_sas_device_pg0(ioc,
2200 &port_info->phy_info[i].attached,
2201 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2202 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2203 port_info->phy_info[i].attached.handle);
2204 }
2205
2206 mptsas_setup_wide_ports(ioc, port_info);
2207
2208 for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
2209 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
2210 &port_info->phy_info[i], ioc->sas_index, 1);
2211
2212 return 0;
2213
2214 out_free_port_info:
2215 kfree(hba);
2216 out:
2217 return error;
2218}
2219
2220static int
2221mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle)
2222{
2223 struct mptsas_portinfo *port_info, *p, *ex;
2224 struct device *parent;
2225 struct sas_rphy *rphy;
2226 int error = -ENOMEM, i, j;
2227
2228 ex = kzalloc(sizeof(*port_info), GFP_KERNEL);
2229 if (!ex)
2230 goto out;
2231
2232 error = mptsas_sas_expander_pg0(ioc, ex,
2233 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
2234 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
2235 if (error)
2236 goto out_free_port_info;
2237
2238 *handle = ex->phy_info[0].handle;
2239
2240 mutex_lock(&ioc->sas_topology_mutex);
2241 port_info = mptsas_find_portinfo_by_handle(ioc, *handle);
2242 if (!port_info) {
2243 port_info = ex;
2244 list_add_tail(&port_info->list, &ioc->sas_topology);
2245 } else {
2246 for (i = 0; i < ex->num_phys; i++) {
2247 port_info->phy_info[i].handle =
2248 ex->phy_info[i].handle;
2249 port_info->phy_info[i].port_id =
2250 ex->phy_info[i].port_id;
2251 }
2252 kfree(ex->phy_info);
2253 kfree(ex);
2254 ex = NULL;
2255 }
2256 mutex_unlock(&ioc->sas_topology_mutex);
2257
2258 for (i = 0; i < port_info->num_phys; i++) {
2259 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
2260 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
2261 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle);
2262
2263 if (port_info->phy_info[i].identify.handle) {
2264 mptsas_sas_device_pg0(ioc,
2265 &port_info->phy_info[i].identify,
2266 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2267 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2268 port_info->phy_info[i].identify.handle);
2269 port_info->phy_info[i].identify.phy_id =
2270 port_info->phy_info[i].phy_id;
2271 }
2272
2273 if (port_info->phy_info[i].attached.handle) {
2274 mptsas_sas_device_pg0(ioc,
2275 &port_info->phy_info[i].attached,
2276 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2277 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2278 port_info->phy_info[i].attached.handle);
2279 port_info->phy_info[i].attached.phy_id =
2280 port_info->phy_info[i].phy_id;
2281 }
2282 }
2283
2284 parent = &ioc->sh->shost_gendev;
2285 for (i = 0; i < port_info->num_phys; i++) {
2286 mutex_lock(&ioc->sas_topology_mutex);
2287 list_for_each_entry(p, &ioc->sas_topology, list) {
2288 for (j = 0; j < p->num_phys; j++) {
2289 if (port_info->phy_info[i].identify.handle !=
2290 p->phy_info[j].attached.handle)
2291 continue;
2292 rphy = mptsas_get_rphy(&p->phy_info[j]);
2293 parent = &rphy->dev;
2294 }
2295 }
2296 mutex_unlock(&ioc->sas_topology_mutex);
2297 }
2298
2299 mptsas_setup_wide_ports(ioc, port_info);
2300
2301 for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
2302 mptsas_probe_one_phy(parent, &port_info->phy_info[i],
2303 ioc->sas_index, 0);
2304
2305 return 0;
2306
2307 out_free_port_info:
2308 if (ex) {
2309 kfree(ex->phy_info);
2310 kfree(ex);
2311 }
2312 out:
2313 return error;
2314}
2315
2316/*
2317 * mptsas_delete_expander_phys
2318 *
2319 *
2320 * This will traverse topology, and remove expanders
2321 * that are no longer present
2322 */
2323static void
2324mptsas_delete_expander_phys(MPT_ADAPTER *ioc)
2325{
2326 struct mptsas_portinfo buffer;
2327 struct mptsas_portinfo *port_info, *n, *parent;
2328 struct mptsas_phyinfo *phy_info;
2329 struct sas_port * port;
2330 int i;
2331 u64 expander_sas_address;
2332
2333 mutex_lock(&ioc->sas_topology_mutex);
2334 list_for_each_entry_safe(port_info, n, &ioc->sas_topology, list) {
2335
2336 if (port_info->phy_info &&
2337 (!(port_info->phy_info[0].identify.device_info &
2338 MPI_SAS_DEVICE_INFO_SMP_TARGET)))
2339 continue;
2340
2341 if (mptsas_sas_expander_pg0(ioc, &buffer,
2342 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
2343 MPI_SAS_EXPAND_PGAD_FORM_SHIFT),
2344 port_info->phy_info[0].handle)) {
2345
2346 /*
2347 * Obtain the port_info instance to the parent port
2348 */
2349 parent = mptsas_find_portinfo_by_handle(ioc,
2350 port_info->phy_info[0].identify.handle_parent);
2351
2352 if (!parent)
2353 goto next_port;
2354
2355 expander_sas_address =
2356 port_info->phy_info[0].identify.sas_address;
2357
2358 /*
2359 * Delete rphys in the parent that point
2360 * to this expander. The transport layer will
2361 * cleanup all the children.
2362 */
2363 phy_info = parent->phy_info;
2364 for (i = 0; i < parent->num_phys; i++, phy_info++) {
2365 port = mptsas_get_port(phy_info);
2366 if (!port)
2367 continue;
2368 if (phy_info->attached.sas_address !=
2369 expander_sas_address)
2370 continue;
2371 dsaswideprintk(ioc,
2372 dev_printk(KERN_DEBUG, &port->dev,
2373 "delete port (%d)\n", port->port_identifier));
2374 sas_port_delete(port);
2375 mptsas_port_delete(ioc, phy_info->port_details);
2376 }
2377 next_port:
2378
2379 phy_info = port_info->phy_info;
2380 for (i = 0; i < port_info->num_phys; i++, phy_info++)
2381 mptsas_port_delete(ioc, phy_info->port_details);
2382
2383 list_del(&port_info->list);
2384 kfree(port_info->phy_info);
2385 kfree(port_info);
2386 }
2387 /*
2388 * Free this memory allocated from inside
2389 * mptsas_sas_expander_pg0
2390 */
2391 kfree(buffer.phy_info);
2392 }
2393 mutex_unlock(&ioc->sas_topology_mutex);
2394}
2395
2396/*
2397 * Start of day discovery
2398 */
2399static void
2400mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
2401{
2402 u32 handle = 0xFFFF;
2403 int i;
2404
2405 mutex_lock(&ioc->sas_discovery_mutex);
2406 mptsas_probe_hba_phys(ioc);
2407 while (!mptsas_probe_expander_phys(ioc, &handle))
2408 ;
2409 /*
2410 Reporting RAID volumes.
2411 */
2412 if (!ioc->ir_firmware)
2413 goto out;
2414 if (!ioc->raid_data.pIocPg2)
2415 goto out;
2416 if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
2417 goto out;
2418 for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
2419 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
2420 ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
2421 }
2422 out:
2423 mutex_unlock(&ioc->sas_discovery_mutex);
2424}
2425
2426/*
2427 * Work queue thread to handle Runtime discovery
2428 * Mere purpose is the hot add/delete of expanders
2429 *(Mutex UNLOCKED)
2430 */
2431static void
2432__mptsas_discovery_work(MPT_ADAPTER *ioc)
2433{
2434 u32 handle = 0xFFFF;
2435
2436 ioc->sas_discovery_runtime=1;
2437 mptsas_delete_expander_phys(ioc);
2438 mptsas_probe_hba_phys(ioc);
2439 while (!mptsas_probe_expander_phys(ioc, &handle))
2440 ;
2441 ioc->sas_discovery_runtime=0;
2442}
2443
2444/*
2445 * Work queue thread to handle Runtime discovery
2446 * Mere purpose is the hot add/delete of expanders
2447 *(Mutex LOCKED)
2448 */
2449static void
2450mptsas_discovery_work(struct work_struct *work)
2451{
2452 struct mptsas_discovery_event *ev =
2453 container_of(work, struct mptsas_discovery_event, work);
2454 MPT_ADAPTER *ioc = ev->ioc;
2455
2456 mutex_lock(&ioc->sas_discovery_mutex);
2457 __mptsas_discovery_work(ioc);
2458 mutex_unlock(&ioc->sas_discovery_mutex);
2459 kfree(ev);
2460}
2461
2462static struct mptsas_phyinfo *
2463mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
2464{
2465 struct mptsas_portinfo *port_info;
2466 struct mptsas_phyinfo *phy_info = NULL;
2467 int i;
2468
2469 mutex_lock(&ioc->sas_topology_mutex);
2470 list_for_each_entry(port_info, &ioc->sas_topology, list) {
2471 for (i = 0; i < port_info->num_phys; i++) {
2472 if (!mptsas_is_end_device(
2473 &port_info->phy_info[i].attached))
2474 continue;
2475 if (port_info->phy_info[i].attached.sas_address
2476 != sas_address)
2477 continue;
2478 phy_info = &port_info->phy_info[i];
2479 break;
2480 }
2481 }
2482 mutex_unlock(&ioc->sas_topology_mutex);
2483 return phy_info;
2484}
2485
2486static struct mptsas_phyinfo *
2487mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u8 channel, u8 id)
2488{
2489 struct mptsas_portinfo *port_info;
2490 struct mptsas_phyinfo *phy_info = NULL;
2491 int i;
2492
2493 mutex_lock(&ioc->sas_topology_mutex);
2494 list_for_each_entry(port_info, &ioc->sas_topology, list) {
2495 for (i = 0; i < port_info->num_phys; i++) {
2496 if (!mptsas_is_end_device(
2497 &port_info->phy_info[i].attached))
2498 continue;
2499 if (port_info->phy_info[i].attached.id != id)
2500 continue;
2501 if (port_info->phy_info[i].attached.channel != channel)
2502 continue;
2503 phy_info = &port_info->phy_info[i];
2504 break;
2505 }
2506 }
2507 mutex_unlock(&ioc->sas_topology_mutex);
2508 return phy_info;
2509}
2510
2511static struct mptsas_phyinfo *
2512mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
2513{
2514 struct mptsas_portinfo *port_info;
2515 struct mptsas_phyinfo *phy_info = NULL;
2516 int i;
2517
2518 mutex_lock(&ioc->sas_topology_mutex);
2519 list_for_each_entry(port_info, &ioc->sas_topology, list) {
2520 for (i = 0; i < port_info->num_phys; i++) {
2521 if (!mptsas_is_end_device(
2522 &port_info->phy_info[i].attached))
2523 continue;
2524 if (port_info->phy_info[i].attached.phys_disk_num == ~0)
2525 continue;
2526 if (port_info->phy_info[i].attached.phys_disk_num != id)
2527 continue;
2528 if (port_info->phy_info[i].attached.channel != channel)
2529 continue;
2530 phy_info = &port_info->phy_info[i];
2531 break;
2532 }
2533 }
2534 mutex_unlock(&ioc->sas_topology_mutex);
2535 return phy_info;
2536}
2537
2538/*
2539 * Work queue thread to clear the persitency table
2540 */
2541static void
2542mptsas_persist_clear_table(struct work_struct *work)
2543{
2544 MPT_ADAPTER *ioc = container_of(work, MPT_ADAPTER, sas_persist_task);
2545
2546 mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
2547}
2548
2549static void
2550mptsas_reprobe_lun(struct scsi_device *sdev, void *data)
2551{
2552 int rc;
2553
2554 sdev->no_uld_attach = data ? 1 : 0;
2555 rc = scsi_device_reprobe(sdev);
2556}
2557
2558static void
2559mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)
2560{
2561 starget_for_each_device(starget, uld_attach ? (void *)1 : NULL,
2562 mptsas_reprobe_lun);
2563}
2564
2565static void
2566mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id)
2567{
2568 CONFIGPARMS cfg;
2569 ConfigPageHeader_t hdr;
2570 dma_addr_t dma_handle;
2571 pRaidVolumePage0_t buffer = NULL;
2572 RaidPhysDiskPage0_t phys_disk;
2573 int i;
2574 struct mptsas_hotplug_event *ev;
2575
2576 memset(&cfg, 0 , sizeof(CONFIGPARMS));
2577 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
2578 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
2579 cfg.pageAddr = (channel << 8) + id;
2580 cfg.cfghdr.hdr = &hdr;
2581 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2582
2583 if (mpt_config(ioc, &cfg) != 0)
2584 goto out;
2585
2586 if (!hdr.PageLength)
2587 goto out;
2588
2589 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
2590 &dma_handle);
2591
2592 if (!buffer)
2593 goto out;
2594
2595 cfg.physAddr = dma_handle;
2596 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2597
2598 if (mpt_config(ioc, &cfg) != 0)
2599 goto out;
2600
2601 if (!(buffer->VolumeStatus.Flags &
2602 MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE))
2603 goto out;
2604
2605 if (!buffer->NumPhysDisks)
2606 goto out;
2607
2608 for (i = 0; i < buffer->NumPhysDisks; i++) {
2609
2610 if (mpt_raid_phys_disk_pg0(ioc,
2611 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
2612 continue;
2613
2614 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2615 if (!ev) {
2616 printk(KERN_WARNING "mptsas: lost hotplug event\n");
2617 goto out;
2618 }
2619
2620 INIT_WORK(&ev->work, mptsas_hotplug_work);
2621 ev->ioc = ioc;
2622 ev->id = phys_disk.PhysDiskID;
2623 ev->channel = phys_disk.PhysDiskBus;
2624 ev->phys_disk_num_valid = 1;
2625 ev->phys_disk_num = phys_disk.PhysDiskNum;
2626 ev->event_type = MPTSAS_ADD_DEVICE;
2627 schedule_work(&ev->work);
2628 }
2629
2630 out:
2631 if (buffer)
2632 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
2633 dma_handle);
2634}
2635/*
2636 * Work queue thread to handle SAS hotplug events
2637 */
2638static void
2639mptsas_hotplug_work(struct work_struct *work)
2640{
2641 struct mptsas_hotplug_event *ev =
2642 container_of(work, struct mptsas_hotplug_event, work);
2643
2644 MPT_ADAPTER *ioc = ev->ioc;
2645 struct mptsas_phyinfo *phy_info;
2646 struct sas_rphy *rphy;
2647 struct sas_port *port;
2648 struct scsi_device *sdev;
2649 struct scsi_target * starget;
2650 struct sas_identify identify;
2651 char *ds = NULL;
2652 struct mptsas_devinfo sas_device;
2653 VirtTarget *vtarget;
2654 VirtDevice *vdevice;
2655
2656 mutex_lock(&ioc->sas_discovery_mutex);
2657 switch (ev->event_type) {
2658 case MPTSAS_DEL_DEVICE:
2659
2660 phy_info = NULL;
2661 if (ev->phys_disk_num_valid) {
2662 if (ev->hidden_raid_component){
2663 if (mptsas_sas_device_pg0(ioc, &sas_device,
2664 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
2665 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2666 (ev->channel << 8) + ev->id)) {
2667 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2668 "%s: exit at line=%d\n", ioc->name,
2669 __FUNCTION__, __LINE__));
2670 break;
2671 }
2672 phy_info = mptsas_find_phyinfo_by_sas_address(
2673 ioc, sas_device.sas_address);
2674 }else
2675 phy_info = mptsas_find_phyinfo_by_phys_disk_num(
2676 ioc, ev->channel, ev->phys_disk_num);
2677 }
2678
2679 if (!phy_info)
2680 phy_info = mptsas_find_phyinfo_by_target(ioc,
2681 ev->channel, ev->id);
2682
2683 /*
2684 * Sanity checks, for non-existing phys and remote rphys.
2685 */
2686 if (!phy_info){
2687 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2688 "%s: exit at line=%d\n", ioc->name,
2689 __FUNCTION__, __LINE__));
2690 break;
2691 }
2692 if (!phy_info->port_details) {
2693 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2694 "%s: exit at line=%d\n", ioc->name,
2695 __FUNCTION__, __LINE__));
2696 break;
2697 }
2698 rphy = mptsas_get_rphy(phy_info);
2699 if (!rphy) {
2700 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2701 "%s: exit at line=%d\n", ioc->name,
2702 __FUNCTION__, __LINE__));
2703 break;
2704 }
2705
2706 port = mptsas_get_port(phy_info);
2707 if (!port) {
2708 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2709 "%s: exit at line=%d\n", ioc->name,
2710 __FUNCTION__, __LINE__));
2711 break;
2712 }
2713
2714 starget = mptsas_get_starget(phy_info);
2715 if (starget) {
2716 vtarget = starget->hostdata;
2717
2718 if (!vtarget) {
2719 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2720 "%s: exit at line=%d\n", ioc->name,
2721 __FUNCTION__, __LINE__));
2722 break;
2723 }
2724
2725 /*
2726 * Handling RAID components
2727 */
2728 if (ev->phys_disk_num_valid &&
2729 ev->hidden_raid_component) {
2730 printk(MYIOC_s_INFO_FMT
2731 "RAID Hidding: channel=%d, id=%d, "
2732 "physdsk %d \n", ioc->name, ev->channel,
2733 ev->id, ev->phys_disk_num);
2734 vtarget->id = ev->phys_disk_num;
2735 vtarget->tflags |=
2736 MPT_TARGET_FLAGS_RAID_COMPONENT;
2737 mptsas_reprobe_target(starget, 1);
2738 phy_info->attached.phys_disk_num =
2739 ev->phys_disk_num;
2740 break;
2741 }
2742 }
2743
2744 if (phy_info->attached.device_info &
2745 MPI_SAS_DEVICE_INFO_SSP_TARGET)
2746 ds = "ssp";
2747 if (phy_info->attached.device_info &
2748 MPI_SAS_DEVICE_INFO_STP_TARGET)
2749 ds = "stp";
2750 if (phy_info->attached.device_info &
2751 MPI_SAS_DEVICE_INFO_SATA_DEVICE)
2752 ds = "sata";
2753
2754 printk(MYIOC_s_INFO_FMT
2755 "removing %s device, channel %d, id %d, phy %d\n",
2756 ioc->name, ds, ev->channel, ev->id, phy_info->phy_id);
2757 dev_printk(KERN_DEBUG, &port->dev,
2758 "delete port (%d)\n", port->port_identifier);
2759 sas_port_delete(port);
2760 mptsas_port_delete(ioc, phy_info->port_details);
2761 break;
2762 case MPTSAS_ADD_DEVICE:
2763
2764 if (ev->phys_disk_num_valid)
2765 mpt_findImVolumes(ioc);
2766
2767 /*
2768 * Refresh sas device pg0 data
2769 */
2770 if (mptsas_sas_device_pg0(ioc, &sas_device,
2771 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
2772 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2773 (ev->channel << 8) + ev->id)) {
2774 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2775 "%s: exit at line=%d\n", ioc->name,
2776 __FUNCTION__, __LINE__));
2777 break;
2778 }
2779
2780 __mptsas_discovery_work(ioc);
2781
2782 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
2783 sas_device.sas_address);
2784
2785 if (!phy_info || !phy_info->port_details) {
2786 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2787 "%s: exit at line=%d\n", ioc->name,
2788 __FUNCTION__, __LINE__));
2789 break;
2790 }
2791
2792 starget = mptsas_get_starget(phy_info);
2793 if (starget && (!ev->hidden_raid_component)){
2794
2795 vtarget = starget->hostdata;
2796
2797 if (!vtarget) {
2798 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2799 "%s: exit at line=%d\n", ioc->name,
2800 __FUNCTION__, __LINE__));
2801 break;
2802 }
2803 /*
2804 * Handling RAID components
2805 */
2806 if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
2807 printk(MYIOC_s_INFO_FMT
2808 "RAID Exposing: channel=%d, id=%d, "
2809 "physdsk %d \n", ioc->name, ev->channel,
2810 ev->id, ev->phys_disk_num);
2811 vtarget->tflags &=
2812 ~MPT_TARGET_FLAGS_RAID_COMPONENT;
2813 vtarget->id = ev->id;
2814 mptsas_reprobe_target(starget, 0);
2815 phy_info->attached.phys_disk_num = ~0;
2816 }
2817 break;
2818 }
2819
2820 if (mptsas_get_rphy(phy_info)) {
2821 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2822 "%s: exit at line=%d\n", ioc->name,
2823 __FUNCTION__, __LINE__));
2824 if (ev->channel) printk("%d\n", __LINE__);
2825 break;
2826 }
2827
2828 port = mptsas_get_port(phy_info);
2829 if (!port) {
2830 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2831 "%s: exit at line=%d\n", ioc->name,
2832 __FUNCTION__, __LINE__));
2833 break;
2834 }
2835 memcpy(&phy_info->attached, &sas_device,
2836 sizeof(struct mptsas_devinfo));
2837
2838 if (phy_info->attached.device_info &
2839 MPI_SAS_DEVICE_INFO_SSP_TARGET)
2840 ds = "ssp";
2841 if (phy_info->attached.device_info &
2842 MPI_SAS_DEVICE_INFO_STP_TARGET)
2843 ds = "stp";
2844 if (phy_info->attached.device_info &
2845 MPI_SAS_DEVICE_INFO_SATA_DEVICE)
2846 ds = "sata";
2847
2848 printk(MYIOC_s_INFO_FMT
2849 "attaching %s device, channel %d, id %d, phy %d\n",
2850 ioc->name, ds, ev->channel, ev->id, ev->phy_id);
2851
2852 mptsas_parse_device_info(&identify, &phy_info->attached);
2853 rphy = sas_end_device_alloc(port);
2854 if (!rphy) {
2855 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2856 "%s: exit at line=%d\n", ioc->name,
2857 __FUNCTION__, __LINE__));
2858 break; /* non-fatal: an rphy can be added later */
2859 }
2860
2861 rphy->identify = identify;
2862 if (sas_rphy_add(rphy)) {
2863 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2864 "%s: exit at line=%d\n", ioc->name,
2865 __FUNCTION__, __LINE__));
2866 sas_rphy_free(rphy);
2867 break;
2868 }
2869 mptsas_set_rphy(ioc, phy_info, rphy);
2870 break;
2871 case MPTSAS_ADD_RAID:
2872 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
2873 ev->id, 0);
2874 if (sdev) {
2875 scsi_device_put(sdev);
2876 break;
2877 }
2878 printk(MYIOC_s_INFO_FMT
2879 "attaching raid volume, channel %d, id %d\n",
2880 ioc->name, MPTSAS_RAID_CHANNEL, ev->id);
2881 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL, ev->id, 0);
2882 mpt_findImVolumes(ioc);
2883 break;
2884 case MPTSAS_DEL_RAID:
2885 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
2886 ev->id, 0);
2887 if (!sdev)
2888 break;
2889 printk(MYIOC_s_INFO_FMT
2890 "removing raid volume, channel %d, id %d\n",
2891 ioc->name, MPTSAS_RAID_CHANNEL, ev->id);
2892 vdevice = sdev->hostdata;
2893 scsi_remove_device(sdev);
2894 scsi_device_put(sdev);
2895 mpt_findImVolumes(ioc);
2896 break;
2897 case MPTSAS_ADD_INACTIVE_VOLUME:
2898 mptsas_adding_inactive_raid_components(ioc,
2899 ev->channel, ev->id);
2900 break;
2901 case MPTSAS_IGNORE_EVENT:
2902 default:
2903 break;
2904 }
2905
2906 mutex_unlock(&ioc->sas_discovery_mutex);
2907 kfree(ev);
2908}
2909
2910static void
2911mptsas_send_sas_event(MPT_ADAPTER *ioc,
2912 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
2913{
2914 struct mptsas_hotplug_event *ev;
2915 u32 device_info = le32_to_cpu(sas_event_data->DeviceInfo);
2916 __le64 sas_address;
2917
2918 if ((device_info &
2919 (MPI_SAS_DEVICE_INFO_SSP_TARGET |
2920 MPI_SAS_DEVICE_INFO_STP_TARGET |
2921 MPI_SAS_DEVICE_INFO_SATA_DEVICE )) == 0)
2922 return;
2923
2924 switch (sas_event_data->ReasonCode) {
2925 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
2926
2927 mptsas_target_reset_queue(ioc, sas_event_data);
2928 break;
2929
2930 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
2931 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2932 if (!ev) {
2933 printk(KERN_WARNING "mptsas: lost hotplug event\n");
2934 break;
2935 }
2936
2937 INIT_WORK(&ev->work, mptsas_hotplug_work);
2938 ev->ioc = ioc;
2939 ev->handle = le16_to_cpu(sas_event_data->DevHandle);
2940 ev->parent_handle =
2941 le16_to_cpu(sas_event_data->ParentDevHandle);
2942 ev->channel = sas_event_data->Bus;
2943 ev->id = sas_event_data->TargetID;
2944 ev->phy_id = sas_event_data->PhyNum;
2945 memcpy(&sas_address, &sas_event_data->SASAddress,
2946 sizeof(__le64));
2947 ev->sas_address = le64_to_cpu(sas_address);
2948 ev->device_info = device_info;
2949
2950 if (sas_event_data->ReasonCode &
2951 MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
2952 ev->event_type = MPTSAS_ADD_DEVICE;
2953 else
2954 ev->event_type = MPTSAS_DEL_DEVICE;
2955 schedule_work(&ev->work);
2956 break;
2957 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
2958 /*
2959 * Persistent table is full.
2960 */
2961 INIT_WORK(&ioc->sas_persist_task,
2962 mptsas_persist_clear_table);
2963 schedule_work(&ioc->sas_persist_task);
2964 break;
2965 /*
2966 * TODO, handle other events
2967 */
2968 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
2969 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
2970 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
2971 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
2972 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
2973 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
2974 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
2975 default:
2976 break;
2977 }
2978}
2979static void
2980mptsas_send_raid_event(MPT_ADAPTER *ioc,
2981 EVENT_DATA_RAID *raid_event_data)
2982{
2983 struct mptsas_hotplug_event *ev;
2984 int status = le32_to_cpu(raid_event_data->SettingsStatus);
2985 int state = (status >> 8) & 0xff;
2986
2987 if (ioc->bus_type != SAS)
2988 return;
2989
2990 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2991 if (!ev) {
2992 printk(KERN_WARNING "mptsas: lost hotplug event\n");
2993 return;
2994 }
2995
2996 INIT_WORK(&ev->work, mptsas_hotplug_work);
2997 ev->ioc = ioc;
2998 ev->id = raid_event_data->VolumeID;
2999 ev->channel = raid_event_data->VolumeBus;
3000 ev->event_type = MPTSAS_IGNORE_EVENT;
3001
3002 switch (raid_event_data->ReasonCode) {
3003 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
3004 ev->phys_disk_num_valid = 1;
3005 ev->phys_disk_num = raid_event_data->PhysDiskNum;
3006 ev->event_type = MPTSAS_ADD_DEVICE;
3007 break;
3008 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
3009 ev->phys_disk_num_valid = 1;
3010 ev->phys_disk_num = raid_event_data->PhysDiskNum;
3011 ev->hidden_raid_component = 1;
3012 ev->event_type = MPTSAS_DEL_DEVICE;
3013 break;
3014 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
3015 switch (state) {
3016 case MPI_PD_STATE_ONLINE:
3017 case MPI_PD_STATE_NOT_COMPATIBLE:
3018 ev->phys_disk_num_valid = 1;
3019 ev->phys_disk_num = raid_event_data->PhysDiskNum;
3020 ev->hidden_raid_component = 1;
3021 ev->event_type = MPTSAS_ADD_DEVICE;
3022 break;
3023 case MPI_PD_STATE_MISSING:
3024 case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST:
3025 case MPI_PD_STATE_FAILED_AT_HOST_REQUEST:
3026 case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON:
3027 ev->phys_disk_num_valid = 1;
3028 ev->phys_disk_num = raid_event_data->PhysDiskNum;
3029 ev->event_type = MPTSAS_DEL_DEVICE;
3030 break;
3031 default:
3032 break;
3033 }
3034 break;
3035 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
3036 ev->event_type = MPTSAS_DEL_RAID;
3037 break;
3038 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
3039 ev->event_type = MPTSAS_ADD_RAID;
3040 break;
3041 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
3042 switch (state) {
3043 case MPI_RAIDVOL0_STATUS_STATE_FAILED:
3044 case MPI_RAIDVOL0_STATUS_STATE_MISSING:
3045 ev->event_type = MPTSAS_DEL_RAID;
3046 break;
3047 case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL:
3048 case MPI_RAIDVOL0_STATUS_STATE_DEGRADED:
3049 ev->event_type = MPTSAS_ADD_RAID;
3050 break;
3051 default:
3052 break;
3053 }
3054 break;
3055 default:
3056 break;
3057 }
3058 schedule_work(&ev->work);
3059}
3060
3061static void
3062mptsas_send_discovery_event(MPT_ADAPTER *ioc,
3063 EVENT_DATA_SAS_DISCOVERY *discovery_data)
3064{
3065 struct mptsas_discovery_event *ev;
3066
3067 /*
3068 * DiscoveryStatus
3069 *
3070 * This flag will be non-zero when firmware
3071 * kicks off discovery, and return to zero
3072 * once its completed.
3073 */
3074 if (discovery_data->DiscoveryStatus)
3075 return;
3076
3077 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
3078 if (!ev)
3079 return;
3080 INIT_WORK(&ev->work, mptsas_discovery_work);
3081 ev->ioc = ioc;
3082 schedule_work(&ev->work);
3083};
3084
3085/*
3086 * mptsas_send_ir2_event - handle exposing hidden disk when
3087 * an inactive raid volume is added
3088 *
3089 * @ioc: Pointer to MPT_ADAPTER structure
3090 * @ir2_data
3091 *
3092 */
3093static void
3094mptsas_send_ir2_event(MPT_ADAPTER *ioc, PTR_MPI_EVENT_DATA_IR2 ir2_data)
3095{
3096 struct mptsas_hotplug_event *ev;
3097
3098 if (ir2_data->ReasonCode !=
3099 MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED)
3100 return;
3101
3102 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
3103 if (!ev)
3104 return;
3105
3106 INIT_WORK(&ev->work, mptsas_hotplug_work);
3107 ev->ioc = ioc;
3108 ev->id = ir2_data->TargetID;
3109 ev->channel = ir2_data->Bus;
3110 ev->event_type = MPTSAS_ADD_INACTIVE_VOLUME;
3111
3112 schedule_work(&ev->work);
3113};
3114
3115static int
3116mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
3117{
3118 int rc=1;
3119 u8 event = le32_to_cpu(reply->Event) & 0xFF;
3120
3121 if (!ioc->sh)
3122 goto out;
3123
3124 /*
3125 * sas_discovery_ignore_events
3126 *
3127 * This flag is to prevent anymore processing of
3128 * sas events once mptsas_remove function is called.
3129 */
3130 if (ioc->sas_discovery_ignore_events) {
3131 rc = mptscsih_event_process(ioc, reply);
3132 goto out;
3133 }
3134
3135 switch (event) {
3136 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
3137 mptsas_send_sas_event(ioc,
3138 (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data);
3139 break;
3140 case MPI_EVENT_INTEGRATED_RAID:
3141 mptsas_send_raid_event(ioc,
3142 (EVENT_DATA_RAID *)reply->Data);
3143 break;
3144 case MPI_EVENT_PERSISTENT_TABLE_FULL:
3145 INIT_WORK(&ioc->sas_persist_task,
3146 mptsas_persist_clear_table);
3147 schedule_work(&ioc->sas_persist_task);
3148 break;
3149 case MPI_EVENT_SAS_DISCOVERY:
3150 mptsas_send_discovery_event(ioc,
3151 (EVENT_DATA_SAS_DISCOVERY *)reply->Data);
3152 break;
3153 case MPI_EVENT_IR2:
3154 mptsas_send_ir2_event(ioc,
3155 (PTR_MPI_EVENT_DATA_IR2)reply->Data);
3156 break;
3157 default:
3158 rc = mptscsih_event_process(ioc, reply);
3159 break;
3160 }
3161 out:
3162
3163 return rc;
3164}
3165
3166static int
3167mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
3168{
3169 struct Scsi_Host *sh;
3170 MPT_SCSI_HOST *hd;
3171 MPT_ADAPTER *ioc;
3172 unsigned long flags;
3173 int ii;
3174 int numSGE = 0;
3175 int scale;
3176 int ioc_cap;
3177 int error=0;
3178 int r;
3179
3180 r = mpt_attach(pdev,id);
3181 if (r)
3182 return r;
3183
3184 ioc = pci_get_drvdata(pdev);
3185 ioc->DoneCtx = mptsasDoneCtx;
3186 ioc->TaskCtx = mptsasTaskCtx;
3187 ioc->InternalCtx = mptsasInternalCtx;
3188
3189 /* Added sanity check on readiness of the MPT adapter.
3190 */
3191 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
3192 printk(MYIOC_s_WARN_FMT
3193 "Skipping because it's not operational!\n",
3194 ioc->name);
3195 error = -ENODEV;
3196 goto out_mptsas_probe;
3197 }
3198
3199 if (!ioc->active) {
3200 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
3201 ioc->name);
3202 error = -ENODEV;
3203 goto out_mptsas_probe;
3204 }
3205
3206 /* Sanity check - ensure at least 1 port is INITIATOR capable
3207 */
3208 ioc_cap = 0;
3209 for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
3210 if (ioc->pfacts[ii].ProtocolFlags &
3211 MPI_PORTFACTS_PROTOCOL_INITIATOR)
3212 ioc_cap++;
3213 }
3214
3215 if (!ioc_cap) {
3216 printk(MYIOC_s_WARN_FMT
3217 "Skipping ioc=%p because SCSI Initiator mode "
3218 "is NOT enabled!\n", ioc->name, ioc);
3219 return 0;
3220 }
3221
3222 sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
3223 if (!sh) {
3224 printk(MYIOC_s_WARN_FMT
3225 "Unable to register controller with SCSI subsystem\n",
3226 ioc->name);
3227 error = -1;
3228 goto out_mptsas_probe;
3229 }
3230
3231 spin_lock_irqsave(&ioc->FreeQlock, flags);
3232
3233 /* Attach the SCSI Host to the IOC structure
3234 */
3235 ioc->sh = sh;
3236
3237 sh->io_port = 0;
3238 sh->n_io_port = 0;
3239 sh->irq = 0;
3240
3241 /* set 16 byte cdb's */
3242 sh->max_cmd_len = 16;
3243
3244 sh->max_id = ioc->pfacts[0].PortSCSIID;
3245 sh->max_lun = max_lun;
3246
3247 sh->transportt = mptsas_transport_template;
3248
3249 sh->this_id = ioc->pfacts[0].PortSCSIID;
3250
3251 /* Required entry.
3252 */
3253 sh->unique_id = ioc->id;
3254
3255 INIT_LIST_HEAD(&ioc->sas_topology);
3256 mutex_init(&ioc->sas_topology_mutex);
3257 mutex_init(&ioc->sas_discovery_mutex);
3258 mutex_init(&ioc->sas_mgmt.mutex);
3259 init_completion(&ioc->sas_mgmt.done);
3260
3261 /* Verify that we won't exceed the maximum
3262 * number of chain buffers
3263 * We can optimize: ZZ = req_sz/sizeof(SGE)
3264 * For 32bit SGE's:
3265 * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
3266 * + (req_sz - 64)/sizeof(SGE)
3267 * A slightly different algorithm is required for
3268 * 64bit SGEs.
3269 */
3270 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3271 if (sizeof(dma_addr_t) == sizeof(u64)) {
3272 numSGE = (scale - 1) *
3273 (ioc->facts.MaxChainDepth-1) + scale +
3274 (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
3275 sizeof(u32));
3276 } else {
3277 numSGE = 1 + (scale - 1) *
3278 (ioc->facts.MaxChainDepth-1) + scale +
3279 (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
3280 sizeof(u32));
3281 }
3282
3283 if (numSGE < sh->sg_tablesize) {
3284 /* Reset this value */
3285 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3286 "Resetting sg_tablesize to %d from %d\n",
3287 ioc->name, numSGE, sh->sg_tablesize));
3288 sh->sg_tablesize = numSGE;
3289 }
3290
3291 hd = (MPT_SCSI_HOST *) sh->hostdata;
3292 hd->ioc = ioc;
3293
3294 /* SCSI needs scsi_cmnd lookup table!
3295 * (with size equal to req_depth*PtrSz!)
3296 */
3297 hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
3298 if (!hd->ScsiLookup) {
3299 error = -ENOMEM;
3300 goto out_mptsas_probe;
3301 }
3302
3303 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
3304 ioc->name, hd->ScsiLookup));
3305
3306 /* Clear the TM flags
3307 */
3308 hd->tmPending = 0;
3309 hd->tmState = TM_STATE_NONE;
3310 hd->resetPending = 0;
3311 hd->abortSCpnt = NULL;
3312
3313 /* Clear the pointer used to store
3314 * single-threaded commands, i.e., those
3315 * issued during a bus scan, dv and
3316 * configuration pages.
3317 */
3318 hd->cmdPtr = NULL;
3319
3320 /* Initialize this SCSI Hosts' timers
3321 * To use, set the timer expires field
3322 * and add_timer
3323 */
3324 init_timer(&hd->timer);
3325 hd->timer.data = (unsigned long) hd;
3326 hd->timer.function = mptscsih_timer_expired;
3327
3328 ioc->sas_data.ptClear = mpt_pt_clear;
3329
3330 init_waitqueue_head(&hd->scandv_waitq);
3331 hd->scandv_wait_done = 0;
3332 hd->last_queue_full = 0;
3333 INIT_LIST_HEAD(&hd->target_reset_list);
3334 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3335
3336 if (ioc->sas_data.ptClear==1) {
3337 mptbase_sas_persist_operation(
3338 ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
3339 }
3340
3341 error = scsi_add_host(sh, &ioc->pcidev->dev);
3342 if (error) {
3343 dprintk(ioc, printk(KERN_ERR MYNAM
3344 "scsi_add_host failed\n"));
3345 goto out_mptsas_probe;
3346 }
3347
3348 mptsas_scan_sas_topology(ioc);
3349
3350 return 0;
3351
3352 out_mptsas_probe:
3353
3354 mptscsih_remove(pdev);
3355 return error;
3356}
3357
3358static void __devexit mptsas_remove(struct pci_dev *pdev)
3359{
3360 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
3361 struct mptsas_portinfo *p, *n;
3362 int i;
3363
3364 ioc->sas_discovery_ignore_events = 1;
3365 sas_remove_host(ioc->sh);
3366
3367 mutex_lock(&ioc->sas_topology_mutex);
3368 list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
3369 list_del(&p->list);
3370 for (i = 0 ; i < p->num_phys ; i++)
3371 mptsas_port_delete(ioc, p->phy_info[i].port_details);
3372 kfree(p->phy_info);
3373 kfree(p);
3374 }
3375 mutex_unlock(&ioc->sas_topology_mutex);
3376
3377 mptscsih_remove(pdev);
3378}
3379
3380static struct pci_device_id mptsas_pci_table[] = {
3381 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064,
3382 PCI_ANY_ID, PCI_ANY_ID },
3383 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068,
3384 PCI_ANY_ID, PCI_ANY_ID },
3385 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064E,
3386 PCI_ANY_ID, PCI_ANY_ID },
3387 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068E,
3388 PCI_ANY_ID, PCI_ANY_ID },
3389 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1078,
3390 PCI_ANY_ID, PCI_ANY_ID },
3391 {0} /* Terminating entry */
3392};
3393MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
3394
3395
3396static struct pci_driver mptsas_driver = {
3397 .name = "mptsas",
3398 .id_table = mptsas_pci_table,
3399 .probe = mptsas_probe,
3400 .remove = __devexit_p(mptsas_remove),
3401 .shutdown = mptscsih_shutdown,
3402#ifdef CONFIG_PM
3403 .suspend = mptscsih_suspend,
3404 .resume = mptscsih_resume,
3405#endif
3406};
3407
3408static int __init
3409mptsas_init(void)
3410{
3411 int error;
3412
3413 show_mptmod_ver(my_NAME, my_VERSION);
3414
3415 mptsas_transport_template =
3416 sas_attach_transport(&mptsas_transport_functions);
3417 if (!mptsas_transport_template)
3418 return -ENODEV;
3419
3420 mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
3421 mptsasTaskCtx = mpt_register(mptsas_taskmgmt_complete, MPTSAS_DRIVER);
3422 mptsasInternalCtx =
3423 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
3424 mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
3425
3426 mpt_event_register(mptsasDoneCtx, mptsas_event_process);
3427 mpt_reset_register(mptsasDoneCtx, mptsas_ioc_reset);
3428
3429 error = pci_register_driver(&mptsas_driver);
3430 if (error)
3431 sas_release_transport(mptsas_transport_template);
3432
3433 return error;
3434}
3435
3436static void __exit
3437mptsas_exit(void)
3438{
3439 pci_unregister_driver(&mptsas_driver);
3440 sas_release_transport(mptsas_transport_template);
3441
3442 mpt_reset_deregister(mptsasDoneCtx);
3443 mpt_event_deregister(mptsasDoneCtx);
3444
3445 mpt_deregister(mptsasMgmtCtx);
3446 mpt_deregister(mptsasInternalCtx);
3447 mpt_deregister(mptsasTaskCtx);
3448 mpt_deregister(mptsasDoneCtx);
3449}
3450
3451module_init(mptsas_init);
3452module_exit(mptsas_exit);