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