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