Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[wrt350n-kernel.git] / drivers / message / fusion / mptsas.c
blob4cd9548ee47b1ea0e80199e785d184a3b4028d7f
1 /*
2 * linux/drivers/message/fusion/mptsas.c
3 * For use with LSI PCI chip/adapter(s)
4 * running LSI Fusion MPT (Message Passing Technology) firmware.
6 * Copyright (c) 1999-2007 LSI Corporation
7 * (mailto:DL-MPTFusionLinux@lsi.com)
8 */
9 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; version 2 of the License.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 NO WARRANTY
21 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
22 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
23 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
24 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
25 solely responsible for determining the appropriateness of using and
26 distributing the Program and assumes all risks associated with its
27 exercise of rights under this Agreement, including but not limited to
28 the risks and costs of program errors, damage to or loss of data,
29 programs or equipment, and unavailability or interruption of operations.
31 DISCLAIMER OF LIABILITY
32 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
33 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
35 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
36 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
37 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
38 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
40 You should have received a copy of the GNU General Public License
41 along with this program; if not, write to the Free Software
42 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
44 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
46 #include <linux/module.h>
47 #include <linux/kernel.h>
48 #include <linux/init.h>
49 #include <linux/errno.h>
50 #include <linux/jiffies.h>
51 #include <linux/workqueue.h>
52 #include <linux/delay.h> /* for mdelay */
54 #include <scsi/scsi.h>
55 #include <scsi/scsi_cmnd.h>
56 #include <scsi/scsi_device.h>
57 #include <scsi/scsi_host.h>
58 #include <scsi/scsi_transport_sas.h>
59 #include <scsi/scsi_dbg.h>
61 #include "mptbase.h"
62 #include "mptscsih.h"
63 #include "mptsas.h"
66 #define my_NAME "Fusion MPT SAS Host driver"
67 #define my_VERSION MPT_LINUX_VERSION_COMMON
68 #define MYNAM "mptsas"
71 * Reserved channel for integrated raid
73 #define MPTSAS_RAID_CHANNEL 1
75 MODULE_AUTHOR(MODULEAUTHOR);
76 MODULE_DESCRIPTION(my_NAME);
77 MODULE_LICENSE("GPL");
78 MODULE_VERSION(my_VERSION);
80 static int mpt_pt_clear;
81 module_param(mpt_pt_clear, int, 0);
82 MODULE_PARM_DESC(mpt_pt_clear,
83 " Clear persistency table: enable=1 "
84 "(default=MPTSCSIH_PT_CLEAR=0)");
86 /* scsi-mid layer global parmeter is max_report_luns, which is 511 */
87 #define MPTSAS_MAX_LUN (16895)
88 static int max_lun = MPTSAS_MAX_LUN;
89 module_param(max_lun, int, 0);
90 MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
92 static u8 mptsasDoneCtx = MPT_MAX_PROTOCOL_DRIVERS;
93 static u8 mptsasTaskCtx = MPT_MAX_PROTOCOL_DRIVERS;
94 static u8 mptsasInternalCtx = MPT_MAX_PROTOCOL_DRIVERS; /* Used only for internal commands */
95 static u8 mptsasMgmtCtx = MPT_MAX_PROTOCOL_DRIVERS;
97 static void mptsas_hotplug_work(struct work_struct *work);
99 static void mptsas_print_phy_data(MPT_ADAPTER *ioc,
100 MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
102 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
103 "---- IO UNIT PAGE 0 ------------\n", ioc->name));
104 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handle=0x%X\n",
105 ioc->name, le16_to_cpu(phy_data->AttachedDeviceHandle)));
106 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Controller Handle=0x%X\n",
107 ioc->name, le16_to_cpu(phy_data->ControllerDevHandle)));
108 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Port=0x%X\n",
109 ioc->name, phy_data->Port));
110 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Port Flags=0x%X\n",
111 ioc->name, phy_data->PortFlags));
112 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Flags=0x%X\n",
113 ioc->name, phy_data->PhyFlags));
114 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Negotiated Link Rate=0x%X\n",
115 ioc->name, phy_data->NegotiatedLinkRate));
116 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
117 "Controller PHY Device Info=0x%X\n", ioc->name,
118 le32_to_cpu(phy_data->ControllerPhyDeviceInfo)));
119 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DiscoveryStatus=0x%X\n\n",
120 ioc->name, le32_to_cpu(phy_data->DiscoveryStatus)));
123 static void mptsas_print_phy_pg0(MPT_ADAPTER *ioc, SasPhyPage0_t *pg0)
125 __le64 sas_address;
127 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
129 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
130 "---- SAS PHY PAGE 0 ------------\n", ioc->name));
131 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
132 "Attached Device Handle=0x%X\n", ioc->name,
133 le16_to_cpu(pg0->AttachedDevHandle)));
134 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SAS Address=0x%llX\n",
135 ioc->name, (unsigned long long)le64_to_cpu(sas_address)));
136 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
137 "Attached PHY Identifier=0x%X\n", ioc->name,
138 pg0->AttachedPhyIdentifier));
139 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Attached Device Info=0x%X\n",
140 ioc->name, le32_to_cpu(pg0->AttachedDeviceInfo)));
141 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Programmed Link Rate=0x%X\n",
142 ioc->name, pg0->ProgrammedLinkRate));
143 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Change Count=0x%X\n",
144 ioc->name, pg0->ChangeCount));
145 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Info=0x%X\n\n",
146 ioc->name, le32_to_cpu(pg0->PhyInfo)));
149 static void mptsas_print_phy_pg1(MPT_ADAPTER *ioc, SasPhyPage1_t *pg1)
151 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
152 "---- SAS PHY PAGE 1 ------------\n", ioc->name));
153 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Invalid Dword Count=0x%x\n",
154 ioc->name, pg1->InvalidDwordCount));
155 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
156 "Running Disparity Error Count=0x%x\n", ioc->name,
157 pg1->RunningDisparityErrorCount));
158 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
159 "Loss Dword Synch Count=0x%x\n", ioc->name,
160 pg1->LossDwordSynchCount));
161 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
162 "PHY Reset Problem Count=0x%x\n\n", ioc->name,
163 pg1->PhyResetProblemCount));
166 static void mptsas_print_device_pg0(MPT_ADAPTER *ioc, SasDevicePage0_t *pg0)
168 __le64 sas_address;
170 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
172 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
173 "---- SAS DEVICE PAGE 0 ---------\n", ioc->name));
174 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handle=0x%X\n",
175 ioc->name, le16_to_cpu(pg0->DevHandle)));
176 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Parent Handle=0x%X\n",
177 ioc->name, le16_to_cpu(pg0->ParentDevHandle)));
178 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Enclosure Handle=0x%X\n",
179 ioc->name, le16_to_cpu(pg0->EnclosureHandle)));
180 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Slot=0x%X\n",
181 ioc->name, le16_to_cpu(pg0->Slot)));
182 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SAS Address=0x%llX\n",
183 ioc->name, (unsigned long long)le64_to_cpu(sas_address)));
184 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Target ID=0x%X\n",
185 ioc->name, pg0->TargetID));
186 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Bus=0x%X\n",
187 ioc->name, pg0->Bus));
188 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Parent Phy Num=0x%X\n",
189 ioc->name, pg0->PhyNum));
190 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Access Status=0x%X\n",
191 ioc->name, le16_to_cpu(pg0->AccessStatus)));
192 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Device Info=0x%X\n",
193 ioc->name, le32_to_cpu(pg0->DeviceInfo)));
194 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Flags=0x%X\n",
195 ioc->name, le16_to_cpu(pg0->Flags)));
196 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Physical Port=0x%X\n\n",
197 ioc->name, pg0->PhysicalPort));
200 static void mptsas_print_expander_pg1(MPT_ADAPTER *ioc, SasExpanderPage1_t *pg1)
202 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
203 "---- SAS EXPANDER PAGE 1 ------------\n", ioc->name));
204 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Physical Port=0x%X\n",
205 ioc->name, pg1->PhysicalPort));
206 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Identifier=0x%X\n",
207 ioc->name, pg1->PhyIdentifier));
208 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Negotiated Link Rate=0x%X\n",
209 ioc->name, pg1->NegotiatedLinkRate));
210 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Programmed Link Rate=0x%X\n",
211 ioc->name, pg1->ProgrammedLinkRate));
212 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Hardware Link Rate=0x%X\n",
213 ioc->name, pg1->HwLinkRate));
214 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Owner Device Handle=0x%X\n",
215 ioc->name, le16_to_cpu(pg1->OwnerDevHandle)));
216 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
217 "Attached Device Handle=0x%X\n\n", ioc->name,
218 le16_to_cpu(pg1->AttachedDevHandle)));
221 static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
223 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
224 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
227 static inline MPT_ADAPTER *rphy_to_ioc(struct sas_rphy *rphy)
229 struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
230 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
234 * mptsas_find_portinfo_by_handle
236 * This function should be called with the sas_topology_mutex already held
238 static struct mptsas_portinfo *
239 mptsas_find_portinfo_by_handle(MPT_ADAPTER *ioc, u16 handle)
241 struct mptsas_portinfo *port_info, *rc=NULL;
242 int i;
244 list_for_each_entry(port_info, &ioc->sas_topology, list)
245 for (i = 0; i < port_info->num_phys; i++)
246 if (port_info->phy_info[i].identify.handle == handle) {
247 rc = port_info;
248 goto out;
250 out:
251 return rc;
255 * Returns true if there is a scsi end device
257 static inline int
258 mptsas_is_end_device(struct mptsas_devinfo * attached)
260 if ((attached->sas_address) &&
261 (attached->device_info &
262 MPI_SAS_DEVICE_INFO_END_DEVICE) &&
263 ((attached->device_info &
264 MPI_SAS_DEVICE_INFO_SSP_TARGET) |
265 (attached->device_info &
266 MPI_SAS_DEVICE_INFO_STP_TARGET) |
267 (attached->device_info &
268 MPI_SAS_DEVICE_INFO_SATA_DEVICE)))
269 return 1;
270 else
271 return 0;
274 /* no mutex */
275 static void
276 mptsas_port_delete(MPT_ADAPTER *ioc, struct mptsas_portinfo_details * port_details)
278 struct mptsas_portinfo *port_info;
279 struct mptsas_phyinfo *phy_info;
280 u8 i;
282 if (!port_details)
283 return;
285 port_info = port_details->port_info;
286 phy_info = port_info->phy_info;
288 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: [%p]: num_phys=%02d "
289 "bitmask=0x%016llX\n", ioc->name, __FUNCTION__, port_details,
290 port_details->num_phys, (unsigned long long)
291 port_details->phy_bitmask));
293 for (i = 0; i < port_info->num_phys; i++, phy_info++) {
294 if(phy_info->port_details != port_details)
295 continue;
296 memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
297 phy_info->port_details = NULL;
299 kfree(port_details);
302 static inline struct sas_rphy *
303 mptsas_get_rphy(struct mptsas_phyinfo *phy_info)
305 if (phy_info->port_details)
306 return phy_info->port_details->rphy;
307 else
308 return NULL;
311 static inline void
312 mptsas_set_rphy(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy)
314 if (phy_info->port_details) {
315 phy_info->port_details->rphy = rphy;
316 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sas_rphy_add: rphy=%p\n",
317 ioc->name, rphy));
320 if (rphy) {
321 dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
322 &rphy->dev, MYIOC_s_FMT "add:", ioc->name));
323 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "rphy=%p release=%p\n",
324 ioc->name, rphy, rphy->dev.release));
328 static inline struct sas_port *
329 mptsas_get_port(struct mptsas_phyinfo *phy_info)
331 if (phy_info->port_details)
332 return phy_info->port_details->port;
333 else
334 return NULL;
337 static inline void
338 mptsas_set_port(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_port *port)
340 if (phy_info->port_details)
341 phy_info->port_details->port = port;
343 if (port) {
344 dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
345 &port->dev, MYIOC_s_FMT "add:", ioc->name));
346 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "port=%p release=%p\n",
347 ioc->name, port, port->dev.release));
351 static inline struct scsi_target *
352 mptsas_get_starget(struct mptsas_phyinfo *phy_info)
354 if (phy_info->port_details)
355 return phy_info->port_details->starget;
356 else
357 return NULL;
360 static inline void
361 mptsas_set_starget(struct mptsas_phyinfo *phy_info, struct scsi_target *
362 starget)
364 if (phy_info->port_details)
365 phy_info->port_details->starget = starget;
370 * mptsas_setup_wide_ports
372 * Updates for new and existing narrow/wide port configuration
373 * in the sas_topology
375 static void
376 mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
378 struct mptsas_portinfo_details * port_details;
379 struct mptsas_phyinfo *phy_info, *phy_info_cmp;
380 u64 sas_address;
381 int i, j;
383 mutex_lock(&ioc->sas_topology_mutex);
385 phy_info = port_info->phy_info;
386 for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
387 if (phy_info->attached.handle)
388 continue;
389 port_details = phy_info->port_details;
390 if (!port_details)
391 continue;
392 if (port_details->num_phys < 2)
393 continue;
395 * Removing a phy from a port, letting the last
396 * phy be removed by firmware events.
398 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
399 "%s: [%p]: deleting phy = %d\n",
400 ioc->name, __FUNCTION__, port_details, i));
401 port_details->num_phys--;
402 port_details->phy_bitmask &= ~ (1 << phy_info->phy_id);
403 memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
404 sas_port_delete_phy(port_details->port, phy_info->phy);
405 phy_info->port_details = NULL;
409 * Populate and refresh the tree
411 phy_info = port_info->phy_info;
412 for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
413 sas_address = phy_info->attached.sas_address;
414 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "phy_id=%d sas_address=0x%018llX\n",
415 ioc->name, i, (unsigned long long)sas_address));
416 if (!sas_address)
417 continue;
418 port_details = phy_info->port_details;
420 * Forming a port
422 if (!port_details) {
423 port_details = kzalloc(sizeof(*port_details),
424 GFP_KERNEL);
425 if (!port_details)
426 goto out;
427 port_details->num_phys = 1;
428 port_details->port_info = port_info;
429 if (phy_info->phy_id < 64 )
430 port_details->phy_bitmask |=
431 (1 << phy_info->phy_id);
432 phy_info->sas_port_add_phy=1;
433 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tForming port\n\t\t"
434 "phy_id=%d sas_address=0x%018llX\n",
435 ioc->name, i, (unsigned long long)sas_address));
436 phy_info->port_details = port_details;
439 if (i == port_info->num_phys - 1)
440 continue;
441 phy_info_cmp = &port_info->phy_info[i + 1];
442 for (j = i + 1 ; j < port_info->num_phys ; j++,
443 phy_info_cmp++) {
444 if (!phy_info_cmp->attached.sas_address)
445 continue;
446 if (sas_address != phy_info_cmp->attached.sas_address)
447 continue;
448 if (phy_info_cmp->port_details == port_details )
449 continue;
450 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
451 "\t\tphy_id=%d sas_address=0x%018llX\n",
452 ioc->name, j, (unsigned long long)
453 phy_info_cmp->attached.sas_address));
454 if (phy_info_cmp->port_details) {
455 port_details->rphy =
456 mptsas_get_rphy(phy_info_cmp);
457 port_details->port =
458 mptsas_get_port(phy_info_cmp);
459 port_details->starget =
460 mptsas_get_starget(phy_info_cmp);
461 port_details->num_phys =
462 phy_info_cmp->port_details->num_phys;
463 if (!phy_info_cmp->port_details->num_phys)
464 kfree(phy_info_cmp->port_details);
465 } else
466 phy_info_cmp->sas_port_add_phy=1;
468 * Adding a phy to a port
470 phy_info_cmp->port_details = port_details;
471 if (phy_info_cmp->phy_id < 64 )
472 port_details->phy_bitmask |=
473 (1 << phy_info_cmp->phy_id);
474 port_details->num_phys++;
478 out:
480 for (i = 0; i < port_info->num_phys; i++) {
481 port_details = port_info->phy_info[i].port_details;
482 if (!port_details)
483 continue;
484 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
485 "%s: [%p]: phy_id=%02d num_phys=%02d "
486 "bitmask=0x%016llX\n", ioc->name, __FUNCTION__,
487 port_details, i, port_details->num_phys,
488 (unsigned long long)port_details->phy_bitmask));
489 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tport = %p rphy=%p\n",
490 ioc->name, port_details->port, port_details->rphy));
492 dsaswideprintk(ioc, printk("\n"));
493 mutex_unlock(&ioc->sas_topology_mutex);
497 * csmisas_find_vtarget
499 * @ioc
500 * @volume_id
501 * @volume_bus
504 static VirtTarget *
505 mptsas_find_vtarget(MPT_ADAPTER *ioc, u8 channel, u8 id)
507 struct scsi_device *sdev;
508 VirtDevice *vdevice;
509 VirtTarget *vtarget = NULL;
511 shost_for_each_device(sdev, ioc->sh) {
512 if ((vdevice = sdev->hostdata) == NULL)
513 continue;
514 if (vdevice->vtarget->id == id &&
515 vdevice->vtarget->channel == channel)
516 vtarget = vdevice->vtarget;
518 return vtarget;
522 * mptsas_target_reset
524 * Issues TARGET_RESET to end device using handshaking method
526 * @ioc
527 * @channel
528 * @id
530 * Returns (1) success
531 * (0) failure
534 static int
535 mptsas_target_reset(MPT_ADAPTER *ioc, u8 channel, u8 id)
537 MPT_FRAME_HDR *mf;
538 SCSITaskMgmt_t *pScsiTm;
540 if ((mf = mpt_get_msg_frame(ioc->TaskCtx, ioc)) == NULL) {
541 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames @%d!!\n",
542 ioc->name,__FUNCTION__, __LINE__));
543 return 0;
546 /* Format the Request
548 pScsiTm = (SCSITaskMgmt_t *) mf;
549 memset (pScsiTm, 0, sizeof(SCSITaskMgmt_t));
550 pScsiTm->TargetID = id;
551 pScsiTm->Bus = channel;
552 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
553 pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
554 pScsiTm->MsgFlags = MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION;
556 DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)mf);
558 mpt_put_msg_frame_hi_pri(ioc->TaskCtx, ioc, mf);
560 return 1;
564 * mptsas_target_reset_queue
566 * Receive request for TARGET_RESET after recieving an firmware
567 * event NOT_RESPONDING_EVENT, then put command in link list
568 * and queue if task_queue already in use.
570 * @ioc
571 * @sas_event_data
574 static void
575 mptsas_target_reset_queue(MPT_ADAPTER *ioc,
576 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
578 MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
579 VirtTarget *vtarget = NULL;
580 struct mptsas_target_reset_event *target_reset_list;
581 u8 id, channel;
583 id = sas_event_data->TargetID;
584 channel = sas_event_data->Bus;
586 if (!(vtarget = mptsas_find_vtarget(ioc, channel, id)))
587 return;
589 vtarget->deleted = 1; /* block IO */
591 target_reset_list = kzalloc(sizeof(*target_reset_list),
592 GFP_ATOMIC);
593 if (!target_reset_list) {
594 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, failed to allocate mem @%d..!!\n",
595 ioc->name,__FUNCTION__, __LINE__));
596 return;
599 memcpy(&target_reset_list->sas_event_data, sas_event_data,
600 sizeof(*sas_event_data));
601 list_add_tail(&target_reset_list->list, &hd->target_reset_list);
603 if (hd->resetPending)
604 return;
606 if (mptsas_target_reset(ioc, channel, id)) {
607 target_reset_list->target_reset_issued = 1;
608 hd->resetPending = 1;
613 * mptsas_dev_reset_complete
615 * Completion for TARGET_RESET after NOT_RESPONDING_EVENT,
616 * enable work queue to finish off removing device from upper layers.
617 * then send next TARGET_RESET in the queue.
619 * @ioc
622 static void
623 mptsas_dev_reset_complete(MPT_ADAPTER *ioc)
625 MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
626 struct list_head *head = &hd->target_reset_list;
627 struct mptsas_target_reset_event *target_reset_list;
628 struct mptsas_hotplug_event *ev;
629 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data;
630 u8 id, channel;
631 __le64 sas_address;
633 if (list_empty(head))
634 return;
636 target_reset_list = list_entry(head->next, struct mptsas_target_reset_event, list);
638 sas_event_data = &target_reset_list->sas_event_data;
639 id = sas_event_data->TargetID;
640 channel = sas_event_data->Bus;
641 hd->resetPending = 0;
644 * retry target reset
646 if (!target_reset_list->target_reset_issued) {
647 if (mptsas_target_reset(ioc, channel, id)) {
648 target_reset_list->target_reset_issued = 1;
649 hd->resetPending = 1;
651 return;
655 * enable work queue to remove device from upper layers
657 list_del(&target_reset_list->list);
659 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
660 if (!ev) {
661 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, failed to allocate mem @%d..!!\n",
662 ioc->name,__FUNCTION__, __LINE__));
663 return;
666 INIT_WORK(&ev->work, mptsas_hotplug_work);
667 ev->ioc = ioc;
668 ev->handle = le16_to_cpu(sas_event_data->DevHandle);
669 ev->parent_handle =
670 le16_to_cpu(sas_event_data->ParentDevHandle);
671 ev->channel = channel;
672 ev->id =id;
673 ev->phy_id = sas_event_data->PhyNum;
674 memcpy(&sas_address, &sas_event_data->SASAddress,
675 sizeof(__le64));
676 ev->sas_address = le64_to_cpu(sas_address);
677 ev->device_info = le32_to_cpu(sas_event_data->DeviceInfo);
678 ev->event_type = MPTSAS_DEL_DEVICE;
679 schedule_work(&ev->work);
680 kfree(target_reset_list);
683 * issue target reset to next device in the queue
686 head = &hd->target_reset_list;
687 if (list_empty(head))
688 return;
690 target_reset_list = list_entry(head->next, struct mptsas_target_reset_event,
691 list);
693 sas_event_data = &target_reset_list->sas_event_data;
694 id = sas_event_data->TargetID;
695 channel = sas_event_data->Bus;
697 if (mptsas_target_reset(ioc, channel, id)) {
698 target_reset_list->target_reset_issued = 1;
699 hd->resetPending = 1;
704 * mptsas_taskmgmt_complete
706 * @ioc
707 * @mf
708 * @mr
711 static int
712 mptsas_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
714 mptsas_dev_reset_complete(ioc);
715 return mptscsih_taskmgmt_complete(ioc, mf, mr);
719 * mptscsih_ioc_reset
721 * @ioc
722 * @reset_phase
725 static int
726 mptsas_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
728 MPT_SCSI_HOST *hd;
729 struct mptsas_target_reset_event *target_reset_list, *n;
730 int rc;
732 rc = mptscsih_ioc_reset(ioc, reset_phase);
734 if (ioc->bus_type != SAS)
735 goto out;
737 if (reset_phase != MPT_IOC_POST_RESET)
738 goto out;
740 if (!ioc->sh || !ioc->sh->hostdata)
741 goto out;
742 hd = shost_priv(ioc->sh);
743 if (!hd->ioc)
744 goto out;
746 if (list_empty(&hd->target_reset_list))
747 goto out;
749 /* flush the target_reset_list */
750 list_for_each_entry_safe(target_reset_list, n,
751 &hd->target_reset_list, list) {
752 list_del(&target_reset_list->list);
753 kfree(target_reset_list);
756 out:
757 return rc;
760 static int
761 mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
762 u32 form, u32 form_specific)
764 ConfigExtendedPageHeader_t hdr;
765 CONFIGPARMS cfg;
766 SasEnclosurePage0_t *buffer;
767 dma_addr_t dma_handle;
768 int error;
769 __le64 le_identifier;
771 memset(&hdr, 0, sizeof(hdr));
772 hdr.PageVersion = MPI_SASENCLOSURE0_PAGEVERSION;
773 hdr.PageNumber = 0;
774 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
775 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_ENCLOSURE;
777 cfg.cfghdr.ehdr = &hdr;
778 cfg.physAddr = -1;
779 cfg.pageAddr = form + form_specific;
780 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
781 cfg.dir = 0; /* read */
782 cfg.timeout = 10;
784 error = mpt_config(ioc, &cfg);
785 if (error)
786 goto out;
787 if (!hdr.ExtPageLength) {
788 error = -ENXIO;
789 goto out;
792 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
793 &dma_handle);
794 if (!buffer) {
795 error = -ENOMEM;
796 goto out;
799 cfg.physAddr = dma_handle;
800 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
802 error = mpt_config(ioc, &cfg);
803 if (error)
804 goto out_free_consistent;
806 /* save config data */
807 memcpy(&le_identifier, &buffer->EnclosureLogicalID, sizeof(__le64));
808 enclosure->enclosure_logical_id = le64_to_cpu(le_identifier);
809 enclosure->enclosure_handle = le16_to_cpu(buffer->EnclosureHandle);
810 enclosure->flags = le16_to_cpu(buffer->Flags);
811 enclosure->num_slot = le16_to_cpu(buffer->NumSlots);
812 enclosure->start_slot = le16_to_cpu(buffer->StartSlot);
813 enclosure->start_id = buffer->StartTargetID;
814 enclosure->start_channel = buffer->StartBus;
815 enclosure->sep_id = buffer->SEPTargetID;
816 enclosure->sep_channel = buffer->SEPBus;
818 out_free_consistent:
819 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
820 buffer, dma_handle);
821 out:
822 return error;
825 static int
826 mptsas_slave_configure(struct scsi_device *sdev)
829 if (sdev->channel == MPTSAS_RAID_CHANNEL)
830 goto out;
832 sas_read_port_mode_page(sdev);
834 out:
835 return mptscsih_slave_configure(sdev);
838 static int
839 mptsas_target_alloc(struct scsi_target *starget)
841 struct Scsi_Host *host = dev_to_shost(&starget->dev);
842 MPT_SCSI_HOST *hd = shost_priv(host);
843 VirtTarget *vtarget;
844 u8 id, channel;
845 struct sas_rphy *rphy;
846 struct mptsas_portinfo *p;
847 int i;
848 MPT_ADAPTER *ioc = hd->ioc;
850 vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
851 if (!vtarget)
852 return -ENOMEM;
854 vtarget->starget = starget;
855 vtarget->ioc_id = ioc->id;
856 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
857 id = starget->id;
858 channel = 0;
861 * RAID volumes placed beyond the last expected port.
863 if (starget->channel == MPTSAS_RAID_CHANNEL) {
864 for (i=0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++)
865 if (id == ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID)
866 channel = ioc->raid_data.pIocPg2->RaidVolume[i].VolumeBus;
867 goto out;
870 rphy = dev_to_rphy(starget->dev.parent);
871 mutex_lock(&ioc->sas_topology_mutex);
872 list_for_each_entry(p, &ioc->sas_topology, list) {
873 for (i = 0; i < p->num_phys; i++) {
874 if (p->phy_info[i].attached.sas_address !=
875 rphy->identify.sas_address)
876 continue;
877 id = p->phy_info[i].attached.id;
878 channel = p->phy_info[i].attached.channel;
879 mptsas_set_starget(&p->phy_info[i], starget);
882 * Exposing hidden raid components
884 if (mptscsih_is_phys_disk(ioc, channel, id)) {
885 id = mptscsih_raid_id_to_num(ioc,
886 channel, id);
887 vtarget->tflags |=
888 MPT_TARGET_FLAGS_RAID_COMPONENT;
889 p->phy_info[i].attached.phys_disk_num = id;
891 mutex_unlock(&ioc->sas_topology_mutex);
892 goto out;
895 mutex_unlock(&ioc->sas_topology_mutex);
897 kfree(vtarget);
898 return -ENXIO;
900 out:
901 vtarget->id = id;
902 vtarget->channel = channel;
903 starget->hostdata = vtarget;
904 return 0;
907 static void
908 mptsas_target_destroy(struct scsi_target *starget)
910 struct Scsi_Host *host = dev_to_shost(&starget->dev);
911 MPT_SCSI_HOST *hd = shost_priv(host);
912 struct sas_rphy *rphy;
913 struct mptsas_portinfo *p;
914 int i;
915 MPT_ADAPTER *ioc = hd->ioc;
917 if (!starget->hostdata)
918 return;
920 if (starget->channel == MPTSAS_RAID_CHANNEL)
921 goto out;
923 rphy = dev_to_rphy(starget->dev.parent);
924 list_for_each_entry(p, &ioc->sas_topology, list) {
925 for (i = 0; i < p->num_phys; i++) {
926 if (p->phy_info[i].attached.sas_address !=
927 rphy->identify.sas_address)
928 continue;
929 mptsas_set_starget(&p->phy_info[i], NULL);
930 goto out;
934 out:
935 kfree(starget->hostdata);
936 starget->hostdata = NULL;
940 static int
941 mptsas_slave_alloc(struct scsi_device *sdev)
943 struct Scsi_Host *host = sdev->host;
944 MPT_SCSI_HOST *hd = shost_priv(host);
945 struct sas_rphy *rphy;
946 struct mptsas_portinfo *p;
947 VirtDevice *vdevice;
948 struct scsi_target *starget;
949 int i;
950 MPT_ADAPTER *ioc = hd->ioc;
952 vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
953 if (!vdevice) {
954 printk(MYIOC_s_ERR_FMT "slave_alloc kzalloc(%zd) FAILED!\n",
955 ioc->name, sizeof(VirtDevice));
956 return -ENOMEM;
958 starget = scsi_target(sdev);
959 vdevice->vtarget = starget->hostdata;
961 if (sdev->channel == MPTSAS_RAID_CHANNEL)
962 goto out;
964 rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
965 mutex_lock(&ioc->sas_topology_mutex);
966 list_for_each_entry(p, &ioc->sas_topology, list) {
967 for (i = 0; i < p->num_phys; i++) {
968 if (p->phy_info[i].attached.sas_address !=
969 rphy->identify.sas_address)
970 continue;
971 vdevice->lun = sdev->lun;
973 * Exposing hidden raid components
975 if (mptscsih_is_phys_disk(ioc,
976 p->phy_info[i].attached.channel,
977 p->phy_info[i].attached.id))
978 sdev->no_uld_attach = 1;
979 mutex_unlock(&ioc->sas_topology_mutex);
980 goto out;
983 mutex_unlock(&ioc->sas_topology_mutex);
985 kfree(vdevice);
986 return -ENXIO;
988 out:
989 vdevice->vtarget->num_luns++;
990 sdev->hostdata = vdevice;
991 return 0;
994 static int
995 mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
997 VirtDevice *vdevice = SCpnt->device->hostdata;
999 if (!vdevice || !vdevice->vtarget || vdevice->vtarget->deleted) {
1000 SCpnt->result = DID_NO_CONNECT << 16;
1001 done(SCpnt);
1002 return 0;
1005 // scsi_print_command(SCpnt);
1007 return mptscsih_qcmd(SCpnt,done);
1011 static struct scsi_host_template mptsas_driver_template = {
1012 .module = THIS_MODULE,
1013 .proc_name = "mptsas",
1014 .proc_info = mptscsih_proc_info,
1015 .name = "MPT SPI Host",
1016 .info = mptscsih_info,
1017 .queuecommand = mptsas_qcmd,
1018 .target_alloc = mptsas_target_alloc,
1019 .slave_alloc = mptsas_slave_alloc,
1020 .slave_configure = mptsas_slave_configure,
1021 .target_destroy = mptsas_target_destroy,
1022 .slave_destroy = mptscsih_slave_destroy,
1023 .change_queue_depth = mptscsih_change_queue_depth,
1024 .eh_abort_handler = mptscsih_abort,
1025 .eh_device_reset_handler = mptscsih_dev_reset,
1026 .eh_bus_reset_handler = mptscsih_bus_reset,
1027 .eh_host_reset_handler = mptscsih_host_reset,
1028 .bios_param = mptscsih_bios_param,
1029 .can_queue = MPT_FC_CAN_QUEUE,
1030 .this_id = -1,
1031 .sg_tablesize = MPT_SCSI_SG_DEPTH,
1032 .max_sectors = 8192,
1033 .cmd_per_lun = 7,
1034 .use_clustering = ENABLE_CLUSTERING,
1035 .shost_attrs = mptscsih_host_attrs,
1038 static int mptsas_get_linkerrors(struct sas_phy *phy)
1040 MPT_ADAPTER *ioc = phy_to_ioc(phy);
1041 ConfigExtendedPageHeader_t hdr;
1042 CONFIGPARMS cfg;
1043 SasPhyPage1_t *buffer;
1044 dma_addr_t dma_handle;
1045 int error;
1047 /* FIXME: only have link errors on local phys */
1048 if (!scsi_is_sas_phy_local(phy))
1049 return -EINVAL;
1051 hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
1052 hdr.ExtPageLength = 0;
1053 hdr.PageNumber = 1 /* page number 1*/;
1054 hdr.Reserved1 = 0;
1055 hdr.Reserved2 = 0;
1056 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1057 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
1059 cfg.cfghdr.ehdr = &hdr;
1060 cfg.physAddr = -1;
1061 cfg.pageAddr = phy->identify.phy_identifier;
1062 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1063 cfg.dir = 0; /* read */
1064 cfg.timeout = 10;
1066 error = mpt_config(ioc, &cfg);
1067 if (error)
1068 return error;
1069 if (!hdr.ExtPageLength)
1070 return -ENXIO;
1072 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1073 &dma_handle);
1074 if (!buffer)
1075 return -ENOMEM;
1077 cfg.physAddr = dma_handle;
1078 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1080 error = mpt_config(ioc, &cfg);
1081 if (error)
1082 goto out_free_consistent;
1084 mptsas_print_phy_pg1(ioc, buffer);
1086 phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
1087 phy->running_disparity_error_count =
1088 le32_to_cpu(buffer->RunningDisparityErrorCount);
1089 phy->loss_of_dword_sync_count =
1090 le32_to_cpu(buffer->LossDwordSynchCount);
1091 phy->phy_reset_problem_count =
1092 le32_to_cpu(buffer->PhyResetProblemCount);
1094 out_free_consistent:
1095 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1096 buffer, dma_handle);
1097 return error;
1100 static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
1101 MPT_FRAME_HDR *reply)
1103 ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_COMMAND_GOOD;
1104 if (reply != NULL) {
1105 ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_RF_VALID;
1106 memcpy(ioc->sas_mgmt.reply, reply,
1107 min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
1109 complete(&ioc->sas_mgmt.done);
1110 return 1;
1113 static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
1115 MPT_ADAPTER *ioc = phy_to_ioc(phy);
1116 SasIoUnitControlRequest_t *req;
1117 SasIoUnitControlReply_t *reply;
1118 MPT_FRAME_HDR *mf;
1119 MPIHeader_t *hdr;
1120 unsigned long timeleft;
1121 int error = -ERESTARTSYS;
1123 /* FIXME: fusion doesn't allow non-local phy reset */
1124 if (!scsi_is_sas_phy_local(phy))
1125 return -EINVAL;
1127 /* not implemented for expanders */
1128 if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
1129 return -ENXIO;
1131 if (mutex_lock_interruptible(&ioc->sas_mgmt.mutex))
1132 goto out;
1134 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
1135 if (!mf) {
1136 error = -ENOMEM;
1137 goto out_unlock;
1140 hdr = (MPIHeader_t *) mf;
1141 req = (SasIoUnitControlRequest_t *)mf;
1142 memset(req, 0, sizeof(SasIoUnitControlRequest_t));
1143 req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
1144 req->MsgContext = hdr->MsgContext;
1145 req->Operation = hard_reset ?
1146 MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
1147 req->PhyNum = phy->identify.phy_identifier;
1149 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
1151 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
1152 10 * HZ);
1153 if (!timeleft) {
1154 /* On timeout reset the board */
1155 mpt_free_msg_frame(ioc, mf);
1156 mpt_HardResetHandler(ioc, CAN_SLEEP);
1157 error = -ETIMEDOUT;
1158 goto out_unlock;
1161 /* a reply frame is expected */
1162 if ((ioc->sas_mgmt.status &
1163 MPT_IOCTL_STATUS_RF_VALID) == 0) {
1164 error = -ENXIO;
1165 goto out_unlock;
1168 /* process the completed Reply Message Frame */
1169 reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
1170 if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
1171 printk(MYIOC_s_INFO_FMT "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
1172 ioc->name, __FUNCTION__, reply->IOCStatus, reply->IOCLogInfo);
1173 error = -ENXIO;
1174 goto out_unlock;
1177 error = 0;
1179 out_unlock:
1180 mutex_unlock(&ioc->sas_mgmt.mutex);
1181 out:
1182 return error;
1185 static int
1186 mptsas_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
1188 MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
1189 int i, error;
1190 struct mptsas_portinfo *p;
1191 struct mptsas_enclosure enclosure_info;
1192 u64 enclosure_handle;
1194 mutex_lock(&ioc->sas_topology_mutex);
1195 list_for_each_entry(p, &ioc->sas_topology, list) {
1196 for (i = 0; i < p->num_phys; i++) {
1197 if (p->phy_info[i].attached.sas_address ==
1198 rphy->identify.sas_address) {
1199 enclosure_handle = p->phy_info[i].
1200 attached.handle_enclosure;
1201 goto found_info;
1205 mutex_unlock(&ioc->sas_topology_mutex);
1206 return -ENXIO;
1208 found_info:
1209 mutex_unlock(&ioc->sas_topology_mutex);
1210 memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
1211 error = mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
1212 (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
1213 MPI_SAS_ENCLOS_PGAD_FORM_SHIFT), enclosure_handle);
1214 if (!error)
1215 *identifier = enclosure_info.enclosure_logical_id;
1216 return error;
1219 static int
1220 mptsas_get_bay_identifier(struct sas_rphy *rphy)
1222 MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
1223 struct mptsas_portinfo *p;
1224 int i, rc;
1226 mutex_lock(&ioc->sas_topology_mutex);
1227 list_for_each_entry(p, &ioc->sas_topology, list) {
1228 for (i = 0; i < p->num_phys; i++) {
1229 if (p->phy_info[i].attached.sas_address ==
1230 rphy->identify.sas_address) {
1231 rc = p->phy_info[i].attached.slot;
1232 goto out;
1236 rc = -ENXIO;
1237 out:
1238 mutex_unlock(&ioc->sas_topology_mutex);
1239 return rc;
1242 static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
1243 struct request *req)
1245 MPT_ADAPTER *ioc = ((MPT_SCSI_HOST *) shost->hostdata)->ioc;
1246 MPT_FRAME_HDR *mf;
1247 SmpPassthroughRequest_t *smpreq;
1248 struct request *rsp = req->next_rq;
1249 int ret;
1250 int flagsLength;
1251 unsigned long timeleft;
1252 char *psge;
1253 dma_addr_t dma_addr_in = 0;
1254 dma_addr_t dma_addr_out = 0;
1255 u64 sas_address = 0;
1257 if (!rsp) {
1258 printk(MYIOC_s_ERR_FMT "%s: the smp response space is missing\n",
1259 ioc->name, __FUNCTION__);
1260 return -EINVAL;
1263 /* do we need to support multiple segments? */
1264 if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) {
1265 printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u %u, rsp %u %u\n",
1266 ioc->name, __FUNCTION__, req->bio->bi_vcnt, req->data_len,
1267 rsp->bio->bi_vcnt, rsp->data_len);
1268 return -EINVAL;
1271 ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
1272 if (ret)
1273 goto out;
1275 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
1276 if (!mf) {
1277 ret = -ENOMEM;
1278 goto out_unlock;
1281 smpreq = (SmpPassthroughRequest_t *)mf;
1282 memset(smpreq, 0, sizeof(*smpreq));
1284 smpreq->RequestDataLength = cpu_to_le16(req->data_len - 4);
1285 smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
1287 if (rphy)
1288 sas_address = rphy->identify.sas_address;
1289 else {
1290 struct mptsas_portinfo *port_info;
1292 mutex_lock(&ioc->sas_topology_mutex);
1293 port_info = mptsas_find_portinfo_by_handle(ioc, ioc->handle);
1294 if (port_info && port_info->phy_info)
1295 sas_address =
1296 port_info->phy_info[0].phy->identify.sas_address;
1297 mutex_unlock(&ioc->sas_topology_mutex);
1300 *((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
1302 psge = (char *)
1303 (((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
1305 /* request */
1306 flagsLength = (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1307 MPI_SGE_FLAGS_END_OF_BUFFER |
1308 MPI_SGE_FLAGS_DIRECTION |
1309 mpt_addr_size()) << MPI_SGE_FLAGS_SHIFT;
1310 flagsLength |= (req->data_len - 4);
1312 dma_addr_out = pci_map_single(ioc->pcidev, bio_data(req->bio),
1313 req->data_len, PCI_DMA_BIDIRECTIONAL);
1314 if (!dma_addr_out)
1315 goto put_mf;
1316 mpt_add_sge(psge, flagsLength, dma_addr_out);
1317 psge += (sizeof(u32) + sizeof(dma_addr_t));
1319 /* response */
1320 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
1321 flagsLength |= rsp->data_len + 4;
1322 dma_addr_in = pci_map_single(ioc->pcidev, bio_data(rsp->bio),
1323 rsp->data_len, PCI_DMA_BIDIRECTIONAL);
1324 if (!dma_addr_in)
1325 goto unmap;
1326 mpt_add_sge(psge, flagsLength, dma_addr_in);
1328 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
1330 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
1331 if (!timeleft) {
1332 printk(MYIOC_s_ERR_FMT "%s: smp timeout!\n", ioc->name, __FUNCTION__);
1333 /* On timeout reset the board */
1334 mpt_HardResetHandler(ioc, CAN_SLEEP);
1335 ret = -ETIMEDOUT;
1336 goto unmap;
1338 mf = NULL;
1340 if (ioc->sas_mgmt.status & MPT_IOCTL_STATUS_RF_VALID) {
1341 SmpPassthroughReply_t *smprep;
1343 smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
1344 memcpy(req->sense, smprep, sizeof(*smprep));
1345 req->sense_len = sizeof(*smprep);
1346 req->data_len = 0;
1347 rsp->data_len -= smprep->ResponseDataLength;
1348 } else {
1349 printk(MYIOC_s_ERR_FMT "%s: smp passthru reply failed to be returned\n",
1350 ioc->name, __FUNCTION__);
1351 ret = -ENXIO;
1353 unmap:
1354 if (dma_addr_out)
1355 pci_unmap_single(ioc->pcidev, dma_addr_out, req->data_len,
1356 PCI_DMA_BIDIRECTIONAL);
1357 if (dma_addr_in)
1358 pci_unmap_single(ioc->pcidev, dma_addr_in, rsp->data_len,
1359 PCI_DMA_BIDIRECTIONAL);
1360 put_mf:
1361 if (mf)
1362 mpt_free_msg_frame(ioc, mf);
1363 out_unlock:
1364 mutex_unlock(&ioc->sas_mgmt.mutex);
1365 out:
1366 return ret;
1369 static struct sas_function_template mptsas_transport_functions = {
1370 .get_linkerrors = mptsas_get_linkerrors,
1371 .get_enclosure_identifier = mptsas_get_enclosure_identifier,
1372 .get_bay_identifier = mptsas_get_bay_identifier,
1373 .phy_reset = mptsas_phy_reset,
1374 .smp_handler = mptsas_smp_handler,
1377 static struct scsi_transport_template *mptsas_transport_template;
1379 static int
1380 mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
1382 ConfigExtendedPageHeader_t hdr;
1383 CONFIGPARMS cfg;
1384 SasIOUnitPage0_t *buffer;
1385 dma_addr_t dma_handle;
1386 int error, i;
1388 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
1389 hdr.ExtPageLength = 0;
1390 hdr.PageNumber = 0;
1391 hdr.Reserved1 = 0;
1392 hdr.Reserved2 = 0;
1393 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1394 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1396 cfg.cfghdr.ehdr = &hdr;
1397 cfg.physAddr = -1;
1398 cfg.pageAddr = 0;
1399 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1400 cfg.dir = 0; /* read */
1401 cfg.timeout = 10;
1403 error = mpt_config(ioc, &cfg);
1404 if (error)
1405 goto out;
1406 if (!hdr.ExtPageLength) {
1407 error = -ENXIO;
1408 goto out;
1411 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1412 &dma_handle);
1413 if (!buffer) {
1414 error = -ENOMEM;
1415 goto out;
1418 cfg.physAddr = dma_handle;
1419 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1421 error = mpt_config(ioc, &cfg);
1422 if (error)
1423 goto out_free_consistent;
1425 port_info->num_phys = buffer->NumPhys;
1426 port_info->phy_info = kcalloc(port_info->num_phys,
1427 sizeof(*port_info->phy_info),GFP_KERNEL);
1428 if (!port_info->phy_info) {
1429 error = -ENOMEM;
1430 goto out_free_consistent;
1433 ioc->nvdata_version_persistent =
1434 le16_to_cpu(buffer->NvdataVersionPersistent);
1435 ioc->nvdata_version_default =
1436 le16_to_cpu(buffer->NvdataVersionDefault);
1438 for (i = 0; i < port_info->num_phys; i++) {
1439 mptsas_print_phy_data(ioc, &buffer->PhyData[i]);
1440 port_info->phy_info[i].phy_id = i;
1441 port_info->phy_info[i].port_id =
1442 buffer->PhyData[i].Port;
1443 port_info->phy_info[i].negotiated_link_rate =
1444 buffer->PhyData[i].NegotiatedLinkRate;
1445 port_info->phy_info[i].portinfo = port_info;
1446 port_info->phy_info[i].handle =
1447 le16_to_cpu(buffer->PhyData[i].ControllerDevHandle);
1450 out_free_consistent:
1451 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1452 buffer, dma_handle);
1453 out:
1454 return error;
1457 static int
1458 mptsas_sas_io_unit_pg1(MPT_ADAPTER *ioc)
1460 ConfigExtendedPageHeader_t hdr;
1461 CONFIGPARMS cfg;
1462 SasIOUnitPage1_t *buffer;
1463 dma_addr_t dma_handle;
1464 int error;
1465 u16 device_missing_delay;
1467 memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
1468 memset(&cfg, 0, sizeof(CONFIGPARMS));
1470 cfg.cfghdr.ehdr = &hdr;
1471 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1472 cfg.timeout = 10;
1473 cfg.cfghdr.ehdr->PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1474 cfg.cfghdr.ehdr->ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1475 cfg.cfghdr.ehdr->PageVersion = MPI_SASIOUNITPAGE1_PAGEVERSION;
1476 cfg.cfghdr.ehdr->PageNumber = 1;
1478 error = mpt_config(ioc, &cfg);
1479 if (error)
1480 goto out;
1481 if (!hdr.ExtPageLength) {
1482 error = -ENXIO;
1483 goto out;
1486 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1487 &dma_handle);
1488 if (!buffer) {
1489 error = -ENOMEM;
1490 goto out;
1493 cfg.physAddr = dma_handle;
1494 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1496 error = mpt_config(ioc, &cfg);
1497 if (error)
1498 goto out_free_consistent;
1500 ioc->io_missing_delay =
1501 le16_to_cpu(buffer->IODeviceMissingDelay);
1502 device_missing_delay = le16_to_cpu(buffer->ReportDeviceMissingDelay);
1503 ioc->device_missing_delay = (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_UNIT_16) ?
1504 (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16 :
1505 device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
1507 out_free_consistent:
1508 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1509 buffer, dma_handle);
1510 out:
1511 return error;
1514 static int
1515 mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
1516 u32 form, u32 form_specific)
1518 ConfigExtendedPageHeader_t hdr;
1519 CONFIGPARMS cfg;
1520 SasPhyPage0_t *buffer;
1521 dma_addr_t dma_handle;
1522 int error;
1524 hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
1525 hdr.ExtPageLength = 0;
1526 hdr.PageNumber = 0;
1527 hdr.Reserved1 = 0;
1528 hdr.Reserved2 = 0;
1529 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1530 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
1532 cfg.cfghdr.ehdr = &hdr;
1533 cfg.dir = 0; /* read */
1534 cfg.timeout = 10;
1536 /* Get Phy Pg 0 for each Phy. */
1537 cfg.physAddr = -1;
1538 cfg.pageAddr = form + form_specific;
1539 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1541 error = mpt_config(ioc, &cfg);
1542 if (error)
1543 goto out;
1545 if (!hdr.ExtPageLength) {
1546 error = -ENXIO;
1547 goto out;
1550 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1551 &dma_handle);
1552 if (!buffer) {
1553 error = -ENOMEM;
1554 goto out;
1557 cfg.physAddr = dma_handle;
1558 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1560 error = mpt_config(ioc, &cfg);
1561 if (error)
1562 goto out_free_consistent;
1564 mptsas_print_phy_pg0(ioc, buffer);
1566 phy_info->hw_link_rate = buffer->HwLinkRate;
1567 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
1568 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
1569 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
1571 out_free_consistent:
1572 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1573 buffer, dma_handle);
1574 out:
1575 return error;
1578 static int
1579 mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
1580 u32 form, u32 form_specific)
1582 ConfigExtendedPageHeader_t hdr;
1583 CONFIGPARMS cfg;
1584 SasDevicePage0_t *buffer;
1585 dma_addr_t dma_handle;
1586 __le64 sas_address;
1587 int error=0;
1589 if (ioc->sas_discovery_runtime &&
1590 mptsas_is_end_device(device_info))
1591 goto out;
1593 hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
1594 hdr.ExtPageLength = 0;
1595 hdr.PageNumber = 0;
1596 hdr.Reserved1 = 0;
1597 hdr.Reserved2 = 0;
1598 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1599 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
1601 cfg.cfghdr.ehdr = &hdr;
1602 cfg.pageAddr = form + form_specific;
1603 cfg.physAddr = -1;
1604 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1605 cfg.dir = 0; /* read */
1606 cfg.timeout = 10;
1608 memset(device_info, 0, sizeof(struct mptsas_devinfo));
1609 error = mpt_config(ioc, &cfg);
1610 if (error)
1611 goto out;
1612 if (!hdr.ExtPageLength) {
1613 error = -ENXIO;
1614 goto out;
1617 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1618 &dma_handle);
1619 if (!buffer) {
1620 error = -ENOMEM;
1621 goto out;
1624 cfg.physAddr = dma_handle;
1625 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1627 error = mpt_config(ioc, &cfg);
1628 if (error)
1629 goto out_free_consistent;
1631 mptsas_print_device_pg0(ioc, buffer);
1633 device_info->handle = le16_to_cpu(buffer->DevHandle);
1634 device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle);
1635 device_info->handle_enclosure =
1636 le16_to_cpu(buffer->EnclosureHandle);
1637 device_info->slot = le16_to_cpu(buffer->Slot);
1638 device_info->phy_id = buffer->PhyNum;
1639 device_info->port_id = buffer->PhysicalPort;
1640 device_info->id = buffer->TargetID;
1641 device_info->phys_disk_num = ~0;
1642 device_info->channel = buffer->Bus;
1643 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
1644 device_info->sas_address = le64_to_cpu(sas_address);
1645 device_info->device_info =
1646 le32_to_cpu(buffer->DeviceInfo);
1648 out_free_consistent:
1649 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1650 buffer, dma_handle);
1651 out:
1652 return error;
1655 static int
1656 mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
1657 u32 form, u32 form_specific)
1659 ConfigExtendedPageHeader_t hdr;
1660 CONFIGPARMS cfg;
1661 SasExpanderPage0_t *buffer;
1662 dma_addr_t dma_handle;
1663 int i, error;
1665 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
1666 hdr.ExtPageLength = 0;
1667 hdr.PageNumber = 0;
1668 hdr.Reserved1 = 0;
1669 hdr.Reserved2 = 0;
1670 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1671 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1673 cfg.cfghdr.ehdr = &hdr;
1674 cfg.physAddr = -1;
1675 cfg.pageAddr = form + form_specific;
1676 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1677 cfg.dir = 0; /* read */
1678 cfg.timeout = 10;
1680 memset(port_info, 0, sizeof(struct mptsas_portinfo));
1681 error = mpt_config(ioc, &cfg);
1682 if (error)
1683 goto out;
1685 if (!hdr.ExtPageLength) {
1686 error = -ENXIO;
1687 goto out;
1690 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1691 &dma_handle);
1692 if (!buffer) {
1693 error = -ENOMEM;
1694 goto out;
1697 cfg.physAddr = dma_handle;
1698 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1700 error = mpt_config(ioc, &cfg);
1701 if (error)
1702 goto out_free_consistent;
1704 <<<<<<< HEAD:drivers/message/fusion/mptsas.c
1705 =======
1706 if (!buffer->NumPhys) {
1707 error = -ENODEV;
1708 goto out_free_consistent;
1711 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:drivers/message/fusion/mptsas.c
1712 /* save config data */
1713 port_info->num_phys = buffer->NumPhys;
1714 port_info->phy_info = kcalloc(port_info->num_phys,
1715 sizeof(*port_info->phy_info),GFP_KERNEL);
1716 if (!port_info->phy_info) {
1717 error = -ENOMEM;
1718 goto out_free_consistent;
1721 for (i = 0; i < port_info->num_phys; i++) {
1722 port_info->phy_info[i].portinfo = port_info;
1723 port_info->phy_info[i].handle =
1724 le16_to_cpu(buffer->DevHandle);
1727 out_free_consistent:
1728 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1729 buffer, dma_handle);
1730 out:
1731 return error;
1734 static int
1735 mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
1736 u32 form, u32 form_specific)
1738 ConfigExtendedPageHeader_t hdr;
1739 CONFIGPARMS cfg;
1740 SasExpanderPage1_t *buffer;
1741 dma_addr_t dma_handle;
1742 int error=0;
1744 if (ioc->sas_discovery_runtime &&
1745 mptsas_is_end_device(&phy_info->attached))
1746 goto out;
1748 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
1749 hdr.ExtPageLength = 0;
1750 hdr.PageNumber = 1;
1751 hdr.Reserved1 = 0;
1752 hdr.Reserved2 = 0;
1753 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1754 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1756 cfg.cfghdr.ehdr = &hdr;
1757 cfg.physAddr = -1;
1758 cfg.pageAddr = form + form_specific;
1759 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1760 cfg.dir = 0; /* read */
1761 cfg.timeout = 10;
1763 error = mpt_config(ioc, &cfg);
1764 if (error)
1765 goto out;
1767 if (!hdr.ExtPageLength) {
1768 error = -ENXIO;
1769 goto out;
1772 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1773 &dma_handle);
1774 if (!buffer) {
1775 error = -ENOMEM;
1776 goto out;
1779 cfg.physAddr = dma_handle;
1780 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1782 error = mpt_config(ioc, &cfg);
1783 if (error)
1784 goto out_free_consistent;
1787 mptsas_print_expander_pg1(ioc, buffer);
1789 /* save config data */
1790 phy_info->phy_id = buffer->PhyIdentifier;
1791 phy_info->port_id = buffer->PhysicalPort;
1792 phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
1793 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
1794 phy_info->hw_link_rate = buffer->HwLinkRate;
1795 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
1796 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
1798 out_free_consistent:
1799 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1800 buffer, dma_handle);
1801 out:
1802 return error;
1805 static void
1806 mptsas_parse_device_info(struct sas_identify *identify,
1807 struct mptsas_devinfo *device_info)
1809 u16 protocols;
1811 identify->sas_address = device_info->sas_address;
1812 identify->phy_identifier = device_info->phy_id;
1815 * Fill in Phy Initiator Port Protocol.
1816 * Bits 6:3, more than one bit can be set, fall through cases.
1818 protocols = device_info->device_info & 0x78;
1819 identify->initiator_port_protocols = 0;
1820 if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
1821 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
1822 if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
1823 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
1824 if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
1825 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
1826 if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
1827 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
1830 * Fill in Phy Target Port Protocol.
1831 * Bits 10:7, more than one bit can be set, fall through cases.
1833 protocols = device_info->device_info & 0x780;
1834 identify->target_port_protocols = 0;
1835 if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
1836 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
1837 if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
1838 identify->target_port_protocols |= SAS_PROTOCOL_STP;
1839 if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
1840 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
1841 if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1842 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
1845 * Fill in Attached device type.
1847 switch (device_info->device_info &
1848 MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
1849 case MPI_SAS_DEVICE_INFO_NO_DEVICE:
1850 identify->device_type = SAS_PHY_UNUSED;
1851 break;
1852 case MPI_SAS_DEVICE_INFO_END_DEVICE:
1853 identify->device_type = SAS_END_DEVICE;
1854 break;
1855 case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
1856 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
1857 break;
1858 case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
1859 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
1860 break;
1864 static int mptsas_probe_one_phy(struct device *dev,
1865 struct mptsas_phyinfo *phy_info, int index, int local)
1867 MPT_ADAPTER *ioc;
1868 struct sas_phy *phy;
1869 struct sas_port *port;
1870 int error = 0;
1872 if (!dev) {
1873 error = -ENODEV;
1874 goto out;
1877 if (!phy_info->phy) {
1878 phy = sas_phy_alloc(dev, index);
1879 if (!phy) {
1880 error = -ENOMEM;
1881 goto out;
1883 } else
1884 phy = phy_info->phy;
1886 mptsas_parse_device_info(&phy->identify, &phy_info->identify);
1889 * Set Negotiated link rate.
1891 switch (phy_info->negotiated_link_rate) {
1892 case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
1893 phy->negotiated_linkrate = SAS_PHY_DISABLED;
1894 break;
1895 case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
1896 phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;
1897 break;
1898 case MPI_SAS_IOUNIT0_RATE_1_5:
1899 phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
1900 break;
1901 case MPI_SAS_IOUNIT0_RATE_3_0:
1902 phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
1903 break;
1904 case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
1905 case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
1906 default:
1907 phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
1908 break;
1912 * Set Max hardware link rate.
1914 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
1915 case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
1916 phy->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
1917 break;
1918 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
1919 phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
1920 break;
1921 default:
1922 break;
1926 * Set Max programmed link rate.
1928 switch (phy_info->programmed_link_rate &
1929 MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
1930 case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
1931 phy->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
1932 break;
1933 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
1934 phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
1935 break;
1936 default:
1937 break;
1941 * Set Min hardware link rate.
1943 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
1944 case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
1945 phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
1946 break;
1947 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
1948 phy->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
1949 break;
1950 default:
1951 break;
1955 * Set Min programmed link rate.
1957 switch (phy_info->programmed_link_rate &
1958 MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
1959 case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
1960 phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
1961 break;
1962 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
1963 phy->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
1964 break;
1965 default:
1966 break;
1969 if (!phy_info->phy) {
1971 error = sas_phy_add(phy);
1972 if (error) {
1973 sas_phy_free(phy);
1974 goto out;
1976 phy_info->phy = phy;
1979 if (!phy_info->attached.handle ||
1980 !phy_info->port_details)
1981 goto out;
1983 port = mptsas_get_port(phy_info);
1984 ioc = phy_to_ioc(phy_info->phy);
1986 if (phy_info->sas_port_add_phy) {
1988 if (!port) {
1989 port = sas_port_alloc_num(dev);
1990 if (!port) {
1991 error = -ENOMEM;
1992 goto out;
1994 error = sas_port_add(port);
1995 if (error) {
1996 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1997 "%s: exit at line=%d\n", ioc->name,
1998 __FUNCTION__, __LINE__));
1999 goto out;
2001 mptsas_set_port(ioc, phy_info, port);
2002 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2003 "sas_port_alloc: port=%p dev=%p port_id=%d\n",
2004 ioc->name, port, dev, port->port_identifier));
2006 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sas_port_add_phy: phy_id=%d\n",
2007 ioc->name, phy_info->phy_id));
2008 sas_port_add_phy(port, phy_info->phy);
2009 phy_info->sas_port_add_phy = 0;
2012 if (!mptsas_get_rphy(phy_info) && port && !port->rphy) {
2014 struct sas_rphy *rphy;
2015 struct device *parent;
2016 struct sas_identify identify;
2018 parent = dev->parent->parent;
2020 * Let the hotplug_work thread handle processing
2021 * the adding/removing of devices that occur
2022 * after start of day.
2024 if (ioc->sas_discovery_runtime &&
2025 mptsas_is_end_device(&phy_info->attached))
2026 goto out;
2028 mptsas_parse_device_info(&identify, &phy_info->attached);
2029 if (scsi_is_host_device(parent)) {
2030 struct mptsas_portinfo *port_info;
2031 int i;
2033 mutex_lock(&ioc->sas_topology_mutex);
2034 port_info = mptsas_find_portinfo_by_handle(ioc,
2035 ioc->handle);
2036 mutex_unlock(&ioc->sas_topology_mutex);
2038 for (i = 0; i < port_info->num_phys; i++)
2039 if (port_info->phy_info[i].identify.sas_address ==
2040 identify.sas_address) {
2041 sas_port_mark_backlink(port);
2042 goto out;
2045 } else if (scsi_is_sas_rphy(parent)) {
2046 struct sas_rphy *parent_rphy = dev_to_rphy(parent);
2047 if (identify.sas_address ==
2048 parent_rphy->identify.sas_address) {
2049 sas_port_mark_backlink(port);
2050 goto out;
2054 switch (identify.device_type) {
2055 case SAS_END_DEVICE:
2056 rphy = sas_end_device_alloc(port);
2057 break;
2058 case SAS_EDGE_EXPANDER_DEVICE:
2059 case SAS_FANOUT_EXPANDER_DEVICE:
2060 rphy = sas_expander_alloc(port, identify.device_type);
2061 break;
2062 default:
2063 rphy = NULL;
2064 break;
2066 if (!rphy) {
2067 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2068 "%s: exit at line=%d\n", ioc->name,
2069 __FUNCTION__, __LINE__));
2070 goto out;
2073 rphy->identify = identify;
2074 error = sas_rphy_add(rphy);
2075 if (error) {
2076 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2077 "%s: exit at line=%d\n", ioc->name,
2078 __FUNCTION__, __LINE__));
2079 sas_rphy_free(rphy);
2080 goto out;
2082 mptsas_set_rphy(ioc, phy_info, rphy);
2085 out:
2086 return error;
2089 static int
2090 mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
2092 struct mptsas_portinfo *port_info, *hba;
2093 int error = -ENOMEM, i;
2095 hba = kzalloc(sizeof(*port_info), GFP_KERNEL);
2096 if (! hba)
2097 goto out;
2099 error = mptsas_sas_io_unit_pg0(ioc, hba);
2100 if (error)
2101 goto out_free_port_info;
2103 mptsas_sas_io_unit_pg1(ioc);
2104 mutex_lock(&ioc->sas_topology_mutex);
2105 ioc->handle = hba->phy_info[0].handle;
2106 port_info = mptsas_find_portinfo_by_handle(ioc, ioc->handle);
2107 if (!port_info) {
2108 port_info = hba;
2109 list_add_tail(&port_info->list, &ioc->sas_topology);
2110 } else {
2111 for (i = 0; i < hba->num_phys; i++) {
2112 port_info->phy_info[i].negotiated_link_rate =
2113 hba->phy_info[i].negotiated_link_rate;
2114 port_info->phy_info[i].handle =
2115 hba->phy_info[i].handle;
2116 port_info->phy_info[i].port_id =
2117 hba->phy_info[i].port_id;
2119 kfree(hba->phy_info);
2120 kfree(hba);
2121 hba = NULL;
2123 mutex_unlock(&ioc->sas_topology_mutex);
2124 for (i = 0; i < port_info->num_phys; i++) {
2125 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
2126 (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
2127 MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
2129 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
2130 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2131 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2132 port_info->phy_info[i].handle);
2133 port_info->phy_info[i].identify.phy_id =
2134 port_info->phy_info[i].phy_id = i;
2135 if (port_info->phy_info[i].attached.handle)
2136 mptsas_sas_device_pg0(ioc,
2137 &port_info->phy_info[i].attached,
2138 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2139 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2140 port_info->phy_info[i].attached.handle);
2143 mptsas_setup_wide_ports(ioc, port_info);
2145 for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
2146 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
2147 &port_info->phy_info[i], ioc->sas_index, 1);
2149 return 0;
2151 out_free_port_info:
2152 kfree(hba);
2153 out:
2154 return error;
2157 static int
2158 mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle)
2160 struct mptsas_portinfo *port_info, *p, *ex;
2161 struct device *parent;
2162 struct sas_rphy *rphy;
2163 int error = -ENOMEM, i, j;
2165 ex = kzalloc(sizeof(*port_info), GFP_KERNEL);
2166 if (!ex)
2167 goto out;
2169 error = mptsas_sas_expander_pg0(ioc, ex,
2170 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
2171 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
2172 if (error)
2173 goto out_free_port_info;
2175 *handle = ex->phy_info[0].handle;
2177 mutex_lock(&ioc->sas_topology_mutex);
2178 port_info = mptsas_find_portinfo_by_handle(ioc, *handle);
2179 if (!port_info) {
2180 port_info = ex;
2181 list_add_tail(&port_info->list, &ioc->sas_topology);
2182 } else {
2183 for (i = 0; i < ex->num_phys; i++) {
2184 port_info->phy_info[i].handle =
2185 ex->phy_info[i].handle;
2186 port_info->phy_info[i].port_id =
2187 ex->phy_info[i].port_id;
2189 kfree(ex->phy_info);
2190 kfree(ex);
2191 ex = NULL;
2193 mutex_unlock(&ioc->sas_topology_mutex);
2195 for (i = 0; i < port_info->num_phys; i++) {
2196 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
2197 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
2198 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle);
2200 if (port_info->phy_info[i].identify.handle) {
2201 mptsas_sas_device_pg0(ioc,
2202 &port_info->phy_info[i].identify,
2203 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2204 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2205 port_info->phy_info[i].identify.handle);
2206 port_info->phy_info[i].identify.phy_id =
2207 port_info->phy_info[i].phy_id;
2210 if (port_info->phy_info[i].attached.handle) {
2211 mptsas_sas_device_pg0(ioc,
2212 &port_info->phy_info[i].attached,
2213 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2214 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2215 port_info->phy_info[i].attached.handle);
2216 port_info->phy_info[i].attached.phy_id =
2217 port_info->phy_info[i].phy_id;
2221 parent = &ioc->sh->shost_gendev;
2222 for (i = 0; i < port_info->num_phys; i++) {
2223 mutex_lock(&ioc->sas_topology_mutex);
2224 list_for_each_entry(p, &ioc->sas_topology, list) {
2225 for (j = 0; j < p->num_phys; j++) {
2226 if (port_info->phy_info[i].identify.handle !=
2227 p->phy_info[j].attached.handle)
2228 continue;
2229 rphy = mptsas_get_rphy(&p->phy_info[j]);
2230 parent = &rphy->dev;
2233 mutex_unlock(&ioc->sas_topology_mutex);
2236 mptsas_setup_wide_ports(ioc, port_info);
2238 for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
2239 mptsas_probe_one_phy(parent, &port_info->phy_info[i],
2240 ioc->sas_index, 0);
2242 return 0;
2244 out_free_port_info:
2245 if (ex) {
2246 kfree(ex->phy_info);
2247 kfree(ex);
2249 out:
2250 return error;
2254 * mptsas_delete_expander_phys
2257 * This will traverse topology, and remove expanders
2258 * that are no longer present
2260 static void
2261 mptsas_delete_expander_phys(MPT_ADAPTER *ioc)
2263 struct mptsas_portinfo buffer;
2264 struct mptsas_portinfo *port_info, *n, *parent;
2265 struct mptsas_phyinfo *phy_info;
2266 struct sas_port * port;
2267 int i;
2268 u64 expander_sas_address;
2270 mutex_lock(&ioc->sas_topology_mutex);
2271 list_for_each_entry_safe(port_info, n, &ioc->sas_topology, list) {
2273 if (port_info->phy_info &&
2274 (!(port_info->phy_info[0].identify.device_info &
2275 MPI_SAS_DEVICE_INFO_SMP_TARGET)))
2276 continue;
2278 if (mptsas_sas_expander_pg0(ioc, &buffer,
2279 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
2280 MPI_SAS_EXPAND_PGAD_FORM_SHIFT),
2281 port_info->phy_info[0].handle)) {
2284 * Obtain the port_info instance to the parent port
2286 parent = mptsas_find_portinfo_by_handle(ioc,
2287 port_info->phy_info[0].identify.handle_parent);
2289 if (!parent)
2290 goto next_port;
2292 expander_sas_address =
2293 port_info->phy_info[0].identify.sas_address;
2296 * Delete rphys in the parent that point
2297 * to this expander. The transport layer will
2298 * cleanup all the children.
2300 phy_info = parent->phy_info;
2301 for (i = 0; i < parent->num_phys; i++, phy_info++) {
2302 port = mptsas_get_port(phy_info);
2303 if (!port)
2304 continue;
2305 if (phy_info->attached.sas_address !=
2306 expander_sas_address)
2307 continue;
2308 dsaswideprintk(ioc,
2309 dev_printk(KERN_DEBUG, &port->dev,
2310 MYIOC_s_FMT "delete port (%d)\n", ioc->name,
2311 port->port_identifier));
2312 sas_port_delete(port);
2313 mptsas_port_delete(ioc, phy_info->port_details);
2315 next_port:
2317 phy_info = port_info->phy_info;
2318 for (i = 0; i < port_info->num_phys; i++, phy_info++)
2319 mptsas_port_delete(ioc, phy_info->port_details);
2321 list_del(&port_info->list);
2322 kfree(port_info->phy_info);
2323 kfree(port_info);
2326 * Free this memory allocated from inside
2327 * mptsas_sas_expander_pg0
2329 kfree(buffer.phy_info);
2331 mutex_unlock(&ioc->sas_topology_mutex);
2335 * Start of day discovery
2337 static void
2338 mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
2340 u32 handle = 0xFFFF;
2341 int i;
2343 mutex_lock(&ioc->sas_discovery_mutex);
2344 mptsas_probe_hba_phys(ioc);
2345 while (!mptsas_probe_expander_phys(ioc, &handle))
2348 Reporting RAID volumes.
2350 if (!ioc->ir_firmware)
2351 goto out;
2352 if (!ioc->raid_data.pIocPg2)
2353 goto out;
2354 if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
2355 goto out;
2356 for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
2357 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
2358 ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
2360 out:
2361 mutex_unlock(&ioc->sas_discovery_mutex);
2365 * Work queue thread to handle Runtime discovery
2366 * Mere purpose is the hot add/delete of expanders
2367 *(Mutex UNLOCKED)
2369 static void
2370 __mptsas_discovery_work(MPT_ADAPTER *ioc)
2372 u32 handle = 0xFFFF;
2374 ioc->sas_discovery_runtime=1;
2375 mptsas_delete_expander_phys(ioc);
2376 mptsas_probe_hba_phys(ioc);
2377 while (!mptsas_probe_expander_phys(ioc, &handle))
2379 ioc->sas_discovery_runtime=0;
2383 * Work queue thread to handle Runtime discovery
2384 * Mere purpose is the hot add/delete of expanders
2385 *(Mutex LOCKED)
2387 static void
2388 mptsas_discovery_work(struct work_struct *work)
2390 struct mptsas_discovery_event *ev =
2391 container_of(work, struct mptsas_discovery_event, work);
2392 MPT_ADAPTER *ioc = ev->ioc;
2394 mutex_lock(&ioc->sas_discovery_mutex);
2395 __mptsas_discovery_work(ioc);
2396 mutex_unlock(&ioc->sas_discovery_mutex);
2397 kfree(ev);
2400 static struct mptsas_phyinfo *
2401 mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
2403 struct mptsas_portinfo *port_info;
2404 struct mptsas_phyinfo *phy_info = NULL;
2405 int i;
2407 mutex_lock(&ioc->sas_topology_mutex);
2408 list_for_each_entry(port_info, &ioc->sas_topology, list) {
2409 for (i = 0; i < port_info->num_phys; i++) {
2410 if (!mptsas_is_end_device(
2411 &port_info->phy_info[i].attached))
2412 continue;
2413 if (port_info->phy_info[i].attached.sas_address
2414 != sas_address)
2415 continue;
2416 phy_info = &port_info->phy_info[i];
2417 break;
2420 mutex_unlock(&ioc->sas_topology_mutex);
2421 return phy_info;
2424 static struct mptsas_phyinfo *
2425 mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u8 channel, u8 id)
2427 struct mptsas_portinfo *port_info;
2428 struct mptsas_phyinfo *phy_info = NULL;
2429 int i;
2431 mutex_lock(&ioc->sas_topology_mutex);
2432 list_for_each_entry(port_info, &ioc->sas_topology, list) {
2433 for (i = 0; i < port_info->num_phys; i++) {
2434 if (!mptsas_is_end_device(
2435 &port_info->phy_info[i].attached))
2436 continue;
2437 if (port_info->phy_info[i].attached.id != id)
2438 continue;
2439 if (port_info->phy_info[i].attached.channel != channel)
2440 continue;
2441 phy_info = &port_info->phy_info[i];
2442 break;
2445 mutex_unlock(&ioc->sas_topology_mutex);
2446 return phy_info;
2449 static struct mptsas_phyinfo *
2450 mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
2452 struct mptsas_portinfo *port_info;
2453 struct mptsas_phyinfo *phy_info = NULL;
2454 int i;
2456 mutex_lock(&ioc->sas_topology_mutex);
2457 list_for_each_entry(port_info, &ioc->sas_topology, list) {
2458 for (i = 0; i < port_info->num_phys; i++) {
2459 if (!mptsas_is_end_device(
2460 &port_info->phy_info[i].attached))
2461 continue;
2462 if (port_info->phy_info[i].attached.phys_disk_num == ~0)
2463 continue;
2464 if (port_info->phy_info[i].attached.phys_disk_num != id)
2465 continue;
2466 if (port_info->phy_info[i].attached.channel != channel)
2467 continue;
2468 phy_info = &port_info->phy_info[i];
2469 break;
2472 mutex_unlock(&ioc->sas_topology_mutex);
2473 return phy_info;
2477 * Work queue thread to clear the persitency table
2479 static void
2480 mptsas_persist_clear_table(struct work_struct *work)
2482 MPT_ADAPTER *ioc = container_of(work, MPT_ADAPTER, sas_persist_task);
2484 mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
2487 static void
2488 mptsas_reprobe_lun(struct scsi_device *sdev, void *data)
2490 int rc;
2492 sdev->no_uld_attach = data ? 1 : 0;
2493 rc = scsi_device_reprobe(sdev);
2496 static void
2497 mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)
2499 starget_for_each_device(starget, uld_attach ? (void *)1 : NULL,
2500 mptsas_reprobe_lun);
2503 static void
2504 mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id)
2506 CONFIGPARMS cfg;
2507 ConfigPageHeader_t hdr;
2508 dma_addr_t dma_handle;
2509 pRaidVolumePage0_t buffer = NULL;
2510 RaidPhysDiskPage0_t phys_disk;
2511 int i;
2512 struct mptsas_hotplug_event *ev;
2514 memset(&cfg, 0 , sizeof(CONFIGPARMS));
2515 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
2516 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
2517 cfg.pageAddr = (channel << 8) + id;
2518 cfg.cfghdr.hdr = &hdr;
2519 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2521 if (mpt_config(ioc, &cfg) != 0)
2522 goto out;
2524 if (!hdr.PageLength)
2525 goto out;
2527 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
2528 &dma_handle);
2530 if (!buffer)
2531 goto out;
2533 cfg.physAddr = dma_handle;
2534 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2536 if (mpt_config(ioc, &cfg) != 0)
2537 goto out;
2539 if (!(buffer->VolumeStatus.Flags &
2540 MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE))
2541 goto out;
2543 if (!buffer->NumPhysDisks)
2544 goto out;
2546 for (i = 0; i < buffer->NumPhysDisks; i++) {
2548 if (mpt_raid_phys_disk_pg0(ioc,
2549 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
2550 continue;
2552 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2553 if (!ev) {
2554 printk(MYIOC_s_WARN_FMT "mptsas: lost hotplug event\n", ioc->name);
2555 goto out;
2558 INIT_WORK(&ev->work, mptsas_hotplug_work);
2559 ev->ioc = ioc;
2560 ev->id = phys_disk.PhysDiskID;
2561 ev->channel = phys_disk.PhysDiskBus;
2562 ev->phys_disk_num_valid = 1;
2563 ev->phys_disk_num = phys_disk.PhysDiskNum;
2564 ev->event_type = MPTSAS_ADD_DEVICE;
2565 schedule_work(&ev->work);
2568 out:
2569 if (buffer)
2570 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
2571 dma_handle);
2574 * Work queue thread to handle SAS hotplug events
2576 static void
2577 mptsas_hotplug_work(struct work_struct *work)
2579 struct mptsas_hotplug_event *ev =
2580 container_of(work, struct mptsas_hotplug_event, work);
2582 MPT_ADAPTER *ioc = ev->ioc;
2583 struct mptsas_phyinfo *phy_info;
2584 struct sas_rphy *rphy;
2585 struct sas_port *port;
2586 struct scsi_device *sdev;
2587 struct scsi_target * starget;
2588 struct sas_identify identify;
2589 char *ds = NULL;
2590 struct mptsas_devinfo sas_device;
2591 VirtTarget *vtarget;
2592 VirtDevice *vdevice;
2594 mutex_lock(&ioc->sas_discovery_mutex);
2595 switch (ev->event_type) {
2596 case MPTSAS_DEL_DEVICE:
2598 phy_info = NULL;
2599 if (ev->phys_disk_num_valid) {
2600 if (ev->hidden_raid_component){
2601 if (mptsas_sas_device_pg0(ioc, &sas_device,
2602 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
2603 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2604 (ev->channel << 8) + ev->id)) {
2605 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2606 "%s: exit at line=%d\n", ioc->name,
2607 __FUNCTION__, __LINE__));
2608 break;
2610 phy_info = mptsas_find_phyinfo_by_sas_address(
2611 ioc, sas_device.sas_address);
2612 }else
2613 phy_info = mptsas_find_phyinfo_by_phys_disk_num(
2614 ioc, ev->channel, ev->phys_disk_num);
2617 if (!phy_info)
2618 phy_info = mptsas_find_phyinfo_by_target(ioc,
2619 ev->channel, ev->id);
2622 * Sanity checks, for non-existing phys and remote rphys.
2624 if (!phy_info){
2625 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2626 "%s: exit at line=%d\n", ioc->name,
2627 __FUNCTION__, __LINE__));
2628 break;
2630 if (!phy_info->port_details) {
2631 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2632 "%s: exit at line=%d\n", ioc->name,
2633 __FUNCTION__, __LINE__));
2634 break;
2636 rphy = mptsas_get_rphy(phy_info);
2637 if (!rphy) {
2638 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2639 "%s: exit at line=%d\n", ioc->name,
2640 __FUNCTION__, __LINE__));
2641 break;
2644 port = mptsas_get_port(phy_info);
2645 if (!port) {
2646 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2647 "%s: exit at line=%d\n", ioc->name,
2648 __FUNCTION__, __LINE__));
2649 break;
2652 starget = mptsas_get_starget(phy_info);
2653 if (starget) {
2654 vtarget = starget->hostdata;
2656 if (!vtarget) {
2657 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2658 "%s: exit at line=%d\n", ioc->name,
2659 __FUNCTION__, __LINE__));
2660 break;
2664 * Handling RAID components
2666 if (ev->phys_disk_num_valid &&
2667 ev->hidden_raid_component) {
2668 printk(MYIOC_s_INFO_FMT
2669 "RAID Hidding: channel=%d, id=%d, "
2670 "physdsk %d \n", ioc->name, ev->channel,
2671 ev->id, ev->phys_disk_num);
2672 vtarget->id = ev->phys_disk_num;
2673 vtarget->tflags |=
2674 MPT_TARGET_FLAGS_RAID_COMPONENT;
2675 mptsas_reprobe_target(starget, 1);
2676 phy_info->attached.phys_disk_num =
2677 ev->phys_disk_num;
2678 break;
2682 if (phy_info->attached.device_info &
2683 MPI_SAS_DEVICE_INFO_SSP_TARGET)
2684 ds = "ssp";
2685 if (phy_info->attached.device_info &
2686 MPI_SAS_DEVICE_INFO_STP_TARGET)
2687 ds = "stp";
2688 if (phy_info->attached.device_info &
2689 MPI_SAS_DEVICE_INFO_SATA_DEVICE)
2690 ds = "sata";
2692 printk(MYIOC_s_INFO_FMT
2693 "removing %s device, channel %d, id %d, phy %d\n",
2694 ioc->name, ds, ev->channel, ev->id, phy_info->phy_id);
2695 dev_printk(KERN_DEBUG, &port->dev, MYIOC_s_FMT
2696 "delete port (%d)\n", ioc->name, port->port_identifier);
2697 sas_port_delete(port);
2698 mptsas_port_delete(ioc, phy_info->port_details);
2699 break;
2700 case MPTSAS_ADD_DEVICE:
2702 if (ev->phys_disk_num_valid)
2703 mpt_findImVolumes(ioc);
2706 * Refresh sas device pg0 data
2708 if (mptsas_sas_device_pg0(ioc, &sas_device,
2709 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
2710 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2711 (ev->channel << 8) + ev->id)) {
2712 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2713 "%s: exit at line=%d\n", ioc->name,
2714 __FUNCTION__, __LINE__));
2715 break;
2718 __mptsas_discovery_work(ioc);
2720 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
2721 sas_device.sas_address);
2723 if (!phy_info || !phy_info->port_details) {
2724 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2725 "%s: exit at line=%d\n", ioc->name,
2726 __FUNCTION__, __LINE__));
2727 break;
2730 starget = mptsas_get_starget(phy_info);
2731 if (starget && (!ev->hidden_raid_component)){
2733 vtarget = starget->hostdata;
2735 if (!vtarget) {
2736 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2737 "%s: exit at line=%d\n", ioc->name,
2738 __FUNCTION__, __LINE__));
2739 break;
2742 * Handling RAID components
2744 if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
2745 printk(MYIOC_s_INFO_FMT
2746 "RAID Exposing: channel=%d, id=%d, "
2747 "physdsk %d \n", ioc->name, ev->channel,
2748 ev->id, ev->phys_disk_num);
2749 vtarget->tflags &=
2750 ~MPT_TARGET_FLAGS_RAID_COMPONENT;
2751 vtarget->id = ev->id;
2752 mptsas_reprobe_target(starget, 0);
2753 phy_info->attached.phys_disk_num = ~0;
2755 break;
2758 if (mptsas_get_rphy(phy_info)) {
2759 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2760 "%s: exit at line=%d\n", ioc->name,
2761 __FUNCTION__, __LINE__));
2762 if (ev->channel) printk("%d\n", __LINE__);
2763 break;
2766 port = mptsas_get_port(phy_info);
2767 if (!port) {
2768 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2769 "%s: exit at line=%d\n", ioc->name,
2770 __FUNCTION__, __LINE__));
2771 break;
2773 memcpy(&phy_info->attached, &sas_device,
2774 sizeof(struct mptsas_devinfo));
2776 if (phy_info->attached.device_info &
2777 MPI_SAS_DEVICE_INFO_SSP_TARGET)
2778 ds = "ssp";
2779 if (phy_info->attached.device_info &
2780 MPI_SAS_DEVICE_INFO_STP_TARGET)
2781 ds = "stp";
2782 if (phy_info->attached.device_info &
2783 MPI_SAS_DEVICE_INFO_SATA_DEVICE)
2784 ds = "sata";
2786 printk(MYIOC_s_INFO_FMT
2787 "attaching %s device, channel %d, id %d, phy %d\n",
2788 ioc->name, ds, ev->channel, ev->id, ev->phy_id);
2790 mptsas_parse_device_info(&identify, &phy_info->attached);
2791 rphy = sas_end_device_alloc(port);
2792 if (!rphy) {
2793 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2794 "%s: exit at line=%d\n", ioc->name,
2795 __FUNCTION__, __LINE__));
2796 break; /* non-fatal: an rphy can be added later */
2799 rphy->identify = identify;
2800 if (sas_rphy_add(rphy)) {
2801 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2802 "%s: exit at line=%d\n", ioc->name,
2803 __FUNCTION__, __LINE__));
2804 sas_rphy_free(rphy);
2805 break;
2807 mptsas_set_rphy(ioc, phy_info, rphy);
2808 break;
2809 case MPTSAS_ADD_RAID:
2810 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
2811 ev->id, 0);
2812 if (sdev) {
2813 scsi_device_put(sdev);
2814 break;
2816 printk(MYIOC_s_INFO_FMT
2817 "attaching raid volume, channel %d, id %d\n",
2818 ioc->name, MPTSAS_RAID_CHANNEL, ev->id);
2819 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL, ev->id, 0);
2820 mpt_findImVolumes(ioc);
2821 break;
2822 case MPTSAS_DEL_RAID:
2823 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
2824 ev->id, 0);
2825 if (!sdev)
2826 break;
2827 printk(MYIOC_s_INFO_FMT
2828 "removing raid volume, channel %d, id %d\n",
2829 ioc->name, MPTSAS_RAID_CHANNEL, ev->id);
2830 vdevice = sdev->hostdata;
2831 scsi_remove_device(sdev);
2832 scsi_device_put(sdev);
2833 mpt_findImVolumes(ioc);
2834 break;
2835 case MPTSAS_ADD_INACTIVE_VOLUME:
2836 mptsas_adding_inactive_raid_components(ioc,
2837 ev->channel, ev->id);
2838 break;
2839 case MPTSAS_IGNORE_EVENT:
2840 default:
2841 break;
2844 mutex_unlock(&ioc->sas_discovery_mutex);
2845 kfree(ev);
2848 static void
2849 mptsas_send_sas_event(MPT_ADAPTER *ioc,
2850 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
2852 struct mptsas_hotplug_event *ev;
2853 u32 device_info = le32_to_cpu(sas_event_data->DeviceInfo);
2854 __le64 sas_address;
2856 if ((device_info &
2857 (MPI_SAS_DEVICE_INFO_SSP_TARGET |
2858 MPI_SAS_DEVICE_INFO_STP_TARGET |
2859 MPI_SAS_DEVICE_INFO_SATA_DEVICE )) == 0)
2860 return;
2862 switch (sas_event_data->ReasonCode) {
2863 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
2865 mptsas_target_reset_queue(ioc, sas_event_data);
2866 break;
2868 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
2869 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2870 if (!ev) {
2871 printk(MYIOC_s_WARN_FMT "lost hotplug event\n", ioc->name);
2872 break;
2875 INIT_WORK(&ev->work, mptsas_hotplug_work);
2876 ev->ioc = ioc;
2877 ev->handle = le16_to_cpu(sas_event_data->DevHandle);
2878 ev->parent_handle =
2879 le16_to_cpu(sas_event_data->ParentDevHandle);
2880 ev->channel = sas_event_data->Bus;
2881 ev->id = sas_event_data->TargetID;
2882 ev->phy_id = sas_event_data->PhyNum;
2883 memcpy(&sas_address, &sas_event_data->SASAddress,
2884 sizeof(__le64));
2885 ev->sas_address = le64_to_cpu(sas_address);
2886 ev->device_info = device_info;
2888 if (sas_event_data->ReasonCode &
2889 MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
2890 ev->event_type = MPTSAS_ADD_DEVICE;
2891 else
2892 ev->event_type = MPTSAS_DEL_DEVICE;
2893 schedule_work(&ev->work);
2894 break;
2895 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
2897 * Persistent table is full.
2899 INIT_WORK(&ioc->sas_persist_task,
2900 mptsas_persist_clear_table);
2901 schedule_work(&ioc->sas_persist_task);
2902 break;
2904 * TODO, handle other events
2906 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
2907 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
2908 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
2909 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
2910 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
2911 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
2912 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
2913 default:
2914 break;
2917 static void
2918 mptsas_send_raid_event(MPT_ADAPTER *ioc,
2919 EVENT_DATA_RAID *raid_event_data)
2921 struct mptsas_hotplug_event *ev;
2922 int status = le32_to_cpu(raid_event_data->SettingsStatus);
2923 int state = (status >> 8) & 0xff;
2925 if (ioc->bus_type != SAS)
2926 return;
2928 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2929 if (!ev) {
2930 printk(MYIOC_s_WARN_FMT "lost hotplug event\n", ioc->name);
2931 return;
2934 INIT_WORK(&ev->work, mptsas_hotplug_work);
2935 ev->ioc = ioc;
2936 ev->id = raid_event_data->VolumeID;
2937 ev->channel = raid_event_data->VolumeBus;
2938 ev->event_type = MPTSAS_IGNORE_EVENT;
2940 switch (raid_event_data->ReasonCode) {
2941 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
2942 ev->phys_disk_num_valid = 1;
2943 ev->phys_disk_num = raid_event_data->PhysDiskNum;
2944 ev->event_type = MPTSAS_ADD_DEVICE;
2945 break;
2946 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
2947 ev->phys_disk_num_valid = 1;
2948 ev->phys_disk_num = raid_event_data->PhysDiskNum;
2949 ev->hidden_raid_component = 1;
2950 ev->event_type = MPTSAS_DEL_DEVICE;
2951 break;
2952 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
2953 switch (state) {
2954 case MPI_PD_STATE_ONLINE:
2955 case MPI_PD_STATE_NOT_COMPATIBLE:
2956 ev->phys_disk_num_valid = 1;
2957 ev->phys_disk_num = raid_event_data->PhysDiskNum;
2958 ev->hidden_raid_component = 1;
2959 ev->event_type = MPTSAS_ADD_DEVICE;
2960 break;
2961 case MPI_PD_STATE_MISSING:
2962 case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST:
2963 case MPI_PD_STATE_FAILED_AT_HOST_REQUEST:
2964 case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON:
2965 ev->phys_disk_num_valid = 1;
2966 ev->phys_disk_num = raid_event_data->PhysDiskNum;
2967 ev->event_type = MPTSAS_DEL_DEVICE;
2968 break;
2969 default:
2970 break;
2972 break;
2973 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
2974 ev->event_type = MPTSAS_DEL_RAID;
2975 break;
2976 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
2977 ev->event_type = MPTSAS_ADD_RAID;
2978 break;
2979 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
2980 switch (state) {
2981 case MPI_RAIDVOL0_STATUS_STATE_FAILED:
2982 case MPI_RAIDVOL0_STATUS_STATE_MISSING:
2983 ev->event_type = MPTSAS_DEL_RAID;
2984 break;
2985 case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL:
2986 case MPI_RAIDVOL0_STATUS_STATE_DEGRADED:
2987 ev->event_type = MPTSAS_ADD_RAID;
2988 break;
2989 default:
2990 break;
2992 break;
2993 default:
2994 break;
2996 schedule_work(&ev->work);
2999 static void
3000 mptsas_send_discovery_event(MPT_ADAPTER *ioc,
3001 EVENT_DATA_SAS_DISCOVERY *discovery_data)
3003 struct mptsas_discovery_event *ev;
3006 * DiscoveryStatus
3008 * This flag will be non-zero when firmware
3009 * kicks off discovery, and return to zero
3010 * once its completed.
3012 if (discovery_data->DiscoveryStatus)
3013 return;
3015 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
3016 if (!ev)
3017 return;
3018 INIT_WORK(&ev->work, mptsas_discovery_work);
3019 ev->ioc = ioc;
3020 schedule_work(&ev->work);
3024 * mptsas_send_ir2_event - handle exposing hidden disk when
3025 * an inactive raid volume is added
3027 * @ioc: Pointer to MPT_ADAPTER structure
3028 * @ir2_data
3031 static void
3032 mptsas_send_ir2_event(MPT_ADAPTER *ioc, PTR_MPI_EVENT_DATA_IR2 ir2_data)
3034 struct mptsas_hotplug_event *ev;
3036 if (ir2_data->ReasonCode !=
3037 MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED)
3038 return;
3040 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
3041 if (!ev)
3042 return;
3044 INIT_WORK(&ev->work, mptsas_hotplug_work);
3045 ev->ioc = ioc;
3046 ev->id = ir2_data->TargetID;
3047 ev->channel = ir2_data->Bus;
3048 ev->event_type = MPTSAS_ADD_INACTIVE_VOLUME;
3050 schedule_work(&ev->work);
3053 static int
3054 mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
3056 int rc=1;
3057 u8 event = le32_to_cpu(reply->Event) & 0xFF;
3059 if (!ioc->sh)
3060 goto out;
3063 * sas_discovery_ignore_events
3065 * This flag is to prevent anymore processing of
3066 * sas events once mptsas_remove function is called.
3068 if (ioc->sas_discovery_ignore_events) {
3069 rc = mptscsih_event_process(ioc, reply);
3070 goto out;
3073 switch (event) {
3074 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
3075 mptsas_send_sas_event(ioc,
3076 (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data);
3077 break;
3078 case MPI_EVENT_INTEGRATED_RAID:
3079 mptsas_send_raid_event(ioc,
3080 (EVENT_DATA_RAID *)reply->Data);
3081 break;
3082 case MPI_EVENT_PERSISTENT_TABLE_FULL:
3083 INIT_WORK(&ioc->sas_persist_task,
3084 mptsas_persist_clear_table);
3085 schedule_work(&ioc->sas_persist_task);
3086 break;
3087 case MPI_EVENT_SAS_DISCOVERY:
3088 mptsas_send_discovery_event(ioc,
3089 (EVENT_DATA_SAS_DISCOVERY *)reply->Data);
3090 break;
3091 case MPI_EVENT_IR2:
3092 mptsas_send_ir2_event(ioc,
3093 (PTR_MPI_EVENT_DATA_IR2)reply->Data);
3094 break;
3095 default:
3096 rc = mptscsih_event_process(ioc, reply);
3097 break;
3099 out:
3101 return rc;
3104 static int
3105 mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
3107 struct Scsi_Host *sh;
3108 MPT_SCSI_HOST *hd;
3109 MPT_ADAPTER *ioc;
3110 unsigned long flags;
3111 int ii;
3112 int numSGE = 0;
3113 int scale;
3114 int ioc_cap;
3115 int error=0;
3116 int r;
3118 r = mpt_attach(pdev,id);
3119 if (r)
3120 return r;
3122 ioc = pci_get_drvdata(pdev);
3123 ioc->DoneCtx = mptsasDoneCtx;
3124 ioc->TaskCtx = mptsasTaskCtx;
3125 ioc->InternalCtx = mptsasInternalCtx;
3127 /* Added sanity check on readiness of the MPT adapter.
3129 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
3130 printk(MYIOC_s_WARN_FMT
3131 "Skipping because it's not operational!\n",
3132 ioc->name);
3133 error = -ENODEV;
3134 goto out_mptsas_probe;
3137 if (!ioc->active) {
3138 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
3139 ioc->name);
3140 error = -ENODEV;
3141 goto out_mptsas_probe;
3144 /* Sanity check - ensure at least 1 port is INITIATOR capable
3146 ioc_cap = 0;
3147 for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
3148 if (ioc->pfacts[ii].ProtocolFlags &
3149 MPI_PORTFACTS_PROTOCOL_INITIATOR)
3150 ioc_cap++;
3153 if (!ioc_cap) {
3154 printk(MYIOC_s_WARN_FMT
3155 "Skipping ioc=%p because SCSI Initiator mode "
3156 "is NOT enabled!\n", ioc->name, ioc);
3157 return 0;
3160 sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
3161 if (!sh) {
3162 printk(MYIOC_s_WARN_FMT
3163 "Unable to register controller with SCSI subsystem\n",
3164 ioc->name);
3165 error = -1;
3166 goto out_mptsas_probe;
3169 spin_lock_irqsave(&ioc->FreeQlock, flags);
3171 /* Attach the SCSI Host to the IOC structure
3173 ioc->sh = sh;
3175 sh->io_port = 0;
3176 sh->n_io_port = 0;
3177 sh->irq = 0;
3179 /* set 16 byte cdb's */
3180 sh->max_cmd_len = 16;
3182 sh->max_id = ioc->pfacts[0].PortSCSIID;
3183 sh->max_lun = max_lun;
3185 sh->transportt = mptsas_transport_template;
3187 sh->this_id = ioc->pfacts[0].PortSCSIID;
3189 /* Required entry.
3191 sh->unique_id = ioc->id;
3193 INIT_LIST_HEAD(&ioc->sas_topology);
3194 mutex_init(&ioc->sas_topology_mutex);
3195 mutex_init(&ioc->sas_discovery_mutex);
3196 mutex_init(&ioc->sas_mgmt.mutex);
3197 init_completion(&ioc->sas_mgmt.done);
3199 /* Verify that we won't exceed the maximum
3200 * number of chain buffers
3201 * We can optimize: ZZ = req_sz/sizeof(SGE)
3202 * For 32bit SGE's:
3203 * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
3204 * + (req_sz - 64)/sizeof(SGE)
3205 * A slightly different algorithm is required for
3206 * 64bit SGEs.
3208 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3209 if (sizeof(dma_addr_t) == sizeof(u64)) {
3210 numSGE = (scale - 1) *
3211 (ioc->facts.MaxChainDepth-1) + scale +
3212 (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
3213 sizeof(u32));
3214 } else {
3215 numSGE = 1 + (scale - 1) *
3216 (ioc->facts.MaxChainDepth-1) + scale +
3217 (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
3218 sizeof(u32));
3221 if (numSGE < sh->sg_tablesize) {
3222 /* Reset this value */
3223 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3224 "Resetting sg_tablesize to %d from %d\n",
3225 ioc->name, numSGE, sh->sg_tablesize));
3226 sh->sg_tablesize = numSGE;
3229 hd = shost_priv(sh);
3230 hd->ioc = ioc;
3232 /* SCSI needs scsi_cmnd lookup table!
3233 * (with size equal to req_depth*PtrSz!)
3235 ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
3236 if (!ioc->ScsiLookup) {
3237 error = -ENOMEM;
3238 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3239 goto out_mptsas_probe;
3241 spin_lock_init(&ioc->scsi_lookup_lock);
3243 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
3244 ioc->name, ioc->ScsiLookup));
3246 /* Clear the TM flags
3248 hd->tmPending = 0;
3249 hd->tmState = TM_STATE_NONE;
3250 hd->resetPending = 0;
3251 hd->abortSCpnt = NULL;
3253 /* Clear the pointer used to store
3254 * single-threaded commands, i.e., those
3255 * issued during a bus scan, dv and
3256 * configuration pages.
3258 hd->cmdPtr = NULL;
3260 /* Initialize this SCSI Hosts' timers
3261 * To use, set the timer expires field
3262 * and add_timer
3264 init_timer(&hd->timer);
3265 hd->timer.data = (unsigned long) hd;
3266 hd->timer.function = mptscsih_timer_expired;
3268 ioc->sas_data.ptClear = mpt_pt_clear;
3270 init_waitqueue_head(&hd->scandv_waitq);
3271 hd->scandv_wait_done = 0;
3272 hd->last_queue_full = 0;
3273 INIT_LIST_HEAD(&hd->target_reset_list);
3274 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3276 if (ioc->sas_data.ptClear==1) {
3277 mptbase_sas_persist_operation(
3278 ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
3281 error = scsi_add_host(sh, &ioc->pcidev->dev);
3282 if (error) {
3283 dprintk(ioc, printk(MYIOC_s_ERR_FMT
3284 "scsi_add_host failed\n", ioc->name));
3285 goto out_mptsas_probe;
3288 mptsas_scan_sas_topology(ioc);
3290 return 0;
3292 out_mptsas_probe:
3294 mptscsih_remove(pdev);
3295 return error;
3298 static void __devexit mptsas_remove(struct pci_dev *pdev)
3300 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
3301 struct mptsas_portinfo *p, *n;
3302 int i;
3304 ioc->sas_discovery_ignore_events = 1;
3305 sas_remove_host(ioc->sh);
3307 mutex_lock(&ioc->sas_topology_mutex);
3308 list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
3309 list_del(&p->list);
3310 for (i = 0 ; i < p->num_phys ; i++)
3311 mptsas_port_delete(ioc, p->phy_info[i].port_details);
3312 kfree(p->phy_info);
3313 kfree(p);
3315 mutex_unlock(&ioc->sas_topology_mutex);
3317 mptscsih_remove(pdev);
3320 static struct pci_device_id mptsas_pci_table[] = {
3321 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064,
3322 PCI_ANY_ID, PCI_ANY_ID },
3323 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068,
3324 PCI_ANY_ID, PCI_ANY_ID },
3325 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064E,
3326 PCI_ANY_ID, PCI_ANY_ID },
3327 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068E,
3328 PCI_ANY_ID, PCI_ANY_ID },
3329 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1078,
3330 PCI_ANY_ID, PCI_ANY_ID },
3331 {0} /* Terminating entry */
3333 MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
3336 static struct pci_driver mptsas_driver = {
3337 .name = "mptsas",
3338 .id_table = mptsas_pci_table,
3339 .probe = mptsas_probe,
3340 .remove = __devexit_p(mptsas_remove),
3341 .shutdown = mptscsih_shutdown,
3342 #ifdef CONFIG_PM
3343 .suspend = mptscsih_suspend,
3344 .resume = mptscsih_resume,
3345 #endif
3348 static int __init
3349 mptsas_init(void)
3351 int error;
3353 show_mptmod_ver(my_NAME, my_VERSION);
3355 mptsas_transport_template =
3356 sas_attach_transport(&mptsas_transport_functions);
3357 if (!mptsas_transport_template)
3358 return -ENODEV;
3360 mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
3361 mptsasTaskCtx = mpt_register(mptsas_taskmgmt_complete, MPTSAS_DRIVER);
3362 mptsasInternalCtx =
3363 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
3364 mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
3366 mpt_event_register(mptsasDoneCtx, mptsas_event_process);
3367 mpt_reset_register(mptsasDoneCtx, mptsas_ioc_reset);
3369 error = pci_register_driver(&mptsas_driver);
3370 if (error)
3371 sas_release_transport(mptsas_transport_template);
3373 return error;
3376 static void __exit
3377 mptsas_exit(void)
3379 pci_unregister_driver(&mptsas_driver);
3380 sas_release_transport(mptsas_transport_template);
3382 mpt_reset_deregister(mptsasDoneCtx);
3383 mpt_event_deregister(mptsasDoneCtx);
3385 mpt_deregister(mptsasMgmtCtx);
3386 mpt_deregister(mptsasInternalCtx);
3387 mpt_deregister(mptsasTaskCtx);
3388 mpt_deregister(mptsasDoneCtx);
3391 module_init(mptsas_init);
3392 module_exit(mptsas_exit);