[SCSI] update additional sense codes and some opcode names
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / message / fusion / mptsas.c
CommitLineData
0c33b27d
CH
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-2005 LSI Logic Corporation
7 * (mailto:mpt_linux_developer@lsil.com)
9a28f49a 8 * Copyright (c) 2005-2006 Dell
0c33b27d
CH
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/sched.h>
52#include <linux/workqueue.h>
547f9a21 53#include <linux/delay.h> /* for mdelay */
0c33b27d 54
547f9a21 55#include <scsi/scsi.h>
0c33b27d
CH
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>
547f9a21 60#include <scsi/scsi_dbg.h>
0c33b27d
CH
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
70MODULE_AUTHOR(MODULEAUTHOR);
71MODULE_DESCRIPTION(my_NAME);
72MODULE_LICENSE("GPL");
73
74static int mpt_pq_filter;
75module_param(mpt_pq_filter, int, 0);
76MODULE_PARM_DESC(mpt_pq_filter,
77 "Enable peripheral qualifier filter: enable=1 "
78 "(default=0)");
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
86static int mptsasDoneCtx = -1;
87static int mptsasTaskCtx = -1;
88static int mptsasInternalCtx = -1; /* Used only for internal commands */
da4fa655 89static int mptsasMgmtCtx = -1;
0c33b27d
CH
90
91
9a28f49a
CH
92enum mptsas_hotplug_action {
93 MPTSAS_ADD_DEVICE,
94 MPTSAS_DEL_DEVICE,
c73787ee
ME
95 MPTSAS_ADD_RAID,
96 MPTSAS_DEL_RAID,
bd23e94c 97 MPTSAS_IGNORE_EVENT,
9a28f49a
CH
98};
99
100struct mptsas_hotplug_event {
101 struct work_struct work;
102 MPT_ADAPTER *ioc;
103 enum mptsas_hotplug_action event_type;
104 u64 sas_address;
105 u32 channel;
106 u32 id;
107 u32 device_info;
108 u16 handle;
109 u16 parent_handle;
110 u8 phy_id;
f44e5461
ME
111 u8 phys_disk_num;
112 u8 phys_disk_num_valid;
9a28f49a
CH
113};
114
e6b2d76a
ME
115struct mptsas_discovery_event {
116 struct work_struct work;
117 MPT_ADAPTER *ioc;
118};
119
0c33b27d
CH
120/*
121 * SAS topology structures
122 *
123 * The MPT Fusion firmware interface spreads information about the
124 * SAS topology over many manufacture pages, thus we need some data
125 * structure to collect it and process it for the SAS transport class.
126 */
127
128struct mptsas_devinfo {
129 u16 handle; /* unique id to address this device */
c73787ee 130 u16 handle_parent; /* unique id to address parent device */
e3094447
CH
131 u16 handle_enclosure; /* enclosure identifier of the enclosure */
132 u16 slot; /* physical slot in enclosure */
0c33b27d
CH
133 u8 phy_id; /* phy number of parent device */
134 u8 port_id; /* sas physical port this device
135 is assoc'd with */
9a28f49a
CH
136 u8 id; /* logical target id of this device */
137 u8 channel; /* logical bus number of this device */
0c33b27d
CH
138 u64 sas_address; /* WWN of this device,
139 SATA is assigned by HBA,expander */
140 u32 device_info; /* bitfield detailed info about this device */
141};
142
547f9a21
EM
143/*
144 * Specific details on ports, wide/narrow
145 */
146struct mptsas_portinfo_details{
147 u8 port_id; /* port number provided to transport */
148 u16 num_phys; /* number of phys belong to this port */
149 u64 phy_bitmask; /* TODO, extend support for 255 phys */
150 struct sas_rphy *rphy; /* transport layer rphy object */
151 struct sas_port *port; /* transport layer port object */
152 struct scsi_target *starget;
153 struct mptsas_portinfo *port_info;
154};
155
0c33b27d
CH
156struct mptsas_phyinfo {
157 u8 phy_id; /* phy index */
547f9a21 158 u8 port_id; /* firmware port identifier */
0c33b27d
CH
159 u8 negotiated_link_rate; /* nego'd link rate for this phy */
160 u8 hw_link_rate; /* hardware max/min phys link rate */
161 u8 programmed_link_rate; /* programmed max/min phy link rate */
547f9a21 162 u8 sas_port_add_phy; /* flag to request sas_port_add_phy*/
0c33b27d
CH
163 struct mptsas_devinfo identify; /* point to phy device info */
164 struct mptsas_devinfo attached; /* point to attached device info */
547f9a21
EM
165 struct sas_phy *phy; /* transport layer phy object */
166 struct mptsas_portinfo *portinfo;
167 struct mptsas_portinfo_details * port_details;
0c33b27d
CH
168};
169
170struct mptsas_portinfo {
171 struct list_head list;
172 u16 handle; /* unique id to address this */
547f9a21 173 u16 num_phys; /* number of phys */
0c33b27d
CH
174 struct mptsas_phyinfo *phy_info;
175};
176
e3094447
CH
177struct mptsas_enclosure {
178 u64 enclosure_logical_id; /* The WWN for the enclosure */
179 u16 enclosure_handle; /* unique id to address this */
180 u16 flags; /* details enclosure management */
181 u16 num_slot; /* num slots */
182 u16 start_slot; /* first slot */
183 u8 start_id; /* starting logical target id */
184 u8 start_channel; /* starting logical channel id */
185 u8 sep_id; /* SEP device logical target id */
186 u8 sep_channel; /* SEP channel logical channel id */
187};
188
547f9a21 189#ifdef MPT_DEBUG_SAS
b5141128
CH
190static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
191{
192 printk("---- IO UNIT PAGE 0 ------------\n");
193 printk("Handle=0x%X\n",
194 le16_to_cpu(phy_data->AttachedDeviceHandle));
195 printk("Controller Handle=0x%X\n",
196 le16_to_cpu(phy_data->ControllerDevHandle));
197 printk("Port=0x%X\n", phy_data->Port);
198 printk("Port Flags=0x%X\n", phy_data->PortFlags);
199 printk("PHY Flags=0x%X\n", phy_data->PhyFlags);
200 printk("Negotiated Link Rate=0x%X\n", phy_data->NegotiatedLinkRate);
201 printk("Controller PHY Device Info=0x%X\n",
202 le32_to_cpu(phy_data->ControllerPhyDeviceInfo));
203 printk("DiscoveryStatus=0x%X\n",
204 le32_to_cpu(phy_data->DiscoveryStatus));
205 printk("\n");
206}
207
208static void mptsas_print_phy_pg0(SasPhyPage0_t *pg0)
209{
210 __le64 sas_address;
211
212 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
213
214 printk("---- SAS PHY PAGE 0 ------------\n");
215 printk("Attached Device Handle=0x%X\n",
216 le16_to_cpu(pg0->AttachedDevHandle));
217 printk("SAS Address=0x%llX\n",
218 (unsigned long long)le64_to_cpu(sas_address));
219 printk("Attached PHY Identifier=0x%X\n", pg0->AttachedPhyIdentifier);
220 printk("Attached Device Info=0x%X\n",
221 le32_to_cpu(pg0->AttachedDeviceInfo));
222 printk("Programmed Link Rate=0x%X\n", pg0->ProgrammedLinkRate);
223 printk("Change Count=0x%X\n", pg0->ChangeCount);
224 printk("PHY Info=0x%X\n", le32_to_cpu(pg0->PhyInfo));
225 printk("\n");
226}
227
228static void mptsas_print_phy_pg1(SasPhyPage1_t *pg1)
229{
230 printk("---- SAS PHY PAGE 1 ------------\n");
f9a2d2e0
CH
231 printk("Invalid Dword Count=0x%x\n", pg1->InvalidDwordCount);
232 printk("Running Disparity Error Count=0x%x\n",
b5141128 233 pg1->RunningDisparityErrorCount);
f9a2d2e0
CH
234 printk("Loss Dword Synch Count=0x%x\n", pg1->LossDwordSynchCount);
235 printk("PHY Reset Problem Count=0x%x\n", pg1->PhyResetProblemCount);
236 printk("\n");
b5141128
CH
237}
238
239static void mptsas_print_device_pg0(SasDevicePage0_t *pg0)
240{
241 __le64 sas_address;
242
243 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
244
245 printk("---- SAS DEVICE PAGE 0 ---------\n");
246 printk("Handle=0x%X\n" ,le16_to_cpu(pg0->DevHandle));
e3094447 247 printk("Parent Handle=0x%X\n" ,le16_to_cpu(pg0->ParentDevHandle));
b5141128
CH
248 printk("Enclosure Handle=0x%X\n", le16_to_cpu(pg0->EnclosureHandle));
249 printk("Slot=0x%X\n", le16_to_cpu(pg0->Slot));
250 printk("SAS Address=0x%llX\n", le64_to_cpu(sas_address));
251 printk("Target ID=0x%X\n", pg0->TargetID);
252 printk("Bus=0x%X\n", pg0->Bus);
f9a2d2e0
CH
253 /* The PhyNum field specifies the PHY number of the parent
254 * device this device is linked to
255 */
256 printk("Parent Phy Num=0x%X\n", pg0->PhyNum);
257 printk("Access Status=0x%X\n", le16_to_cpu(pg0->AccessStatus));
b5141128
CH
258 printk("Device Info=0x%X\n", le32_to_cpu(pg0->DeviceInfo));
259 printk("Flags=0x%X\n", le16_to_cpu(pg0->Flags));
260 printk("Physical Port=0x%X\n", pg0->PhysicalPort);
261 printk("\n");
262}
263
264static void mptsas_print_expander_pg1(SasExpanderPage1_t *pg1)
265{
266 printk("---- SAS EXPANDER PAGE 1 ------------\n");
267
268 printk("Physical Port=0x%X\n", pg1->PhysicalPort);
f9a2d2e0 269 printk("PHY Identifier=0x%X\n", pg1->PhyIdentifier);
b5141128
CH
270 printk("Negotiated Link Rate=0x%X\n", pg1->NegotiatedLinkRate);
271 printk("Programmed Link Rate=0x%X\n", pg1->ProgrammedLinkRate);
272 printk("Hardware Link Rate=0x%X\n", pg1->HwLinkRate);
273 printk("Owner Device Handle=0x%X\n",
274 le16_to_cpu(pg1->OwnerDevHandle));
275 printk("Attached Device Handle=0x%X\n",
276 le16_to_cpu(pg1->AttachedDevHandle));
277}
278#else
279#define mptsas_print_phy_data(phy_data) do { } while (0)
280#define mptsas_print_phy_pg0(pg0) do { } while (0)
281#define mptsas_print_phy_pg1(pg1) do { } while (0)
282#define mptsas_print_device_pg0(pg0) do { } while (0)
283#define mptsas_print_expander_pg1(pg1) do { } while (0)
284#endif
285
e3094447
CH
286static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
287{
288 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
289 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
290}
291
292static inline MPT_ADAPTER *rphy_to_ioc(struct sas_rphy *rphy)
293{
294 struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
295 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
296}
297
e6b2d76a
ME
298/*
299 * mptsas_find_portinfo_by_handle
300 *
301 * This function should be called with the sas_topology_mutex already held
302 */
303static struct mptsas_portinfo *
304mptsas_find_portinfo_by_handle(MPT_ADAPTER *ioc, u16 handle)
305{
306 struct mptsas_portinfo *port_info, *rc=NULL;
307 int i;
308
309 list_for_each_entry(port_info, &ioc->sas_topology, list)
310 for (i = 0; i < port_info->num_phys; i++)
311 if (port_info->phy_info[i].identify.handle == handle) {
312 rc = port_info;
313 goto out;
314 }
315 out:
316 return rc;
317}
318
bd23e94c
ME
319/*
320 * Returns true if there is a scsi end device
321 */
322static inline int
323mptsas_is_end_device(struct mptsas_devinfo * attached)
324{
547f9a21 325 if ((attached->sas_address) &&
bd23e94c
ME
326 (attached->device_info &
327 MPI_SAS_DEVICE_INFO_END_DEVICE) &&
328 ((attached->device_info &
329 MPI_SAS_DEVICE_INFO_SSP_TARGET) |
330 (attached->device_info &
331 MPI_SAS_DEVICE_INFO_STP_TARGET) |
332 (attached->device_info &
333 MPI_SAS_DEVICE_INFO_SATA_DEVICE)))
334 return 1;
335 else
336 return 0;
337}
338
547f9a21 339/* no mutex */
376ac830 340static void
547f9a21
EM
341mptsas_port_delete(struct mptsas_portinfo_details * port_details)
342{
343 struct mptsas_portinfo *port_info;
344 struct mptsas_phyinfo *phy_info;
345 u8 i;
346
347 if (!port_details)
348 return;
349
350 port_info = port_details->port_info;
351 phy_info = port_info->phy_info;
352
353 dsaswideprintk((KERN_DEBUG "%s: [%p]: port=%02d num_phys=%02d "
354 "bitmask=0x%016llX\n",
355 __FUNCTION__, port_details, port_details->port_id,
356 port_details->num_phys, port_details->phy_bitmask));
357
358 for (i = 0; i < port_info->num_phys; i++, phy_info++) {
359 if(phy_info->port_details != port_details)
360 continue;
361 memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
362 phy_info->port_details = NULL;
363 }
364 kfree(port_details);
365}
366
367static inline struct sas_rphy *
368mptsas_get_rphy(struct mptsas_phyinfo *phy_info)
369{
370 if (phy_info->port_details)
371 return phy_info->port_details->rphy;
372 else
373 return NULL;
374}
375
376static inline void
377mptsas_set_rphy(struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy)
378{
379 if (phy_info->port_details) {
380 phy_info->port_details->rphy = rphy;
381 dsaswideprintk((KERN_DEBUG "sas_rphy_add: rphy=%p\n", rphy));
382 }
383
384#ifdef MPT_DEBUG_SAS_WIDE
385 if (rphy) {
386 dev_printk(KERN_DEBUG, &rphy->dev, "add:");
387 printk("rphy=%p release=%p\n",
388 rphy, rphy->dev.release);
389 }
390#endif
391}
392
393static inline struct sas_port *
394mptsas_get_port(struct mptsas_phyinfo *phy_info)
395{
396 if (phy_info->port_details)
397 return phy_info->port_details->port;
398 else
399 return NULL;
400}
401
402static inline void
403mptsas_set_port(struct mptsas_phyinfo *phy_info, struct sas_port *port)
404{
405 if (phy_info->port_details)
406 phy_info->port_details->port = port;
407
408#ifdef MPT_DEBUG_SAS_WIDE
409 if (port) {
410 dev_printk(KERN_DEBUG, &port->dev, "add: ");
411 printk("port=%p release=%p\n",
412 port, port->dev.release);
413 }
414#endif
415}
416
417static inline struct scsi_target *
418mptsas_get_starget(struct mptsas_phyinfo *phy_info)
419{
420 if (phy_info->port_details)
421 return phy_info->port_details->starget;
422 else
423 return NULL;
424}
425
426static inline void
427mptsas_set_starget(struct mptsas_phyinfo *phy_info, struct scsi_target *
428starget)
429{
430 if (phy_info->port_details)
431 phy_info->port_details->starget = starget;
432}
433
434
435/*
436 * mptsas_setup_wide_ports
437 *
438 * Updates for new and existing narrow/wide port configuration
439 * in the sas_topology
440 */
376ac830 441static void
547f9a21
EM
442mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
443{
444 struct mptsas_portinfo_details * port_details;
445 struct mptsas_phyinfo *phy_info, *phy_info_cmp;
446 u64 sas_address;
447 int i, j;
448
449 mutex_lock(&ioc->sas_topology_mutex);
450
451 phy_info = port_info->phy_info;
452 for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
453 if (phy_info->attached.handle)
454 continue;
455 port_details = phy_info->port_details;
456 if (!port_details)
457 continue;
458 if (port_details->num_phys < 2)
459 continue;
460 /*
461 * Removing a phy from a port, letting the last
462 * phy be removed by firmware events.
463 */
464 dsaswideprintk((KERN_DEBUG
465 "%s: [%p]: port=%d deleting phy = %d\n",
466 __FUNCTION__, port_details,
467 port_details->port_id, i));
468 port_details->num_phys--;
469 port_details->phy_bitmask &= ~ (1 << phy_info->phy_id);
470 memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
471 sas_port_delete_phy(port_details->port, phy_info->phy);
472 phy_info->port_details = NULL;
473 }
474
475 /*
476 * Populate and refresh the tree
477 */
478 phy_info = port_info->phy_info;
479 for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
480 sas_address = phy_info->attached.sas_address;
481 dsaswideprintk((KERN_DEBUG "phy_id=%d sas_address=0x%018llX\n",
482 i, sas_address));
483 if (!sas_address)
484 continue;
485 port_details = phy_info->port_details;
486 /*
487 * Forming a port
488 */
489 if (!port_details) {
490 port_details = kzalloc(sizeof(*port_details),
491 GFP_KERNEL);
492 if (!port_details)
493 goto out;
494 port_details->num_phys = 1;
495 port_details->port_info = port_info;
496 port_details->port_id = ioc->port_serial_number++;
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((KERN_DEBUG "\t\tForming port\n\t\t"
502 "phy_id=%d sas_address=0x%018llX\n",
503 i, 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((KERN_DEBUG
519 "\t\tphy_id=%d sas_address=0x%018llX\n",
520 j, phy_info_cmp->attached.sas_address));
521 if (phy_info_cmp->port_details) {
522 port_details->rphy =
523 mptsas_get_rphy(phy_info_cmp);
524 port_details->port =
525 mptsas_get_port(phy_info_cmp);
526 port_details->starget =
527 mptsas_get_starget(phy_info_cmp);
528 port_details->port_id =
529 phy_info_cmp->port_details->port_id;
530 port_details->num_phys =
531 phy_info_cmp->port_details->num_phys;
532// port_info->port_serial_number--;
533 ioc->port_serial_number--;
534 if (!phy_info_cmp->port_details->num_phys)
535 kfree(phy_info_cmp->port_details);
536 } else
537 phy_info_cmp->sas_port_add_phy=1;
538 /*
539 * Adding a phy to a port
540 */
541 phy_info_cmp->port_details = port_details;
542 if (phy_info_cmp->phy_id < 64 )
543 port_details->phy_bitmask |=
544 (1 << phy_info_cmp->phy_id);
545 port_details->num_phys++;
546 }
547 }
548
549 out:
550
551#ifdef MPT_DEBUG_SAS_WIDE
552 for (i = 0; i < port_info->num_phys; i++) {
553 port_details = port_info->phy_info[i].port_details;
554 if (!port_details)
555 continue;
556 dsaswideprintk((KERN_DEBUG
557 "%s: [%p]: phy_id=%02d port_id=%02d num_phys=%02d "
558 "bitmask=0x%016llX\n",
559 __FUNCTION__,
560 port_details, i, port_details->port_id,
561 port_details->num_phys, port_details->phy_bitmask));
562 dsaswideprintk((KERN_DEBUG"\t\tport = %p rphy=%p\n",
563 port_details->port, port_details->rphy));
564 }
565 dsaswideprintk((KERN_DEBUG"\n"));
566#endif
567 mutex_unlock(&ioc->sas_topology_mutex);
568}
569
570static void
571mptsas_target_reset(MPT_ADAPTER *ioc, VirtTarget * vtarget)
572{
573 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
574
575 if (mptscsih_TMHandler(hd,
576 MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
577 vtarget->bus_id, vtarget->target_id, 0, 0, 5) < 0) {
578 hd->tmPending = 0;
579 hd->tmState = TM_STATE_NONE;
580 printk(MYIOC_s_WARN_FMT
581 "Error processing TaskMgmt id=%d TARGET_RESET\n",
582 ioc->name, vtarget->target_id);
583 }
584}
585
e3094447 586static int
52435430 587mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
e3094447
CH
588 u32 form, u32 form_specific)
589{
590 ConfigExtendedPageHeader_t hdr;
591 CONFIGPARMS cfg;
592 SasEnclosurePage0_t *buffer;
593 dma_addr_t dma_handle;
594 int error;
595 __le64 le_identifier;
596
597 memset(&hdr, 0, sizeof(hdr));
598 hdr.PageVersion = MPI_SASENCLOSURE0_PAGEVERSION;
599 hdr.PageNumber = 0;
600 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
601 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_ENCLOSURE;
602
603 cfg.cfghdr.ehdr = &hdr;
604 cfg.physAddr = -1;
605 cfg.pageAddr = form + form_specific;
606 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
607 cfg.dir = 0; /* read */
608 cfg.timeout = 10;
609
610 error = mpt_config(ioc, &cfg);
611 if (error)
612 goto out;
613 if (!hdr.ExtPageLength) {
614 error = -ENXIO;
615 goto out;
616 }
617
618 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
619 &dma_handle);
620 if (!buffer) {
621 error = -ENOMEM;
622 goto out;
623 }
624
625 cfg.physAddr = dma_handle;
626 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
627
628 error = mpt_config(ioc, &cfg);
629 if (error)
630 goto out_free_consistent;
631
632 /* save config data */
633 memcpy(&le_identifier, &buffer->EnclosureLogicalID, sizeof(__le64));
634 enclosure->enclosure_logical_id = le64_to_cpu(le_identifier);
635 enclosure->enclosure_handle = le16_to_cpu(buffer->EnclosureHandle);
636 enclosure->flags = le16_to_cpu(buffer->Flags);
637 enclosure->num_slot = le16_to_cpu(buffer->NumSlots);
638 enclosure->start_slot = le16_to_cpu(buffer->StartSlot);
639 enclosure->start_id = buffer->StartTargetID;
640 enclosure->start_channel = buffer->StartBus;
641 enclosure->sep_id = buffer->SEPTargetID;
642 enclosure->sep_channel = buffer->SEPBus;
643
644 out_free_consistent:
645 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
646 buffer, dma_handle);
647 out:
648 return error;
649}
b5141128 650
f013db32
JB
651static int
652mptsas_slave_configure(struct scsi_device *sdev)
653{
3c0c25b9
ME
654 struct Scsi_Host *host = sdev->host;
655 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
656
657 /*
658 * RAID volumes placed beyond the last expected port.
659 * Ignore sending sas mode pages in that case..
660 */
661 if (sdev->channel < hd->ioc->num_ports)
662 sas_read_port_mode_page(sdev);
f013db32
JB
663
664 return mptscsih_slave_configure(sdev);
665}
666
547f9a21
EM
667static int
668mptsas_target_alloc(struct scsi_target *starget)
669{
670 struct Scsi_Host *host = dev_to_shost(&starget->dev);
671 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
672 VirtTarget *vtarget;
673 u32 target_id;
674 u32 channel;
675 struct sas_rphy *rphy;
676 struct mptsas_portinfo *p;
677 int i;
678
679 vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
680 if (!vtarget)
681 return -ENOMEM;
682
683 vtarget->starget = starget;
684 vtarget->ioc_id = hd->ioc->id;
685 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY;
686
687 target_id = starget->id;
688 channel = 0;
689
690 hd->Targets[target_id] = vtarget;
691
692 /*
693 * RAID volumes placed beyond the last expected port.
694 */
695 if (starget->channel == hd->ioc->num_ports)
696 goto out;
697
698 rphy = dev_to_rphy(starget->dev.parent);
699 mutex_lock(&hd->ioc->sas_topology_mutex);
700 list_for_each_entry(p, &hd->ioc->sas_topology, list) {
701 for (i = 0; i < p->num_phys; i++) {
702 if (p->phy_info[i].attached.sas_address !=
703 rphy->identify.sas_address)
704 continue;
705 target_id = p->phy_info[i].attached.id;
706 channel = p->phy_info[i].attached.channel;
707 mptsas_set_starget(&p->phy_info[i], starget);
708
709 /*
710 * Exposing hidden raid components
711 */
712 if (mptscsih_is_phys_disk(hd->ioc, target_id)) {
713 target_id = mptscsih_raid_id_to_num(hd,
714 target_id);
715 vtarget->tflags |=
716 MPT_TARGET_FLAGS_RAID_COMPONENT;
717 }
718 mutex_unlock(&hd->ioc->sas_topology_mutex);
719 goto out;
720 }
721 }
722 mutex_unlock(&hd->ioc->sas_topology_mutex);
723
724 kfree(vtarget);
725 return -ENXIO;
726
727 out:
728 vtarget->target_id = target_id;
729 vtarget->bus_id = channel;
730 starget->hostdata = vtarget;
731 return 0;
732}
733
734static void
735mptsas_target_destroy(struct scsi_target *starget)
736{
737 struct Scsi_Host *host = dev_to_shost(&starget->dev);
738 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
739 struct sas_rphy *rphy;
740 struct mptsas_portinfo *p;
741 int i;
742
743 if (!starget->hostdata)
744 return;
745
746 if (starget->channel == hd->ioc->num_ports)
747 goto out;
748
749 rphy = dev_to_rphy(starget->dev.parent);
750 list_for_each_entry(p, &hd->ioc->sas_topology, list) {
751 for (i = 0; i < p->num_phys; i++) {
752 if (p->phy_info[i].attached.sas_address !=
753 rphy->identify.sas_address)
754 continue;
755 mptsas_set_starget(&p->phy_info[i], NULL);
756 goto out;
757 }
758 }
759
760 out:
761 kfree(starget->hostdata);
762 starget->hostdata = NULL;
763}
764
765
0c33b27d 766static int
c7c82987 767mptsas_slave_alloc(struct scsi_device *sdev)
0c33b27d 768{
c7c82987 769 struct Scsi_Host *host = sdev->host;
0c33b27d
CH
770 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
771 struct sas_rphy *rphy;
772 struct mptsas_portinfo *p;
773 VirtDevice *vdev;
c7c82987 774 struct scsi_target *starget;
547f9a21 775 int i;
0c33b27d 776
1ca00bb7 777 vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
0c33b27d 778 if (!vdev) {
547f9a21 779 printk(MYIOC_s_ERR_FMT "slave_alloc kzalloc(%zd) FAILED!\n",
0c33b27d
CH
780 hd->ioc->name, sizeof(VirtDevice));
781 return -ENOMEM;
782 }
c7c82987 783 starget = scsi_target(sdev);
547f9a21 784 vdev->vtarget = starget->hostdata;
0c33b27d 785
816aa907 786 /*
547f9a21
EM
787 * RAID volumes placed beyond the last expected port.
788 */
789 if (sdev->channel == hd->ioc->num_ports)
816aa907 790 goto out;
816aa907 791
c7c82987 792 rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
9a28f49a 793 mutex_lock(&hd->ioc->sas_topology_mutex);
0c33b27d
CH
794 list_for_each_entry(p, &hd->ioc->sas_topology, list) {
795 for (i = 0; i < p->num_phys; i++) {
547f9a21
EM
796 if (p->phy_info[i].attached.sas_address !=
797 rphy->identify.sas_address)
798 continue;
799 vdev->lun = sdev->lun;
800 /*
801 * Exposing hidden raid components
802 */
803 if (mptscsih_is_phys_disk(hd->ioc,
804 p->phy_info[i].attached.id))
805 sdev->no_uld_attach = 1;
806 mutex_unlock(&hd->ioc->sas_topology_mutex);
807 goto out;
0c33b27d
CH
808 }
809 }
9a28f49a 810 mutex_unlock(&hd->ioc->sas_topology_mutex);
0c33b27d 811
0c33b27d 812 kfree(vdev);
23f236ed 813 return -ENXIO;
0c33b27d
CH
814
815 out:
547f9a21
EM
816 vdev->vtarget->num_luns++;
817 sdev->hostdata = vdev;
0c33b27d
CH
818 return 0;
819}
820
547f9a21
EM
821static int
822mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
9a28f49a 823{
547f9a21 824 VirtDevice *vdev = SCpnt->device->hostdata;
7d3eecf7 825
547f9a21
EM
826// scsi_print_command(SCpnt);
827 if (vdev->vtarget->deleted) {
828 SCpnt->result = DID_NO_CONNECT << 16;
829 done(SCpnt);
830 return 0;
7d3eecf7 831 }
547f9a21
EM
832
833 return mptscsih_qcmd(SCpnt,done);
9a28f49a
CH
834}
835
547f9a21 836
0c33b27d 837static struct scsi_host_template mptsas_driver_template = {
f78496da 838 .module = THIS_MODULE,
0c33b27d
CH
839 .proc_name = "mptsas",
840 .proc_info = mptscsih_proc_info,
841 .name = "MPT SPI Host",
842 .info = mptscsih_info,
547f9a21
EM
843 .queuecommand = mptsas_qcmd,
844 .target_alloc = mptsas_target_alloc,
0c33b27d 845 .slave_alloc = mptsas_slave_alloc,
f013db32 846 .slave_configure = mptsas_slave_configure,
547f9a21
EM
847 .target_destroy = mptsas_target_destroy,
848 .slave_destroy = mptscsih_slave_destroy,
0c33b27d
CH
849 .change_queue_depth = mptscsih_change_queue_depth,
850 .eh_abort_handler = mptscsih_abort,
851 .eh_device_reset_handler = mptscsih_dev_reset,
852 .eh_bus_reset_handler = mptscsih_bus_reset,
853 .eh_host_reset_handler = mptscsih_host_reset,
854 .bios_param = mptscsih_bios_param,
855 .can_queue = MPT_FC_CAN_QUEUE,
856 .this_id = -1,
857 .sg_tablesize = MPT_SCSI_SG_DEPTH,
858 .max_sectors = 8192,
859 .cmd_per_lun = 7,
860 .use_clustering = ENABLE_CLUSTERING,
861};
862
b5141128 863static int mptsas_get_linkerrors(struct sas_phy *phy)
0c33b27d 864{
b5141128
CH
865 MPT_ADAPTER *ioc = phy_to_ioc(phy);
866 ConfigExtendedPageHeader_t hdr;
867 CONFIGPARMS cfg;
868 SasPhyPage1_t *buffer;
869 dma_addr_t dma_handle;
870 int error;
0c33b27d 871
b5141128
CH
872 hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
873 hdr.ExtPageLength = 0;
874 hdr.PageNumber = 1 /* page number 1*/;
875 hdr.Reserved1 = 0;
876 hdr.Reserved2 = 0;
877 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
878 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
0c33b27d 879
b5141128
CH
880 cfg.cfghdr.ehdr = &hdr;
881 cfg.physAddr = -1;
882 cfg.pageAddr = phy->identify.phy_identifier;
883 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
884 cfg.dir = 0; /* read */
885 cfg.timeout = 10;
0c33b27d 886
b5141128
CH
887 error = mpt_config(ioc, &cfg);
888 if (error)
889 return error;
890 if (!hdr.ExtPageLength)
891 return -ENXIO;
0c33b27d 892
b5141128
CH
893 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
894 &dma_handle);
895 if (!buffer)
896 return -ENOMEM;
0c33b27d 897
b5141128
CH
898 cfg.physAddr = dma_handle;
899 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
900
901 error = mpt_config(ioc, &cfg);
902 if (error)
903 goto out_free_consistent;
904
905 mptsas_print_phy_pg1(buffer);
906
907 phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
908 phy->running_disparity_error_count =
909 le32_to_cpu(buffer->RunningDisparityErrorCount);
910 phy->loss_of_dword_sync_count =
911 le32_to_cpu(buffer->LossDwordSynchCount);
912 phy->phy_reset_problem_count =
913 le32_to_cpu(buffer->PhyResetProblemCount);
914
915 out_free_consistent:
916 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
917 buffer, dma_handle);
918 return error;
0c33b27d
CH
919}
920
da4fa655
CH
921static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
922 MPT_FRAME_HDR *reply)
923{
924 ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_COMMAND_GOOD;
925 if (reply != NULL) {
926 ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_RF_VALID;
927 memcpy(ioc->sas_mgmt.reply, reply,
928 min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
929 }
930 complete(&ioc->sas_mgmt.done);
931 return 1;
932}
933
934static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
935{
936 MPT_ADAPTER *ioc = phy_to_ioc(phy);
937 SasIoUnitControlRequest_t *req;
938 SasIoUnitControlReply_t *reply;
939 MPT_FRAME_HDR *mf;
940 MPIHeader_t *hdr;
941 unsigned long timeleft;
942 int error = -ERESTARTSYS;
943
944 /* not implemented for expanders */
945 if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
946 return -ENXIO;
947
eeb846ce 948 if (mutex_lock_interruptible(&ioc->sas_mgmt.mutex))
da4fa655
CH
949 goto out;
950
951 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
952 if (!mf) {
953 error = -ENOMEM;
954 goto out_unlock;
955 }
956
957 hdr = (MPIHeader_t *) mf;
958 req = (SasIoUnitControlRequest_t *)mf;
959 memset(req, 0, sizeof(SasIoUnitControlRequest_t));
960 req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
961 req->MsgContext = hdr->MsgContext;
962 req->Operation = hard_reset ?
963 MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
964 req->PhyNum = phy->identify.phy_identifier;
965
966 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
967
968 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
969 10 * HZ);
970 if (!timeleft) {
971 /* On timeout reset the board */
972 mpt_free_msg_frame(ioc, mf);
973 mpt_HardResetHandler(ioc, CAN_SLEEP);
974 error = -ETIMEDOUT;
975 goto out_unlock;
976 }
977
978 /* a reply frame is expected */
979 if ((ioc->sas_mgmt.status &
980 MPT_IOCTL_STATUS_RF_VALID) == 0) {
981 error = -ENXIO;
982 goto out_unlock;
983 }
984
985 /* process the completed Reply Message Frame */
986 reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
987 if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
988 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
989 __FUNCTION__,
990 reply->IOCStatus,
991 reply->IOCLogInfo);
992 error = -ENXIO;
993 goto out_unlock;
994 }
995
996 error = 0;
997
998 out_unlock:
eeb846ce 999 mutex_unlock(&ioc->sas_mgmt.mutex);
da4fa655
CH
1000 out:
1001 return error;
1002}
0c33b27d 1003
e3094447
CH
1004static int
1005mptsas_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
1006{
1007 MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
1008 int i, error;
1009 struct mptsas_portinfo *p;
1010 struct mptsas_enclosure enclosure_info;
1011 u64 enclosure_handle;
1012
1013 mutex_lock(&ioc->sas_topology_mutex);
1014 list_for_each_entry(p, &ioc->sas_topology, list) {
1015 for (i = 0; i < p->num_phys; i++) {
1016 if (p->phy_info[i].attached.sas_address ==
1017 rphy->identify.sas_address) {
1018 enclosure_handle = p->phy_info[i].
1019 attached.handle_enclosure;
1020 goto found_info;
1021 }
1022 }
1023 }
1024 mutex_unlock(&ioc->sas_topology_mutex);
1025 return -ENXIO;
1026
1027 found_info:
1028 mutex_unlock(&ioc->sas_topology_mutex);
1029 memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
52435430 1030 error = mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
e3094447
CH
1031 (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
1032 MPI_SAS_ENCLOS_PGAD_FORM_SHIFT), enclosure_handle);
1033 if (!error)
1034 *identifier = enclosure_info.enclosure_logical_id;
1035 return error;
1036}
1037
1038static int
1039mptsas_get_bay_identifier(struct sas_rphy *rphy)
1040{
1041 MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
1042 struct mptsas_portinfo *p;
1043 int i, rc;
1044
1045 mutex_lock(&ioc->sas_topology_mutex);
1046 list_for_each_entry(p, &ioc->sas_topology, list) {
1047 for (i = 0; i < p->num_phys; i++) {
1048 if (p->phy_info[i].attached.sas_address ==
1049 rphy->identify.sas_address) {
1050 rc = p->phy_info[i].attached.slot;
1051 goto out;
1052 }
1053 }
1054 }
1055 rc = -ENXIO;
1056 out:
1057 mutex_unlock(&ioc->sas_topology_mutex);
1058 return rc;
1059}
1060
b5141128
CH
1061static struct sas_function_template mptsas_transport_functions = {
1062 .get_linkerrors = mptsas_get_linkerrors,
e3094447
CH
1063 .get_enclosure_identifier = mptsas_get_enclosure_identifier,
1064 .get_bay_identifier = mptsas_get_bay_identifier,
da4fa655 1065 .phy_reset = mptsas_phy_reset,
b5141128
CH
1066};
1067
1068static struct scsi_transport_template *mptsas_transport_template;
0c33b27d
CH
1069
1070static int
1071mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
1072{
1073 ConfigExtendedPageHeader_t hdr;
1074 CONFIGPARMS cfg;
1075 SasIOUnitPage0_t *buffer;
1076 dma_addr_t dma_handle;
1077 int error, i;
1078
1079 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
1080 hdr.ExtPageLength = 0;
1081 hdr.PageNumber = 0;
1082 hdr.Reserved1 = 0;
1083 hdr.Reserved2 = 0;
1084 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1085 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1086
1087 cfg.cfghdr.ehdr = &hdr;
1088 cfg.physAddr = -1;
1089 cfg.pageAddr = 0;
1090 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1091 cfg.dir = 0; /* read */
1092 cfg.timeout = 10;
1093
1094 error = mpt_config(ioc, &cfg);
1095 if (error)
1096 goto out;
1097 if (!hdr.ExtPageLength) {
1098 error = -ENXIO;
1099 goto out;
1100 }
1101
1102 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1103 &dma_handle);
1104 if (!buffer) {
1105 error = -ENOMEM;
1106 goto out;
1107 }
1108
1109 cfg.physAddr = dma_handle;
1110 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1111
1112 error = mpt_config(ioc, &cfg);
1113 if (error)
1114 goto out_free_consistent;
1115
1116 port_info->num_phys = buffer->NumPhys;
1117 port_info->phy_info = kcalloc(port_info->num_phys,
547f9a21 1118 sizeof(*port_info->phy_info),GFP_KERNEL);
0c33b27d
CH
1119 if (!port_info->phy_info) {
1120 error = -ENOMEM;
1121 goto out_free_consistent;
1122 }
1123
db9c9174
ME
1124 if (port_info->num_phys)
1125 port_info->handle =
1126 le16_to_cpu(buffer->PhyData[0].ControllerDevHandle);
0c33b27d
CH
1127 for (i = 0; i < port_info->num_phys; i++) {
1128 mptsas_print_phy_data(&buffer->PhyData[i]);
1129 port_info->phy_info[i].phy_id = i;
1130 port_info->phy_info[i].port_id =
1131 buffer->PhyData[i].Port;
1132 port_info->phy_info[i].negotiated_link_rate =
1133 buffer->PhyData[i].NegotiatedLinkRate;
547f9a21 1134 port_info->phy_info[i].portinfo = port_info;
0c33b27d
CH
1135 }
1136
1137 out_free_consistent:
1138 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1139 buffer, dma_handle);
1140 out:
1141 return error;
1142}
1143
1144static int
1145mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
1146 u32 form, u32 form_specific)
1147{
1148 ConfigExtendedPageHeader_t hdr;
1149 CONFIGPARMS cfg;
1150 SasPhyPage0_t *buffer;
1151 dma_addr_t dma_handle;
1152 int error;
1153
1154 hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
1155 hdr.ExtPageLength = 0;
1156 hdr.PageNumber = 0;
1157 hdr.Reserved1 = 0;
1158 hdr.Reserved2 = 0;
1159 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1160 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
1161
1162 cfg.cfghdr.ehdr = &hdr;
1163 cfg.dir = 0; /* read */
1164 cfg.timeout = 10;
1165
1166 /* Get Phy Pg 0 for each Phy. */
1167 cfg.physAddr = -1;
1168 cfg.pageAddr = form + form_specific;
1169 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1170
1171 error = mpt_config(ioc, &cfg);
1172 if (error)
1173 goto out;
1174
1175 if (!hdr.ExtPageLength) {
1176 error = -ENXIO;
1177 goto out;
1178 }
1179
1180 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1181 &dma_handle);
1182 if (!buffer) {
1183 error = -ENOMEM;
1184 goto out;
1185 }
1186
1187 cfg.physAddr = dma_handle;
1188 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1189
1190 error = mpt_config(ioc, &cfg);
1191 if (error)
1192 goto out_free_consistent;
1193
1194 mptsas_print_phy_pg0(buffer);
1195
1196 phy_info->hw_link_rate = buffer->HwLinkRate;
1197 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
1198 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
1199 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
1200
1201 out_free_consistent:
1202 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1203 buffer, dma_handle);
1204 out:
1205 return error;
1206}
1207
1208static int
1209mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
1210 u32 form, u32 form_specific)
1211{
1212 ConfigExtendedPageHeader_t hdr;
1213 CONFIGPARMS cfg;
1214 SasDevicePage0_t *buffer;
1215 dma_addr_t dma_handle;
1216 __le64 sas_address;
bd23e94c
ME
1217 int error=0;
1218
1219 if (ioc->sas_discovery_runtime &&
1220 mptsas_is_end_device(device_info))
1221 goto out;
0c33b27d
CH
1222
1223 hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
1224 hdr.ExtPageLength = 0;
1225 hdr.PageNumber = 0;
1226 hdr.Reserved1 = 0;
1227 hdr.Reserved2 = 0;
1228 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1229 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
1230
1231 cfg.cfghdr.ehdr = &hdr;
1232 cfg.pageAddr = form + form_specific;
1233 cfg.physAddr = -1;
1234 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1235 cfg.dir = 0; /* read */
1236 cfg.timeout = 10;
1237
db9c9174 1238 memset(device_info, 0, sizeof(struct mptsas_devinfo));
0c33b27d
CH
1239 error = mpt_config(ioc, &cfg);
1240 if (error)
1241 goto out;
1242 if (!hdr.ExtPageLength) {
1243 error = -ENXIO;
1244 goto out;
1245 }
1246
1247 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1248 &dma_handle);
1249 if (!buffer) {
1250 error = -ENOMEM;
1251 goto out;
1252 }
1253
1254 cfg.physAddr = dma_handle;
1255 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1256
1257 error = mpt_config(ioc, &cfg);
1258 if (error)
1259 goto out_free_consistent;
1260
1261 mptsas_print_device_pg0(buffer);
1262
1263 device_info->handle = le16_to_cpu(buffer->DevHandle);
c73787ee 1264 device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle);
e3094447
CH
1265 device_info->handle_enclosure =
1266 le16_to_cpu(buffer->EnclosureHandle);
1267 device_info->slot = le16_to_cpu(buffer->Slot);
0c33b27d
CH
1268 device_info->phy_id = buffer->PhyNum;
1269 device_info->port_id = buffer->PhysicalPort;
9a28f49a
CH
1270 device_info->id = buffer->TargetID;
1271 device_info->channel = buffer->Bus;
0c33b27d
CH
1272 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
1273 device_info->sas_address = le64_to_cpu(sas_address);
1274 device_info->device_info =
1275 le32_to_cpu(buffer->DeviceInfo);
1276
1277 out_free_consistent:
1278 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1279 buffer, dma_handle);
1280 out:
1281 return error;
1282}
1283
1284static int
1285mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
1286 u32 form, u32 form_specific)
1287{
1288 ConfigExtendedPageHeader_t hdr;
1289 CONFIGPARMS cfg;
1290 SasExpanderPage0_t *buffer;
1291 dma_addr_t dma_handle;
547f9a21 1292 int i, error;
0c33b27d
CH
1293
1294 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
1295 hdr.ExtPageLength = 0;
1296 hdr.PageNumber = 0;
1297 hdr.Reserved1 = 0;
1298 hdr.Reserved2 = 0;
1299 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1300 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1301
1302 cfg.cfghdr.ehdr = &hdr;
1303 cfg.physAddr = -1;
1304 cfg.pageAddr = form + form_specific;
1305 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1306 cfg.dir = 0; /* read */
1307 cfg.timeout = 10;
1308
db9c9174 1309 memset(port_info, 0, sizeof(struct mptsas_portinfo));
0c33b27d
CH
1310 error = mpt_config(ioc, &cfg);
1311 if (error)
1312 goto out;
1313
1314 if (!hdr.ExtPageLength) {
1315 error = -ENXIO;
1316 goto out;
1317 }
1318
1319 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1320 &dma_handle);
1321 if (!buffer) {
1322 error = -ENOMEM;
1323 goto out;
1324 }
1325
1326 cfg.physAddr = dma_handle;
1327 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1328
1329 error = mpt_config(ioc, &cfg);
1330 if (error)
1331 goto out_free_consistent;
1332
1333 /* save config data */
1334 port_info->num_phys = buffer->NumPhys;
1335 port_info->handle = le16_to_cpu(buffer->DevHandle);
1336 port_info->phy_info = kcalloc(port_info->num_phys,
547f9a21 1337 sizeof(*port_info->phy_info),GFP_KERNEL);
0c33b27d
CH
1338 if (!port_info->phy_info) {
1339 error = -ENOMEM;
1340 goto out_free_consistent;
1341 }
1342
547f9a21
EM
1343 for (i = 0; i < port_info->num_phys; i++)
1344 port_info->phy_info[i].portinfo = port_info;
1345
0c33b27d
CH
1346 out_free_consistent:
1347 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1348 buffer, dma_handle);
1349 out:
1350 return error;
1351}
1352
1353static int
1354mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
1355 u32 form, u32 form_specific)
1356{
1357 ConfigExtendedPageHeader_t hdr;
1358 CONFIGPARMS cfg;
1359 SasExpanderPage1_t *buffer;
1360 dma_addr_t dma_handle;
bd23e94c
ME
1361 int error=0;
1362
1363 if (ioc->sas_discovery_runtime &&
1364 mptsas_is_end_device(&phy_info->attached))
1365 goto out;
0c33b27d
CH
1366
1367 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
1368 hdr.ExtPageLength = 0;
1369 hdr.PageNumber = 1;
1370 hdr.Reserved1 = 0;
1371 hdr.Reserved2 = 0;
1372 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1373 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1374
1375 cfg.cfghdr.ehdr = &hdr;
1376 cfg.physAddr = -1;
1377 cfg.pageAddr = form + form_specific;
1378 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1379 cfg.dir = 0; /* read */
1380 cfg.timeout = 10;
1381
1382 error = mpt_config(ioc, &cfg);
1383 if (error)
1384 goto out;
1385
1386 if (!hdr.ExtPageLength) {
1387 error = -ENXIO;
1388 goto out;
1389 }
1390
1391 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1392 &dma_handle);
1393 if (!buffer) {
1394 error = -ENOMEM;
1395 goto out;
1396 }
1397
1398 cfg.physAddr = dma_handle;
1399 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1400
1401 error = mpt_config(ioc, &cfg);
1402 if (error)
1403 goto out_free_consistent;
1404
1405
1406 mptsas_print_expander_pg1(buffer);
1407
1408 /* save config data */
024358ee 1409 phy_info->phy_id = buffer->PhyIdentifier;
0c33b27d
CH
1410 phy_info->port_id = buffer->PhysicalPort;
1411 phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
1412 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
1413 phy_info->hw_link_rate = buffer->HwLinkRate;
1414 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
1415 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
1416
0c33b27d
CH
1417 out_free_consistent:
1418 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1419 buffer, dma_handle);
1420 out:
1421 return error;
1422}
1423
1424static void
1425mptsas_parse_device_info(struct sas_identify *identify,
1426 struct mptsas_devinfo *device_info)
1427{
1428 u16 protocols;
1429
1430 identify->sas_address = device_info->sas_address;
1431 identify->phy_identifier = device_info->phy_id;
1432
1433 /*
1434 * Fill in Phy Initiator Port Protocol.
1435 * Bits 6:3, more than one bit can be set, fall through cases.
1436 */
1437 protocols = device_info->device_info & 0x78;
1438 identify->initiator_port_protocols = 0;
1439 if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
1440 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
1441 if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
1442 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
1443 if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
1444 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
1445 if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
1446 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
1447
1448 /*
1449 * Fill in Phy Target Port Protocol.
1450 * Bits 10:7, more than one bit can be set, fall through cases.
1451 */
1452 protocols = device_info->device_info & 0x780;
1453 identify->target_port_protocols = 0;
1454 if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
1455 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
1456 if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
1457 identify->target_port_protocols |= SAS_PROTOCOL_STP;
1458 if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
1459 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
1460 if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1461 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
1462
1463 /*
1464 * Fill in Attached device type.
1465 */
1466 switch (device_info->device_info &
1467 MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
1468 case MPI_SAS_DEVICE_INFO_NO_DEVICE:
1469 identify->device_type = SAS_PHY_UNUSED;
1470 break;
1471 case MPI_SAS_DEVICE_INFO_END_DEVICE:
1472 identify->device_type = SAS_END_DEVICE;
1473 break;
1474 case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
1475 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
1476 break;
1477 case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
1478 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
1479 break;
1480 }
1481}
1482
1483static int mptsas_probe_one_phy(struct device *dev,
ac01bbbd 1484 struct mptsas_phyinfo *phy_info, int index, int local)
0c33b27d 1485{
e6b2d76a 1486 MPT_ADAPTER *ioc;
9a28f49a 1487 struct sas_phy *phy;
547f9a21
EM
1488 struct sas_port *port;
1489 int error = 0;
0c33b27d 1490
547f9a21
EM
1491 if (!dev) {
1492 error = -ENODEV;
1493 goto out;
1494 }
e6b2d76a
ME
1495
1496 if (!phy_info->phy) {
1497 phy = sas_phy_alloc(dev, index);
547f9a21
EM
1498 if (!phy) {
1499 error = -ENOMEM;
1500 goto out;
1501 }
e6b2d76a
ME
1502 } else
1503 phy = phy_info->phy;
0c33b27d 1504
9a28f49a 1505 mptsas_parse_device_info(&phy->identify, &phy_info->identify);
0c33b27d
CH
1506
1507 /*
1508 * Set Negotiated link rate.
1509 */
1510 switch (phy_info->negotiated_link_rate) {
1511 case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
9a28f49a 1512 phy->negotiated_linkrate = SAS_PHY_DISABLED;
0c33b27d
CH
1513 break;
1514 case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
9a28f49a 1515 phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;
0c33b27d
CH
1516 break;
1517 case MPI_SAS_IOUNIT0_RATE_1_5:
9a28f49a 1518 phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
0c33b27d
CH
1519 break;
1520 case MPI_SAS_IOUNIT0_RATE_3_0:
9a28f49a 1521 phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
0c33b27d
CH
1522 break;
1523 case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
1524 case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
1525 default:
9a28f49a 1526 phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
0c33b27d
CH
1527 break;
1528 }
1529
1530 /*
1531 * Set Max hardware link rate.
1532 */
1533 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
1534 case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
9a28f49a 1535 phy->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
0c33b27d
CH
1536 break;
1537 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
9a28f49a 1538 phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
0c33b27d
CH
1539 break;
1540 default:
1541 break;
1542 }
1543
1544 /*
1545 * Set Max programmed link rate.
1546 */
1547 switch (phy_info->programmed_link_rate &
1548 MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
1549 case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
9a28f49a 1550 phy->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
0c33b27d
CH
1551 break;
1552 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
9a28f49a 1553 phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
0c33b27d
CH
1554 break;
1555 default:
1556 break;
1557 }
1558
1559 /*
1560 * Set Min hardware link rate.
1561 */
1562 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
1563 case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
9a28f49a 1564 phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
0c33b27d
CH
1565 break;
1566 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
9a28f49a 1567 phy->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
0c33b27d
CH
1568 break;
1569 default:
1570 break;
1571 }
1572
1573 /*
1574 * Set Min programmed link rate.
1575 */
1576 switch (phy_info->programmed_link_rate &
1577 MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
1578 case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
9a28f49a 1579 phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
0c33b27d
CH
1580 break;
1581 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
9a28f49a 1582 phy->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
0c33b27d
CH
1583 break;
1584 default:
1585 break;
1586 }
1587
e6b2d76a 1588 if (!phy_info->phy) {
ac01bbbd 1589
e6b2d76a
ME
1590 if (local)
1591 phy->local_attached = 1;
1592
1593 error = sas_phy_add(phy);
1594 if (error) {
1595 sas_phy_free(phy);
547f9a21 1596 goto out;
e6b2d76a
ME
1597 }
1598 phy_info->phy = phy;
0c33b27d
CH
1599 }
1600
547f9a21
EM
1601 if (!phy_info->attached.handle ||
1602 !phy_info->port_details)
1603 goto out;
1604
1605 port = mptsas_get_port(phy_info);
1606 ioc = phy_to_ioc(phy_info->phy);
1607
1608 if (phy_info->sas_port_add_phy) {
1609
1610 if (!port) {
1611 port = sas_port_alloc(dev,
1612 phy_info->port_details->port_id);
1613 dsaswideprintk((KERN_DEBUG
1614 "sas_port_alloc: port=%p dev=%p port_id=%d\n",
1615 port, dev, phy_info->port_details->port_id));
1616 if (!port) {
1617 error = -ENOMEM;
1618 goto out;
1619 }
1620 error = sas_port_add(port);
1621 if (error) {
1622 dfailprintk((MYIOC_s_ERR_FMT
1623 "%s: exit at line=%d\n", ioc->name,
1624 __FUNCTION__, __LINE__));
1625 goto out;
1626 }
1627 mptsas_set_port(phy_info, port);
1628 }
1629 dsaswideprintk((KERN_DEBUG "sas_port_add_phy: phy_id=%d\n",
1630 phy_info->phy_id));
1631 sas_port_add_phy(port, phy_info->phy);
1632 phy_info->sas_port_add_phy = 0;
1633 }
1634
1635 if (!mptsas_get_rphy(phy_info) && port && !port->rphy) {
e6b2d76a 1636
0c33b27d 1637 struct sas_rphy *rphy;
2686de27 1638 struct device *parent;
f013db32 1639 struct sas_identify identify;
0c33b27d 1640
2686de27 1641 parent = dev->parent->parent;
e6b2d76a
ME
1642 /*
1643 * Let the hotplug_work thread handle processing
1644 * the adding/removing of devices that occur
1645 * after start of day.
1646 */
1647 if (ioc->sas_discovery_runtime &&
1648 mptsas_is_end_device(&phy_info->attached))
547f9a21 1649 goto out;
e6b2d76a 1650
f013db32 1651 mptsas_parse_device_info(&identify, &phy_info->attached);
2686de27
JB
1652 if (scsi_is_host_device(parent)) {
1653 struct mptsas_portinfo *port_info;
1654 int i;
1655
1656 mutex_lock(&ioc->sas_topology_mutex);
1657 port_info = mptsas_find_portinfo_by_handle(ioc,
1658 ioc->handle);
1659 mutex_unlock(&ioc->sas_topology_mutex);
1660
1661 for (i = 0; i < port_info->num_phys; i++)
1662 if (port_info->phy_info[i].identify.sas_address ==
1663 identify.sas_address)
1664 goto out;
1665
1666 } else if (scsi_is_sas_rphy(parent)) {
1667 struct sas_rphy *parent_rphy = dev_to_rphy(parent);
1668 if (identify.sas_address ==
1669 parent_rphy->identify.sas_address)
1670 goto out;
1671 }
1672
f013db32
JB
1673 switch (identify.device_type) {
1674 case SAS_END_DEVICE:
547f9a21 1675 rphy = sas_end_device_alloc(port);
f013db32
JB
1676 break;
1677 case SAS_EDGE_EXPANDER_DEVICE:
1678 case SAS_FANOUT_EXPANDER_DEVICE:
547f9a21 1679 rphy = sas_expander_alloc(port, identify.device_type);
f013db32
JB
1680 break;
1681 default:
1682 rphy = NULL;
1683 break;
1684 }
547f9a21
EM
1685 if (!rphy) {
1686 dfailprintk((MYIOC_s_ERR_FMT
1687 "%s: exit at line=%d\n", ioc->name,
1688 __FUNCTION__, __LINE__));
1689 goto out;
1690 }
0c33b27d 1691
f013db32 1692 rphy->identify = identify;
0c33b27d
CH
1693 error = sas_rphy_add(rphy);
1694 if (error) {
547f9a21
EM
1695 dfailprintk((MYIOC_s_ERR_FMT
1696 "%s: exit at line=%d\n", ioc->name,
1697 __FUNCTION__, __LINE__));
0c33b27d 1698 sas_rphy_free(rphy);
547f9a21 1699 goto out;
0c33b27d 1700 }
547f9a21 1701 mptsas_set_rphy(phy_info, rphy);
0c33b27d
CH
1702 }
1703
547f9a21
EM
1704 out:
1705 return error;
0c33b27d
CH
1706}
1707
1708static int
e6b2d76a 1709mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
0c33b27d 1710{
e6b2d76a 1711 struct mptsas_portinfo *port_info, *hba;
0c33b27d
CH
1712 u32 handle = 0xFFFF;
1713 int error = -ENOMEM, i;
1714
e6b2d76a
ME
1715 hba = kzalloc(sizeof(*port_info), GFP_KERNEL);
1716 if (! hba)
0c33b27d 1717 goto out;
0c33b27d 1718
e6b2d76a 1719 error = mptsas_sas_io_unit_pg0(ioc, hba);
0c33b27d
CH
1720 if (error)
1721 goto out_free_port_info;
1722
9a28f49a 1723 mutex_lock(&ioc->sas_topology_mutex);
2686de27 1724 ioc->handle = hba->handle;
e6b2d76a
ME
1725 port_info = mptsas_find_portinfo_by_handle(ioc, hba->handle);
1726 if (!port_info) {
1727 port_info = hba;
1728 list_add_tail(&port_info->list, &ioc->sas_topology);
1729 } else {
1730 port_info->handle = hba->handle;
1731 for (i = 0; i < hba->num_phys; i++)
1732 port_info->phy_info[i].negotiated_link_rate =
1733 hba->phy_info[i].negotiated_link_rate;
547f9a21 1734 kfree(hba->phy_info);
e6b2d76a
ME
1735 kfree(hba);
1736 hba = NULL;
1737 }
9a28f49a 1738 mutex_unlock(&ioc->sas_topology_mutex);
e6b2d76a 1739 ioc->num_ports = port_info->num_phys;
9a28f49a 1740
0c33b27d
CH
1741 for (i = 0; i < port_info->num_phys; i++) {
1742 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
1743 (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
1744 MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
1745
1746 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
1747 (MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE <<
1748 MPI_SAS_DEVICE_PGAD_FORM_SHIFT), handle);
024358ee
EM
1749 port_info->phy_info[i].identify.phy_id =
1750 port_info->phy_info[i].phy_id;
0c33b27d
CH
1751 handle = port_info->phy_info[i].identify.handle;
1752
547f9a21 1753 if (port_info->phy_info[i].attached.handle)
0c33b27d
CH
1754 mptsas_sas_device_pg0(ioc,
1755 &port_info->phy_info[i].attached,
1756 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1757 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1758 port_info->phy_info[i].attached.handle);
547f9a21 1759 }
0c33b27d 1760
547f9a21
EM
1761 mptsas_setup_wide_ports(ioc, port_info);
1762
1763 for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
0c33b27d 1764 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
e6b2d76a 1765 &port_info->phy_info[i], ioc->sas_index, 1);
0c33b27d
CH
1766
1767 return 0;
1768
1769 out_free_port_info:
547f9a21 1770 kfree(hba);
0c33b27d
CH
1771 out:
1772 return error;
1773}
1774
1775static int
e6b2d76a 1776mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle)
0c33b27d 1777{
e6b2d76a 1778 struct mptsas_portinfo *port_info, *p, *ex;
547f9a21
EM
1779 struct device *parent;
1780 struct sas_rphy *rphy;
0c33b27d
CH
1781 int error = -ENOMEM, i, j;
1782
e6b2d76a
ME
1783 ex = kzalloc(sizeof(*port_info), GFP_KERNEL);
1784 if (!ex)
0c33b27d 1785 goto out;
0c33b27d 1786
e6b2d76a 1787 error = mptsas_sas_expander_pg0(ioc, ex,
0c33b27d
CH
1788 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
1789 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
1790 if (error)
1791 goto out_free_port_info;
1792
e6b2d76a 1793 *handle = ex->handle;
0c33b27d 1794
9a28f49a 1795 mutex_lock(&ioc->sas_topology_mutex);
e6b2d76a
ME
1796 port_info = mptsas_find_portinfo_by_handle(ioc, *handle);
1797 if (!port_info) {
1798 port_info = ex;
1799 list_add_tail(&port_info->list, &ioc->sas_topology);
1800 } else {
1801 port_info->handle = ex->handle;
547f9a21 1802 kfree(ex->phy_info);
e6b2d76a
ME
1803 kfree(ex);
1804 ex = NULL;
1805 }
9a28f49a
CH
1806 mutex_unlock(&ioc->sas_topology_mutex);
1807
0c33b27d 1808 for (i = 0; i < port_info->num_phys; i++) {
0c33b27d
CH
1809 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
1810 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
1811 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle);
1812
1813 if (port_info->phy_info[i].identify.handle) {
1814 mptsas_sas_device_pg0(ioc,
1815 &port_info->phy_info[i].identify,
1816 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1817 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1818 port_info->phy_info[i].identify.handle);
024358ee
EM
1819 port_info->phy_info[i].identify.phy_id =
1820 port_info->phy_info[i].phy_id;
0c33b27d
CH
1821 }
1822
1823 if (port_info->phy_info[i].attached.handle) {
1824 mptsas_sas_device_pg0(ioc,
1825 &port_info->phy_info[i].attached,
1826 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1827 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1828 port_info->phy_info[i].attached.handle);
db9c9174
ME
1829 port_info->phy_info[i].attached.phy_id =
1830 port_info->phy_info[i].phy_id;
0c33b27d 1831 }
547f9a21 1832 }
0c33b27d 1833
547f9a21
EM
1834 parent = &ioc->sh->shost_gendev;
1835 for (i = 0; i < port_info->num_phys; i++) {
9a28f49a 1836 mutex_lock(&ioc->sas_topology_mutex);
0c33b27d
CH
1837 list_for_each_entry(p, &ioc->sas_topology, list) {
1838 for (j = 0; j < p->num_phys; j++) {
547f9a21 1839 if (port_info->phy_info[i].identify.handle !=
0c33b27d 1840 p->phy_info[j].attached.handle)
547f9a21
EM
1841 continue;
1842 rphy = mptsas_get_rphy(&p->phy_info[j]);
1843 parent = &rphy->dev;
0c33b27d
CH
1844 }
1845 }
9a28f49a 1846 mutex_unlock(&ioc->sas_topology_mutex);
547f9a21
EM
1847 }
1848
1849 mptsas_setup_wide_ports(ioc, port_info);
0c33b27d 1850
547f9a21 1851 for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
ac01bbbd 1852 mptsas_probe_one_phy(parent, &port_info->phy_info[i],
e6b2d76a 1853 ioc->sas_index, 0);
0c33b27d
CH
1854
1855 return 0;
1856
1857 out_free_port_info:
e6b2d76a 1858 if (ex) {
547f9a21 1859 kfree(ex->phy_info);
e6b2d76a
ME
1860 kfree(ex);
1861 }
0c33b27d
CH
1862 out:
1863 return error;
1864}
1865
e6b2d76a
ME
1866/*
1867 * mptsas_delete_expander_phys
1868 *
1869 *
1870 * This will traverse topology, and remove expanders
1871 * that are no longer present
1872 */
1873static void
1874mptsas_delete_expander_phys(MPT_ADAPTER *ioc)
1875{
1876 struct mptsas_portinfo buffer;
1877 struct mptsas_portinfo *port_info, *n, *parent;
547f9a21
EM
1878 struct mptsas_phyinfo *phy_info;
1879 struct scsi_target * starget;
1880 VirtTarget * vtarget;
1881 struct sas_port * port;
e6b2d76a 1882 int i;
547f9a21 1883 u64 expander_sas_address;
e6b2d76a
ME
1884
1885 mutex_lock(&ioc->sas_topology_mutex);
1886 list_for_each_entry_safe(port_info, n, &ioc->sas_topology, list) {
1887
1888 if (port_info->phy_info &&
1889 (!(port_info->phy_info[0].identify.device_info &
1890 MPI_SAS_DEVICE_INFO_SMP_TARGET)))
1891 continue;
1892
1893 if (mptsas_sas_expander_pg0(ioc, &buffer,
1894 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
1895 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), port_info->handle)) {
1896
547f9a21
EM
1897 /*
1898 * Issue target reset to all child end devices
1899 * then mark them deleted to prevent further
1900 * IO going to them.
1901 */
1902 phy_info = port_info->phy_info;
1903 for (i = 0; i < port_info->num_phys; i++, phy_info++) {
1904 starget = mptsas_get_starget(phy_info);
1905 if (!starget)
1906 continue;
1907 vtarget = starget->hostdata;
1908 if(vtarget->deleted)
1909 continue;
1910 vtarget->deleted = 1;
1911 mptsas_target_reset(ioc, vtarget);
1912 sas_port_delete(mptsas_get_port(phy_info));
1913 mptsas_port_delete(phy_info->port_details);
1914 }
1915
e6b2d76a
ME
1916 /*
1917 * Obtain the port_info instance to the parent port
1918 */
1919 parent = mptsas_find_portinfo_by_handle(ioc,
1920 port_info->phy_info[0].identify.handle_parent);
1921
1922 if (!parent)
1923 goto next_port;
1924
547f9a21
EM
1925 expander_sas_address =
1926 port_info->phy_info[0].identify.sas_address;
1927
e6b2d76a
ME
1928 /*
1929 * Delete rphys in the parent that point
1930 * to this expander. The transport layer will
1931 * cleanup all the children.
1932 */
547f9a21
EM
1933 phy_info = parent->phy_info;
1934 for (i = 0; i < parent->num_phys; i++, phy_info++) {
1935 port = mptsas_get_port(phy_info);
1936 if (!port)
1937 continue;
1938 if (phy_info->attached.sas_address !=
1939 expander_sas_address)
e6b2d76a 1940 continue;
547f9a21
EM
1941#ifdef MPT_DEBUG_SAS_WIDE
1942 dev_printk(KERN_DEBUG, &port->dev, "delete\n");
1943#endif
1944 sas_port_delete(port);
1945 mptsas_port_delete(phy_info->port_details);
e6b2d76a
ME
1946 }
1947 next_port:
547f9a21
EM
1948
1949 phy_info = port_info->phy_info;
1950 for (i = 0; i < port_info->num_phys; i++, phy_info++)
1951 mptsas_port_delete(phy_info->port_details);
1952
e6b2d76a 1953 list_del(&port_info->list);
547f9a21 1954 kfree(port_info->phy_info);
e6b2d76a
ME
1955 kfree(port_info);
1956 }
1957 /*
1958 * Free this memory allocated from inside
1959 * mptsas_sas_expander_pg0
1960 */
547f9a21 1961 kfree(buffer.phy_info);
e6b2d76a
ME
1962 }
1963 mutex_unlock(&ioc->sas_topology_mutex);
1964}
1965
1966/*
1967 * Start of day discovery
1968 */
0c33b27d
CH
1969static void
1970mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
1971{
1972 u32 handle = 0xFFFF;
f44e5461 1973 int i;
0c33b27d 1974
e6b2d76a
ME
1975 mutex_lock(&ioc->sas_discovery_mutex);
1976 mptsas_probe_hba_phys(ioc);
1977 while (!mptsas_probe_expander_phys(ioc, &handle))
0c33b27d 1978 ;
f44e5461
ME
1979 /*
1980 Reporting RAID volumes.
1981 */
1982 if (!ioc->raid_data.pIocPg2)
1983 goto out;
1984 if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
1985 goto out;
1986 for (i=0; i<ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
1987 scsi_add_device(ioc->sh, ioc->num_ports,
1988 ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
1989 }
1990 out:
e6b2d76a
ME
1991 mutex_unlock(&ioc->sas_discovery_mutex);
1992}
1993
1994/*
1995 * Work queue thread to handle Runtime discovery
1996 * Mere purpose is the hot add/delete of expanders
547f9a21 1997 *(Mutex UNLOCKED)
e6b2d76a
ME
1998 */
1999static void
547f9a21 2000__mptsas_discovery_work(MPT_ADAPTER *ioc)
e6b2d76a 2001{
e6b2d76a
ME
2002 u32 handle = 0xFFFF;
2003
e6b2d76a
ME
2004 ioc->sas_discovery_runtime=1;
2005 mptsas_delete_expander_phys(ioc);
2006 mptsas_probe_hba_phys(ioc);
2007 while (!mptsas_probe_expander_phys(ioc, &handle))
2008 ;
e6b2d76a 2009 ioc->sas_discovery_runtime=0;
547f9a21
EM
2010}
2011
2012/*
2013 * Work queue thread to handle Runtime discovery
2014 * Mere purpose is the hot add/delete of expanders
2015 *(Mutex LOCKED)
2016 */
2017static void
2018mptsas_discovery_work(void * arg)
2019{
2020 struct mptsas_discovery_event *ev = arg;
2021 MPT_ADAPTER *ioc = ev->ioc;
2022
2023 mutex_lock(&ioc->sas_discovery_mutex);
2024 __mptsas_discovery_work(ioc);
e6b2d76a 2025 mutex_unlock(&ioc->sas_discovery_mutex);
547f9a21 2026 kfree(ev);
0c33b27d
CH
2027}
2028
9a28f49a 2029static struct mptsas_phyinfo *
547f9a21 2030mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
9a28f49a
CH
2031{
2032 struct mptsas_portinfo *port_info;
9a28f49a 2033 struct mptsas_phyinfo *phy_info = NULL;
547f9a21 2034 int i;
9a28f49a 2035
9a28f49a
CH
2036 mutex_lock(&ioc->sas_topology_mutex);
2037 list_for_each_entry(port_info, &ioc->sas_topology, list) {
2038 for (i = 0; i < port_info->num_phys; i++) {
547f9a21
EM
2039 if (port_info->phy_info[i].attached.sas_address
2040 != sas_address)
2041 continue;
2042 if (!mptsas_is_end_device(
2043 &port_info->phy_info[i].attached))
2044 continue;
2045 phy_info = &port_info->phy_info[i];
2046 break;
9a28f49a
CH
2047 }
2048 }
2049 mutex_unlock(&ioc->sas_topology_mutex);
9a28f49a
CH
2050 return phy_info;
2051}
2052
2053static struct mptsas_phyinfo *
c73787ee 2054mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u32 id)
9a28f49a
CH
2055{
2056 struct mptsas_portinfo *port_info;
2057 struct mptsas_phyinfo *phy_info = NULL;
2058 int i;
2059
9a28f49a
CH
2060 mutex_lock(&ioc->sas_topology_mutex);
2061 list_for_each_entry(port_info, &ioc->sas_topology, list) {
547f9a21
EM
2062 for (i = 0; i < port_info->num_phys; i++) {
2063 if (port_info->phy_info[i].attached.id != id)
2064 continue;
2065 if (!mptsas_is_end_device(
2066 &port_info->phy_info[i].attached))
2067 continue;
2068 phy_info = &port_info->phy_info[i];
2069 break;
2070 }
9a28f49a
CH
2071 }
2072 mutex_unlock(&ioc->sas_topology_mutex);
9a28f49a
CH
2073 return phy_info;
2074}
2075
4b766471
ME
2076/*
2077 * Work queue thread to clear the persitency table
2078 */
2079static void
547f9a21 2080mptsas_persist_clear_table(void * arg)
4b766471
ME
2081{
2082 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
2083
2084 mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
2085}
2086
f44e5461
ME
2087static void
2088mptsas_reprobe_lun(struct scsi_device *sdev, void *data)
2089{
2090 sdev->no_uld_attach = data ? 1 : 0;
2091 scsi_device_reprobe(sdev);
2092}
2093
2094static void
2095mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)
2096{
2097 starget_for_each_device(starget, uld_attach ? (void *)1 : NULL,
2098 mptsas_reprobe_lun);
2099}
2100
e6b2d76a
ME
2101/*
2102 * Work queue thread to handle SAS hotplug events
2103 */
9a28f49a
CH
2104static void
2105mptsas_hotplug_work(void *arg)
2106{
2107 struct mptsas_hotplug_event *ev = arg;
2108 MPT_ADAPTER *ioc = ev->ioc;
2109 struct mptsas_phyinfo *phy_info;
2110 struct sas_rphy *rphy;
547f9a21 2111 struct sas_port *port;
c73787ee 2112 struct scsi_device *sdev;
547f9a21 2113 struct scsi_target * starget;
f013db32 2114 struct sas_identify identify;
9a28f49a 2115 char *ds = NULL;
c73787ee 2116 struct mptsas_devinfo sas_device;
f44e5461 2117 VirtTarget *vtarget;
547f9a21 2118 VirtDevice *vdevice;
9a28f49a 2119
e6b2d76a 2120
547f9a21 2121 mutex_lock(&ioc->sas_discovery_mutex);
9a28f49a
CH
2122 switch (ev->event_type) {
2123 case MPTSAS_DEL_DEVICE:
9a28f49a 2124
c73787ee 2125 phy_info = mptsas_find_phyinfo_by_target(ioc, ev->id);
e6b2d76a 2126
f44e5461
ME
2127 /*
2128 * Sanity checks, for non-existing phys and remote rphys.
2129 */
547f9a21
EM
2130 if (!phy_info || !phy_info->port_details) {
2131 dfailprintk((MYIOC_s_ERR_FMT
2132 "%s: exit at line=%d\n", ioc->name,
2133 __FUNCTION__, __LINE__));
9a28f49a 2134 break;
547f9a21
EM
2135 }
2136 rphy = mptsas_get_rphy(phy_info);
2137 if (!rphy) {
2138 dfailprintk((MYIOC_s_ERR_FMT
2139 "%s: exit at line=%d\n", ioc->name,
2140 __FUNCTION__, __LINE__));
2141 break;
2142 }
2143 port = mptsas_get_port(phy_info);
2144 if (!port) {
2145 dfailprintk((MYIOC_s_ERR_FMT
2146 "%s: exit at line=%d\n", ioc->name,
2147 __FUNCTION__, __LINE__));
f44e5461 2148 break;
547f9a21
EM
2149 }
2150
2151 starget = mptsas_get_starget(phy_info);
2152 if (starget) {
2153 vtarget = starget->hostdata;
f44e5461 2154
547f9a21
EM
2155 if (!vtarget) {
2156 dfailprintk((MYIOC_s_ERR_FMT
2157 "%s: exit at line=%d\n", ioc->name,
2158 __FUNCTION__, __LINE__));
f44e5461 2159 break;
547f9a21
EM
2160 }
2161
f44e5461
ME
2162 /*
2163 * Handling RAID components
2164 */
2165 if (ev->phys_disk_num_valid) {
2166 vtarget->target_id = ev->phys_disk_num;
2167 vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
547f9a21 2168 mptsas_reprobe_target(starget, 1);
f44e5461
ME
2169 break;
2170 }
547f9a21
EM
2171
2172 vtarget->deleted = 1;
2173 mptsas_target_reset(ioc, vtarget);
9a28f49a
CH
2174 }
2175
c73787ee
ME
2176 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET)
2177 ds = "ssp";
2178 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_STP_TARGET)
2179 ds = "stp";
2180 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
2181 ds = "sata";
2182
2183 printk(MYIOC_s_INFO_FMT
2184 "removing %s device, channel %d, id %d, phy %d\n",
2185 ioc->name, ds, ev->channel, ev->id, phy_info->phy_id);
2186
547f9a21
EM
2187#ifdef MPT_DEBUG_SAS_WIDE
2188 dev_printk(KERN_DEBUG, &port->dev, "delete\n");
2189#endif
2190 sas_port_delete(port);
2191 mptsas_port_delete(phy_info->port_details);
9a28f49a
CH
2192 break;
2193 case MPTSAS_ADD_DEVICE:
c73787ee 2194
bd23e94c
ME
2195 if (ev->phys_disk_num_valid)
2196 mpt_findImVolumes(ioc);
2197
c73787ee 2198 /*
e3094447 2199 * Refresh sas device pg0 data
c73787ee 2200 */
e3094447
CH
2201 if (mptsas_sas_device_pg0(ioc, &sas_device,
2202 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
547f9a21
EM
2203 MPI_SAS_DEVICE_PGAD_FORM_SHIFT), ev->id)) {
2204 dfailprintk((MYIOC_s_ERR_FMT
2205 "%s: exit at line=%d\n", ioc->name,
2206 __FUNCTION__, __LINE__));
e3094447 2207 break;
547f9a21 2208 }
9a28f49a 2209
547f9a21
EM
2210 ssleep(2);
2211 __mptsas_discovery_work(ioc);
e6b2d76a 2212
547f9a21
EM
2213 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
2214 sas_device.sas_address);
e6b2d76a 2215
547f9a21
EM
2216 if (!phy_info || !phy_info->port_details) {
2217 dfailprintk((MYIOC_s_ERR_FMT
2218 "%s: exit at line=%d\n", ioc->name,
2219 __FUNCTION__, __LINE__));
2220 break;
e6b2d76a
ME
2221 }
2222
547f9a21
EM
2223 starget = mptsas_get_starget(phy_info);
2224 if (starget) {
2225 vtarget = starget->hostdata;
9a28f49a 2226
547f9a21
EM
2227 if (!vtarget) {
2228 dfailprintk((MYIOC_s_ERR_FMT
2229 "%s: exit at line=%d\n", ioc->name,
2230 __FUNCTION__, __LINE__));
f44e5461 2231 break;
547f9a21 2232 }
f44e5461
ME
2233 /*
2234 * Handling RAID components
2235 */
2236 if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
2237 vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT;
2238 vtarget->target_id = ev->id;
547f9a21 2239 mptsas_reprobe_target(starget, 0);
f44e5461 2240 }
9a28f49a
CH
2241 break;
2242 }
2243
547f9a21
EM
2244 if (mptsas_get_rphy(phy_info)) {
2245 dfailprintk((MYIOC_s_ERR_FMT
2246 "%s: exit at line=%d\n", ioc->name,
2247 __FUNCTION__, __LINE__));
f44e5461 2248 break;
547f9a21
EM
2249 }
2250 port = mptsas_get_port(phy_info);
2251 if (!port) {
2252 dfailprintk((MYIOC_s_ERR_FMT
2253 "%s: exit at line=%d\n", ioc->name,
2254 __FUNCTION__, __LINE__));
2255 break;
2256 }
f44e5461 2257
e3094447
CH
2258 memcpy(&phy_info->attached, &sas_device,
2259 sizeof(struct mptsas_devinfo));
9a28f49a 2260
c73787ee
ME
2261 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET)
2262 ds = "ssp";
2263 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_STP_TARGET)
2264 ds = "stp";
2265 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
2266 ds = "sata";
2267
2268 printk(MYIOC_s_INFO_FMT
2269 "attaching %s device, channel %d, id %d, phy %d\n",
2270 ioc->name, ds, ev->channel, ev->id, ev->phy_id);
2271
f013db32 2272 mptsas_parse_device_info(&identify, &phy_info->attached);
547f9a21
EM
2273 rphy = sas_end_device_alloc(port);
2274 if (!rphy) {
2275 dfailprintk((MYIOC_s_ERR_FMT
2276 "%s: exit at line=%d\n", ioc->name,
2277 __FUNCTION__, __LINE__));
9a28f49a 2278 break; /* non-fatal: an rphy can be added later */
547f9a21 2279 }
9a28f49a 2280
f013db32 2281 rphy->identify = identify;
9a28f49a 2282 if (sas_rphy_add(rphy)) {
547f9a21
EM
2283 dfailprintk((MYIOC_s_ERR_FMT
2284 "%s: exit at line=%d\n", ioc->name,
2285 __FUNCTION__, __LINE__));
9a28f49a
CH
2286 sas_rphy_free(rphy);
2287 break;
2288 }
547f9a21 2289 mptsas_set_rphy(phy_info, rphy);
9a28f49a 2290 break;
c73787ee
ME
2291 case MPTSAS_ADD_RAID:
2292 sdev = scsi_device_lookup(
2293 ioc->sh,
2294 ioc->num_ports,
2295 ev->id,
2296 0);
2297 if (sdev) {
2298 scsi_device_put(sdev);
2299 break;
2300 }
2301 printk(MYIOC_s_INFO_FMT
4b766471 2302 "attaching raid volume, channel %d, id %d\n",
c73787ee
ME
2303 ioc->name, ioc->num_ports, ev->id);
2304 scsi_add_device(ioc->sh,
2305 ioc->num_ports,
2306 ev->id,
2307 0);
2308 mpt_findImVolumes(ioc);
2309 break;
2310 case MPTSAS_DEL_RAID:
2311 sdev = scsi_device_lookup(
2312 ioc->sh,
2313 ioc->num_ports,
2314 ev->id,
2315 0);
2316 if (!sdev)
2317 break;
2318 printk(MYIOC_s_INFO_FMT
4b766471 2319 "removing raid volume, channel %d, id %d\n",
c73787ee 2320 ioc->name, ioc->num_ports, ev->id);
547f9a21
EM
2321 vdevice = sdev->hostdata;
2322 vdevice->vtarget->deleted = 1;
2323 mptsas_target_reset(ioc, vdevice->vtarget);
c73787ee
ME
2324 scsi_remove_device(sdev);
2325 scsi_device_put(sdev);
2326 mpt_findImVolumes(ioc);
2327 break;
bd23e94c
ME
2328 case MPTSAS_IGNORE_EVENT:
2329 default:
2330 break;
9a28f49a
CH
2331 }
2332
e6b2d76a 2333 mutex_unlock(&ioc->sas_discovery_mutex);
547f9a21
EM
2334 kfree(ev);
2335
9a28f49a
CH
2336}
2337
2338static void
547f9a21 2339mptsas_send_sas_event(MPT_ADAPTER *ioc,
9a28f49a
CH
2340 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
2341{
2342 struct mptsas_hotplug_event *ev;
2343 u32 device_info = le32_to_cpu(sas_event_data->DeviceInfo);
2344 __le64 sas_address;
2345
2346 if ((device_info &
2347 (MPI_SAS_DEVICE_INFO_SSP_TARGET |
2348 MPI_SAS_DEVICE_INFO_STP_TARGET |
2349 MPI_SAS_DEVICE_INFO_SATA_DEVICE )) == 0)
2350 return;
2351
4b766471
ME
2352 switch (sas_event_data->ReasonCode) {
2353 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
2354 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
547f9a21 2355 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
4b766471
ME
2356 if (!ev) {
2357 printk(KERN_WARNING "mptsas: lost hotplug event\n");
2358 break;
2359 }
9a28f49a 2360
4b766471
ME
2361 INIT_WORK(&ev->work, mptsas_hotplug_work, ev);
2362 ev->ioc = ioc;
2363 ev->handle = le16_to_cpu(sas_event_data->DevHandle);
2364 ev->parent_handle =
2365 le16_to_cpu(sas_event_data->ParentDevHandle);
2366 ev->channel = sas_event_data->Bus;
2367 ev->id = sas_event_data->TargetID;
2368 ev->phy_id = sas_event_data->PhyNum;
2369 memcpy(&sas_address, &sas_event_data->SASAddress,
2370 sizeof(__le64));
2371 ev->sas_address = le64_to_cpu(sas_address);
2372 ev->device_info = device_info;
2373
2374 if (sas_event_data->ReasonCode &
2375 MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
2376 ev->event_type = MPTSAS_ADD_DEVICE;
2377 else
2378 ev->event_type = MPTSAS_DEL_DEVICE;
2379 schedule_work(&ev->work);
2380 break;
2381 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
2382 /*
2383 * Persistent table is full.
2384 */
547f9a21
EM
2385 INIT_WORK(&ioc->sas_persist_task,
2386 mptsas_persist_clear_table, (void *)ioc);
2387 schedule_work(&ioc->sas_persist_task);
4b766471
ME
2388 break;
2389 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
2390 /* TODO */
2391 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
2392 /* TODO */
2393 default:
2394 break;
9a28f49a 2395 }
9a28f49a
CH
2396}
2397
c73787ee 2398static void
547f9a21 2399mptsas_send_raid_event(MPT_ADAPTER *ioc,
c73787ee
ME
2400 EVENT_DATA_RAID *raid_event_data)
2401{
2402 struct mptsas_hotplug_event *ev;
bd23e94c
ME
2403 int status = le32_to_cpu(raid_event_data->SettingsStatus);
2404 int state = (status >> 8) & 0xff;
c73787ee
ME
2405
2406 if (ioc->bus_type != SAS)
2407 return;
2408
547f9a21 2409 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
c73787ee
ME
2410 if (!ev) {
2411 printk(KERN_WARNING "mptsas: lost hotplug event\n");
2412 return;
2413 }
2414
c73787ee
ME
2415 INIT_WORK(&ev->work, mptsas_hotplug_work, ev);
2416 ev->ioc = ioc;
2417 ev->id = raid_event_data->VolumeID;
bd23e94c 2418 ev->event_type = MPTSAS_IGNORE_EVENT;
c73787ee
ME
2419
2420 switch (raid_event_data->ReasonCode) {
2421 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
2422 ev->event_type = MPTSAS_ADD_DEVICE;
2423 break;
2424 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
f44e5461
ME
2425 ioc->raid_data.isRaid = 1;
2426 ev->phys_disk_num_valid = 1;
2427 ev->phys_disk_num = raid_event_data->PhysDiskNum;
c73787ee
ME
2428 ev->event_type = MPTSAS_DEL_DEVICE;
2429 break;
bd23e94c
ME
2430 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
2431 switch (state) {
2432 case MPI_PD_STATE_ONLINE:
2433 ioc->raid_data.isRaid = 1;
2434 ev->phys_disk_num_valid = 1;
2435 ev->phys_disk_num = raid_event_data->PhysDiskNum;
2436 ev->event_type = MPTSAS_ADD_DEVICE;
2437 break;
2438 case MPI_PD_STATE_MISSING:
2439 case MPI_PD_STATE_NOT_COMPATIBLE:
2440 case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST:
2441 case MPI_PD_STATE_FAILED_AT_HOST_REQUEST:
2442 case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON:
2443 ev->event_type = MPTSAS_DEL_DEVICE;
2444 break;
2445 default:
2446 break;
2447 }
2448 break;
c73787ee
ME
2449 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
2450 ev->event_type = MPTSAS_DEL_RAID;
2451 break;
2452 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
2453 ev->event_type = MPTSAS_ADD_RAID;
2454 break;
2455 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
bd23e94c
ME
2456 switch (state) {
2457 case MPI_RAIDVOL0_STATUS_STATE_FAILED:
2458 case MPI_RAIDVOL0_STATUS_STATE_MISSING:
2459 ev->event_type = MPTSAS_DEL_RAID;
2460 break;
2461 case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL:
2462 case MPI_RAIDVOL0_STATUS_STATE_DEGRADED:
2463 ev->event_type = MPTSAS_ADD_RAID;
2464 break;
2465 default:
2466 break;
2467 }
c73787ee
ME
2468 break;
2469 default:
2470 break;
2471 }
2472 schedule_work(&ev->work);
2473}
2474
e6b2d76a 2475static void
547f9a21 2476mptsas_send_discovery_event(MPT_ADAPTER *ioc,
e6b2d76a
ME
2477 EVENT_DATA_SAS_DISCOVERY *discovery_data)
2478{
2479 struct mptsas_discovery_event *ev;
2480
2481 /*
2482 * DiscoveryStatus
2483 *
2484 * This flag will be non-zero when firmware
2485 * kicks off discovery, and return to zero
2486 * once its completed.
2487 */
2488 if (discovery_data->DiscoveryStatus)
2489 return;
2490
547f9a21 2491 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
e6b2d76a
ME
2492 if (!ev)
2493 return;
547f9a21 2494 INIT_WORK(&ev->work, mptsas_discovery_work, ev);
e6b2d76a
ME
2495 ev->ioc = ioc;
2496 schedule_work(&ev->work);
2497};
2498
2499
9a28f49a
CH
2500static int
2501mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
2502{
c73787ee 2503 int rc=1;
9a28f49a
CH
2504 u8 event = le32_to_cpu(reply->Event) & 0xFF;
2505
2506 if (!ioc->sh)
c73787ee 2507 goto out;
9a28f49a 2508
e6b2d76a
ME
2509 /*
2510 * sas_discovery_ignore_events
2511 *
2512 * This flag is to prevent anymore processing of
2513 * sas events once mptsas_remove function is called.
2514 */
2515 if (ioc->sas_discovery_ignore_events) {
2516 rc = mptscsih_event_process(ioc, reply);
2517 goto out;
2518 }
2519
9a28f49a
CH
2520 switch (event) {
2521 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
547f9a21 2522 mptsas_send_sas_event(ioc,
9a28f49a 2523 (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data);
c73787ee
ME
2524 break;
2525 case MPI_EVENT_INTEGRATED_RAID:
547f9a21 2526 mptsas_send_raid_event(ioc,
c73787ee
ME
2527 (EVENT_DATA_RAID *)reply->Data);
2528 break;
79de278e 2529 case MPI_EVENT_PERSISTENT_TABLE_FULL:
547f9a21
EM
2530 INIT_WORK(&ioc->sas_persist_task,
2531 mptsas_persist_clear_table,
79de278e 2532 (void *)ioc);
547f9a21 2533 schedule_work(&ioc->sas_persist_task);
79de278e 2534 break;
4b766471 2535 case MPI_EVENT_SAS_DISCOVERY:
547f9a21 2536 mptsas_send_discovery_event(ioc,
e6b2d76a
ME
2537 (EVENT_DATA_SAS_DISCOVERY *)reply->Data);
2538 break;
9a28f49a 2539 default:
c73787ee
ME
2540 rc = mptscsih_event_process(ioc, reply);
2541 break;
9a28f49a 2542 }
c73787ee
ME
2543 out:
2544
2545 return rc;
9a28f49a
CH
2546}
2547
0c33b27d
CH
2548static int
2549mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
2550{
2551 struct Scsi_Host *sh;
2552 MPT_SCSI_HOST *hd;
2553 MPT_ADAPTER *ioc;
2554 unsigned long flags;
1ca00bb7 2555 int ii;
0c33b27d
CH
2556 int numSGE = 0;
2557 int scale;
2558 int ioc_cap;
0c33b27d
CH
2559 int error=0;
2560 int r;
2561
2562 r = mpt_attach(pdev,id);
2563 if (r)
2564 return r;
2565
2566 ioc = pci_get_drvdata(pdev);
2567 ioc->DoneCtx = mptsasDoneCtx;
2568 ioc->TaskCtx = mptsasTaskCtx;
2569 ioc->InternalCtx = mptsasInternalCtx;
2570
2571 /* Added sanity check on readiness of the MPT adapter.
2572 */
2573 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
2574 printk(MYIOC_s_WARN_FMT
2575 "Skipping because it's not operational!\n",
2576 ioc->name);
7acec1e7
MED
2577 error = -ENODEV;
2578 goto out_mptsas_probe;
0c33b27d
CH
2579 }
2580
2581 if (!ioc->active) {
2582 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
2583 ioc->name);
7acec1e7
MED
2584 error = -ENODEV;
2585 goto out_mptsas_probe;
0c33b27d
CH
2586 }
2587
2588 /* Sanity check - ensure at least 1 port is INITIATOR capable
2589 */
2590 ioc_cap = 0;
2591 for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
2592 if (ioc->pfacts[ii].ProtocolFlags &
2593 MPI_PORTFACTS_PROTOCOL_INITIATOR)
2594 ioc_cap++;
2595 }
2596
2597 if (!ioc_cap) {
2598 printk(MYIOC_s_WARN_FMT
2599 "Skipping ioc=%p because SCSI Initiator mode "
2600 "is NOT enabled!\n", ioc->name, ioc);
466544d8 2601 return 0;
0c33b27d
CH
2602 }
2603
2604 sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
2605 if (!sh) {
2606 printk(MYIOC_s_WARN_FMT
2607 "Unable to register controller with SCSI subsystem\n",
2608 ioc->name);
7acec1e7
MED
2609 error = -1;
2610 goto out_mptsas_probe;
0c33b27d
CH
2611 }
2612
2613 spin_lock_irqsave(&ioc->FreeQlock, flags);
2614
2615 /* Attach the SCSI Host to the IOC structure
2616 */
2617 ioc->sh = sh;
2618
2619 sh->io_port = 0;
2620 sh->n_io_port = 0;
2621 sh->irq = 0;
2622
2623 /* set 16 byte cdb's */
2624 sh->max_cmd_len = 16;
2625
2626 sh->max_id = ioc->pfacts->MaxDevices + 1;
2627
2628 sh->transportt = mptsas_transport_template;
2629
2630 sh->max_lun = MPT_LAST_LUN + 1;
2631 sh->max_channel = 0;
2632 sh->this_id = ioc->pfacts[0].PortSCSIID;
2633
2634 /* Required entry.
2635 */
2636 sh->unique_id = ioc->id;
2637
2638 INIT_LIST_HEAD(&ioc->sas_topology);
9a28f49a 2639 mutex_init(&ioc->sas_topology_mutex);
e6b2d76a 2640 mutex_init(&ioc->sas_discovery_mutex);
eeb846ce 2641 mutex_init(&ioc->sas_mgmt.mutex);
da4fa655 2642 init_completion(&ioc->sas_mgmt.done);
0c33b27d
CH
2643
2644 /* Verify that we won't exceed the maximum
2645 * number of chain buffers
2646 * We can optimize: ZZ = req_sz/sizeof(SGE)
2647 * For 32bit SGE's:
2648 * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
2649 * + (req_sz - 64)/sizeof(SGE)
2650 * A slightly different algorithm is required for
2651 * 64bit SGEs.
2652 */
2653 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
2654 if (sizeof(dma_addr_t) == sizeof(u64)) {
2655 numSGE = (scale - 1) *
2656 (ioc->facts.MaxChainDepth-1) + scale +
2657 (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
2658 sizeof(u32));
2659 } else {
2660 numSGE = 1 + (scale - 1) *
2661 (ioc->facts.MaxChainDepth-1) + scale +
2662 (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
2663 sizeof(u32));
2664 }
2665
2666 if (numSGE < sh->sg_tablesize) {
2667 /* Reset this value */
2668 dprintk((MYIOC_s_INFO_FMT
2669 "Resetting sg_tablesize to %d from %d\n",
2670 ioc->name, numSGE, sh->sg_tablesize));
2671 sh->sg_tablesize = numSGE;
2672 }
2673
2674 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2675
2676 hd = (MPT_SCSI_HOST *) sh->hostdata;
2677 hd->ioc = ioc;
2678
2679 /* SCSI needs scsi_cmnd lookup table!
2680 * (with size equal to req_depth*PtrSz!)
2681 */
1ca00bb7
CH
2682 hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
2683 if (!hd->ScsiLookup) {
0c33b27d 2684 error = -ENOMEM;
7acec1e7 2685 goto out_mptsas_probe;
0c33b27d
CH
2686 }
2687
1ca00bb7
CH
2688 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n",
2689 ioc->name, hd->ScsiLookup));
0c33b27d
CH
2690
2691 /* Allocate memory for the device structures.
2692 * A non-Null pointer at an offset
2693 * indicates a device exists.
2694 * max_id = 1 + maximum id (hosts.h)
2695 */
1ca00bb7
CH
2696 hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC);
2697 if (!hd->Targets) {
0c33b27d 2698 error = -ENOMEM;
7acec1e7 2699 goto out_mptsas_probe;
0c33b27d
CH
2700 }
2701
1ca00bb7 2702 dprintk((KERN_INFO " vtarget @ %p\n", hd->Targets));
0c33b27d
CH
2703
2704 /* Clear the TM flags
2705 */
2706 hd->tmPending = 0;
2707 hd->tmState = TM_STATE_NONE;
2708 hd->resetPending = 0;
2709 hd->abortSCpnt = NULL;
2710
2711 /* Clear the pointer used to store
2712 * single-threaded commands, i.e., those
2713 * issued during a bus scan, dv and
2714 * configuration pages.
2715 */
2716 hd->cmdPtr = NULL;
2717
2718 /* Initialize this SCSI Hosts' timers
2719 * To use, set the timer expires field
2720 * and add_timer
2721 */
2722 init_timer(&hd->timer);
2723 hd->timer.data = (unsigned long) hd;
2724 hd->timer.function = mptscsih_timer_expired;
2725
2726 hd->mpt_pq_filter = mpt_pq_filter;
2727 ioc->sas_data.ptClear = mpt_pt_clear;
2728
2729 if (ioc->sas_data.ptClear==1) {
2730 mptbase_sas_persist_operation(
2731 ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
2732 }
2733
2734 ddvprintk((MYIOC_s_INFO_FMT
2735 "mpt_pq_filter %x mpt_pq_filter %x\n",
2736 ioc->name,
2737 mpt_pq_filter,
2738 mpt_pq_filter));
2739
2740 init_waitqueue_head(&hd->scandv_waitq);
2741 hd->scandv_wait_done = 0;
2742 hd->last_queue_full = 0;
2743
2744 error = scsi_add_host(sh, &ioc->pcidev->dev);
2745 if (error) {
2746 dprintk((KERN_ERR MYNAM
2747 "scsi_add_host failed\n"));
7acec1e7 2748 goto out_mptsas_probe;
0c33b27d
CH
2749 }
2750
2751 mptsas_scan_sas_topology(ioc);
2752
2753 return 0;
2754
547f9a21 2755 out_mptsas_probe:
0c33b27d
CH
2756
2757 mptscsih_remove(pdev);
2758 return error;
2759}
2760
2761static void __devexit mptsas_remove(struct pci_dev *pdev)
2762{
2763 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2764 struct mptsas_portinfo *p, *n;
547f9a21 2765 int i;
0c33b27d 2766
e6b2d76a 2767 ioc->sas_discovery_ignore_events=1;
0c33b27d
CH
2768 sas_remove_host(ioc->sh);
2769
9a28f49a 2770 mutex_lock(&ioc->sas_topology_mutex);
0c33b27d
CH
2771 list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
2772 list_del(&p->list);
547f9a21
EM
2773 for (i = 0 ; i < p->num_phys ; i++)
2774 mptsas_port_delete(p->phy_info[i].port_details);
2775 kfree(p->phy_info);
0c33b27d
CH
2776 kfree(p);
2777 }
9a28f49a 2778 mutex_unlock(&ioc->sas_topology_mutex);
0c33b27d
CH
2779
2780 mptscsih_remove(pdev);
2781}
2782
2783static struct pci_device_id mptsas_pci_table[] = {
87cf8986 2784 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064,
0c33b27d 2785 PCI_ANY_ID, PCI_ANY_ID },
87cf8986 2786 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068,
0c33b27d 2787 PCI_ANY_ID, PCI_ANY_ID },
87cf8986 2788 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064E,
0c33b27d 2789 PCI_ANY_ID, PCI_ANY_ID },
87cf8986 2790 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068E,
0c33b27d 2791 PCI_ANY_ID, PCI_ANY_ID },
87cf8986 2792 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1078,
0c33b27d
CH
2793 PCI_ANY_ID, PCI_ANY_ID },
2794 {0} /* Terminating entry */
2795};
2796MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
2797
2798
2799static struct pci_driver mptsas_driver = {
2800 .name = "mptsas",
2801 .id_table = mptsas_pci_table,
2802 .probe = mptsas_probe,
2803 .remove = __devexit_p(mptsas_remove),
2804 .shutdown = mptscsih_shutdown,
2805#ifdef CONFIG_PM
2806 .suspend = mptscsih_suspend,
2807 .resume = mptscsih_resume,
2808#endif
2809};
2810
2811static int __init
2812mptsas_init(void)
2813{
2814 show_mptmod_ver(my_NAME, my_VERSION);
2815
2816 mptsas_transport_template =
2817 sas_attach_transport(&mptsas_transport_functions);
2818 if (!mptsas_transport_template)
2819 return -ENODEV;
2820
2821 mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
2822 mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER);
2823 mptsasInternalCtx =
2824 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
da4fa655 2825 mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
0c33b27d 2826
9a28f49a 2827 if (mpt_event_register(mptsasDoneCtx, mptsas_event_process) == 0) {
3a892bef 2828 devtverboseprintk((KERN_INFO MYNAM
0c33b27d
CH
2829 ": Registered for IOC event notifications\n"));
2830 }
2831
2832 if (mpt_reset_register(mptsasDoneCtx, mptscsih_ioc_reset) == 0) {
2833 dprintk((KERN_INFO MYNAM
2834 ": Registered for IOC reset notifications\n"));
2835 }
2836
2837 return pci_register_driver(&mptsas_driver);
2838}
2839
2840static void __exit
2841mptsas_exit(void)
2842{
2843 pci_unregister_driver(&mptsas_driver);
2844 sas_release_transport(mptsas_transport_template);
2845
2846 mpt_reset_deregister(mptsasDoneCtx);
2847 mpt_event_deregister(mptsasDoneCtx);
2848
da4fa655 2849 mpt_deregister(mptsasMgmtCtx);
0c33b27d
CH
2850 mpt_deregister(mptsasInternalCtx);
2851 mpt_deregister(mptsasTaskCtx);
2852 mpt_deregister(mptsasDoneCtx);
2853}
2854
2855module_init(mptsas_init);
2856module_exit(mptsas_exit);