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