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