[SCSI] fusion - exclosure misspelled
[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>
53
54#include <scsi/scsi_cmnd.h>
55#include <scsi/scsi_device.h>
56#include <scsi/scsi_host.h>
57#include <scsi/scsi_transport_sas.h>
58
59#include "mptbase.h"
60#include "mptscsih.h"
61
62
63#define my_NAME "Fusion MPT SAS Host driver"
64#define my_VERSION MPT_LINUX_VERSION_COMMON
65#define MYNAM "mptsas"
66
67MODULE_AUTHOR(MODULEAUTHOR);
68MODULE_DESCRIPTION(my_NAME);
69MODULE_LICENSE("GPL");
70
71static int mpt_pq_filter;
72module_param(mpt_pq_filter, int, 0);
73MODULE_PARM_DESC(mpt_pq_filter,
74 "Enable peripheral qualifier filter: enable=1 "
75 "(default=0)");
76
77static int mpt_pt_clear;
78module_param(mpt_pt_clear, int, 0);
79MODULE_PARM_DESC(mpt_pt_clear,
80 "Clear persistency table: enable=1 "
81 "(default=MPTSCSIH_PT_CLEAR=0)");
82
83static int mptsasDoneCtx = -1;
84static int mptsasTaskCtx = -1;
85static int mptsasInternalCtx = -1; /* Used only for internal commands */
da4fa655 86static int mptsasMgmtCtx = -1;
0c33b27d
CH
87
88
9a28f49a
CH
89enum mptsas_hotplug_action {
90 MPTSAS_ADD_DEVICE,
91 MPTSAS_DEL_DEVICE,
c73787ee
ME
92 MPTSAS_ADD_RAID,
93 MPTSAS_DEL_RAID,
9a28f49a
CH
94};
95
96struct mptsas_hotplug_event {
97 struct work_struct work;
98 MPT_ADAPTER *ioc;
99 enum mptsas_hotplug_action event_type;
100 u64 sas_address;
101 u32 channel;
102 u32 id;
103 u32 device_info;
104 u16 handle;
105 u16 parent_handle;
106 u8 phy_id;
107};
108
0c33b27d
CH
109/*
110 * SAS topology structures
111 *
112 * The MPT Fusion firmware interface spreads information about the
113 * SAS topology over many manufacture pages, thus we need some data
114 * structure to collect it and process it for the SAS transport class.
115 */
116
117struct mptsas_devinfo {
118 u16 handle; /* unique id to address this device */
c73787ee 119 u16 handle_parent; /* unique id to address parent device */
e3094447
CH
120 u16 handle_enclosure; /* enclosure identifier of the enclosure */
121 u16 slot; /* physical slot in enclosure */
0c33b27d
CH
122 u8 phy_id; /* phy number of parent device */
123 u8 port_id; /* sas physical port this device
124 is assoc'd with */
9a28f49a
CH
125 u8 id; /* logical target id of this device */
126 u8 channel; /* logical bus number of this device */
0c33b27d
CH
127 u64 sas_address; /* WWN of this device,
128 SATA is assigned by HBA,expander */
129 u32 device_info; /* bitfield detailed info about this device */
130};
131
132struct mptsas_phyinfo {
133 u8 phy_id; /* phy index */
134 u8 port_id; /* port number this phy is part of */
135 u8 negotiated_link_rate; /* nego'd link rate for this phy */
136 u8 hw_link_rate; /* hardware max/min phys link rate */
137 u8 programmed_link_rate; /* programmed max/min phy link rate */
138 struct mptsas_devinfo identify; /* point to phy device info */
139 struct mptsas_devinfo attached; /* point to attached device info */
9a28f49a 140 struct sas_phy *phy;
0c33b27d
CH
141 struct sas_rphy *rphy;
142};
143
144struct mptsas_portinfo {
145 struct list_head list;
146 u16 handle; /* unique id to address this */
147 u8 num_phys; /* number of phys */
148 struct mptsas_phyinfo *phy_info;
149};
150
e3094447
CH
151struct mptsas_enclosure {
152 u64 enclosure_logical_id; /* The WWN for the enclosure */
153 u16 enclosure_handle; /* unique id to address this */
154 u16 flags; /* details enclosure management */
155 u16 num_slot; /* num slots */
156 u16 start_slot; /* first slot */
157 u8 start_id; /* starting logical target id */
158 u8 start_channel; /* starting logical channel id */
159 u8 sep_id; /* SEP device logical target id */
160 u8 sep_channel; /* SEP channel logical channel id */
161};
162
b5141128
CH
163
164#ifdef SASDEBUG
165static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
166{
167 printk("---- IO UNIT PAGE 0 ------------\n");
168 printk("Handle=0x%X\n",
169 le16_to_cpu(phy_data->AttachedDeviceHandle));
170 printk("Controller Handle=0x%X\n",
171 le16_to_cpu(phy_data->ControllerDevHandle));
172 printk("Port=0x%X\n", phy_data->Port);
173 printk("Port Flags=0x%X\n", phy_data->PortFlags);
174 printk("PHY Flags=0x%X\n", phy_data->PhyFlags);
175 printk("Negotiated Link Rate=0x%X\n", phy_data->NegotiatedLinkRate);
176 printk("Controller PHY Device Info=0x%X\n",
177 le32_to_cpu(phy_data->ControllerPhyDeviceInfo));
178 printk("DiscoveryStatus=0x%X\n",
179 le32_to_cpu(phy_data->DiscoveryStatus));
180 printk("\n");
181}
182
183static void mptsas_print_phy_pg0(SasPhyPage0_t *pg0)
184{
185 __le64 sas_address;
186
187 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
188
189 printk("---- SAS PHY PAGE 0 ------------\n");
190 printk("Attached Device Handle=0x%X\n",
191 le16_to_cpu(pg0->AttachedDevHandle));
192 printk("SAS Address=0x%llX\n",
193 (unsigned long long)le64_to_cpu(sas_address));
194 printk("Attached PHY Identifier=0x%X\n", pg0->AttachedPhyIdentifier);
195 printk("Attached Device Info=0x%X\n",
196 le32_to_cpu(pg0->AttachedDeviceInfo));
197 printk("Programmed Link Rate=0x%X\n", pg0->ProgrammedLinkRate);
198 printk("Change Count=0x%X\n", pg0->ChangeCount);
199 printk("PHY Info=0x%X\n", le32_to_cpu(pg0->PhyInfo));
200 printk("\n");
201}
202
203static void mptsas_print_phy_pg1(SasPhyPage1_t *pg1)
204{
205 printk("---- SAS PHY PAGE 1 ------------\n");
f9a2d2e0
CH
206 printk("Invalid Dword Count=0x%x\n", pg1->InvalidDwordCount);
207 printk("Running Disparity Error Count=0x%x\n",
b5141128 208 pg1->RunningDisparityErrorCount);
f9a2d2e0
CH
209 printk("Loss Dword Synch Count=0x%x\n", pg1->LossDwordSynchCount);
210 printk("PHY Reset Problem Count=0x%x\n", pg1->PhyResetProblemCount);
211 printk("\n");
b5141128
CH
212}
213
214static void mptsas_print_device_pg0(SasDevicePage0_t *pg0)
215{
216 __le64 sas_address;
217
218 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
219
220 printk("---- SAS DEVICE PAGE 0 ---------\n");
221 printk("Handle=0x%X\n" ,le16_to_cpu(pg0->DevHandle));
e3094447 222 printk("Parent Handle=0x%X\n" ,le16_to_cpu(pg0->ParentDevHandle));
b5141128
CH
223 printk("Enclosure Handle=0x%X\n", le16_to_cpu(pg0->EnclosureHandle));
224 printk("Slot=0x%X\n", le16_to_cpu(pg0->Slot));
225 printk("SAS Address=0x%llX\n", le64_to_cpu(sas_address));
226 printk("Target ID=0x%X\n", pg0->TargetID);
227 printk("Bus=0x%X\n", pg0->Bus);
f9a2d2e0
CH
228 /* The PhyNum field specifies the PHY number of the parent
229 * device this device is linked to
230 */
231 printk("Parent Phy Num=0x%X\n", pg0->PhyNum);
232 printk("Access Status=0x%X\n", le16_to_cpu(pg0->AccessStatus));
b5141128
CH
233 printk("Device Info=0x%X\n", le32_to_cpu(pg0->DeviceInfo));
234 printk("Flags=0x%X\n", le16_to_cpu(pg0->Flags));
235 printk("Physical Port=0x%X\n", pg0->PhysicalPort);
236 printk("\n");
237}
238
239static void mptsas_print_expander_pg1(SasExpanderPage1_t *pg1)
240{
241 printk("---- SAS EXPANDER PAGE 1 ------------\n");
242
243 printk("Physical Port=0x%X\n", pg1->PhysicalPort);
f9a2d2e0 244 printk("PHY Identifier=0x%X\n", pg1->PhyIdentifier);
b5141128
CH
245 printk("Negotiated Link Rate=0x%X\n", pg1->NegotiatedLinkRate);
246 printk("Programmed Link Rate=0x%X\n", pg1->ProgrammedLinkRate);
247 printk("Hardware Link Rate=0x%X\n", pg1->HwLinkRate);
248 printk("Owner Device Handle=0x%X\n",
249 le16_to_cpu(pg1->OwnerDevHandle));
250 printk("Attached Device Handle=0x%X\n",
251 le16_to_cpu(pg1->AttachedDevHandle));
252}
253#else
254#define mptsas_print_phy_data(phy_data) do { } while (0)
255#define mptsas_print_phy_pg0(pg0) do { } while (0)
256#define mptsas_print_phy_pg1(pg1) do { } while (0)
257#define mptsas_print_device_pg0(pg0) do { } while (0)
258#define mptsas_print_expander_pg1(pg1) do { } while (0)
259#endif
260
e3094447
CH
261static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
262{
263 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
264 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
265}
266
267static inline MPT_ADAPTER *rphy_to_ioc(struct sas_rphy *rphy)
268{
269 struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
270 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
271}
272
273static int
52435430 274mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
e3094447
CH
275 u32 form, u32 form_specific)
276{
277 ConfigExtendedPageHeader_t hdr;
278 CONFIGPARMS cfg;
279 SasEnclosurePage0_t *buffer;
280 dma_addr_t dma_handle;
281 int error;
282 __le64 le_identifier;
283
284 memset(&hdr, 0, sizeof(hdr));
285 hdr.PageVersion = MPI_SASENCLOSURE0_PAGEVERSION;
286 hdr.PageNumber = 0;
287 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
288 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_ENCLOSURE;
289
290 cfg.cfghdr.ehdr = &hdr;
291 cfg.physAddr = -1;
292 cfg.pageAddr = form + form_specific;
293 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
294 cfg.dir = 0; /* read */
295 cfg.timeout = 10;
296
297 error = mpt_config(ioc, &cfg);
298 if (error)
299 goto out;
300 if (!hdr.ExtPageLength) {
301 error = -ENXIO;
302 goto out;
303 }
304
305 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
306 &dma_handle);
307 if (!buffer) {
308 error = -ENOMEM;
309 goto out;
310 }
311
312 cfg.physAddr = dma_handle;
313 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
314
315 error = mpt_config(ioc, &cfg);
316 if (error)
317 goto out_free_consistent;
318
319 /* save config data */
320 memcpy(&le_identifier, &buffer->EnclosureLogicalID, sizeof(__le64));
321 enclosure->enclosure_logical_id = le64_to_cpu(le_identifier);
322 enclosure->enclosure_handle = le16_to_cpu(buffer->EnclosureHandle);
323 enclosure->flags = le16_to_cpu(buffer->Flags);
324 enclosure->num_slot = le16_to_cpu(buffer->NumSlots);
325 enclosure->start_slot = le16_to_cpu(buffer->StartSlot);
326 enclosure->start_id = buffer->StartTargetID;
327 enclosure->start_channel = buffer->StartBus;
328 enclosure->sep_id = buffer->SEPTargetID;
329 enclosure->sep_channel = buffer->SEPBus;
330
331 out_free_consistent:
332 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
333 buffer, dma_handle);
334 out:
335 return error;
336}
b5141128 337
0c33b27d
CH
338/*
339 * This is pretty ugly. We will be able to seriously clean it up
340 * once the DV code in mptscsih goes away and we can properly
341 * implement ->target_alloc.
342 */
343static int
c7c82987 344mptsas_slave_alloc(struct scsi_device *sdev)
0c33b27d 345{
c7c82987 346 struct Scsi_Host *host = sdev->host;
0c33b27d
CH
347 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
348 struct sas_rphy *rphy;
349 struct mptsas_portinfo *p;
c7c82987 350 VirtTarget *vtarget;
0c33b27d 351 VirtDevice *vdev;
c7c82987 352 struct scsi_target *starget;
914c2d8e 353 u32 target_id;
0c33b27d
CH
354 int i;
355
1ca00bb7 356 vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
0c33b27d
CH
357 if (!vdev) {
358 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
359 hd->ioc->name, sizeof(VirtDevice));
360 return -ENOMEM;
361 }
c7c82987
MED
362 sdev->hostdata = vdev;
363 starget = scsi_target(sdev);
364 vtarget = starget->hostdata;
914c2d8e 365 vtarget->ioc_id = hd->ioc->id;
c7c82987
MED
366 vdev->vtarget = vtarget;
367 if (vtarget->num_luns == 0) {
368 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY;
369 hd->Targets[sdev->id] = vtarget;
370 }
0c33b27d 371
816aa907
ME
372 /*
373 RAID volumes placed beyond the last expected port.
374 */
375 if (sdev->channel == hd->ioc->num_ports) {
914c2d8e
ME
376 target_id = sdev->id;
377 vtarget->bus_id = 0;
816aa907
ME
378 vdev->lun = 0;
379 goto out;
380 }
381
c7c82987 382 rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
9a28f49a 383 mutex_lock(&hd->ioc->sas_topology_mutex);
0c33b27d
CH
384 list_for_each_entry(p, &hd->ioc->sas_topology, list) {
385 for (i = 0; i < p->num_phys; i++) {
386 if (p->phy_info[i].attached.sas_address ==
387 rphy->identify.sas_address) {
914c2d8e
ME
388 target_id = p->phy_info[i].attached.id;
389 vtarget->bus_id = p->phy_info[i].attached.channel;
c7c82987 390 vdev->lun = sdev->lun;
914c2d8e 391 mutex_unlock(&hd->ioc->sas_topology_mutex);
0c33b27d
CH
392 goto out;
393 }
394 }
395 }
9a28f49a 396 mutex_unlock(&hd->ioc->sas_topology_mutex);
0c33b27d 397
0c33b27d 398 kfree(vdev);
23f236ed 399 return -ENXIO;
0c33b27d
CH
400
401 out:
914c2d8e 402 vtarget->target_id = target_id;
c7c82987 403 vtarget->num_luns++;
0c33b27d
CH
404 return 0;
405}
406
9a28f49a
CH
407static void
408mptsas_slave_destroy(struct scsi_device *sdev)
409{
410 struct Scsi_Host *host = sdev->host;
411 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
412 struct sas_rphy *rphy;
413 struct mptsas_portinfo *p;
414 int i;
7d3eecf7 415 VirtDevice *vdev;
9a28f49a
CH
416
417 /*
418 * Handle hotplug removal case.
419 * We need to clear out attached data structure.
420 */
421 rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
422
423 mutex_lock(&hd->ioc->sas_topology_mutex);
424 list_for_each_entry(p, &hd->ioc->sas_topology, list) {
425 for (i = 0; i < p->num_phys; i++) {
426 if (p->phy_info[i].attached.sas_address ==
427 rphy->identify.sas_address) {
428 memset(&p->phy_info[i].attached, 0,
429 sizeof(struct mptsas_devinfo));
430 p->phy_info[i].rphy = NULL;
431 goto out;
432 }
433 }
434 }
435
436 out:
437 mutex_unlock(&hd->ioc->sas_topology_mutex);
438 /*
7d3eecf7 439 * Issue target reset to flush firmware outstanding commands.
9a28f49a 440 */
7d3eecf7
ME
441 vdev = sdev->hostdata;
442 if (vdev->configured_lun){
443 if (mptscsih_TMHandler(hd,
444 MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
914c2d8e
ME
445 vdev->vtarget->bus_id,
446 vdev->vtarget->target_id,
7d3eecf7
ME
447 0, 0, 5 /* 5 second timeout */)
448 < 0){
449
450 /* The TM request failed!
451 * Fatal error case.
452 */
453 printk(MYIOC_s_WARN_FMT
454 "Error processing TaskMgmt id=%d TARGET_RESET\n",
455 hd->ioc->name,
914c2d8e 456 vdev->vtarget->target_id);
7d3eecf7
ME
457
458 hd->tmPending = 0;
459 hd->tmState = TM_STATE_NONE;
460 }
461 }
9a28f49a
CH
462 mptscsih_slave_destroy(sdev);
463}
464
0c33b27d 465static struct scsi_host_template mptsas_driver_template = {
f78496da 466 .module = THIS_MODULE,
0c33b27d
CH
467 .proc_name = "mptsas",
468 .proc_info = mptscsih_proc_info,
469 .name = "MPT SPI Host",
470 .info = mptscsih_info,
471 .queuecommand = mptscsih_qcmd,
c7c82987 472 .target_alloc = mptscsih_target_alloc,
0c33b27d
CH
473 .slave_alloc = mptsas_slave_alloc,
474 .slave_configure = mptscsih_slave_configure,
c7c82987 475 .target_destroy = mptscsih_target_destroy,
9a28f49a 476 .slave_destroy = mptsas_slave_destroy,
0c33b27d
CH
477 .change_queue_depth = mptscsih_change_queue_depth,
478 .eh_abort_handler = mptscsih_abort,
479 .eh_device_reset_handler = mptscsih_dev_reset,
480 .eh_bus_reset_handler = mptscsih_bus_reset,
481 .eh_host_reset_handler = mptscsih_host_reset,
482 .bios_param = mptscsih_bios_param,
483 .can_queue = MPT_FC_CAN_QUEUE,
484 .this_id = -1,
485 .sg_tablesize = MPT_SCSI_SG_DEPTH,
486 .max_sectors = 8192,
487 .cmd_per_lun = 7,
488 .use_clustering = ENABLE_CLUSTERING,
489};
490
b5141128 491static int mptsas_get_linkerrors(struct sas_phy *phy)
0c33b27d 492{
b5141128
CH
493 MPT_ADAPTER *ioc = phy_to_ioc(phy);
494 ConfigExtendedPageHeader_t hdr;
495 CONFIGPARMS cfg;
496 SasPhyPage1_t *buffer;
497 dma_addr_t dma_handle;
498 int error;
0c33b27d 499
b5141128
CH
500 hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
501 hdr.ExtPageLength = 0;
502 hdr.PageNumber = 1 /* page number 1*/;
503 hdr.Reserved1 = 0;
504 hdr.Reserved2 = 0;
505 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
506 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
0c33b27d 507
b5141128
CH
508 cfg.cfghdr.ehdr = &hdr;
509 cfg.physAddr = -1;
510 cfg.pageAddr = phy->identify.phy_identifier;
511 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
512 cfg.dir = 0; /* read */
513 cfg.timeout = 10;
0c33b27d 514
b5141128
CH
515 error = mpt_config(ioc, &cfg);
516 if (error)
517 return error;
518 if (!hdr.ExtPageLength)
519 return -ENXIO;
0c33b27d 520
b5141128
CH
521 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
522 &dma_handle);
523 if (!buffer)
524 return -ENOMEM;
0c33b27d 525
b5141128
CH
526 cfg.physAddr = dma_handle;
527 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
528
529 error = mpt_config(ioc, &cfg);
530 if (error)
531 goto out_free_consistent;
532
533 mptsas_print_phy_pg1(buffer);
534
535 phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
536 phy->running_disparity_error_count =
537 le32_to_cpu(buffer->RunningDisparityErrorCount);
538 phy->loss_of_dword_sync_count =
539 le32_to_cpu(buffer->LossDwordSynchCount);
540 phy->phy_reset_problem_count =
541 le32_to_cpu(buffer->PhyResetProblemCount);
542
543 out_free_consistent:
544 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
545 buffer, dma_handle);
546 return error;
0c33b27d
CH
547}
548
da4fa655
CH
549static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
550 MPT_FRAME_HDR *reply)
551{
552 ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_COMMAND_GOOD;
553 if (reply != NULL) {
554 ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_RF_VALID;
555 memcpy(ioc->sas_mgmt.reply, reply,
556 min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
557 }
558 complete(&ioc->sas_mgmt.done);
559 return 1;
560}
561
562static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
563{
564 MPT_ADAPTER *ioc = phy_to_ioc(phy);
565 SasIoUnitControlRequest_t *req;
566 SasIoUnitControlReply_t *reply;
567 MPT_FRAME_HDR *mf;
568 MPIHeader_t *hdr;
569 unsigned long timeleft;
570 int error = -ERESTARTSYS;
571
572 /* not implemented for expanders */
573 if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
574 return -ENXIO;
575
eeb846ce 576 if (mutex_lock_interruptible(&ioc->sas_mgmt.mutex))
da4fa655
CH
577 goto out;
578
579 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
580 if (!mf) {
581 error = -ENOMEM;
582 goto out_unlock;
583 }
584
585 hdr = (MPIHeader_t *) mf;
586 req = (SasIoUnitControlRequest_t *)mf;
587 memset(req, 0, sizeof(SasIoUnitControlRequest_t));
588 req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
589 req->MsgContext = hdr->MsgContext;
590 req->Operation = hard_reset ?
591 MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
592 req->PhyNum = phy->identify.phy_identifier;
593
594 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
595
596 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
597 10 * HZ);
598 if (!timeleft) {
599 /* On timeout reset the board */
600 mpt_free_msg_frame(ioc, mf);
601 mpt_HardResetHandler(ioc, CAN_SLEEP);
602 error = -ETIMEDOUT;
603 goto out_unlock;
604 }
605
606 /* a reply frame is expected */
607 if ((ioc->sas_mgmt.status &
608 MPT_IOCTL_STATUS_RF_VALID) == 0) {
609 error = -ENXIO;
610 goto out_unlock;
611 }
612
613 /* process the completed Reply Message Frame */
614 reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
615 if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
616 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
617 __FUNCTION__,
618 reply->IOCStatus,
619 reply->IOCLogInfo);
620 error = -ENXIO;
621 goto out_unlock;
622 }
623
624 error = 0;
625
626 out_unlock:
eeb846ce 627 mutex_unlock(&ioc->sas_mgmt.mutex);
da4fa655
CH
628 out:
629 return error;
630}
0c33b27d 631
e3094447
CH
632static int
633mptsas_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
634{
635 MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
636 int i, error;
637 struct mptsas_portinfo *p;
638 struct mptsas_enclosure enclosure_info;
639 u64 enclosure_handle;
640
641 mutex_lock(&ioc->sas_topology_mutex);
642 list_for_each_entry(p, &ioc->sas_topology, list) {
643 for (i = 0; i < p->num_phys; i++) {
644 if (p->phy_info[i].attached.sas_address ==
645 rphy->identify.sas_address) {
646 enclosure_handle = p->phy_info[i].
647 attached.handle_enclosure;
648 goto found_info;
649 }
650 }
651 }
652 mutex_unlock(&ioc->sas_topology_mutex);
653 return -ENXIO;
654
655 found_info:
656 mutex_unlock(&ioc->sas_topology_mutex);
657 memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
52435430 658 error = mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
e3094447
CH
659 (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
660 MPI_SAS_ENCLOS_PGAD_FORM_SHIFT), enclosure_handle);
661 if (!error)
662 *identifier = enclosure_info.enclosure_logical_id;
663 return error;
664}
665
666static int
667mptsas_get_bay_identifier(struct sas_rphy *rphy)
668{
669 MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
670 struct mptsas_portinfo *p;
671 int i, rc;
672
673 mutex_lock(&ioc->sas_topology_mutex);
674 list_for_each_entry(p, &ioc->sas_topology, list) {
675 for (i = 0; i < p->num_phys; i++) {
676 if (p->phy_info[i].attached.sas_address ==
677 rphy->identify.sas_address) {
678 rc = p->phy_info[i].attached.slot;
679 goto out;
680 }
681 }
682 }
683 rc = -ENXIO;
684 out:
685 mutex_unlock(&ioc->sas_topology_mutex);
686 return rc;
687}
688
b5141128
CH
689static struct sas_function_template mptsas_transport_functions = {
690 .get_linkerrors = mptsas_get_linkerrors,
e3094447
CH
691 .get_enclosure_identifier = mptsas_get_enclosure_identifier,
692 .get_bay_identifier = mptsas_get_bay_identifier,
da4fa655 693 .phy_reset = mptsas_phy_reset,
b5141128
CH
694};
695
696static struct scsi_transport_template *mptsas_transport_template;
0c33b27d
CH
697
698static int
699mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
700{
701 ConfigExtendedPageHeader_t hdr;
702 CONFIGPARMS cfg;
703 SasIOUnitPage0_t *buffer;
704 dma_addr_t dma_handle;
705 int error, i;
706
707 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
708 hdr.ExtPageLength = 0;
709 hdr.PageNumber = 0;
710 hdr.Reserved1 = 0;
711 hdr.Reserved2 = 0;
712 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
713 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
714
715 cfg.cfghdr.ehdr = &hdr;
716 cfg.physAddr = -1;
717 cfg.pageAddr = 0;
718 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
719 cfg.dir = 0; /* read */
720 cfg.timeout = 10;
721
722 error = mpt_config(ioc, &cfg);
723 if (error)
724 goto out;
725 if (!hdr.ExtPageLength) {
726 error = -ENXIO;
727 goto out;
728 }
729
730 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
731 &dma_handle);
732 if (!buffer) {
733 error = -ENOMEM;
734 goto out;
735 }
736
737 cfg.physAddr = dma_handle;
738 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
739
740 error = mpt_config(ioc, &cfg);
741 if (error)
742 goto out_free_consistent;
743
744 port_info->num_phys = buffer->NumPhys;
745 port_info->phy_info = kcalloc(port_info->num_phys,
746 sizeof(struct mptsas_phyinfo),GFP_KERNEL);
747 if (!port_info->phy_info) {
748 error = -ENOMEM;
749 goto out_free_consistent;
750 }
751
752 for (i = 0; i < port_info->num_phys; i++) {
753 mptsas_print_phy_data(&buffer->PhyData[i]);
754 port_info->phy_info[i].phy_id = i;
755 port_info->phy_info[i].port_id =
756 buffer->PhyData[i].Port;
757 port_info->phy_info[i].negotiated_link_rate =
758 buffer->PhyData[i].NegotiatedLinkRate;
759 }
760
761 out_free_consistent:
762 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
763 buffer, dma_handle);
764 out:
765 return error;
766}
767
768static int
769mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
770 u32 form, u32 form_specific)
771{
772 ConfigExtendedPageHeader_t hdr;
773 CONFIGPARMS cfg;
774 SasPhyPage0_t *buffer;
775 dma_addr_t dma_handle;
776 int error;
777
778 hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
779 hdr.ExtPageLength = 0;
780 hdr.PageNumber = 0;
781 hdr.Reserved1 = 0;
782 hdr.Reserved2 = 0;
783 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
784 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
785
786 cfg.cfghdr.ehdr = &hdr;
787 cfg.dir = 0; /* read */
788 cfg.timeout = 10;
789
790 /* Get Phy Pg 0 for each Phy. */
791 cfg.physAddr = -1;
792 cfg.pageAddr = form + form_specific;
793 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
794
795 error = mpt_config(ioc, &cfg);
796 if (error)
797 goto out;
798
799 if (!hdr.ExtPageLength) {
800 error = -ENXIO;
801 goto out;
802 }
803
804 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
805 &dma_handle);
806 if (!buffer) {
807 error = -ENOMEM;
808 goto out;
809 }
810
811 cfg.physAddr = dma_handle;
812 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
813
814 error = mpt_config(ioc, &cfg);
815 if (error)
816 goto out_free_consistent;
817
818 mptsas_print_phy_pg0(buffer);
819
820 phy_info->hw_link_rate = buffer->HwLinkRate;
821 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
822 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
823 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
824
825 out_free_consistent:
826 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
827 buffer, dma_handle);
828 out:
829 return error;
830}
831
832static int
833mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
834 u32 form, u32 form_specific)
835{
836 ConfigExtendedPageHeader_t hdr;
837 CONFIGPARMS cfg;
838 SasDevicePage0_t *buffer;
839 dma_addr_t dma_handle;
840 __le64 sas_address;
841 int error;
842
843 hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
844 hdr.ExtPageLength = 0;
845 hdr.PageNumber = 0;
846 hdr.Reserved1 = 0;
847 hdr.Reserved2 = 0;
848 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
849 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
850
851 cfg.cfghdr.ehdr = &hdr;
852 cfg.pageAddr = form + form_specific;
853 cfg.physAddr = -1;
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 mptsas_print_device_pg0(buffer);
881
882 device_info->handle = le16_to_cpu(buffer->DevHandle);
c73787ee 883 device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle);
e3094447
CH
884 device_info->handle_enclosure =
885 le16_to_cpu(buffer->EnclosureHandle);
886 device_info->slot = le16_to_cpu(buffer->Slot);
0c33b27d
CH
887 device_info->phy_id = buffer->PhyNum;
888 device_info->port_id = buffer->PhysicalPort;
9a28f49a
CH
889 device_info->id = buffer->TargetID;
890 device_info->channel = buffer->Bus;
0c33b27d
CH
891 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
892 device_info->sas_address = le64_to_cpu(sas_address);
893 device_info->device_info =
894 le32_to_cpu(buffer->DeviceInfo);
895
896 out_free_consistent:
897 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
898 buffer, dma_handle);
899 out:
900 return error;
901}
902
903static int
904mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
905 u32 form, u32 form_specific)
906{
907 ConfigExtendedPageHeader_t hdr;
908 CONFIGPARMS cfg;
909 SasExpanderPage0_t *buffer;
910 dma_addr_t dma_handle;
911 int error;
912
913 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
914 hdr.ExtPageLength = 0;
915 hdr.PageNumber = 0;
916 hdr.Reserved1 = 0;
917 hdr.Reserved2 = 0;
918 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
919 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
920
921 cfg.cfghdr.ehdr = &hdr;
922 cfg.physAddr = -1;
923 cfg.pageAddr = form + form_specific;
924 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
925 cfg.dir = 0; /* read */
926 cfg.timeout = 10;
927
928 error = mpt_config(ioc, &cfg);
929 if (error)
930 goto out;
931
932 if (!hdr.ExtPageLength) {
933 error = -ENXIO;
934 goto out;
935 }
936
937 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
938 &dma_handle);
939 if (!buffer) {
940 error = -ENOMEM;
941 goto out;
942 }
943
944 cfg.physAddr = dma_handle;
945 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
946
947 error = mpt_config(ioc, &cfg);
948 if (error)
949 goto out_free_consistent;
950
951 /* save config data */
952 port_info->num_phys = buffer->NumPhys;
953 port_info->handle = le16_to_cpu(buffer->DevHandle);
954 port_info->phy_info = kcalloc(port_info->num_phys,
955 sizeof(struct mptsas_phyinfo),GFP_KERNEL);
956 if (!port_info->phy_info) {
957 error = -ENOMEM;
958 goto out_free_consistent;
959 }
960
961 out_free_consistent:
962 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
963 buffer, dma_handle);
964 out:
965 return error;
966}
967
968static int
969mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
970 u32 form, u32 form_specific)
971{
972 ConfigExtendedPageHeader_t hdr;
973 CONFIGPARMS cfg;
974 SasExpanderPage1_t *buffer;
975 dma_addr_t dma_handle;
976 int error;
977
978 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
979 hdr.ExtPageLength = 0;
980 hdr.PageNumber = 1;
981 hdr.Reserved1 = 0;
982 hdr.Reserved2 = 0;
983 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
984 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
985
986 cfg.cfghdr.ehdr = &hdr;
987 cfg.physAddr = -1;
988 cfg.pageAddr = form + form_specific;
989 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
990 cfg.dir = 0; /* read */
991 cfg.timeout = 10;
992
993 error = mpt_config(ioc, &cfg);
994 if (error)
995 goto out;
996
997 if (!hdr.ExtPageLength) {
998 error = -ENXIO;
999 goto out;
1000 }
1001
1002 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1003 &dma_handle);
1004 if (!buffer) {
1005 error = -ENOMEM;
1006 goto out;
1007 }
1008
1009 cfg.physAddr = dma_handle;
1010 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1011
1012 error = mpt_config(ioc, &cfg);
1013 if (error)
1014 goto out_free_consistent;
1015
1016
1017 mptsas_print_expander_pg1(buffer);
1018
1019 /* save config data */
024358ee 1020 phy_info->phy_id = buffer->PhyIdentifier;
0c33b27d
CH
1021 phy_info->port_id = buffer->PhysicalPort;
1022 phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
1023 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
1024 phy_info->hw_link_rate = buffer->HwLinkRate;
1025 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
1026 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
1027
1028
1029 out_free_consistent:
1030 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1031 buffer, dma_handle);
1032 out:
1033 return error;
1034}
1035
c73787ee
ME
1036/*
1037 * Returns true if there is a scsi end device
1038 */
1039static inline int
1040mptsas_is_end_device(struct mptsas_devinfo * attached)
1041{
1042 if ((attached->handle) &&
1043 (attached->device_info &
1044 MPI_SAS_DEVICE_INFO_END_DEVICE) &&
1045 ((attached->device_info &
1046 MPI_SAS_DEVICE_INFO_SSP_TARGET) |
1047 (attached->device_info &
1048 MPI_SAS_DEVICE_INFO_STP_TARGET) |
1049 (attached->device_info &
1050 MPI_SAS_DEVICE_INFO_SATA_DEVICE)))
1051 return 1;
1052 else
1053 return 0;
1054}
1055
0c33b27d
CH
1056static void
1057mptsas_parse_device_info(struct sas_identify *identify,
1058 struct mptsas_devinfo *device_info)
1059{
1060 u16 protocols;
1061
1062 identify->sas_address = device_info->sas_address;
1063 identify->phy_identifier = device_info->phy_id;
1064
1065 /*
1066 * Fill in Phy Initiator Port Protocol.
1067 * Bits 6:3, more than one bit can be set, fall through cases.
1068 */
1069 protocols = device_info->device_info & 0x78;
1070 identify->initiator_port_protocols = 0;
1071 if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
1072 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
1073 if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
1074 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
1075 if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
1076 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
1077 if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
1078 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
1079
1080 /*
1081 * Fill in Phy Target Port Protocol.
1082 * Bits 10:7, more than one bit can be set, fall through cases.
1083 */
1084 protocols = device_info->device_info & 0x780;
1085 identify->target_port_protocols = 0;
1086 if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
1087 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
1088 if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
1089 identify->target_port_protocols |= SAS_PROTOCOL_STP;
1090 if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
1091 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
1092 if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1093 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
1094
1095 /*
1096 * Fill in Attached device type.
1097 */
1098 switch (device_info->device_info &
1099 MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
1100 case MPI_SAS_DEVICE_INFO_NO_DEVICE:
1101 identify->device_type = SAS_PHY_UNUSED;
1102 break;
1103 case MPI_SAS_DEVICE_INFO_END_DEVICE:
1104 identify->device_type = SAS_END_DEVICE;
1105 break;
1106 case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
1107 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
1108 break;
1109 case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
1110 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
1111 break;
1112 }
1113}
1114
1115static int mptsas_probe_one_phy(struct device *dev,
ac01bbbd 1116 struct mptsas_phyinfo *phy_info, int index, int local)
0c33b27d 1117{
9a28f49a 1118 struct sas_phy *phy;
0c33b27d
CH
1119 int error;
1120
9a28f49a
CH
1121 phy = sas_phy_alloc(dev, index);
1122 if (!phy)
0c33b27d
CH
1123 return -ENOMEM;
1124
9a28f49a
CH
1125 phy->port_identifier = phy_info->port_id;
1126 mptsas_parse_device_info(&phy->identify, &phy_info->identify);
0c33b27d
CH
1127
1128 /*
1129 * Set Negotiated link rate.
1130 */
1131 switch (phy_info->negotiated_link_rate) {
1132 case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
9a28f49a 1133 phy->negotiated_linkrate = SAS_PHY_DISABLED;
0c33b27d
CH
1134 break;
1135 case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
9a28f49a 1136 phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;
0c33b27d
CH
1137 break;
1138 case MPI_SAS_IOUNIT0_RATE_1_5:
9a28f49a 1139 phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
0c33b27d
CH
1140 break;
1141 case MPI_SAS_IOUNIT0_RATE_3_0:
9a28f49a 1142 phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
0c33b27d
CH
1143 break;
1144 case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
1145 case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
1146 default:
9a28f49a 1147 phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
0c33b27d
CH
1148 break;
1149 }
1150
1151 /*
1152 * Set Max hardware link rate.
1153 */
1154 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
1155 case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
9a28f49a 1156 phy->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
0c33b27d
CH
1157 break;
1158 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
9a28f49a 1159 phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
0c33b27d
CH
1160 break;
1161 default:
1162 break;
1163 }
1164
1165 /*
1166 * Set Max programmed link rate.
1167 */
1168 switch (phy_info->programmed_link_rate &
1169 MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
1170 case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
9a28f49a 1171 phy->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
0c33b27d
CH
1172 break;
1173 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
9a28f49a 1174 phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
0c33b27d
CH
1175 break;
1176 default:
1177 break;
1178 }
1179
1180 /*
1181 * Set Min hardware link rate.
1182 */
1183 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
1184 case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
9a28f49a 1185 phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
0c33b27d
CH
1186 break;
1187 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
9a28f49a 1188 phy->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
0c33b27d
CH
1189 break;
1190 default:
1191 break;
1192 }
1193
1194 /*
1195 * Set Min programmed link rate.
1196 */
1197 switch (phy_info->programmed_link_rate &
1198 MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
1199 case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
9a28f49a 1200 phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
0c33b27d
CH
1201 break;
1202 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
9a28f49a 1203 phy->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
0c33b27d
CH
1204 break;
1205 default:
1206 break;
1207 }
1208
ac01bbbd 1209 if (local)
9a28f49a 1210 phy->local_attached = 1;
ac01bbbd 1211
9a28f49a 1212 error = sas_phy_add(phy);
0c33b27d 1213 if (error) {
9a28f49a 1214 sas_phy_free(phy);
0c33b27d
CH
1215 return error;
1216 }
9a28f49a 1217 phy_info->phy = phy;
0c33b27d
CH
1218
1219 if (phy_info->attached.handle) {
1220 struct sas_rphy *rphy;
1221
9a28f49a 1222 rphy = sas_rphy_alloc(phy);
0c33b27d
CH
1223 if (!rphy)
1224 return 0; /* non-fatal: an rphy can be added later */
1225
1226 mptsas_parse_device_info(&rphy->identify, &phy_info->attached);
1227 error = sas_rphy_add(rphy);
1228 if (error) {
1229 sas_rphy_free(rphy);
1230 return error;
1231 }
1232
1233 phy_info->rphy = rphy;
1234 }
1235
1236 return 0;
1237}
1238
1239static int
1240mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index)
1241{
1242 struct mptsas_portinfo *port_info;
1243 u32 handle = 0xFFFF;
1244 int error = -ENOMEM, i;
1245
1ca00bb7 1246 port_info = kzalloc(sizeof(*port_info), GFP_KERNEL);
0c33b27d
CH
1247 if (!port_info)
1248 goto out;
0c33b27d
CH
1249
1250 error = mptsas_sas_io_unit_pg0(ioc, port_info);
1251 if (error)
1252 goto out_free_port_info;
1253
816aa907 1254 ioc->num_ports = port_info->num_phys;
9a28f49a 1255 mutex_lock(&ioc->sas_topology_mutex);
0c33b27d 1256 list_add_tail(&port_info->list, &ioc->sas_topology);
9a28f49a
CH
1257 mutex_unlock(&ioc->sas_topology_mutex);
1258
0c33b27d
CH
1259 for (i = 0; i < port_info->num_phys; i++) {
1260 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
1261 (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
1262 MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
1263
1264 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
1265 (MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE <<
1266 MPI_SAS_DEVICE_PGAD_FORM_SHIFT), handle);
024358ee
EM
1267 port_info->phy_info[i].identify.phy_id =
1268 port_info->phy_info[i].phy_id;
0c33b27d
CH
1269 handle = port_info->phy_info[i].identify.handle;
1270
1271 if (port_info->phy_info[i].attached.handle) {
1272 mptsas_sas_device_pg0(ioc,
1273 &port_info->phy_info[i].attached,
1274 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1275 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1276 port_info->phy_info[i].attached.handle);
1277 }
1278
1279 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
ac01bbbd 1280 &port_info->phy_info[i], *index, 1);
0c33b27d
CH
1281 (*index)++;
1282 }
1283
1284 return 0;
1285
1286 out_free_port_info:
1287 kfree(port_info);
1288 out:
1289 return error;
1290}
1291
1292static int
1293mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
1294{
1295 struct mptsas_portinfo *port_info, *p;
1296 int error = -ENOMEM, i, j;
1297
1ca00bb7 1298 port_info = kzalloc(sizeof(*port_info), GFP_KERNEL);
0c33b27d
CH
1299 if (!port_info)
1300 goto out;
0c33b27d
CH
1301
1302 error = mptsas_sas_expander_pg0(ioc, port_info,
1303 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
1304 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
1305 if (error)
1306 goto out_free_port_info;
1307
1308 *handle = port_info->handle;
1309
9a28f49a 1310 mutex_lock(&ioc->sas_topology_mutex);
0c33b27d 1311 list_add_tail(&port_info->list, &ioc->sas_topology);
9a28f49a
CH
1312 mutex_unlock(&ioc->sas_topology_mutex);
1313
0c33b27d
CH
1314 for (i = 0; i < port_info->num_phys; i++) {
1315 struct device *parent;
1316
1317 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
1318 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
1319 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle);
1320
1321 if (port_info->phy_info[i].identify.handle) {
1322 mptsas_sas_device_pg0(ioc,
1323 &port_info->phy_info[i].identify,
1324 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1325 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1326 port_info->phy_info[i].identify.handle);
024358ee
EM
1327 port_info->phy_info[i].identify.phy_id =
1328 port_info->phy_info[i].phy_id;
0c33b27d
CH
1329 }
1330
1331 if (port_info->phy_info[i].attached.handle) {
1332 mptsas_sas_device_pg0(ioc,
1333 &port_info->phy_info[i].attached,
1334 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1335 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1336 port_info->phy_info[i].attached.handle);
1337 }
1338
1339 /*
1340 * If we find a parent port handle this expander is
1341 * attached to another expander, else it hangs of the
1342 * HBA phys.
1343 */
1344 parent = &ioc->sh->shost_gendev;
9a28f49a 1345 mutex_lock(&ioc->sas_topology_mutex);
0c33b27d
CH
1346 list_for_each_entry(p, &ioc->sas_topology, list) {
1347 for (j = 0; j < p->num_phys; j++) {
1348 if (port_info->phy_info[i].identify.handle ==
1349 p->phy_info[j].attached.handle)
1350 parent = &p->phy_info[j].rphy->dev;
1351 }
1352 }
9a28f49a 1353 mutex_unlock(&ioc->sas_topology_mutex);
0c33b27d 1354
ac01bbbd
CH
1355 mptsas_probe_one_phy(parent, &port_info->phy_info[i],
1356 *index, 0);
0c33b27d
CH
1357 (*index)++;
1358 }
1359
1360 return 0;
1361
1362 out_free_port_info:
1363 kfree(port_info);
1364 out:
1365 return error;
1366}
1367
1368static void
1369mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
1370{
1371 u32 handle = 0xFFFF;
1372 int index = 0;
1373
1374 mptsas_probe_hba_phys(ioc, &index);
1375 while (!mptsas_probe_expander_phys(ioc, &handle, &index))
1376 ;
1377}
1378
9a28f49a
CH
1379static struct mptsas_phyinfo *
1380mptsas_find_phyinfo_by_parent(MPT_ADAPTER *ioc, u16 parent_handle, u8 phy_id)
1381{
1382 struct mptsas_portinfo *port_info;
1383 struct mptsas_devinfo device_info;
1384 struct mptsas_phyinfo *phy_info = NULL;
1385 int i, error;
1386
1387 /*
1388 * Retrieve the parent sas_address
1389 */
1390 error = mptsas_sas_device_pg0(ioc, &device_info,
1391 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1392 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1393 parent_handle);
1394 if (error) {
1395 printk("mptsas: failed to retrieve device page\n");
1396 return NULL;
1397 }
1398
1399 /*
1400 * The phy_info structures are never deallocated during lifetime of
1401 * a host, so the code below is safe without additional refcounting.
1402 */
1403 mutex_lock(&ioc->sas_topology_mutex);
1404 list_for_each_entry(port_info, &ioc->sas_topology, list) {
1405 for (i = 0; i < port_info->num_phys; i++) {
1406 if (port_info->phy_info[i].identify.sas_address ==
1407 device_info.sas_address &&
1408 port_info->phy_info[i].phy_id == phy_id) {
1409 phy_info = &port_info->phy_info[i];
1410 break;
1411 }
1412 }
1413 }
1414 mutex_unlock(&ioc->sas_topology_mutex);
1415
1416 return phy_info;
1417}
1418
1419static struct mptsas_phyinfo *
c73787ee 1420mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u32 id)
9a28f49a
CH
1421{
1422 struct mptsas_portinfo *port_info;
1423 struct mptsas_phyinfo *phy_info = NULL;
1424 int i;
1425
1426 /*
1427 * The phy_info structures are never deallocated during lifetime of
1428 * a host, so the code below is safe without additional refcounting.
1429 */
1430 mutex_lock(&ioc->sas_topology_mutex);
1431 list_for_each_entry(port_info, &ioc->sas_topology, list) {
c73787ee
ME
1432 for (i = 0; i < port_info->num_phys; i++)
1433 if (mptsas_is_end_device(&port_info->phy_info[i].attached))
1434 if (port_info->phy_info[i].attached.id == id) {
1435 phy_info = &port_info->phy_info[i];
1436 break;
1437 }
9a28f49a
CH
1438 }
1439 mutex_unlock(&ioc->sas_topology_mutex);
1440
1441 return phy_info;
1442}
1443
4b766471
ME
1444/*
1445 * Work queue thread to clear the persitency table
1446 */
1447static void
1448mptscsih_sas_persist_clear_table(void * arg)
1449{
1450 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
1451
1452 mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
1453}
1454
9a28f49a
CH
1455static void
1456mptsas_hotplug_work(void *arg)
1457{
1458 struct mptsas_hotplug_event *ev = arg;
1459 MPT_ADAPTER *ioc = ev->ioc;
1460 struct mptsas_phyinfo *phy_info;
1461 struct sas_rphy *rphy;
c73787ee 1462 struct scsi_device *sdev;
9a28f49a 1463 char *ds = NULL;
c73787ee 1464 struct mptsas_devinfo sas_device;
9a28f49a
CH
1465
1466 switch (ev->event_type) {
1467 case MPTSAS_DEL_DEVICE:
9a28f49a 1468
c73787ee 1469 phy_info = mptsas_find_phyinfo_by_target(ioc, ev->id);
9a28f49a
CH
1470 if (!phy_info) {
1471 printk("mptsas: remove event for non-existant PHY.\n");
1472 break;
1473 }
1474
c73787ee
ME
1475 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET)
1476 ds = "ssp";
1477 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_STP_TARGET)
1478 ds = "stp";
1479 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1480 ds = "sata";
1481
1482 printk(MYIOC_s_INFO_FMT
1483 "removing %s device, channel %d, id %d, phy %d\n",
1484 ioc->name, ds, ev->channel, ev->id, phy_info->phy_id);
1485
9a28f49a
CH
1486 if (phy_info->rphy) {
1487 sas_rphy_delete(phy_info->rphy);
1488 phy_info->rphy = NULL;
1489 }
1490 break;
1491 case MPTSAS_ADD_DEVICE:
c73787ee
ME
1492
1493 /*
e3094447 1494 * Refresh sas device pg0 data
c73787ee 1495 */
e3094447
CH
1496 if (mptsas_sas_device_pg0(ioc, &sas_device,
1497 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
1498 MPI_SAS_DEVICE_PGAD_FORM_SHIFT), ev->id))
1499 break;
9a28f49a
CH
1500
1501 phy_info = mptsas_find_phyinfo_by_parent(ioc,
e3094447 1502 sas_device.handle_parent, sas_device.phy_id);
9a28f49a
CH
1503 if (!phy_info) {
1504 printk("mptsas: add event for non-existant PHY.\n");
1505 break;
1506 }
1507
1508 if (phy_info->rphy) {
1509 printk("mptsas: trying to add existing device.\n");
1510 break;
1511 }
1512
e3094447
CH
1513 memcpy(&phy_info->attached, &sas_device,
1514 sizeof(struct mptsas_devinfo));
9a28f49a 1515
c73787ee
ME
1516 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET)
1517 ds = "ssp";
1518 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_STP_TARGET)
1519 ds = "stp";
1520 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1521 ds = "sata";
1522
1523 printk(MYIOC_s_INFO_FMT
1524 "attaching %s device, channel %d, id %d, phy %d\n",
1525 ioc->name, ds, ev->channel, ev->id, ev->phy_id);
1526
1527
9a28f49a
CH
1528 rphy = sas_rphy_alloc(phy_info->phy);
1529 if (!rphy)
1530 break; /* non-fatal: an rphy can be added later */
1531
1532 mptsas_parse_device_info(&rphy->identify, &phy_info->attached);
1533 if (sas_rphy_add(rphy)) {
1534 sas_rphy_free(rphy);
1535 break;
1536 }
1537
1538 phy_info->rphy = rphy;
1539 break;
c73787ee
ME
1540 case MPTSAS_ADD_RAID:
1541 sdev = scsi_device_lookup(
1542 ioc->sh,
1543 ioc->num_ports,
1544 ev->id,
1545 0);
1546 if (sdev) {
1547 scsi_device_put(sdev);
1548 break;
1549 }
1550 printk(MYIOC_s_INFO_FMT
4b766471 1551 "attaching raid volume, channel %d, id %d\n",
c73787ee
ME
1552 ioc->name, ioc->num_ports, ev->id);
1553 scsi_add_device(ioc->sh,
1554 ioc->num_ports,
1555 ev->id,
1556 0);
1557 mpt_findImVolumes(ioc);
1558 break;
1559 case MPTSAS_DEL_RAID:
1560 sdev = scsi_device_lookup(
1561 ioc->sh,
1562 ioc->num_ports,
1563 ev->id,
1564 0);
1565 if (!sdev)
1566 break;
1567 printk(MYIOC_s_INFO_FMT
4b766471 1568 "removing raid volume, channel %d, id %d\n",
c73787ee
ME
1569 ioc->name, ioc->num_ports, ev->id);
1570 scsi_remove_device(sdev);
1571 scsi_device_put(sdev);
1572 mpt_findImVolumes(ioc);
1573 break;
9a28f49a
CH
1574 }
1575
1576 kfree(ev);
1577}
1578
1579static void
1580mptscsih_send_sas_event(MPT_ADAPTER *ioc,
1581 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
1582{
1583 struct mptsas_hotplug_event *ev;
1584 u32 device_info = le32_to_cpu(sas_event_data->DeviceInfo);
1585 __le64 sas_address;
1586
1587 if ((device_info &
1588 (MPI_SAS_DEVICE_INFO_SSP_TARGET |
1589 MPI_SAS_DEVICE_INFO_STP_TARGET |
1590 MPI_SAS_DEVICE_INFO_SATA_DEVICE )) == 0)
1591 return;
1592
4b766471
ME
1593 switch (sas_event_data->ReasonCode) {
1594 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
1595 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
1596 ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
1597 if (!ev) {
1598 printk(KERN_WARNING "mptsas: lost hotplug event\n");
1599 break;
1600 }
9a28f49a 1601
4b766471
ME
1602 INIT_WORK(&ev->work, mptsas_hotplug_work, ev);
1603 ev->ioc = ioc;
1604 ev->handle = le16_to_cpu(sas_event_data->DevHandle);
1605 ev->parent_handle =
1606 le16_to_cpu(sas_event_data->ParentDevHandle);
1607 ev->channel = sas_event_data->Bus;
1608 ev->id = sas_event_data->TargetID;
1609 ev->phy_id = sas_event_data->PhyNum;
1610 memcpy(&sas_address, &sas_event_data->SASAddress,
1611 sizeof(__le64));
1612 ev->sas_address = le64_to_cpu(sas_address);
1613 ev->device_info = device_info;
1614
1615 if (sas_event_data->ReasonCode &
1616 MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
1617 ev->event_type = MPTSAS_ADD_DEVICE;
1618 else
1619 ev->event_type = MPTSAS_DEL_DEVICE;
1620 schedule_work(&ev->work);
1621 break;
1622 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
1623 /*
1624 * Persistent table is full.
1625 */
1626 INIT_WORK(&ioc->mptscsih_persistTask,
1627 mptscsih_sas_persist_clear_table,
1628 (void *)ioc);
1629 schedule_work(&ioc->mptscsih_persistTask);
1630 break;
1631 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
1632 /* TODO */
1633 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
1634 /* TODO */
1635 default:
1636 break;
9a28f49a 1637 }
9a28f49a
CH
1638}
1639
c73787ee
ME
1640static void
1641mptscsih_send_raid_event(MPT_ADAPTER *ioc,
1642 EVENT_DATA_RAID *raid_event_data)
1643{
1644 struct mptsas_hotplug_event *ev;
1645 RAID_VOL0_STATUS * volumeStatus;
1646
1647 if (ioc->bus_type != SAS)
1648 return;
1649
1650 ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
1651 if (!ev) {
1652 printk(KERN_WARNING "mptsas: lost hotplug event\n");
1653 return;
1654 }
1655
1656 memset(ev,0,sizeof(struct mptsas_hotplug_event));
1657 INIT_WORK(&ev->work, mptsas_hotplug_work, ev);
1658 ev->ioc = ioc;
1659 ev->id = raid_event_data->VolumeID;
1660
1661 switch (raid_event_data->ReasonCode) {
1662 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
1663 ev->event_type = MPTSAS_ADD_DEVICE;
1664 break;
1665 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
1666 ev->event_type = MPTSAS_DEL_DEVICE;
1667 break;
1668 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
1669 ev->event_type = MPTSAS_DEL_RAID;
1670 break;
1671 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
1672 ev->event_type = MPTSAS_ADD_RAID;
1673 break;
1674 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
1675 volumeStatus = (RAID_VOL0_STATUS *) &
1676 raid_event_data->SettingsStatus;
1677 ev->event_type = (volumeStatus->State ==
1678 MPI_RAIDVOL0_STATUS_STATE_FAILED) ?
1679 MPTSAS_DEL_RAID : MPTSAS_ADD_RAID;
1680 break;
1681 default:
1682 break;
1683 }
1684 schedule_work(&ev->work);
1685}
1686
9a28f49a
CH
1687static int
1688mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
1689{
c73787ee 1690 int rc=1;
9a28f49a
CH
1691 u8 event = le32_to_cpu(reply->Event) & 0xFF;
1692
1693 if (!ioc->sh)
c73787ee 1694 goto out;
9a28f49a
CH
1695
1696 switch (event) {
1697 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
1698 mptscsih_send_sas_event(ioc,
1699 (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data);
c73787ee
ME
1700 break;
1701 case MPI_EVENT_INTEGRATED_RAID:
1702 mptscsih_send_raid_event(ioc,
1703 (EVENT_DATA_RAID *)reply->Data);
1704 break;
79de278e
ME
1705 case MPI_EVENT_PERSISTENT_TABLE_FULL:
1706 INIT_WORK(&ioc->mptscsih_persistTask,
1707 mptscsih_sas_persist_clear_table,
1708 (void *)ioc);
1709 schedule_work(&ioc->mptscsih_persistTask);
1710 break;
4b766471 1711 case MPI_EVENT_SAS_DISCOVERY:
9a28f49a 1712 default:
c73787ee
ME
1713 rc = mptscsih_event_process(ioc, reply);
1714 break;
9a28f49a 1715 }
c73787ee
ME
1716 out:
1717
1718 return rc;
9a28f49a
CH
1719}
1720
0c33b27d
CH
1721static int
1722mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1723{
1724 struct Scsi_Host *sh;
1725 MPT_SCSI_HOST *hd;
1726 MPT_ADAPTER *ioc;
1727 unsigned long flags;
1ca00bb7 1728 int ii;
0c33b27d
CH
1729 int numSGE = 0;
1730 int scale;
1731 int ioc_cap;
0c33b27d
CH
1732 int error=0;
1733 int r;
1734
1735 r = mpt_attach(pdev,id);
1736 if (r)
1737 return r;
1738
1739 ioc = pci_get_drvdata(pdev);
1740 ioc->DoneCtx = mptsasDoneCtx;
1741 ioc->TaskCtx = mptsasTaskCtx;
1742 ioc->InternalCtx = mptsasInternalCtx;
1743
1744 /* Added sanity check on readiness of the MPT adapter.
1745 */
1746 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
1747 printk(MYIOC_s_WARN_FMT
1748 "Skipping because it's not operational!\n",
1749 ioc->name);
7acec1e7
MED
1750 error = -ENODEV;
1751 goto out_mptsas_probe;
0c33b27d
CH
1752 }
1753
1754 if (!ioc->active) {
1755 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
1756 ioc->name);
7acec1e7
MED
1757 error = -ENODEV;
1758 goto out_mptsas_probe;
0c33b27d
CH
1759 }
1760
1761 /* Sanity check - ensure at least 1 port is INITIATOR capable
1762 */
1763 ioc_cap = 0;
1764 for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
1765 if (ioc->pfacts[ii].ProtocolFlags &
1766 MPI_PORTFACTS_PROTOCOL_INITIATOR)
1767 ioc_cap++;
1768 }
1769
1770 if (!ioc_cap) {
1771 printk(MYIOC_s_WARN_FMT
1772 "Skipping ioc=%p because SCSI Initiator mode "
1773 "is NOT enabled!\n", ioc->name, ioc);
466544d8 1774 return 0;
0c33b27d
CH
1775 }
1776
1777 sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
1778 if (!sh) {
1779 printk(MYIOC_s_WARN_FMT
1780 "Unable to register controller with SCSI subsystem\n",
1781 ioc->name);
7acec1e7
MED
1782 error = -1;
1783 goto out_mptsas_probe;
0c33b27d
CH
1784 }
1785
1786 spin_lock_irqsave(&ioc->FreeQlock, flags);
1787
1788 /* Attach the SCSI Host to the IOC structure
1789 */
1790 ioc->sh = sh;
1791
1792 sh->io_port = 0;
1793 sh->n_io_port = 0;
1794 sh->irq = 0;
1795
1796 /* set 16 byte cdb's */
1797 sh->max_cmd_len = 16;
1798
1799 sh->max_id = ioc->pfacts->MaxDevices + 1;
1800
1801 sh->transportt = mptsas_transport_template;
1802
1803 sh->max_lun = MPT_LAST_LUN + 1;
1804 sh->max_channel = 0;
1805 sh->this_id = ioc->pfacts[0].PortSCSIID;
1806
1807 /* Required entry.
1808 */
1809 sh->unique_id = ioc->id;
1810
1811 INIT_LIST_HEAD(&ioc->sas_topology);
9a28f49a
CH
1812 mutex_init(&ioc->sas_topology_mutex);
1813
eeb846ce 1814 mutex_init(&ioc->sas_mgmt.mutex);
da4fa655 1815 init_completion(&ioc->sas_mgmt.done);
0c33b27d
CH
1816
1817 /* Verify that we won't exceed the maximum
1818 * number of chain buffers
1819 * We can optimize: ZZ = req_sz/sizeof(SGE)
1820 * For 32bit SGE's:
1821 * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
1822 * + (req_sz - 64)/sizeof(SGE)
1823 * A slightly different algorithm is required for
1824 * 64bit SGEs.
1825 */
1826 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
1827 if (sizeof(dma_addr_t) == sizeof(u64)) {
1828 numSGE = (scale - 1) *
1829 (ioc->facts.MaxChainDepth-1) + scale +
1830 (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
1831 sizeof(u32));
1832 } else {
1833 numSGE = 1 + (scale - 1) *
1834 (ioc->facts.MaxChainDepth-1) + scale +
1835 (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
1836 sizeof(u32));
1837 }
1838
1839 if (numSGE < sh->sg_tablesize) {
1840 /* Reset this value */
1841 dprintk((MYIOC_s_INFO_FMT
1842 "Resetting sg_tablesize to %d from %d\n",
1843 ioc->name, numSGE, sh->sg_tablesize));
1844 sh->sg_tablesize = numSGE;
1845 }
1846
1847 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1848
1849 hd = (MPT_SCSI_HOST *) sh->hostdata;
1850 hd->ioc = ioc;
1851
1852 /* SCSI needs scsi_cmnd lookup table!
1853 * (with size equal to req_depth*PtrSz!)
1854 */
1ca00bb7
CH
1855 hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
1856 if (!hd->ScsiLookup) {
0c33b27d 1857 error = -ENOMEM;
7acec1e7 1858 goto out_mptsas_probe;
0c33b27d
CH
1859 }
1860
1ca00bb7
CH
1861 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n",
1862 ioc->name, hd->ScsiLookup));
0c33b27d
CH
1863
1864 /* Allocate memory for the device structures.
1865 * A non-Null pointer at an offset
1866 * indicates a device exists.
1867 * max_id = 1 + maximum id (hosts.h)
1868 */
1ca00bb7
CH
1869 hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC);
1870 if (!hd->Targets) {
0c33b27d 1871 error = -ENOMEM;
7acec1e7 1872 goto out_mptsas_probe;
0c33b27d
CH
1873 }
1874
1ca00bb7 1875 dprintk((KERN_INFO " vtarget @ %p\n", hd->Targets));
0c33b27d
CH
1876
1877 /* Clear the TM flags
1878 */
1879 hd->tmPending = 0;
1880 hd->tmState = TM_STATE_NONE;
1881 hd->resetPending = 0;
1882 hd->abortSCpnt = NULL;
1883
1884 /* Clear the pointer used to store
1885 * single-threaded commands, i.e., those
1886 * issued during a bus scan, dv and
1887 * configuration pages.
1888 */
1889 hd->cmdPtr = NULL;
1890
1891 /* Initialize this SCSI Hosts' timers
1892 * To use, set the timer expires field
1893 * and add_timer
1894 */
1895 init_timer(&hd->timer);
1896 hd->timer.data = (unsigned long) hd;
1897 hd->timer.function = mptscsih_timer_expired;
1898
1899 hd->mpt_pq_filter = mpt_pq_filter;
1900 ioc->sas_data.ptClear = mpt_pt_clear;
1901
1902 if (ioc->sas_data.ptClear==1) {
1903 mptbase_sas_persist_operation(
1904 ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
1905 }
1906
1907 ddvprintk((MYIOC_s_INFO_FMT
1908 "mpt_pq_filter %x mpt_pq_filter %x\n",
1909 ioc->name,
1910 mpt_pq_filter,
1911 mpt_pq_filter));
1912
1913 init_waitqueue_head(&hd->scandv_waitq);
1914 hd->scandv_wait_done = 0;
1915 hd->last_queue_full = 0;
1916
1917 error = scsi_add_host(sh, &ioc->pcidev->dev);
1918 if (error) {
1919 dprintk((KERN_ERR MYNAM
1920 "scsi_add_host failed\n"));
7acec1e7 1921 goto out_mptsas_probe;
0c33b27d
CH
1922 }
1923
1924 mptsas_scan_sas_topology(ioc);
1925
816aa907
ME
1926 /*
1927 Reporting RAID volumes.
1928 */
1929 if (!ioc->raid_data.pIocPg2)
1930 return 0;
1931 if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
1932 return 0;
1933 for (ii=0;ii<ioc->raid_data.pIocPg2->NumActiveVolumes;ii++) {
1934 scsi_add_device(sh,
1935 ioc->num_ports,
1936 ioc->raid_data.pIocPg2->RaidVolume[ii].VolumeID,
1937 0);
1938 }
1939
0c33b27d
CH
1940 return 0;
1941
7acec1e7 1942out_mptsas_probe:
0c33b27d
CH
1943
1944 mptscsih_remove(pdev);
1945 return error;
1946}
1947
1948static void __devexit mptsas_remove(struct pci_dev *pdev)
1949{
1950 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1951 struct mptsas_portinfo *p, *n;
1952
1953 sas_remove_host(ioc->sh);
1954
9a28f49a 1955 mutex_lock(&ioc->sas_topology_mutex);
0c33b27d
CH
1956 list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
1957 list_del(&p->list);
1958 kfree(p);
1959 }
9a28f49a 1960 mutex_unlock(&ioc->sas_topology_mutex);
0c33b27d
CH
1961
1962 mptscsih_remove(pdev);
1963}
1964
1965static struct pci_device_id mptsas_pci_table[] = {
1966 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064,
1967 PCI_ANY_ID, PCI_ANY_ID },
1968 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066,
1969 PCI_ANY_ID, PCI_ANY_ID },
1970 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068,
1971 PCI_ANY_ID, PCI_ANY_ID },
1972 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064E,
1973 PCI_ANY_ID, PCI_ANY_ID },
1974 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066E,
1975 PCI_ANY_ID, PCI_ANY_ID },
1976 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068E,
1977 PCI_ANY_ID, PCI_ANY_ID },
1978 {0} /* Terminating entry */
1979};
1980MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
1981
1982
1983static struct pci_driver mptsas_driver = {
1984 .name = "mptsas",
1985 .id_table = mptsas_pci_table,
1986 .probe = mptsas_probe,
1987 .remove = __devexit_p(mptsas_remove),
1988 .shutdown = mptscsih_shutdown,
1989#ifdef CONFIG_PM
1990 .suspend = mptscsih_suspend,
1991 .resume = mptscsih_resume,
1992#endif
1993};
1994
1995static int __init
1996mptsas_init(void)
1997{
1998 show_mptmod_ver(my_NAME, my_VERSION);
1999
2000 mptsas_transport_template =
2001 sas_attach_transport(&mptsas_transport_functions);
2002 if (!mptsas_transport_template)
2003 return -ENODEV;
2004
2005 mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
2006 mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER);
2007 mptsasInternalCtx =
2008 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
da4fa655 2009 mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
0c33b27d 2010
9a28f49a 2011 if (mpt_event_register(mptsasDoneCtx, mptsas_event_process) == 0) {
3a892bef 2012 devtverboseprintk((KERN_INFO MYNAM
0c33b27d
CH
2013 ": Registered for IOC event notifications\n"));
2014 }
2015
2016 if (mpt_reset_register(mptsasDoneCtx, mptscsih_ioc_reset) == 0) {
2017 dprintk((KERN_INFO MYNAM
2018 ": Registered for IOC reset notifications\n"));
2019 }
2020
2021 return pci_register_driver(&mptsas_driver);
2022}
2023
2024static void __exit
2025mptsas_exit(void)
2026{
2027 pci_unregister_driver(&mptsas_driver);
2028 sas_release_transport(mptsas_transport_template);
2029
2030 mpt_reset_deregister(mptsasDoneCtx);
2031 mpt_event_deregister(mptsasDoneCtx);
2032
da4fa655 2033 mpt_deregister(mptsasMgmtCtx);
0c33b27d
CH
2034 mpt_deregister(mptsasInternalCtx);
2035 mpt_deregister(mptsasTaskCtx);
2036 mpt_deregister(mptsasDoneCtx);
2037}
2038
2039module_init(mptsas_init);
2040module_exit(mptsas_exit);