xref: /linux/drivers/message/fusion/mptsas.c (revision 858259cf7d1c443c836a2022b78cb281f0a9b95e)
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)
8  *  Copyright (c) 2005 Dell
9  */
10 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
11 /*
12     This program is free software; you can redistribute it and/or modify
13     it under the terms of the GNU General Public License as published by
14     the Free Software Foundation; version 2 of the License.
15 
16     This program is distributed in the hope that it will be useful,
17     but WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19     GNU General Public License for more details.
20 
21     NO WARRANTY
22     THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
23     CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
24     LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
25     MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
26     solely responsible for determining the appropriateness of using and
27     distributing the Program and assumes all risks associated with its
28     exercise of rights under this Agreement, including but not limited to
29     the risks and costs of program errors, damage to or loss of data,
30     programs or equipment, and unavailability or interruption of operations.
31 
32     DISCLAIMER OF LIABILITY
33     NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
34     DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35     DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
36     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
37     TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
38     USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
39     HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
40 
41     You should have received a copy of the GNU General Public License
42     along with this program; if not, write to the Free Software
43     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
44 */
45 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
46 
47 #include <linux/module.h>
48 #include <linux/kernel.h>
49 #include <linux/init.h>
50 #include <linux/errno.h>
51 #include <linux/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 
67 MODULE_AUTHOR(MODULEAUTHOR);
68 MODULE_DESCRIPTION(my_NAME);
69 MODULE_LICENSE("GPL");
70 
71 static int mpt_pq_filter;
72 module_param(mpt_pq_filter, int, 0);
73 MODULE_PARM_DESC(mpt_pq_filter,
74 		"Enable peripheral qualifier filter: enable=1  "
75 		"(default=0)");
76 
77 static int mpt_pt_clear;
78 module_param(mpt_pt_clear, int, 0);
79 MODULE_PARM_DESC(mpt_pt_clear,
80 		"Clear persistency table: enable=1  "
81 		"(default=MPTSCSIH_PT_CLEAR=0)");
82 
83 static int	mptsasDoneCtx = -1;
84 static int	mptsasTaskCtx = -1;
85 static int	mptsasInternalCtx = -1; /* Used only for internal commands */
86 static int	mptsasMgmtCtx = -1;
87 
88 
89 /*
90  * SAS topology structures
91  *
92  * The MPT Fusion firmware interface spreads information about the
93  * SAS topology over many manufacture pages, thus we need some data
94  * structure to collect it and process it for the SAS transport class.
95  */
96 
97 struct mptsas_devinfo {
98 	u16	handle;		/* unique id to address this device */
99 	u8	phy_id;		/* phy number of parent device */
100 	u8	port_id;	/* sas physical port this device
101 				   is assoc'd with */
102 	u8	target;		/* logical target id of this device */
103 	u8	bus;		/* logical bus number of this device */
104 	u64	sas_address;    /* WWN of this device,
105 				   SATA is assigned by HBA,expander */
106 	u32	device_info;	/* bitfield detailed info about this device */
107 };
108 
109 struct mptsas_phyinfo {
110 	u8	phy_id; 		/* phy index */
111 	u8	port_id; 		/* port number this phy is part of */
112 	u8	negotiated_link_rate;	/* nego'd link rate for this phy */
113 	u8	hw_link_rate; 		/* hardware max/min phys link rate */
114 	u8	programmed_link_rate;	/* programmed max/min phy link rate */
115 	struct mptsas_devinfo identify;	/* point to phy device info */
116 	struct mptsas_devinfo attached;	/* point to attached device info */
117 	struct sas_rphy *rphy;
118 };
119 
120 struct mptsas_portinfo {
121 	struct list_head list;
122 	u16		handle;		/* unique id to address this */
123 	u8		num_phys;	/* number of phys */
124 	struct mptsas_phyinfo *phy_info;
125 };
126 
127 
128 #ifdef SASDEBUG
129 static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
130 {
131 	printk("---- IO UNIT PAGE 0 ------------\n");
132 	printk("Handle=0x%X\n",
133 		le16_to_cpu(phy_data->AttachedDeviceHandle));
134 	printk("Controller Handle=0x%X\n",
135 		le16_to_cpu(phy_data->ControllerDevHandle));
136 	printk("Port=0x%X\n", phy_data->Port);
137 	printk("Port Flags=0x%X\n", phy_data->PortFlags);
138 	printk("PHY Flags=0x%X\n", phy_data->PhyFlags);
139 	printk("Negotiated Link Rate=0x%X\n", phy_data->NegotiatedLinkRate);
140 	printk("Controller PHY Device Info=0x%X\n",
141 		le32_to_cpu(phy_data->ControllerPhyDeviceInfo));
142 	printk("DiscoveryStatus=0x%X\n",
143 		le32_to_cpu(phy_data->DiscoveryStatus));
144 	printk("\n");
145 }
146 
147 static void mptsas_print_phy_pg0(SasPhyPage0_t *pg0)
148 {
149 	__le64 sas_address;
150 
151 	memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
152 
153 	printk("---- SAS PHY PAGE 0 ------------\n");
154 	printk("Attached Device Handle=0x%X\n",
155 			le16_to_cpu(pg0->AttachedDevHandle));
156 	printk("SAS Address=0x%llX\n",
157 			(unsigned long long)le64_to_cpu(sas_address));
158 	printk("Attached PHY Identifier=0x%X\n", pg0->AttachedPhyIdentifier);
159 	printk("Attached Device Info=0x%X\n",
160 			le32_to_cpu(pg0->AttachedDeviceInfo));
161 	printk("Programmed Link Rate=0x%X\n", pg0->ProgrammedLinkRate);
162 	printk("Change Count=0x%X\n", pg0->ChangeCount);
163 	printk("PHY Info=0x%X\n", le32_to_cpu(pg0->PhyInfo));
164 	printk("\n");
165 }
166 
167 static void mptsas_print_phy_pg1(SasPhyPage1_t *pg1)
168 {
169 	printk("---- SAS PHY PAGE 1 ------------\n");
170 	printk("Invalid Dword Count=0x%x\n", pg1->InvalidDwordCount);
171 	printk("Running Disparity Error Count=0x%x\n",
172 			pg1->RunningDisparityErrorCount);
173 	printk("Loss Dword Synch Count=0x%x\n", pg1->LossDwordSynchCount);
174 	printk("PHY Reset Problem Count=0x%x\n", pg1->PhyResetProblemCount);
175 	printk("\n");
176 }
177 
178 static void mptsas_print_device_pg0(SasDevicePage0_t *pg0)
179 {
180 	__le64 sas_address;
181 
182 	memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
183 
184 	printk("---- SAS DEVICE PAGE 0 ---------\n");
185 	printk("Handle=0x%X\n" ,le16_to_cpu(pg0->DevHandle));
186 	printk("Enclosure Handle=0x%X\n", le16_to_cpu(pg0->EnclosureHandle));
187 	printk("Slot=0x%X\n", le16_to_cpu(pg0->Slot));
188 	printk("SAS Address=0x%llX\n", le64_to_cpu(sas_address));
189 	printk("Target ID=0x%X\n", pg0->TargetID);
190 	printk("Bus=0x%X\n", pg0->Bus);
191 	/* The PhyNum field specifies the PHY number of the parent
192 	 * device this device is linked to
193 	 */
194 	printk("Parent Phy Num=0x%X\n", pg0->PhyNum);
195 	printk("Access Status=0x%X\n", le16_to_cpu(pg0->AccessStatus));
196 	printk("Device Info=0x%X\n", le32_to_cpu(pg0->DeviceInfo));
197 	printk("Flags=0x%X\n", le16_to_cpu(pg0->Flags));
198 	printk("Physical Port=0x%X\n", pg0->PhysicalPort);
199 	printk("\n");
200 }
201 
202 static void mptsas_print_expander_pg1(SasExpanderPage1_t *pg1)
203 {
204 	printk("---- SAS EXPANDER PAGE 1 ------------\n");
205 
206 	printk("Physical Port=0x%X\n", pg1->PhysicalPort);
207 	printk("PHY Identifier=0x%X\n", pg1->PhyIdentifier);
208 	printk("Negotiated Link Rate=0x%X\n", pg1->NegotiatedLinkRate);
209 	printk("Programmed Link Rate=0x%X\n", pg1->ProgrammedLinkRate);
210 	printk("Hardware Link Rate=0x%X\n", pg1->HwLinkRate);
211 	printk("Owner Device Handle=0x%X\n",
212 			le16_to_cpu(pg1->OwnerDevHandle));
213 	printk("Attached Device Handle=0x%X\n",
214 			le16_to_cpu(pg1->AttachedDevHandle));
215 }
216 #else
217 #define mptsas_print_phy_data(phy_data)		do { } while (0)
218 #define mptsas_print_phy_pg0(pg0)		do { } while (0)
219 #define mptsas_print_phy_pg1(pg1)		do { } while (0)
220 #define mptsas_print_device_pg0(pg0)		do { } while (0)
221 #define mptsas_print_expander_pg1(pg1)		do { } while (0)
222 #endif
223 
224 
225 /*
226  * This is pretty ugly.  We will be able to seriously clean it up
227  * once the DV code in mptscsih goes away and we can properly
228  * implement ->target_alloc.
229  */
230 static int
231 mptsas_slave_alloc(struct scsi_device *device)
232 {
233 	struct Scsi_Host	*host = device->host;
234 	MPT_SCSI_HOST		*hd = (MPT_SCSI_HOST *)host->hostdata;
235 	struct sas_rphy		*rphy;
236 	struct mptsas_portinfo	*p;
237 	VirtDevice		*vdev;
238 	uint			target = device->id;
239 	int i;
240 
241 	if ((vdev = hd->Targets[target]) != NULL)
242 		goto out;
243 
244 	vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
245 	if (!vdev) {
246 		printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
247 				hd->ioc->name, sizeof(VirtDevice));
248 		return -ENOMEM;
249 	}
250 
251 	memset(vdev, 0, sizeof(VirtDevice));
252 	vdev->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY;
253 	vdev->ioc_id = hd->ioc->id;
254 
255 	rphy = dev_to_rphy(device->sdev_target->dev.parent);
256 	list_for_each_entry(p, &hd->ioc->sas_topology, list) {
257 		for (i = 0; i < p->num_phys; i++) {
258 			if (p->phy_info[i].attached.sas_address ==
259 					rphy->identify.sas_address) {
260 				vdev->target_id =
261 					p->phy_info[i].attached.target;
262 				vdev->bus_id = p->phy_info[i].attached.bus;
263 				hd->Targets[device->id] = vdev;
264 				goto out;
265 			}
266 		}
267 	}
268 
269 	printk("No matching SAS device found!!\n");
270 	kfree(vdev);
271 	return -ENODEV;
272 
273  out:
274 	vdev->num_luns++;
275 	device->hostdata = vdev;
276 	return 0;
277 }
278 
279 static struct scsi_host_template mptsas_driver_template = {
280 	.proc_name			= "mptsas",
281 	.proc_info			= mptscsih_proc_info,
282 	.name				= "MPT SPI Host",
283 	.info				= mptscsih_info,
284 	.queuecommand			= mptscsih_qcmd,
285 	.slave_alloc			= mptsas_slave_alloc,
286 	.slave_configure		= mptscsih_slave_configure,
287 	.slave_destroy			= mptscsih_slave_destroy,
288 	.change_queue_depth 		= mptscsih_change_queue_depth,
289 	.eh_abort_handler		= mptscsih_abort,
290 	.eh_device_reset_handler	= mptscsih_dev_reset,
291 	.eh_bus_reset_handler		= mptscsih_bus_reset,
292 	.eh_host_reset_handler		= mptscsih_host_reset,
293 	.bios_param			= mptscsih_bios_param,
294 	.can_queue			= MPT_FC_CAN_QUEUE,
295 	.this_id			= -1,
296 	.sg_tablesize			= MPT_SCSI_SG_DEPTH,
297 	.max_sectors			= 8192,
298 	.cmd_per_lun			= 7,
299 	.use_clustering			= ENABLE_CLUSTERING,
300 };
301 
302 static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
303 {
304 	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
305 	return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
306 }
307 
308 static int mptsas_get_linkerrors(struct sas_phy *phy)
309 {
310 	MPT_ADAPTER *ioc = phy_to_ioc(phy);
311 	ConfigExtendedPageHeader_t hdr;
312 	CONFIGPARMS cfg;
313 	SasPhyPage1_t *buffer;
314 	dma_addr_t dma_handle;
315 	int error;
316 
317 	hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
318 	hdr.ExtPageLength = 0;
319 	hdr.PageNumber = 1 /* page number 1*/;
320 	hdr.Reserved1 = 0;
321 	hdr.Reserved2 = 0;
322 	hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
323 	hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
324 
325 	cfg.cfghdr.ehdr = &hdr;
326 	cfg.physAddr = -1;
327 	cfg.pageAddr = phy->identify.phy_identifier;
328 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
329 	cfg.dir = 0;    /* read */
330 	cfg.timeout = 10;
331 
332 	error = mpt_config(ioc, &cfg);
333 	if (error)
334 		return error;
335 	if (!hdr.ExtPageLength)
336 		return -ENXIO;
337 
338 	buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
339 				      &dma_handle);
340 	if (!buffer)
341 		return -ENOMEM;
342 
343 	cfg.physAddr = dma_handle;
344 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
345 
346 	error = mpt_config(ioc, &cfg);
347 	if (error)
348 		goto out_free_consistent;
349 
350 	mptsas_print_phy_pg1(buffer);
351 
352 	phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
353 	phy->running_disparity_error_count =
354 		le32_to_cpu(buffer->RunningDisparityErrorCount);
355 	phy->loss_of_dword_sync_count =
356 		le32_to_cpu(buffer->LossDwordSynchCount);
357 	phy->phy_reset_problem_count =
358 		le32_to_cpu(buffer->PhyResetProblemCount);
359 
360  out_free_consistent:
361 	pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
362 			    buffer, dma_handle);
363 	return error;
364 }
365 
366 static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
367 		MPT_FRAME_HDR *reply)
368 {
369 	ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_COMMAND_GOOD;
370 	if (reply != NULL) {
371 		ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_RF_VALID;
372 		memcpy(ioc->sas_mgmt.reply, reply,
373 		    min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
374 	}
375 	complete(&ioc->sas_mgmt.done);
376 	return 1;
377 }
378 
379 static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
380 {
381 	MPT_ADAPTER *ioc = phy_to_ioc(phy);
382 	SasIoUnitControlRequest_t *req;
383 	SasIoUnitControlReply_t *reply;
384 	MPT_FRAME_HDR *mf;
385 	MPIHeader_t *hdr;
386 	unsigned long timeleft;
387 	int error = -ERESTARTSYS;
388 
389 	/* not implemented for expanders */
390 	if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
391 		return -ENXIO;
392 
393 	if (down_interruptible(&ioc->sas_mgmt.mutex))
394 		goto out;
395 
396 	mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
397 	if (!mf) {
398 		error = -ENOMEM;
399 		goto out_unlock;
400 	}
401 
402 	hdr = (MPIHeader_t *) mf;
403 	req = (SasIoUnitControlRequest_t *)mf;
404 	memset(req, 0, sizeof(SasIoUnitControlRequest_t));
405 	req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
406 	req->MsgContext = hdr->MsgContext;
407 	req->Operation = hard_reset ?
408 		MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
409 	req->PhyNum = phy->identify.phy_identifier;
410 
411 	mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
412 
413 	timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
414 			10 * HZ);
415 	if (!timeleft) {
416 		/* On timeout reset the board */
417 		mpt_free_msg_frame(ioc, mf);
418 		mpt_HardResetHandler(ioc, CAN_SLEEP);
419 		error = -ETIMEDOUT;
420 		goto out_unlock;
421 	}
422 
423 	/* a reply frame is expected */
424 	if ((ioc->sas_mgmt.status &
425 	    MPT_IOCTL_STATUS_RF_VALID) == 0) {
426 		error = -ENXIO;
427 		goto out_unlock;
428 	}
429 
430 	/* process the completed Reply Message Frame */
431 	reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
432 	if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
433 		printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
434 		    __FUNCTION__,
435 		    reply->IOCStatus,
436 		    reply->IOCLogInfo);
437 		error = -ENXIO;
438 		goto out_unlock;
439 	}
440 
441 	error = 0;
442 
443  out_unlock:
444 	up(&ioc->sas_mgmt.mutex);
445  out:
446 	return error;
447 }
448 
449 static struct sas_function_template mptsas_transport_functions = {
450 	.get_linkerrors		= mptsas_get_linkerrors,
451 	.phy_reset		= mptsas_phy_reset,
452 };
453 
454 static struct scsi_transport_template *mptsas_transport_template;
455 
456 static int
457 mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
458 {
459 	ConfigExtendedPageHeader_t hdr;
460 	CONFIGPARMS cfg;
461 	SasIOUnitPage0_t *buffer;
462 	dma_addr_t dma_handle;
463 	int error, i;
464 
465 	hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
466 	hdr.ExtPageLength = 0;
467 	hdr.PageNumber = 0;
468 	hdr.Reserved1 = 0;
469 	hdr.Reserved2 = 0;
470 	hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
471 	hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
472 
473 	cfg.cfghdr.ehdr = &hdr;
474 	cfg.physAddr = -1;
475 	cfg.pageAddr = 0;
476 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
477 	cfg.dir = 0;	/* read */
478 	cfg.timeout = 10;
479 
480 	error = mpt_config(ioc, &cfg);
481 	if (error)
482 		goto out;
483 	if (!hdr.ExtPageLength) {
484 		error = -ENXIO;
485 		goto out;
486 	}
487 
488 	buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
489 					    &dma_handle);
490 	if (!buffer) {
491 		error = -ENOMEM;
492 		goto out;
493 	}
494 
495 	cfg.physAddr = dma_handle;
496 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
497 
498 	error = mpt_config(ioc, &cfg);
499 	if (error)
500 		goto out_free_consistent;
501 
502 	port_info->num_phys = buffer->NumPhys;
503 	port_info->phy_info = kcalloc(port_info->num_phys,
504 		sizeof(struct mptsas_phyinfo),GFP_KERNEL);
505 	if (!port_info->phy_info) {
506 		error = -ENOMEM;
507 		goto out_free_consistent;
508 	}
509 
510 	for (i = 0; i < port_info->num_phys; i++) {
511 		mptsas_print_phy_data(&buffer->PhyData[i]);
512 		port_info->phy_info[i].phy_id = i;
513 		port_info->phy_info[i].port_id =
514 		    buffer->PhyData[i].Port;
515 		port_info->phy_info[i].negotiated_link_rate =
516 		    buffer->PhyData[i].NegotiatedLinkRate;
517 	}
518 
519  out_free_consistent:
520 	pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
521 			    buffer, dma_handle);
522  out:
523 	return error;
524 }
525 
526 static int
527 mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
528 		u32 form, u32 form_specific)
529 {
530 	ConfigExtendedPageHeader_t hdr;
531 	CONFIGPARMS cfg;
532 	SasPhyPage0_t *buffer;
533 	dma_addr_t dma_handle;
534 	int error;
535 
536 	hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
537 	hdr.ExtPageLength = 0;
538 	hdr.PageNumber = 0;
539 	hdr.Reserved1 = 0;
540 	hdr.Reserved2 = 0;
541 	hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
542 	hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
543 
544 	cfg.cfghdr.ehdr = &hdr;
545 	cfg.dir = 0;	/* read */
546 	cfg.timeout = 10;
547 
548 	/* Get Phy Pg 0 for each Phy. */
549 	cfg.physAddr = -1;
550 	cfg.pageAddr = form + form_specific;
551 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
552 
553 	error = mpt_config(ioc, &cfg);
554 	if (error)
555 		goto out;
556 
557 	if (!hdr.ExtPageLength) {
558 		error = -ENXIO;
559 		goto out;
560 	}
561 
562 	buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
563 				      &dma_handle);
564 	if (!buffer) {
565 		error = -ENOMEM;
566 		goto out;
567 	}
568 
569 	cfg.physAddr = dma_handle;
570 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
571 
572 	error = mpt_config(ioc, &cfg);
573 	if (error)
574 		goto out_free_consistent;
575 
576 	mptsas_print_phy_pg0(buffer);
577 
578 	phy_info->hw_link_rate = buffer->HwLinkRate;
579 	phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
580 	phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
581 	phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
582 
583  out_free_consistent:
584 	pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
585 			    buffer, dma_handle);
586  out:
587 	return error;
588 }
589 
590 static int
591 mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
592 		u32 form, u32 form_specific)
593 {
594 	ConfigExtendedPageHeader_t hdr;
595 	CONFIGPARMS cfg;
596 	SasDevicePage0_t *buffer;
597 	dma_addr_t dma_handle;
598 	__le64 sas_address;
599 	int error;
600 
601 	hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
602 	hdr.ExtPageLength = 0;
603 	hdr.PageNumber = 0;
604 	hdr.Reserved1 = 0;
605 	hdr.Reserved2 = 0;
606 	hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
607 	hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
608 
609 	cfg.cfghdr.ehdr = &hdr;
610 	cfg.pageAddr = form + form_specific;
611 	cfg.physAddr = -1;
612 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
613 	cfg.dir = 0;	/* read */
614 	cfg.timeout = 10;
615 
616 	error = mpt_config(ioc, &cfg);
617 	if (error)
618 		goto out;
619 	if (!hdr.ExtPageLength) {
620 		error = -ENXIO;
621 		goto out;
622 	}
623 
624 	buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
625 				      &dma_handle);
626 	if (!buffer) {
627 		error = -ENOMEM;
628 		goto out;
629 	}
630 
631 	cfg.physAddr = dma_handle;
632 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
633 
634 	error = mpt_config(ioc, &cfg);
635 	if (error)
636 		goto out_free_consistent;
637 
638 	mptsas_print_device_pg0(buffer);
639 
640 	device_info->handle = le16_to_cpu(buffer->DevHandle);
641 	device_info->phy_id = buffer->PhyNum;
642 	device_info->port_id = buffer->PhysicalPort;
643 	device_info->target = buffer->TargetID;
644 	device_info->bus = buffer->Bus;
645 	memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
646 	device_info->sas_address = le64_to_cpu(sas_address);
647 	device_info->device_info =
648 	    le32_to_cpu(buffer->DeviceInfo);
649 
650  out_free_consistent:
651 	pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
652 			    buffer, dma_handle);
653  out:
654 	return error;
655 }
656 
657 static int
658 mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
659 		u32 form, u32 form_specific)
660 {
661 	ConfigExtendedPageHeader_t hdr;
662 	CONFIGPARMS cfg;
663 	SasExpanderPage0_t *buffer;
664 	dma_addr_t dma_handle;
665 	int error;
666 
667 	hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
668 	hdr.ExtPageLength = 0;
669 	hdr.PageNumber = 0;
670 	hdr.Reserved1 = 0;
671 	hdr.Reserved2 = 0;
672 	hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
673 	hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
674 
675 	cfg.cfghdr.ehdr = &hdr;
676 	cfg.physAddr = -1;
677 	cfg.pageAddr = form + form_specific;
678 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
679 	cfg.dir = 0;	/* read */
680 	cfg.timeout = 10;
681 
682 	error = mpt_config(ioc, &cfg);
683 	if (error)
684 		goto out;
685 
686 	if (!hdr.ExtPageLength) {
687 		error = -ENXIO;
688 		goto out;
689 	}
690 
691 	buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
692 				      &dma_handle);
693 	if (!buffer) {
694 		error = -ENOMEM;
695 		goto out;
696 	}
697 
698 	cfg.physAddr = dma_handle;
699 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
700 
701 	error = mpt_config(ioc, &cfg);
702 	if (error)
703 		goto out_free_consistent;
704 
705 	/* save config data */
706 	port_info->num_phys = buffer->NumPhys;
707 	port_info->handle = le16_to_cpu(buffer->DevHandle);
708 	port_info->phy_info = kcalloc(port_info->num_phys,
709 		sizeof(struct mptsas_phyinfo),GFP_KERNEL);
710 	if (!port_info->phy_info) {
711 		error = -ENOMEM;
712 		goto out_free_consistent;
713 	}
714 
715  out_free_consistent:
716 	pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
717 			    buffer, dma_handle);
718  out:
719 	return error;
720 }
721 
722 static int
723 mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
724 		u32 form, u32 form_specific)
725 {
726 	ConfigExtendedPageHeader_t hdr;
727 	CONFIGPARMS cfg;
728 	SasExpanderPage1_t *buffer;
729 	dma_addr_t dma_handle;
730 	int error;
731 
732 	hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
733 	hdr.ExtPageLength = 0;
734 	hdr.PageNumber = 1;
735 	hdr.Reserved1 = 0;
736 	hdr.Reserved2 = 0;
737 	hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
738 	hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
739 
740 	cfg.cfghdr.ehdr = &hdr;
741 	cfg.physAddr = -1;
742 	cfg.pageAddr = form + form_specific;
743 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
744 	cfg.dir = 0;	/* read */
745 	cfg.timeout = 10;
746 
747 	error = mpt_config(ioc, &cfg);
748 	if (error)
749 		goto out;
750 
751 	if (!hdr.ExtPageLength) {
752 		error = -ENXIO;
753 		goto out;
754 	}
755 
756 	buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
757 				      &dma_handle);
758 	if (!buffer) {
759 		error = -ENOMEM;
760 		goto out;
761 	}
762 
763 	cfg.physAddr = dma_handle;
764 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
765 
766 	error = mpt_config(ioc, &cfg);
767 	if (error)
768 		goto out_free_consistent;
769 
770 
771 	mptsas_print_expander_pg1(buffer);
772 
773 	/* save config data */
774 	phy_info->phy_id = buffer->PhyIdentifier;
775 	phy_info->port_id = buffer->PhysicalPort;
776 	phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
777 	phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
778 	phy_info->hw_link_rate = buffer->HwLinkRate;
779 	phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
780 	phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
781 
782 
783  out_free_consistent:
784 	pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
785 			    buffer, dma_handle);
786  out:
787 	return error;
788 }
789 
790 static void
791 mptsas_parse_device_info(struct sas_identify *identify,
792 		struct mptsas_devinfo *device_info)
793 {
794 	u16 protocols;
795 
796 	identify->sas_address = device_info->sas_address;
797 	identify->phy_identifier = device_info->phy_id;
798 
799 	/*
800 	 * Fill in Phy Initiator Port Protocol.
801 	 * Bits 6:3, more than one bit can be set, fall through cases.
802 	 */
803 	protocols = device_info->device_info & 0x78;
804 	identify->initiator_port_protocols = 0;
805 	if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
806 		identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
807 	if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
808 		identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
809 	if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
810 		identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
811 	if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
812 		identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
813 
814 	/*
815 	 * Fill in Phy Target Port Protocol.
816 	 * Bits 10:7, more than one bit can be set, fall through cases.
817 	 */
818 	protocols = device_info->device_info & 0x780;
819 	identify->target_port_protocols = 0;
820 	if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
821 		identify->target_port_protocols |= SAS_PROTOCOL_SSP;
822 	if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
823 		identify->target_port_protocols |= SAS_PROTOCOL_STP;
824 	if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
825 		identify->target_port_protocols |= SAS_PROTOCOL_SMP;
826 	if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
827 		identify->target_port_protocols |= SAS_PROTOCOL_SATA;
828 
829 	/*
830 	 * Fill in Attached device type.
831 	 */
832 	switch (device_info->device_info &
833 			MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
834 	case MPI_SAS_DEVICE_INFO_NO_DEVICE:
835 		identify->device_type = SAS_PHY_UNUSED;
836 		break;
837 	case MPI_SAS_DEVICE_INFO_END_DEVICE:
838 		identify->device_type = SAS_END_DEVICE;
839 		break;
840 	case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
841 		identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
842 		break;
843 	case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
844 		identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
845 		break;
846 	}
847 }
848 
849 static int mptsas_probe_one_phy(struct device *dev,
850 		struct mptsas_phyinfo *phy_info, int index, int local)
851 {
852 	struct sas_phy *port;
853 	int error;
854 
855 	port = sas_phy_alloc(dev, index);
856 	if (!port)
857 		return -ENOMEM;
858 
859 	port->port_identifier = phy_info->port_id;
860 	mptsas_parse_device_info(&port->identify, &phy_info->identify);
861 
862 	/*
863 	 * Set Negotiated link rate.
864 	 */
865 	switch (phy_info->negotiated_link_rate) {
866 	case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
867 		port->negotiated_linkrate = SAS_PHY_DISABLED;
868 		break;
869 	case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
870 		port->negotiated_linkrate = SAS_LINK_RATE_FAILED;
871 		break;
872 	case MPI_SAS_IOUNIT0_RATE_1_5:
873 		port->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
874 		break;
875 	case MPI_SAS_IOUNIT0_RATE_3_0:
876 		port->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
877 		break;
878 	case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
879 	case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
880 	default:
881 		port->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
882 		break;
883 	}
884 
885 	/*
886 	 * Set Max hardware link rate.
887 	 */
888 	switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
889 	case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
890 		port->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
891 		break;
892 	case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
893 		port->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
894 		break;
895 	default:
896 		break;
897 	}
898 
899 	/*
900 	 * Set Max programmed link rate.
901 	 */
902 	switch (phy_info->programmed_link_rate &
903 			MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
904 	case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
905 		port->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
906 		break;
907 	case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
908 		port->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
909 		break;
910 	default:
911 		break;
912 	}
913 
914 	/*
915 	 * Set Min hardware link rate.
916 	 */
917 	switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
918 	case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
919 		port->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
920 		break;
921 	case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
922 		port->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
923 		break;
924 	default:
925 		break;
926 	}
927 
928 	/*
929 	 * Set Min programmed link rate.
930 	 */
931 	switch (phy_info->programmed_link_rate &
932 			MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
933 	case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
934 		port->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
935 		break;
936 	case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
937 		port->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
938 		break;
939 	default:
940 		break;
941 	}
942 
943 	if (local)
944 		port->local_attached = 1;
945 
946 	error = sas_phy_add(port);
947 	if (error) {
948 		sas_phy_free(port);
949 		return error;
950 	}
951 
952 	if (phy_info->attached.handle) {
953 		struct sas_rphy *rphy;
954 
955 		rphy = sas_rphy_alloc(port);
956 		if (!rphy)
957 			return 0; /* non-fatal: an rphy can be added later */
958 
959 		mptsas_parse_device_info(&rphy->identify, &phy_info->attached);
960 		error = sas_rphy_add(rphy);
961 		if (error) {
962 			sas_rphy_free(rphy);
963 			return error;
964 		}
965 
966 		phy_info->rphy = rphy;
967 	}
968 
969 	return 0;
970 }
971 
972 static int
973 mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index)
974 {
975 	struct mptsas_portinfo *port_info;
976 	u32 handle = 0xFFFF;
977 	int error = -ENOMEM, i;
978 
979 	port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);
980 	if (!port_info)
981 		goto out;
982 	memset(port_info, 0, sizeof(*port_info));
983 
984 	error = mptsas_sas_io_unit_pg0(ioc, port_info);
985 	if (error)
986 		goto out_free_port_info;
987 
988 	list_add_tail(&port_info->list, &ioc->sas_topology);
989 
990 	for (i = 0; i < port_info->num_phys; i++) {
991 		mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
992 			(MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
993 			 MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
994 
995 		mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
996 			(MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE <<
997 			 MPI_SAS_DEVICE_PGAD_FORM_SHIFT), handle);
998 		port_info->phy_info[i].identify.phy_id =
999 		    port_info->phy_info[i].phy_id;
1000 		handle = port_info->phy_info[i].identify.handle;
1001 
1002 		if (port_info->phy_info[i].attached.handle) {
1003 			mptsas_sas_device_pg0(ioc,
1004 				&port_info->phy_info[i].attached,
1005 				(MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1006 				 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1007 				port_info->phy_info[i].attached.handle);
1008 		}
1009 
1010 		mptsas_probe_one_phy(&ioc->sh->shost_gendev,
1011 				     &port_info->phy_info[i], *index, 1);
1012 		(*index)++;
1013 	}
1014 
1015 	return 0;
1016 
1017  out_free_port_info:
1018 	kfree(port_info);
1019  out:
1020 	return error;
1021 }
1022 
1023 static int
1024 mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
1025 {
1026 	struct mptsas_portinfo *port_info, *p;
1027 	int error = -ENOMEM, i, j;
1028 
1029 	port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);
1030 	if (!port_info)
1031 		goto out;
1032 	memset(port_info, 0, sizeof(*port_info));
1033 
1034 	error = mptsas_sas_expander_pg0(ioc, port_info,
1035 		(MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
1036 		 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
1037 	if (error)
1038 		goto out_free_port_info;
1039 
1040 	*handle = port_info->handle;
1041 
1042 	list_add_tail(&port_info->list, &ioc->sas_topology);
1043 	for (i = 0; i < port_info->num_phys; i++) {
1044 		struct device *parent;
1045 
1046 		mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
1047 			(MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
1048 			 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle);
1049 
1050 		if (port_info->phy_info[i].identify.handle) {
1051 			mptsas_sas_device_pg0(ioc,
1052 				&port_info->phy_info[i].identify,
1053 				(MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1054 				 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1055 				port_info->phy_info[i].identify.handle);
1056 			port_info->phy_info[i].identify.phy_id =
1057 			    port_info->phy_info[i].phy_id;
1058 		}
1059 
1060 		if (port_info->phy_info[i].attached.handle) {
1061 			mptsas_sas_device_pg0(ioc,
1062 				&port_info->phy_info[i].attached,
1063 				(MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1064 				 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1065 				port_info->phy_info[i].attached.handle);
1066 		}
1067 
1068 		/*
1069 		 * If we find a parent port handle this expander is
1070 		 * attached to another expander, else it hangs of the
1071 		 * HBA phys.
1072 		 */
1073 		parent = &ioc->sh->shost_gendev;
1074 		list_for_each_entry(p, &ioc->sas_topology, list) {
1075 			for (j = 0; j < p->num_phys; j++) {
1076 				if (port_info->phy_info[i].identify.handle ==
1077 						p->phy_info[j].attached.handle)
1078 					parent = &p->phy_info[j].rphy->dev;
1079 			}
1080 		}
1081 
1082 		mptsas_probe_one_phy(parent, &port_info->phy_info[i],
1083 				     *index, 0);
1084 		(*index)++;
1085 	}
1086 
1087 	return 0;
1088 
1089  out_free_port_info:
1090 	kfree(port_info);
1091  out:
1092 	return error;
1093 }
1094 
1095 static void
1096 mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
1097 {
1098 	u32 handle = 0xFFFF;
1099 	int index = 0;
1100 
1101 	mptsas_probe_hba_phys(ioc, &index);
1102 	while (!mptsas_probe_expander_phys(ioc, &handle, &index))
1103 		;
1104 }
1105 
1106 static int
1107 mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1108 {
1109 	struct Scsi_Host	*sh;
1110 	MPT_SCSI_HOST		*hd;
1111 	MPT_ADAPTER 		*ioc;
1112 	unsigned long		 flags;
1113 	int			 sz, ii;
1114 	int			 numSGE = 0;
1115 	int			 scale;
1116 	int			 ioc_cap;
1117 	u8			*mem;
1118 	int			error=0;
1119 	int			r;
1120 
1121 	r = mpt_attach(pdev,id);
1122 	if (r)
1123 		return r;
1124 
1125 	ioc = pci_get_drvdata(pdev);
1126 	ioc->DoneCtx = mptsasDoneCtx;
1127 	ioc->TaskCtx = mptsasTaskCtx;
1128 	ioc->InternalCtx = mptsasInternalCtx;
1129 
1130 	/*  Added sanity check on readiness of the MPT adapter.
1131 	 */
1132 	if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
1133 		printk(MYIOC_s_WARN_FMT
1134 		  "Skipping because it's not operational!\n",
1135 		  ioc->name);
1136 		return -ENODEV;
1137 	}
1138 
1139 	if (!ioc->active) {
1140 		printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
1141 		  ioc->name);
1142 		return -ENODEV;
1143 	}
1144 
1145 	/*  Sanity check - ensure at least 1 port is INITIATOR capable
1146 	 */
1147 	ioc_cap = 0;
1148 	for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
1149 		if (ioc->pfacts[ii].ProtocolFlags &
1150 				MPI_PORTFACTS_PROTOCOL_INITIATOR)
1151 			ioc_cap++;
1152 	}
1153 
1154 	if (!ioc_cap) {
1155 		printk(MYIOC_s_WARN_FMT
1156 			"Skipping ioc=%p because SCSI Initiator mode "
1157 			"is NOT enabled!\n", ioc->name, ioc);
1158 		return 0;
1159 	}
1160 
1161 	sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
1162 	if (!sh) {
1163 		printk(MYIOC_s_WARN_FMT
1164 			"Unable to register controller with SCSI subsystem\n",
1165 			ioc->name);
1166                 return -1;
1167         }
1168 
1169 	spin_lock_irqsave(&ioc->FreeQlock, flags);
1170 
1171 	/* Attach the SCSI Host to the IOC structure
1172 	 */
1173 	ioc->sh = sh;
1174 
1175 	sh->io_port = 0;
1176 	sh->n_io_port = 0;
1177 	sh->irq = 0;
1178 
1179 	/* set 16 byte cdb's */
1180 	sh->max_cmd_len = 16;
1181 
1182 	sh->max_id = ioc->pfacts->MaxDevices + 1;
1183 
1184 	sh->transportt = mptsas_transport_template;
1185 
1186 	sh->max_lun = MPT_LAST_LUN + 1;
1187 	sh->max_channel = 0;
1188 	sh->this_id = ioc->pfacts[0].PortSCSIID;
1189 
1190 	/* Required entry.
1191 	 */
1192 	sh->unique_id = ioc->id;
1193 
1194 	INIT_LIST_HEAD(&ioc->sas_topology);
1195 	init_MUTEX(&ioc->sas_mgmt.mutex);
1196 	init_completion(&ioc->sas_mgmt.done);
1197 
1198 	/* Verify that we won't exceed the maximum
1199 	 * number of chain buffers
1200 	 * We can optimize:  ZZ = req_sz/sizeof(SGE)
1201 	 * For 32bit SGE's:
1202 	 *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
1203 	 *               + (req_sz - 64)/sizeof(SGE)
1204 	 * A slightly different algorithm is required for
1205 	 * 64bit SGEs.
1206 	 */
1207 	scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
1208 	if (sizeof(dma_addr_t) == sizeof(u64)) {
1209 		numSGE = (scale - 1) *
1210 		  (ioc->facts.MaxChainDepth-1) + scale +
1211 		  (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
1212 		  sizeof(u32));
1213 	} else {
1214 		numSGE = 1 + (scale - 1) *
1215 		  (ioc->facts.MaxChainDepth-1) + scale +
1216 		  (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
1217 		  sizeof(u32));
1218 	}
1219 
1220 	if (numSGE < sh->sg_tablesize) {
1221 		/* Reset this value */
1222 		dprintk((MYIOC_s_INFO_FMT
1223 		  "Resetting sg_tablesize to %d from %d\n",
1224 		  ioc->name, numSGE, sh->sg_tablesize));
1225 		sh->sg_tablesize = numSGE;
1226 	}
1227 
1228 	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1229 
1230 	hd = (MPT_SCSI_HOST *) sh->hostdata;
1231 	hd->ioc = ioc;
1232 
1233 	/* SCSI needs scsi_cmnd lookup table!
1234 	 * (with size equal to req_depth*PtrSz!)
1235 	 */
1236 	sz = ioc->req_depth * sizeof(void *);
1237 	mem = kmalloc(sz, GFP_ATOMIC);
1238 	if (mem == NULL) {
1239 		error = -ENOMEM;
1240 		goto mptsas_probe_failed;
1241 	}
1242 
1243 	memset(mem, 0, sz);
1244 	hd->ScsiLookup = (struct scsi_cmnd **) mem;
1245 
1246 	dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
1247 		 ioc->name, hd->ScsiLookup, sz));
1248 
1249 	/* Allocate memory for the device structures.
1250 	 * A non-Null pointer at an offset
1251 	 * indicates a device exists.
1252 	 * max_id = 1 + maximum id (hosts.h)
1253 	 */
1254 	sz = sh->max_id * sizeof(void *);
1255 	mem = kmalloc(sz, GFP_ATOMIC);
1256 	if (mem == NULL) {
1257 		error = -ENOMEM;
1258 		goto mptsas_probe_failed;
1259 	}
1260 
1261 	memset(mem, 0, sz);
1262 	hd->Targets = (VirtDevice **) mem;
1263 
1264 	dprintk((KERN_INFO
1265 	  "  Targets @ %p, sz=%d\n", hd->Targets, sz));
1266 
1267 	/* Clear the TM flags
1268 	 */
1269 	hd->tmPending = 0;
1270 	hd->tmState = TM_STATE_NONE;
1271 	hd->resetPending = 0;
1272 	hd->abortSCpnt = NULL;
1273 
1274 	/* Clear the pointer used to store
1275 	 * single-threaded commands, i.e., those
1276 	 * issued during a bus scan, dv and
1277 	 * configuration pages.
1278 	 */
1279 	hd->cmdPtr = NULL;
1280 
1281 	/* Initialize this SCSI Hosts' timers
1282 	 * To use, set the timer expires field
1283 	 * and add_timer
1284 	 */
1285 	init_timer(&hd->timer);
1286 	hd->timer.data = (unsigned long) hd;
1287 	hd->timer.function = mptscsih_timer_expired;
1288 
1289 	hd->mpt_pq_filter = mpt_pq_filter;
1290 	ioc->sas_data.ptClear = mpt_pt_clear;
1291 
1292 	if (ioc->sas_data.ptClear==1) {
1293 		mptbase_sas_persist_operation(
1294 		    ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
1295 	}
1296 
1297 	ddvprintk((MYIOC_s_INFO_FMT
1298 		"mpt_pq_filter %x mpt_pq_filter %x\n",
1299 		ioc->name,
1300 		mpt_pq_filter,
1301 		mpt_pq_filter));
1302 
1303 	init_waitqueue_head(&hd->scandv_waitq);
1304 	hd->scandv_wait_done = 0;
1305 	hd->last_queue_full = 0;
1306 
1307 	error = scsi_add_host(sh, &ioc->pcidev->dev);
1308 	if (error) {
1309 		dprintk((KERN_ERR MYNAM
1310 		  "scsi_add_host failed\n"));
1311 		goto mptsas_probe_failed;
1312 	}
1313 
1314 	mptsas_scan_sas_topology(ioc);
1315 
1316 	return 0;
1317 
1318 mptsas_probe_failed:
1319 
1320 	mptscsih_remove(pdev);
1321 	return error;
1322 }
1323 
1324 static void __devexit mptsas_remove(struct pci_dev *pdev)
1325 {
1326 	MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1327 	struct mptsas_portinfo *p, *n;
1328 
1329 	sas_remove_host(ioc->sh);
1330 
1331 	list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
1332 		list_del(&p->list);
1333 		kfree(p);
1334 	}
1335 
1336 	mptscsih_remove(pdev);
1337 }
1338 
1339 static struct pci_device_id mptsas_pci_table[] = {
1340 	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064,
1341 		PCI_ANY_ID, PCI_ANY_ID },
1342 	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066,
1343 		PCI_ANY_ID, PCI_ANY_ID },
1344 	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068,
1345 		PCI_ANY_ID, PCI_ANY_ID },
1346 	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064E,
1347 		PCI_ANY_ID, PCI_ANY_ID },
1348 	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066E,
1349 		PCI_ANY_ID, PCI_ANY_ID },
1350 	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068E,
1351 		PCI_ANY_ID, PCI_ANY_ID },
1352 	{0}	/* Terminating entry */
1353 };
1354 MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
1355 
1356 
1357 static struct pci_driver mptsas_driver = {
1358 	.name		= "mptsas",
1359 	.id_table	= mptsas_pci_table,
1360 	.probe		= mptsas_probe,
1361 	.remove		= __devexit_p(mptsas_remove),
1362 	.shutdown	= mptscsih_shutdown,
1363 #ifdef CONFIG_PM
1364 	.suspend	= mptscsih_suspend,
1365 	.resume		= mptscsih_resume,
1366 #endif
1367 };
1368 
1369 static int __init
1370 mptsas_init(void)
1371 {
1372 	show_mptmod_ver(my_NAME, my_VERSION);
1373 
1374 	mptsas_transport_template =
1375 	    sas_attach_transport(&mptsas_transport_functions);
1376 	if (!mptsas_transport_template)
1377 		return -ENODEV;
1378 
1379 	mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
1380 	mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER);
1381 	mptsasInternalCtx =
1382 		mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
1383 	mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
1384 
1385 	if (mpt_event_register(mptsasDoneCtx, mptscsih_event_process) == 0) {
1386 		devtprintk((KERN_INFO MYNAM
1387 		  ": Registered for IOC event notifications\n"));
1388 	}
1389 
1390 	if (mpt_reset_register(mptsasDoneCtx, mptscsih_ioc_reset) == 0) {
1391 		dprintk((KERN_INFO MYNAM
1392 		  ": Registered for IOC reset notifications\n"));
1393 	}
1394 
1395 	return pci_register_driver(&mptsas_driver);
1396 }
1397 
1398 static void __exit
1399 mptsas_exit(void)
1400 {
1401 	pci_unregister_driver(&mptsas_driver);
1402 	sas_release_transport(mptsas_transport_template);
1403 
1404 	mpt_reset_deregister(mptsasDoneCtx);
1405 	mpt_event_deregister(mptsasDoneCtx);
1406 
1407 	mpt_deregister(mptsasMgmtCtx);
1408 	mpt_deregister(mptsasInternalCtx);
1409 	mpt_deregister(mptsasTaskCtx);
1410 	mpt_deregister(mptsasDoneCtx);
1411 }
1412 
1413 module_init(mptsas_init);
1414 module_exit(mptsas_exit);
1415