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.
6 * Copyright (c) 1999-2005 LSI Logic Corporation
7 * (mailto:mpt_linux_developer@lsil.com)
8 * Copyright (c) 2005-2006 Dell
10 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
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.
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.
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.
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
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
45 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
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>
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>
63 #define my_NAME "Fusion MPT SAS Host driver"
64 #define my_VERSION MPT_LINUX_VERSION_COMMON
65 #define MYNAM "mptsas"
67 MODULE_AUTHOR(MODULEAUTHOR
);
68 MODULE_DESCRIPTION(my_NAME
);
69 MODULE_LICENSE("GPL");
71 static int mpt_pq_filter
;
72 module_param(mpt_pq_filter
, int, 0);
73 MODULE_PARM_DESC(mpt_pq_filter
,
74 "Enable peripheral qualifier filter: enable=1 "
77 static int mpt_pt_clear
;
78 module_param(mpt_pt_clear
, int, 0);
79 MODULE_PARM_DESC(mpt_pt_clear
,
80 "Clear persistency table: enable=1 "
81 "(default=MPTSCSIH_PT_CLEAR=0)");
83 static int mptsasDoneCtx
= -1;
84 static int mptsasTaskCtx
= -1;
85 static int mptsasInternalCtx
= -1; /* Used only for internal commands */
86 static int mptsasMgmtCtx
= -1;
89 enum mptsas_hotplug_action
{
94 struct mptsas_hotplug_event
{
95 struct work_struct work
;
97 enum mptsas_hotplug_action event_type
;
108 * SAS topology structures
110 * The MPT Fusion firmware interface spreads information about the
111 * SAS topology over many manufacture pages, thus we need some data
112 * structure to collect it and process it for the SAS transport class.
115 struct mptsas_devinfo
{
116 u16 handle
; /* unique id to address this device */
117 u8 phy_id
; /* phy number of parent device */
118 u8 port_id
; /* sas physical port this device
120 u8 id
; /* logical target id of this device */
121 u8 channel
; /* logical bus number of this device */
122 u64 sas_address
; /* WWN of this device,
123 SATA is assigned by HBA,expander */
124 u32 device_info
; /* bitfield detailed info about this device */
127 struct mptsas_phyinfo
{
128 u8 phy_id
; /* phy index */
129 u8 port_id
; /* port number this phy is part of */
130 u8 negotiated_link_rate
; /* nego'd link rate for this phy */
131 u8 hw_link_rate
; /* hardware max/min phys link rate */
132 u8 programmed_link_rate
; /* programmed max/min phy link rate */
133 struct mptsas_devinfo identify
; /* point to phy device info */
134 struct mptsas_devinfo attached
; /* point to attached device info */
136 struct sas_rphy
*rphy
;
139 struct mptsas_portinfo
{
140 struct list_head list
;
141 u16 handle
; /* unique id to address this */
142 u8 num_phys
; /* number of phys */
143 struct mptsas_phyinfo
*phy_info
;
148 static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA
*phy_data
)
150 printk("---- IO UNIT PAGE 0 ------------\n");
151 printk("Handle=0x%X\n",
152 le16_to_cpu(phy_data
->AttachedDeviceHandle
));
153 printk("Controller Handle=0x%X\n",
154 le16_to_cpu(phy_data
->ControllerDevHandle
));
155 printk("Port=0x%X\n", phy_data
->Port
);
156 printk("Port Flags=0x%X\n", phy_data
->PortFlags
);
157 printk("PHY Flags=0x%X\n", phy_data
->PhyFlags
);
158 printk("Negotiated Link Rate=0x%X\n", phy_data
->NegotiatedLinkRate
);
159 printk("Controller PHY Device Info=0x%X\n",
160 le32_to_cpu(phy_data
->ControllerPhyDeviceInfo
));
161 printk("DiscoveryStatus=0x%X\n",
162 le32_to_cpu(phy_data
->DiscoveryStatus
));
166 static void mptsas_print_phy_pg0(SasPhyPage0_t
*pg0
)
170 memcpy(&sas_address
, &pg0
->SASAddress
, sizeof(__le64
));
172 printk("---- SAS PHY PAGE 0 ------------\n");
173 printk("Attached Device Handle=0x%X\n",
174 le16_to_cpu(pg0
->AttachedDevHandle
));
175 printk("SAS Address=0x%llX\n",
176 (unsigned long long)le64_to_cpu(sas_address
));
177 printk("Attached PHY Identifier=0x%X\n", pg0
->AttachedPhyIdentifier
);
178 printk("Attached Device Info=0x%X\n",
179 le32_to_cpu(pg0
->AttachedDeviceInfo
));
180 printk("Programmed Link Rate=0x%X\n", pg0
->ProgrammedLinkRate
);
181 printk("Change Count=0x%X\n", pg0
->ChangeCount
);
182 printk("PHY Info=0x%X\n", le32_to_cpu(pg0
->PhyInfo
));
186 static void mptsas_print_phy_pg1(SasPhyPage1_t
*pg1
)
188 printk("---- SAS PHY PAGE 1 ------------\n");
189 printk("Invalid Dword Count=0x%x\n", pg1
->InvalidDwordCount
);
190 printk("Running Disparity Error Count=0x%x\n",
191 pg1
->RunningDisparityErrorCount
);
192 printk("Loss Dword Synch Count=0x%x\n", pg1
->LossDwordSynchCount
);
193 printk("PHY Reset Problem Count=0x%x\n", pg1
->PhyResetProblemCount
);
197 static void mptsas_print_device_pg0(SasDevicePage0_t
*pg0
)
201 memcpy(&sas_address
, &pg0
->SASAddress
, sizeof(__le64
));
203 printk("---- SAS DEVICE PAGE 0 ---------\n");
204 printk("Handle=0x%X\n" ,le16_to_cpu(pg0
->DevHandle
));
205 printk("Enclosure Handle=0x%X\n", le16_to_cpu(pg0
->EnclosureHandle
));
206 printk("Slot=0x%X\n", le16_to_cpu(pg0
->Slot
));
207 printk("SAS Address=0x%llX\n", le64_to_cpu(sas_address
));
208 printk("Target ID=0x%X\n", pg0
->TargetID
);
209 printk("Bus=0x%X\n", pg0
->Bus
);
210 /* The PhyNum field specifies the PHY number of the parent
211 * device this device is linked to
213 printk("Parent Phy Num=0x%X\n", pg0
->PhyNum
);
214 printk("Access Status=0x%X\n", le16_to_cpu(pg0
->AccessStatus
));
215 printk("Device Info=0x%X\n", le32_to_cpu(pg0
->DeviceInfo
));
216 printk("Flags=0x%X\n", le16_to_cpu(pg0
->Flags
));
217 printk("Physical Port=0x%X\n", pg0
->PhysicalPort
);
221 static void mptsas_print_expander_pg1(SasExpanderPage1_t
*pg1
)
223 printk("---- SAS EXPANDER PAGE 1 ------------\n");
225 printk("Physical Port=0x%X\n", pg1
->PhysicalPort
);
226 printk("PHY Identifier=0x%X\n", pg1
->PhyIdentifier
);
227 printk("Negotiated Link Rate=0x%X\n", pg1
->NegotiatedLinkRate
);
228 printk("Programmed Link Rate=0x%X\n", pg1
->ProgrammedLinkRate
);
229 printk("Hardware Link Rate=0x%X\n", pg1
->HwLinkRate
);
230 printk("Owner Device Handle=0x%X\n",
231 le16_to_cpu(pg1
->OwnerDevHandle
));
232 printk("Attached Device Handle=0x%X\n",
233 le16_to_cpu(pg1
->AttachedDevHandle
));
236 #define mptsas_print_phy_data(phy_data) do { } while (0)
237 #define mptsas_print_phy_pg0(pg0) do { } while (0)
238 #define mptsas_print_phy_pg1(pg1) do { } while (0)
239 #define mptsas_print_device_pg0(pg0) do { } while (0)
240 #define mptsas_print_expander_pg1(pg1) do { } while (0)
245 * This is pretty ugly. We will be able to seriously clean it up
246 * once the DV code in mptscsih goes away and we can properly
247 * implement ->target_alloc.
250 mptsas_slave_alloc(struct scsi_device
*sdev
)
252 struct Scsi_Host
*host
= sdev
->host
;
253 MPT_SCSI_HOST
*hd
= (MPT_SCSI_HOST
*)host
->hostdata
;
254 struct sas_rphy
*rphy
;
255 struct mptsas_portinfo
*p
;
258 struct scsi_target
*starget
;
261 vdev
= kmalloc(sizeof(VirtDevice
), GFP_KERNEL
);
263 printk(MYIOC_s_ERR_FMT
"slave_alloc kmalloc(%zd) FAILED!\n",
264 hd
->ioc
->name
, sizeof(VirtDevice
));
267 memset(vdev
, 0, sizeof(VirtDevice
));
268 vdev
->ioc_id
= hd
->ioc
->id
;
269 sdev
->hostdata
= vdev
;
270 starget
= scsi_target(sdev
);
271 vtarget
= starget
->hostdata
;
272 vdev
->vtarget
= vtarget
;
273 if (vtarget
->num_luns
== 0) {
274 vtarget
->tflags
= MPT_TARGET_FLAGS_Q_YES
|MPT_TARGET_FLAGS_VALID_INQUIRY
;
275 hd
->Targets
[sdev
->id
] = vtarget
;
278 rphy
= dev_to_rphy(sdev
->sdev_target
->dev
.parent
);
279 mutex_lock(&hd
->ioc
->sas_topology_mutex
);
280 list_for_each_entry(p
, &hd
->ioc
->sas_topology
, list
) {
281 for (i
= 0; i
< p
->num_phys
; i
++) {
282 if (p
->phy_info
[i
].attached
.sas_address
==
283 rphy
->identify
.sas_address
) {
285 p
->phy_info
[i
].attached
.id
;
286 vdev
->bus_id
= p
->phy_info
[i
].attached
.channel
;
287 vdev
->lun
= sdev
->lun
;
292 mutex_unlock(&hd
->ioc
->sas_topology_mutex
);
294 printk("No matching SAS device found!!\n");
299 mutex_unlock(&hd
->ioc
->sas_topology_mutex
);
300 vtarget
->ioc_id
= vdev
->ioc_id
;
301 vtarget
->target_id
= vdev
->target_id
;
302 vtarget
->bus_id
= vdev
->bus_id
;
308 mptsas_slave_destroy(struct scsi_device
*sdev
)
310 struct Scsi_Host
*host
= sdev
->host
;
311 MPT_SCSI_HOST
*hd
= (MPT_SCSI_HOST
*)host
->hostdata
;
312 struct sas_rphy
*rphy
;
313 struct mptsas_portinfo
*p
;
317 * Handle hotplug removal case.
318 * We need to clear out attached data structure.
320 rphy
= dev_to_rphy(sdev
->sdev_target
->dev
.parent
);
322 mutex_lock(&hd
->ioc
->sas_topology_mutex
);
323 list_for_each_entry(p
, &hd
->ioc
->sas_topology
, list
) {
324 for (i
= 0; i
< p
->num_phys
; i
++) {
325 if (p
->phy_info
[i
].attached
.sas_address
==
326 rphy
->identify
.sas_address
) {
327 memset(&p
->phy_info
[i
].attached
, 0,
328 sizeof(struct mptsas_devinfo
));
329 p
->phy_info
[i
].rphy
= NULL
;
336 mutex_unlock(&hd
->ioc
->sas_topology_mutex
);
338 * TODO: Issue target reset to flush firmware outstanding commands.
340 mptscsih_slave_destroy(sdev
);
343 static struct scsi_host_template mptsas_driver_template
= {
344 .module
= THIS_MODULE
,
345 .proc_name
= "mptsas",
346 .proc_info
= mptscsih_proc_info
,
347 .name
= "MPT SPI Host",
348 .info
= mptscsih_info
,
349 .queuecommand
= mptscsih_qcmd
,
350 .target_alloc
= mptscsih_target_alloc
,
351 .slave_alloc
= mptsas_slave_alloc
,
352 .slave_configure
= mptscsih_slave_configure
,
353 .target_destroy
= mptscsih_target_destroy
,
354 .slave_destroy
= mptsas_slave_destroy
,
355 .change_queue_depth
= mptscsih_change_queue_depth
,
356 .eh_abort_handler
= mptscsih_abort
,
357 .eh_device_reset_handler
= mptscsih_dev_reset
,
358 .eh_bus_reset_handler
= mptscsih_bus_reset
,
359 .eh_host_reset_handler
= mptscsih_host_reset
,
360 .bios_param
= mptscsih_bios_param
,
361 .can_queue
= MPT_FC_CAN_QUEUE
,
363 .sg_tablesize
= MPT_SCSI_SG_DEPTH
,
366 .use_clustering
= ENABLE_CLUSTERING
,
369 static inline MPT_ADAPTER
*phy_to_ioc(struct sas_phy
*phy
)
371 struct Scsi_Host
*shost
= dev_to_shost(phy
->dev
.parent
);
372 return ((MPT_SCSI_HOST
*)shost
->hostdata
)->ioc
;
375 static int mptsas_get_linkerrors(struct sas_phy
*phy
)
377 MPT_ADAPTER
*ioc
= phy_to_ioc(phy
);
378 ConfigExtendedPageHeader_t hdr
;
380 SasPhyPage1_t
*buffer
;
381 dma_addr_t dma_handle
;
384 hdr
.PageVersion
= MPI_SASPHY1_PAGEVERSION
;
385 hdr
.ExtPageLength
= 0;
386 hdr
.PageNumber
= 1 /* page number 1*/;
389 hdr
.PageType
= MPI_CONFIG_PAGETYPE_EXTENDED
;
390 hdr
.ExtPageType
= MPI_CONFIG_EXTPAGETYPE_SAS_PHY
;
392 cfg
.cfghdr
.ehdr
= &hdr
;
394 cfg
.pageAddr
= phy
->identify
.phy_identifier
;
395 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
396 cfg
.dir
= 0; /* read */
399 error
= mpt_config(ioc
, &cfg
);
402 if (!hdr
.ExtPageLength
)
405 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.ExtPageLength
* 4,
410 cfg
.physAddr
= dma_handle
;
411 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
413 error
= mpt_config(ioc
, &cfg
);
415 goto out_free_consistent
;
417 mptsas_print_phy_pg1(buffer
);
419 phy
->invalid_dword_count
= le32_to_cpu(buffer
->InvalidDwordCount
);
420 phy
->running_disparity_error_count
=
421 le32_to_cpu(buffer
->RunningDisparityErrorCount
);
422 phy
->loss_of_dword_sync_count
=
423 le32_to_cpu(buffer
->LossDwordSynchCount
);
424 phy
->phy_reset_problem_count
=
425 le32_to_cpu(buffer
->PhyResetProblemCount
);
428 pci_free_consistent(ioc
->pcidev
, hdr
.ExtPageLength
* 4,
433 static int mptsas_mgmt_done(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*req
,
434 MPT_FRAME_HDR
*reply
)
436 ioc
->sas_mgmt
.status
|= MPT_SAS_MGMT_STATUS_COMMAND_GOOD
;
438 ioc
->sas_mgmt
.status
|= MPT_SAS_MGMT_STATUS_RF_VALID
;
439 memcpy(ioc
->sas_mgmt
.reply
, reply
,
440 min(ioc
->reply_sz
, 4 * reply
->u
.reply
.MsgLength
));
442 complete(&ioc
->sas_mgmt
.done
);
446 static int mptsas_phy_reset(struct sas_phy
*phy
, int hard_reset
)
448 MPT_ADAPTER
*ioc
= phy_to_ioc(phy
);
449 SasIoUnitControlRequest_t
*req
;
450 SasIoUnitControlReply_t
*reply
;
453 unsigned long timeleft
;
454 int error
= -ERESTARTSYS
;
456 /* not implemented for expanders */
457 if (phy
->identify
.target_port_protocols
& SAS_PROTOCOL_SMP
)
460 if (mutex_lock_interruptible(&ioc
->sas_mgmt
.mutex
))
463 mf
= mpt_get_msg_frame(mptsasMgmtCtx
, ioc
);
469 hdr
= (MPIHeader_t
*) mf
;
470 req
= (SasIoUnitControlRequest_t
*)mf
;
471 memset(req
, 0, sizeof(SasIoUnitControlRequest_t
));
472 req
->Function
= MPI_FUNCTION_SAS_IO_UNIT_CONTROL
;
473 req
->MsgContext
= hdr
->MsgContext
;
474 req
->Operation
= hard_reset
?
475 MPI_SAS_OP_PHY_HARD_RESET
: MPI_SAS_OP_PHY_LINK_RESET
;
476 req
->PhyNum
= phy
->identify
.phy_identifier
;
478 mpt_put_msg_frame(mptsasMgmtCtx
, ioc
, mf
);
480 timeleft
= wait_for_completion_timeout(&ioc
->sas_mgmt
.done
,
483 /* On timeout reset the board */
484 mpt_free_msg_frame(ioc
, mf
);
485 mpt_HardResetHandler(ioc
, CAN_SLEEP
);
490 /* a reply frame is expected */
491 if ((ioc
->sas_mgmt
.status
&
492 MPT_IOCTL_STATUS_RF_VALID
) == 0) {
497 /* process the completed Reply Message Frame */
498 reply
= (SasIoUnitControlReply_t
*)ioc
->sas_mgmt
.reply
;
499 if (reply
->IOCStatus
!= MPI_IOCSTATUS_SUCCESS
) {
500 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
511 mutex_unlock(&ioc
->sas_mgmt
.mutex
);
516 static struct sas_function_template mptsas_transport_functions
= {
517 .get_linkerrors
= mptsas_get_linkerrors
,
518 .phy_reset
= mptsas_phy_reset
,
521 static struct scsi_transport_template
*mptsas_transport_template
;
524 mptsas_sas_io_unit_pg0(MPT_ADAPTER
*ioc
, struct mptsas_portinfo
*port_info
)
526 ConfigExtendedPageHeader_t hdr
;
528 SasIOUnitPage0_t
*buffer
;
529 dma_addr_t dma_handle
;
532 hdr
.PageVersion
= MPI_SASIOUNITPAGE0_PAGEVERSION
;
533 hdr
.ExtPageLength
= 0;
537 hdr
.PageType
= MPI_CONFIG_PAGETYPE_EXTENDED
;
538 hdr
.ExtPageType
= MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT
;
540 cfg
.cfghdr
.ehdr
= &hdr
;
543 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
544 cfg
.dir
= 0; /* read */
547 error
= mpt_config(ioc
, &cfg
);
550 if (!hdr
.ExtPageLength
) {
555 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.ExtPageLength
* 4,
562 cfg
.physAddr
= dma_handle
;
563 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
565 error
= mpt_config(ioc
, &cfg
);
567 goto out_free_consistent
;
569 port_info
->num_phys
= buffer
->NumPhys
;
570 port_info
->phy_info
= kcalloc(port_info
->num_phys
,
571 sizeof(struct mptsas_phyinfo
),GFP_KERNEL
);
572 if (!port_info
->phy_info
) {
574 goto out_free_consistent
;
577 for (i
= 0; i
< port_info
->num_phys
; i
++) {
578 mptsas_print_phy_data(&buffer
->PhyData
[i
]);
579 port_info
->phy_info
[i
].phy_id
= i
;
580 port_info
->phy_info
[i
].port_id
=
581 buffer
->PhyData
[i
].Port
;
582 port_info
->phy_info
[i
].negotiated_link_rate
=
583 buffer
->PhyData
[i
].NegotiatedLinkRate
;
587 pci_free_consistent(ioc
->pcidev
, hdr
.ExtPageLength
* 4,
594 mptsas_sas_phy_pg0(MPT_ADAPTER
*ioc
, struct mptsas_phyinfo
*phy_info
,
595 u32 form
, u32 form_specific
)
597 ConfigExtendedPageHeader_t hdr
;
599 SasPhyPage0_t
*buffer
;
600 dma_addr_t dma_handle
;
603 hdr
.PageVersion
= MPI_SASPHY0_PAGEVERSION
;
604 hdr
.ExtPageLength
= 0;
608 hdr
.PageType
= MPI_CONFIG_PAGETYPE_EXTENDED
;
609 hdr
.ExtPageType
= MPI_CONFIG_EXTPAGETYPE_SAS_PHY
;
611 cfg
.cfghdr
.ehdr
= &hdr
;
612 cfg
.dir
= 0; /* read */
615 /* Get Phy Pg 0 for each Phy. */
617 cfg
.pageAddr
= form
+ form_specific
;
618 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
620 error
= mpt_config(ioc
, &cfg
);
624 if (!hdr
.ExtPageLength
) {
629 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.ExtPageLength
* 4,
636 cfg
.physAddr
= dma_handle
;
637 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
639 error
= mpt_config(ioc
, &cfg
);
641 goto out_free_consistent
;
643 mptsas_print_phy_pg0(buffer
);
645 phy_info
->hw_link_rate
= buffer
->HwLinkRate
;
646 phy_info
->programmed_link_rate
= buffer
->ProgrammedLinkRate
;
647 phy_info
->identify
.handle
= le16_to_cpu(buffer
->OwnerDevHandle
);
648 phy_info
->attached
.handle
= le16_to_cpu(buffer
->AttachedDevHandle
);
651 pci_free_consistent(ioc
->pcidev
, hdr
.ExtPageLength
* 4,
658 mptsas_sas_device_pg0(MPT_ADAPTER
*ioc
, struct mptsas_devinfo
*device_info
,
659 u32 form
, u32 form_specific
)
661 ConfigExtendedPageHeader_t hdr
;
663 SasDevicePage0_t
*buffer
;
664 dma_addr_t dma_handle
;
668 hdr
.PageVersion
= MPI_SASDEVICE0_PAGEVERSION
;
669 hdr
.ExtPageLength
= 0;
673 hdr
.PageType
= MPI_CONFIG_PAGETYPE_EXTENDED
;
674 hdr
.ExtPageType
= MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE
;
676 cfg
.cfghdr
.ehdr
= &hdr
;
677 cfg
.pageAddr
= form
+ form_specific
;
679 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
680 cfg
.dir
= 0; /* read */
683 error
= mpt_config(ioc
, &cfg
);
686 if (!hdr
.ExtPageLength
) {
691 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.ExtPageLength
* 4,
698 cfg
.physAddr
= dma_handle
;
699 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
701 error
= mpt_config(ioc
, &cfg
);
703 goto out_free_consistent
;
705 mptsas_print_device_pg0(buffer
);
707 device_info
->handle
= le16_to_cpu(buffer
->DevHandle
);
708 device_info
->phy_id
= buffer
->PhyNum
;
709 device_info
->port_id
= buffer
->PhysicalPort
;
710 device_info
->id
= buffer
->TargetID
;
711 device_info
->channel
= buffer
->Bus
;
712 memcpy(&sas_address
, &buffer
->SASAddress
, sizeof(__le64
));
713 device_info
->sas_address
= le64_to_cpu(sas_address
);
714 device_info
->device_info
=
715 le32_to_cpu(buffer
->DeviceInfo
);
718 pci_free_consistent(ioc
->pcidev
, hdr
.ExtPageLength
* 4,
725 mptsas_sas_expander_pg0(MPT_ADAPTER
*ioc
, struct mptsas_portinfo
*port_info
,
726 u32 form
, u32 form_specific
)
728 ConfigExtendedPageHeader_t hdr
;
730 SasExpanderPage0_t
*buffer
;
731 dma_addr_t dma_handle
;
734 hdr
.PageVersion
= MPI_SASEXPANDER0_PAGEVERSION
;
735 hdr
.ExtPageLength
= 0;
739 hdr
.PageType
= MPI_CONFIG_PAGETYPE_EXTENDED
;
740 hdr
.ExtPageType
= MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER
;
742 cfg
.cfghdr
.ehdr
= &hdr
;
744 cfg
.pageAddr
= form
+ form_specific
;
745 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
746 cfg
.dir
= 0; /* read */
749 error
= mpt_config(ioc
, &cfg
);
753 if (!hdr
.ExtPageLength
) {
758 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.ExtPageLength
* 4,
765 cfg
.physAddr
= dma_handle
;
766 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
768 error
= mpt_config(ioc
, &cfg
);
770 goto out_free_consistent
;
772 /* save config data */
773 port_info
->num_phys
= buffer
->NumPhys
;
774 port_info
->handle
= le16_to_cpu(buffer
->DevHandle
);
775 port_info
->phy_info
= kcalloc(port_info
->num_phys
,
776 sizeof(struct mptsas_phyinfo
),GFP_KERNEL
);
777 if (!port_info
->phy_info
) {
779 goto out_free_consistent
;
783 pci_free_consistent(ioc
->pcidev
, hdr
.ExtPageLength
* 4,
790 mptsas_sas_expander_pg1(MPT_ADAPTER
*ioc
, struct mptsas_phyinfo
*phy_info
,
791 u32 form
, u32 form_specific
)
793 ConfigExtendedPageHeader_t hdr
;
795 SasExpanderPage1_t
*buffer
;
796 dma_addr_t dma_handle
;
799 hdr
.PageVersion
= MPI_SASEXPANDER0_PAGEVERSION
;
800 hdr
.ExtPageLength
= 0;
804 hdr
.PageType
= MPI_CONFIG_PAGETYPE_EXTENDED
;
805 hdr
.ExtPageType
= MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER
;
807 cfg
.cfghdr
.ehdr
= &hdr
;
809 cfg
.pageAddr
= form
+ form_specific
;
810 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
811 cfg
.dir
= 0; /* read */
814 error
= mpt_config(ioc
, &cfg
);
818 if (!hdr
.ExtPageLength
) {
823 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.ExtPageLength
* 4,
830 cfg
.physAddr
= dma_handle
;
831 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
833 error
= mpt_config(ioc
, &cfg
);
835 goto out_free_consistent
;
838 mptsas_print_expander_pg1(buffer
);
840 /* save config data */
841 phy_info
->phy_id
= buffer
->PhyIdentifier
;
842 phy_info
->port_id
= buffer
->PhysicalPort
;
843 phy_info
->negotiated_link_rate
= buffer
->NegotiatedLinkRate
;
844 phy_info
->programmed_link_rate
= buffer
->ProgrammedLinkRate
;
845 phy_info
->hw_link_rate
= buffer
->HwLinkRate
;
846 phy_info
->identify
.handle
= le16_to_cpu(buffer
->OwnerDevHandle
);
847 phy_info
->attached
.handle
= le16_to_cpu(buffer
->AttachedDevHandle
);
851 pci_free_consistent(ioc
->pcidev
, hdr
.ExtPageLength
* 4,
858 mptsas_parse_device_info(struct sas_identify
*identify
,
859 struct mptsas_devinfo
*device_info
)
863 identify
->sas_address
= device_info
->sas_address
;
864 identify
->phy_identifier
= device_info
->phy_id
;
867 * Fill in Phy Initiator Port Protocol.
868 * Bits 6:3, more than one bit can be set, fall through cases.
870 protocols
= device_info
->device_info
& 0x78;
871 identify
->initiator_port_protocols
= 0;
872 if (protocols
& MPI_SAS_DEVICE_INFO_SSP_INITIATOR
)
873 identify
->initiator_port_protocols
|= SAS_PROTOCOL_SSP
;
874 if (protocols
& MPI_SAS_DEVICE_INFO_STP_INITIATOR
)
875 identify
->initiator_port_protocols
|= SAS_PROTOCOL_STP
;
876 if (protocols
& MPI_SAS_DEVICE_INFO_SMP_INITIATOR
)
877 identify
->initiator_port_protocols
|= SAS_PROTOCOL_SMP
;
878 if (protocols
& MPI_SAS_DEVICE_INFO_SATA_HOST
)
879 identify
->initiator_port_protocols
|= SAS_PROTOCOL_SATA
;
882 * Fill in Phy Target Port Protocol.
883 * Bits 10:7, more than one bit can be set, fall through cases.
885 protocols
= device_info
->device_info
& 0x780;
886 identify
->target_port_protocols
= 0;
887 if (protocols
& MPI_SAS_DEVICE_INFO_SSP_TARGET
)
888 identify
->target_port_protocols
|= SAS_PROTOCOL_SSP
;
889 if (protocols
& MPI_SAS_DEVICE_INFO_STP_TARGET
)
890 identify
->target_port_protocols
|= SAS_PROTOCOL_STP
;
891 if (protocols
& MPI_SAS_DEVICE_INFO_SMP_TARGET
)
892 identify
->target_port_protocols
|= SAS_PROTOCOL_SMP
;
893 if (protocols
& MPI_SAS_DEVICE_INFO_SATA_DEVICE
)
894 identify
->target_port_protocols
|= SAS_PROTOCOL_SATA
;
897 * Fill in Attached device type.
899 switch (device_info
->device_info
&
900 MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE
) {
901 case MPI_SAS_DEVICE_INFO_NO_DEVICE
:
902 identify
->device_type
= SAS_PHY_UNUSED
;
904 case MPI_SAS_DEVICE_INFO_END_DEVICE
:
905 identify
->device_type
= SAS_END_DEVICE
;
907 case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER
:
908 identify
->device_type
= SAS_EDGE_EXPANDER_DEVICE
;
910 case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER
:
911 identify
->device_type
= SAS_FANOUT_EXPANDER_DEVICE
;
916 static int mptsas_probe_one_phy(struct device
*dev
,
917 struct mptsas_phyinfo
*phy_info
, int index
, int local
)
922 phy
= sas_phy_alloc(dev
, index
);
926 phy
->port_identifier
= phy_info
->port_id
;
927 mptsas_parse_device_info(&phy
->identify
, &phy_info
->identify
);
930 * Set Negotiated link rate.
932 switch (phy_info
->negotiated_link_rate
) {
933 case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED
:
934 phy
->negotiated_linkrate
= SAS_PHY_DISABLED
;
936 case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION
:
937 phy
->negotiated_linkrate
= SAS_LINK_RATE_FAILED
;
939 case MPI_SAS_IOUNIT0_RATE_1_5
:
940 phy
->negotiated_linkrate
= SAS_LINK_RATE_1_5_GBPS
;
942 case MPI_SAS_IOUNIT0_RATE_3_0
:
943 phy
->negotiated_linkrate
= SAS_LINK_RATE_3_0_GBPS
;
945 case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE
:
946 case MPI_SAS_IOUNIT0_RATE_UNKNOWN
:
948 phy
->negotiated_linkrate
= SAS_LINK_RATE_UNKNOWN
;
953 * Set Max hardware link rate.
955 switch (phy_info
->hw_link_rate
& MPI_SAS_PHY0_PRATE_MAX_RATE_MASK
) {
956 case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5
:
957 phy
->maximum_linkrate_hw
= SAS_LINK_RATE_1_5_GBPS
;
959 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0
:
960 phy
->maximum_linkrate_hw
= SAS_LINK_RATE_3_0_GBPS
;
967 * Set Max programmed link rate.
969 switch (phy_info
->programmed_link_rate
&
970 MPI_SAS_PHY0_PRATE_MAX_RATE_MASK
) {
971 case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5
:
972 phy
->maximum_linkrate
= SAS_LINK_RATE_1_5_GBPS
;
974 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0
:
975 phy
->maximum_linkrate
= SAS_LINK_RATE_3_0_GBPS
;
982 * Set Min hardware link rate.
984 switch (phy_info
->hw_link_rate
& MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK
) {
985 case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5
:
986 phy
->minimum_linkrate_hw
= SAS_LINK_RATE_1_5_GBPS
;
988 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0
:
989 phy
->minimum_linkrate_hw
= SAS_LINK_RATE_3_0_GBPS
;
996 * Set Min programmed link rate.
998 switch (phy_info
->programmed_link_rate
&
999 MPI_SAS_PHY0_PRATE_MIN_RATE_MASK
) {
1000 case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5
:
1001 phy
->minimum_linkrate
= SAS_LINK_RATE_1_5_GBPS
;
1003 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0
:
1004 phy
->minimum_linkrate
= SAS_LINK_RATE_3_0_GBPS
;
1011 phy
->local_attached
= 1;
1013 error
= sas_phy_add(phy
);
1018 phy_info
->phy
= phy
;
1020 if (phy_info
->attached
.handle
) {
1021 struct sas_rphy
*rphy
;
1023 rphy
= sas_rphy_alloc(phy
);
1025 return 0; /* non-fatal: an rphy can be added later */
1027 mptsas_parse_device_info(&rphy
->identify
, &phy_info
->attached
);
1028 error
= sas_rphy_add(rphy
);
1030 sas_rphy_free(rphy
);
1034 phy_info
->rphy
= rphy
;
1041 mptsas_probe_hba_phys(MPT_ADAPTER
*ioc
, int *index
)
1043 struct mptsas_portinfo
*port_info
;
1044 u32 handle
= 0xFFFF;
1045 int error
= -ENOMEM
, i
;
1047 port_info
= kmalloc(sizeof(*port_info
), GFP_KERNEL
);
1050 memset(port_info
, 0, sizeof(*port_info
));
1052 error
= mptsas_sas_io_unit_pg0(ioc
, port_info
);
1054 goto out_free_port_info
;
1056 mutex_lock(&ioc
->sas_topology_mutex
);
1057 list_add_tail(&port_info
->list
, &ioc
->sas_topology
);
1058 mutex_unlock(&ioc
->sas_topology_mutex
);
1060 for (i
= 0; i
< port_info
->num_phys
; i
++) {
1061 mptsas_sas_phy_pg0(ioc
, &port_info
->phy_info
[i
],
1062 (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER
<<
1063 MPI_SAS_PHY_PGAD_FORM_SHIFT
), i
);
1065 mptsas_sas_device_pg0(ioc
, &port_info
->phy_info
[i
].identify
,
1066 (MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE
<<
1067 MPI_SAS_DEVICE_PGAD_FORM_SHIFT
), handle
);
1068 port_info
->phy_info
[i
].identify
.phy_id
=
1069 port_info
->phy_info
[i
].phy_id
;
1070 handle
= port_info
->phy_info
[i
].identify
.handle
;
1072 if (port_info
->phy_info
[i
].attached
.handle
) {
1073 mptsas_sas_device_pg0(ioc
,
1074 &port_info
->phy_info
[i
].attached
,
1075 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE
<<
1076 MPI_SAS_DEVICE_PGAD_FORM_SHIFT
),
1077 port_info
->phy_info
[i
].attached
.handle
);
1080 mptsas_probe_one_phy(&ioc
->sh
->shost_gendev
,
1081 &port_info
->phy_info
[i
], *index
, 1);
1094 mptsas_probe_expander_phys(MPT_ADAPTER
*ioc
, u32
*handle
, int *index
)
1096 struct mptsas_portinfo
*port_info
, *p
;
1097 int error
= -ENOMEM
, i
, j
;
1099 port_info
= kmalloc(sizeof(*port_info
), GFP_KERNEL
);
1102 memset(port_info
, 0, sizeof(*port_info
));
1104 error
= mptsas_sas_expander_pg0(ioc
, port_info
,
1105 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE
<<
1106 MPI_SAS_EXPAND_PGAD_FORM_SHIFT
), *handle
);
1108 goto out_free_port_info
;
1110 *handle
= port_info
->handle
;
1112 mutex_lock(&ioc
->sas_topology_mutex
);
1113 list_add_tail(&port_info
->list
, &ioc
->sas_topology
);
1114 mutex_unlock(&ioc
->sas_topology_mutex
);
1116 for (i
= 0; i
< port_info
->num_phys
; i
++) {
1117 struct device
*parent
;
1119 mptsas_sas_expander_pg1(ioc
, &port_info
->phy_info
[i
],
1120 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM
<<
1121 MPI_SAS_EXPAND_PGAD_FORM_SHIFT
), (i
<< 16) + *handle
);
1123 if (port_info
->phy_info
[i
].identify
.handle
) {
1124 mptsas_sas_device_pg0(ioc
,
1125 &port_info
->phy_info
[i
].identify
,
1126 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE
<<
1127 MPI_SAS_DEVICE_PGAD_FORM_SHIFT
),
1128 port_info
->phy_info
[i
].identify
.handle
);
1129 port_info
->phy_info
[i
].identify
.phy_id
=
1130 port_info
->phy_info
[i
].phy_id
;
1133 if (port_info
->phy_info
[i
].attached
.handle
) {
1134 mptsas_sas_device_pg0(ioc
,
1135 &port_info
->phy_info
[i
].attached
,
1136 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE
<<
1137 MPI_SAS_DEVICE_PGAD_FORM_SHIFT
),
1138 port_info
->phy_info
[i
].attached
.handle
);
1142 * If we find a parent port handle this expander is
1143 * attached to another expander, else it hangs of the
1146 parent
= &ioc
->sh
->shost_gendev
;
1147 mutex_lock(&ioc
->sas_topology_mutex
);
1148 list_for_each_entry(p
, &ioc
->sas_topology
, list
) {
1149 for (j
= 0; j
< p
->num_phys
; j
++) {
1150 if (port_info
->phy_info
[i
].identify
.handle
==
1151 p
->phy_info
[j
].attached
.handle
)
1152 parent
= &p
->phy_info
[j
].rphy
->dev
;
1155 mutex_unlock(&ioc
->sas_topology_mutex
);
1157 mptsas_probe_one_phy(parent
, &port_info
->phy_info
[i
],
1171 mptsas_scan_sas_topology(MPT_ADAPTER
*ioc
)
1173 u32 handle
= 0xFFFF;
1176 mptsas_probe_hba_phys(ioc
, &index
);
1177 while (!mptsas_probe_expander_phys(ioc
, &handle
, &index
))
1181 static struct mptsas_phyinfo
*
1182 mptsas_find_phyinfo_by_parent(MPT_ADAPTER
*ioc
, u16 parent_handle
, u8 phy_id
)
1184 struct mptsas_portinfo
*port_info
;
1185 struct mptsas_devinfo device_info
;
1186 struct mptsas_phyinfo
*phy_info
= NULL
;
1190 * Retrieve the parent sas_address
1192 error
= mptsas_sas_device_pg0(ioc
, &device_info
,
1193 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE
<<
1194 MPI_SAS_DEVICE_PGAD_FORM_SHIFT
),
1197 printk("mptsas: failed to retrieve device page\n");
1202 * The phy_info structures are never deallocated during lifetime of
1203 * a host, so the code below is safe without additional refcounting.
1205 mutex_lock(&ioc
->sas_topology_mutex
);
1206 list_for_each_entry(port_info
, &ioc
->sas_topology
, list
) {
1207 for (i
= 0; i
< port_info
->num_phys
; i
++) {
1208 if (port_info
->phy_info
[i
].identify
.sas_address
==
1209 device_info
.sas_address
&&
1210 port_info
->phy_info
[i
].phy_id
== phy_id
) {
1211 phy_info
= &port_info
->phy_info
[i
];
1216 mutex_unlock(&ioc
->sas_topology_mutex
);
1221 static struct mptsas_phyinfo
*
1222 mptsas_find_phyinfo_by_handle(MPT_ADAPTER
*ioc
, u16 handle
)
1224 struct mptsas_portinfo
*port_info
;
1225 struct mptsas_phyinfo
*phy_info
= NULL
;
1229 * The phy_info structures are never deallocated during lifetime of
1230 * a host, so the code below is safe without additional refcounting.
1232 mutex_lock(&ioc
->sas_topology_mutex
);
1233 list_for_each_entry(port_info
, &ioc
->sas_topology
, list
) {
1234 for (i
= 0; i
< port_info
->num_phys
; i
++) {
1235 if (port_info
->phy_info
[i
].attached
.handle
== handle
) {
1236 phy_info
= &port_info
->phy_info
[i
];
1241 mutex_unlock(&ioc
->sas_topology_mutex
);
1247 mptsas_hotplug_work(void *arg
)
1249 struct mptsas_hotplug_event
*ev
= arg
;
1250 MPT_ADAPTER
*ioc
= ev
->ioc
;
1251 struct mptsas_phyinfo
*phy_info
;
1252 struct sas_rphy
*rphy
;
1255 if (ev
->device_info
& MPI_SAS_DEVICE_INFO_SSP_TARGET
)
1257 if (ev
->device_info
& MPI_SAS_DEVICE_INFO_STP_TARGET
)
1259 if (ev
->device_info
& MPI_SAS_DEVICE_INFO_SATA_DEVICE
)
1262 switch (ev
->event_type
) {
1263 case MPTSAS_DEL_DEVICE
:
1264 printk(MYIOC_s_INFO_FMT
1265 "removing %s device, channel %d, id %d, phy %d\n",
1266 ioc
->name
, ds
, ev
->channel
, ev
->id
, ev
->phy_id
);
1268 phy_info
= mptsas_find_phyinfo_by_handle(ioc
, ev
->handle
);
1270 printk("mptsas: remove event for non-existant PHY.\n");
1274 if (phy_info
->rphy
) {
1275 sas_rphy_delete(phy_info
->rphy
);
1276 phy_info
->rphy
= NULL
;
1279 case MPTSAS_ADD_DEVICE
:
1280 printk(MYIOC_s_INFO_FMT
1281 "attaching %s device, channel %d, id %d, phy %d\n",
1282 ioc
->name
, ds
, ev
->channel
, ev
->id
, ev
->phy_id
);
1284 phy_info
= mptsas_find_phyinfo_by_parent(ioc
,
1285 ev
->parent_handle
, ev
->phy_id
);
1287 printk("mptsas: add event for non-existant PHY.\n");
1291 if (phy_info
->rphy
) {
1292 printk("mptsas: trying to add existing device.\n");
1296 /* fill attached info */
1297 phy_info
->attached
.handle
= ev
->handle
;
1298 phy_info
->attached
.phy_id
= ev
->phy_id
;
1299 phy_info
->attached
.port_id
= phy_info
->identify
.port_id
;
1300 phy_info
->attached
.id
= ev
->id
;
1301 phy_info
->attached
.channel
= ev
->channel
;
1302 phy_info
->attached
.sas_address
= ev
->sas_address
;
1303 phy_info
->attached
.device_info
= ev
->device_info
;
1305 rphy
= sas_rphy_alloc(phy_info
->phy
);
1307 break; /* non-fatal: an rphy can be added later */
1309 mptsas_parse_device_info(&rphy
->identify
, &phy_info
->attached
);
1310 if (sas_rphy_add(rphy
)) {
1311 sas_rphy_free(rphy
);
1315 phy_info
->rphy
= rphy
;
1323 mptscsih_send_sas_event(MPT_ADAPTER
*ioc
,
1324 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE
*sas_event_data
)
1326 struct mptsas_hotplug_event
*ev
;
1327 u32 device_info
= le32_to_cpu(sas_event_data
->DeviceInfo
);
1331 (MPI_SAS_DEVICE_INFO_SSP_TARGET
|
1332 MPI_SAS_DEVICE_INFO_STP_TARGET
|
1333 MPI_SAS_DEVICE_INFO_SATA_DEVICE
)) == 0)
1336 if ((sas_event_data
->ReasonCode
&
1337 (MPI_EVENT_SAS_DEV_STAT_RC_ADDED
|
1338 MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING
)) == 0)
1341 ev
= kmalloc(sizeof(*ev
), GFP_ATOMIC
);
1343 printk(KERN_WARNING
"mptsas: lost hotplug event\n");
1348 INIT_WORK(&ev
->work
, mptsas_hotplug_work
, ev
);
1350 ev
->handle
= le16_to_cpu(sas_event_data
->DevHandle
);
1351 ev
->parent_handle
= le16_to_cpu(sas_event_data
->ParentDevHandle
);
1352 ev
->channel
= sas_event_data
->Bus
;
1353 ev
->id
= sas_event_data
->TargetID
;
1354 ev
->phy_id
= sas_event_data
->PhyNum
;
1355 memcpy(&sas_address
, &sas_event_data
->SASAddress
, sizeof(__le64
));
1356 ev
->sas_address
= le64_to_cpu(sas_address
);
1357 ev
->device_info
= device_info
;
1359 if (sas_event_data
->ReasonCode
& MPI_EVENT_SAS_DEV_STAT_RC_ADDED
)
1360 ev
->event_type
= MPTSAS_ADD_DEVICE
;
1362 ev
->event_type
= MPTSAS_DEL_DEVICE
;
1364 schedule_work(&ev
->work
);
1368 mptsas_event_process(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*reply
)
1370 u8 event
= le32_to_cpu(reply
->Event
) & 0xFF;
1376 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE
:
1377 mptscsih_send_sas_event(ioc
,
1378 (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE
*)reply
->Data
);
1379 return 1; /* currently means nothing really */
1382 return mptscsih_event_process(ioc
, reply
);
1387 mptsas_probe(struct pci_dev
*pdev
, const struct pci_device_id
*id
)
1389 struct Scsi_Host
*sh
;
1392 unsigned long flags
;
1401 r
= mpt_attach(pdev
,id
);
1405 ioc
= pci_get_drvdata(pdev
);
1406 ioc
->DoneCtx
= mptsasDoneCtx
;
1407 ioc
->TaskCtx
= mptsasTaskCtx
;
1408 ioc
->InternalCtx
= mptsasInternalCtx
;
1410 /* Added sanity check on readiness of the MPT adapter.
1412 if (ioc
->last_state
!= MPI_IOC_STATE_OPERATIONAL
) {
1413 printk(MYIOC_s_WARN_FMT
1414 "Skipping because it's not operational!\n",
1417 goto out_mptsas_probe
;
1421 printk(MYIOC_s_WARN_FMT
"Skipping because it's disabled!\n",
1424 goto out_mptsas_probe
;
1427 /* Sanity check - ensure at least 1 port is INITIATOR capable
1430 for (ii
= 0; ii
< ioc
->facts
.NumberOfPorts
; ii
++) {
1431 if (ioc
->pfacts
[ii
].ProtocolFlags
&
1432 MPI_PORTFACTS_PROTOCOL_INITIATOR
)
1437 printk(MYIOC_s_WARN_FMT
1438 "Skipping ioc=%p because SCSI Initiator mode "
1439 "is NOT enabled!\n", ioc
->name
, ioc
);
1443 sh
= scsi_host_alloc(&mptsas_driver_template
, sizeof(MPT_SCSI_HOST
));
1445 printk(MYIOC_s_WARN_FMT
1446 "Unable to register controller with SCSI subsystem\n",
1449 goto out_mptsas_probe
;
1452 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
1454 /* Attach the SCSI Host to the IOC structure
1462 /* set 16 byte cdb's */
1463 sh
->max_cmd_len
= 16;
1465 sh
->max_id
= ioc
->pfacts
->MaxDevices
+ 1;
1467 sh
->transportt
= mptsas_transport_template
;
1469 sh
->max_lun
= MPT_LAST_LUN
+ 1;
1470 sh
->max_channel
= 0;
1471 sh
->this_id
= ioc
->pfacts
[0].PortSCSIID
;
1475 sh
->unique_id
= ioc
->id
;
1477 INIT_LIST_HEAD(&ioc
->sas_topology
);
1478 mutex_init(&ioc
->sas_topology_mutex
);
1480 mutex_init(&ioc
->sas_mgmt
.mutex
);
1481 init_completion(&ioc
->sas_mgmt
.done
);
1483 /* Verify that we won't exceed the maximum
1484 * number of chain buffers
1485 * We can optimize: ZZ = req_sz/sizeof(SGE)
1487 * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
1488 * + (req_sz - 64)/sizeof(SGE)
1489 * A slightly different algorithm is required for
1492 scale
= ioc
->req_sz
/(sizeof(dma_addr_t
) + sizeof(u32
));
1493 if (sizeof(dma_addr_t
) == sizeof(u64
)) {
1494 numSGE
= (scale
- 1) *
1495 (ioc
->facts
.MaxChainDepth
-1) + scale
+
1496 (ioc
->req_sz
- 60) / (sizeof(dma_addr_t
) +
1499 numSGE
= 1 + (scale
- 1) *
1500 (ioc
->facts
.MaxChainDepth
-1) + scale
+
1501 (ioc
->req_sz
- 64) / (sizeof(dma_addr_t
) +
1505 if (numSGE
< sh
->sg_tablesize
) {
1506 /* Reset this value */
1507 dprintk((MYIOC_s_INFO_FMT
1508 "Resetting sg_tablesize to %d from %d\n",
1509 ioc
->name
, numSGE
, sh
->sg_tablesize
));
1510 sh
->sg_tablesize
= numSGE
;
1513 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
1515 hd
= (MPT_SCSI_HOST
*) sh
->hostdata
;
1518 /* SCSI needs scsi_cmnd lookup table!
1519 * (with size equal to req_depth*PtrSz!)
1521 sz
= ioc
->req_depth
* sizeof(void *);
1522 mem
= kmalloc(sz
, GFP_ATOMIC
);
1525 goto out_mptsas_probe
;
1529 hd
->ScsiLookup
= (struct scsi_cmnd
**) mem
;
1531 dprintk((MYIOC_s_INFO_FMT
"ScsiLookup @ %p, sz=%d\n",
1532 ioc
->name
, hd
->ScsiLookup
, sz
));
1534 /* Allocate memory for the device structures.
1535 * A non-Null pointer at an offset
1536 * indicates a device exists.
1537 * max_id = 1 + maximum id (hosts.h)
1539 sz
= sh
->max_id
* sizeof(void *);
1540 mem
= kmalloc(sz
, GFP_ATOMIC
);
1543 goto out_mptsas_probe
;
1547 hd
->Targets
= (VirtTarget
**) mem
;
1550 " vtarget @ %p, sz=%d\n", hd
->Targets
, sz
));
1552 /* Clear the TM flags
1555 hd
->tmState
= TM_STATE_NONE
;
1556 hd
->resetPending
= 0;
1557 hd
->abortSCpnt
= NULL
;
1559 /* Clear the pointer used to store
1560 * single-threaded commands, i.e., those
1561 * issued during a bus scan, dv and
1562 * configuration pages.
1566 /* Initialize this SCSI Hosts' timers
1567 * To use, set the timer expires field
1570 init_timer(&hd
->timer
);
1571 hd
->timer
.data
= (unsigned long) hd
;
1572 hd
->timer
.function
= mptscsih_timer_expired
;
1574 hd
->mpt_pq_filter
= mpt_pq_filter
;
1575 ioc
->sas_data
.ptClear
= mpt_pt_clear
;
1577 if (ioc
->sas_data
.ptClear
==1) {
1578 mptbase_sas_persist_operation(
1579 ioc
, MPI_SAS_OP_CLEAR_ALL_PERSISTENT
);
1582 ddvprintk((MYIOC_s_INFO_FMT
1583 "mpt_pq_filter %x mpt_pq_filter %x\n",
1588 init_waitqueue_head(&hd
->scandv_waitq
);
1589 hd
->scandv_wait_done
= 0;
1590 hd
->last_queue_full
= 0;
1592 error
= scsi_add_host(sh
, &ioc
->pcidev
->dev
);
1594 dprintk((KERN_ERR MYNAM
1595 "scsi_add_host failed\n"));
1596 goto out_mptsas_probe
;
1599 mptsas_scan_sas_topology(ioc
);
1605 mptscsih_remove(pdev
);
1609 static void __devexit
mptsas_remove(struct pci_dev
*pdev
)
1611 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
1612 struct mptsas_portinfo
*p
, *n
;
1614 sas_remove_host(ioc
->sh
);
1616 mutex_lock(&ioc
->sas_topology_mutex
);
1617 list_for_each_entry_safe(p
, n
, &ioc
->sas_topology
, list
) {
1621 mutex_unlock(&ioc
->sas_topology_mutex
);
1623 mptscsih_remove(pdev
);
1626 static struct pci_device_id mptsas_pci_table
[] = {
1627 { PCI_VENDOR_ID_LSI_LOGIC
, PCI_DEVICE_ID_LSI_SAS1064
,
1628 PCI_ANY_ID
, PCI_ANY_ID
},
1629 { PCI_VENDOR_ID_LSI_LOGIC
, PCI_DEVICE_ID_LSI_SAS1066
,
1630 PCI_ANY_ID
, PCI_ANY_ID
},
1631 { PCI_VENDOR_ID_LSI_LOGIC
, PCI_DEVICE_ID_LSI_SAS1068
,
1632 PCI_ANY_ID
, PCI_ANY_ID
},
1633 { PCI_VENDOR_ID_LSI_LOGIC
, PCI_DEVICE_ID_LSI_SAS1064E
,
1634 PCI_ANY_ID
, PCI_ANY_ID
},
1635 { PCI_VENDOR_ID_LSI_LOGIC
, PCI_DEVICE_ID_LSI_SAS1066E
,
1636 PCI_ANY_ID
, PCI_ANY_ID
},
1637 { PCI_VENDOR_ID_LSI_LOGIC
, PCI_DEVICE_ID_LSI_SAS1068E
,
1638 PCI_ANY_ID
, PCI_ANY_ID
},
1639 {0} /* Terminating entry */
1641 MODULE_DEVICE_TABLE(pci
, mptsas_pci_table
);
1644 static struct pci_driver mptsas_driver
= {
1646 .id_table
= mptsas_pci_table
,
1647 .probe
= mptsas_probe
,
1648 .remove
= __devexit_p(mptsas_remove
),
1649 .shutdown
= mptscsih_shutdown
,
1651 .suspend
= mptscsih_suspend
,
1652 .resume
= mptscsih_resume
,
1659 show_mptmod_ver(my_NAME
, my_VERSION
);
1661 mptsas_transport_template
=
1662 sas_attach_transport(&mptsas_transport_functions
);
1663 if (!mptsas_transport_template
)
1666 mptsasDoneCtx
= mpt_register(mptscsih_io_done
, MPTSAS_DRIVER
);
1667 mptsasTaskCtx
= mpt_register(mptscsih_taskmgmt_complete
, MPTSAS_DRIVER
);
1669 mpt_register(mptscsih_scandv_complete
, MPTSAS_DRIVER
);
1670 mptsasMgmtCtx
= mpt_register(mptsas_mgmt_done
, MPTSAS_DRIVER
);
1672 if (mpt_event_register(mptsasDoneCtx
, mptsas_event_process
) == 0) {
1673 devtprintk((KERN_INFO MYNAM
1674 ": Registered for IOC event notifications\n"));
1677 if (mpt_reset_register(mptsasDoneCtx
, mptscsih_ioc_reset
) == 0) {
1678 dprintk((KERN_INFO MYNAM
1679 ": Registered for IOC reset notifications\n"));
1682 return pci_register_driver(&mptsas_driver
);
1688 pci_unregister_driver(&mptsas_driver
);
1689 sas_release_transport(mptsas_transport_template
);
1691 mpt_reset_deregister(mptsasDoneCtx
);
1692 mpt_event_deregister(mptsasDoneCtx
);
1694 mpt_deregister(mptsasMgmtCtx
);
1695 mpt_deregister(mptsasInternalCtx
);
1696 mpt_deregister(mptsasTaskCtx
);
1697 mpt_deregister(mptsasDoneCtx
);
1700 module_init(mptsas_init
);
1701 module_exit(mptsas_exit
);