1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
25 * Copyright (c) 2014, Joyent, Inc. All rights reserved.
26 * Copyright 2014 OmniTI Computer Consulting, Inc. All rights reserved.
27 * Copyright (c) 2014, Tegile Systems Inc. All rights reserved.
28 */
29
30 /*
31 * Copyright (c) 2000 to 2010, LSI Corporation.
32 * All rights reserved.
33 *
34 * Redistribution and use in source and binary forms of all code within
35 * this file that is exclusively owned by LSI, with or without
36 * modification, is permitted provided that, in addition to the CDDL 1.0
37 * License requirements, the following conditions are met:
38 *
39 * Neither the name of the author nor the names of its contributors may be
40 * used to endorse or promote products derived from this software without
41 * specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
46 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
47 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
48 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
49 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
50 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
51 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
52 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
53 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
54 * DAMAGE.
55 */
56
57 /*
58 * mptsas - This is a driver based on LSI Logic's MPT2.0/2.5 interface.
59 *
60 */
61
62 #if defined(lint) || defined(DEBUG)
63 #define MPTSAS_DEBUG
64 #endif
65
66 /*
67 * standard header files.
68 */
69 #include <sys/note.h>
70 #include <sys/scsi/scsi.h>
71 #include <sys/pci.h>
72 #include <sys/file.h>
73 #include <sys/policy.h>
74 #include <sys/model.h>
75 #include <sys/sysevent.h>
76 #include <sys/sysevent/eventdefs.h>
77 #include <sys/sysevent/dr.h>
78 #include <sys/sata/sata_defs.h>
79 #include <sys/scsi/generic/sas.h>
80 #include <sys/scsi/impl/scsi_sas.h>
81
82 #pragma pack(1)
83 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h>
84 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h>
85 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h>
86 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h>
87 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h>
88 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_sas.h>
89 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h>
90 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_raid.h>
91 #pragma pack()
92
93 /*
94 * private header files.
95 *
96 */
97 #include <sys/scsi/impl/scsi_reset_notify.h>
98 #include <sys/scsi/adapters/mpt_sas/mptsas_var.h>
99 #include <sys/scsi/adapters/mpt_sas/mptsas_ioctl.h>
100 #include <sys/scsi/adapters/mpt_sas/mptsas_smhba.h>
101 #include <sys/scsi/adapters/mpt_sas/mptsas_hash.h>
102 #include <sys/raidioctl.h>
103
104 #include <sys/fs/dv_node.h> /* devfs_clean */
105
106 /*
107 * FMA header files
108 */
109 #include <sys/ddifm.h>
110 #include <sys/fm/protocol.h>
111 #include <sys/fm/util.h>
112 #include <sys/fm/io/ddi.h>
113
114 /*
115 * autoconfiguration data and routines.
116 */
117 static int mptsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
118 static int mptsas_detach(dev_info_t *devi, ddi_detach_cmd_t cmd);
119 static int mptsas_power(dev_info_t *dip, int component, int level);
120
121 /*
122 * cb_ops function
123 */
124 static int mptsas_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
125 cred_t *credp, int *rval);
126 #ifdef __sparc
127 static int mptsas_reset(dev_info_t *devi, ddi_reset_cmd_t cmd);
128 #else /* __sparc */
129 static int mptsas_quiesce(dev_info_t *devi);
130 #endif /* __sparc */
131
132 /*
133 * Resource initilaization for hardware
134 */
135 static void mptsas_setup_cmd_reg(mptsas_t *mpt);
136 static void mptsas_disable_bus_master(mptsas_t *mpt);
137 static void mptsas_hba_fini(mptsas_t *mpt);
138 static void mptsas_cfg_fini(mptsas_t *mptsas_blkp);
139 static int mptsas_hba_setup(mptsas_t *mpt);
140 static void mptsas_hba_teardown(mptsas_t *mpt);
141 static int mptsas_config_space_init(mptsas_t *mpt);
142 static void mptsas_config_space_fini(mptsas_t *mpt);
143 static void mptsas_iport_register(mptsas_t *mpt);
144 static int mptsas_smp_setup(mptsas_t *mpt);
145 static void mptsas_smp_teardown(mptsas_t *mpt);
146 static int mptsas_cache_create(mptsas_t *mpt);
147 static void mptsas_cache_destroy(mptsas_t *mpt);
148 static int mptsas_alloc_request_frames(mptsas_t *mpt);
149 static int mptsas_alloc_reply_frames(mptsas_t *mpt);
150 static int mptsas_alloc_free_queue(mptsas_t *mpt);
151 static int mptsas_alloc_post_queue(mptsas_t *mpt);
152 static void mptsas_alloc_reply_args(mptsas_t *mpt);
153 static int mptsas_alloc_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd);
154 static void mptsas_free_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd);
155 static int mptsas_init_chip(mptsas_t *mpt, int first_time);
156
157 /*
158 * SCSA function prototypes
159 */
160 static int mptsas_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt);
161 static int mptsas_scsi_reset(struct scsi_address *ap, int level);
162 static int mptsas_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt);
163 static int mptsas_scsi_getcap(struct scsi_address *ap, char *cap, int tgtonly);
164 static int mptsas_scsi_setcap(struct scsi_address *ap, char *cap, int value,
165 int tgtonly);
166 static void mptsas_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt);
167 static struct scsi_pkt *mptsas_scsi_init_pkt(struct scsi_address *ap,
168 struct scsi_pkt *pkt, struct buf *bp, int cmdlen, int statuslen,
169 int tgtlen, int flags, int (*callback)(), caddr_t arg);
170 static void mptsas_scsi_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt);
171 static void mptsas_scsi_destroy_pkt(struct scsi_address *ap,
172 struct scsi_pkt *pkt);
173 static int mptsas_scsi_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
174 scsi_hba_tran_t *hba_tran, struct scsi_device *sd);
175 static void mptsas_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip,
176 scsi_hba_tran_t *hba_tran, struct scsi_device *sd);
177 static int mptsas_scsi_reset_notify(struct scsi_address *ap, int flag,
178 void (*callback)(caddr_t), caddr_t arg);
179 static int mptsas_get_name(struct scsi_device *sd, char *name, int len);
180 static int mptsas_get_bus_addr(struct scsi_device *sd, char *name, int len);
181 static int mptsas_scsi_quiesce(dev_info_t *dip);
182 static int mptsas_scsi_unquiesce(dev_info_t *dip);
183 static int mptsas_bus_config(dev_info_t *pdip, uint_t flags,
184 ddi_bus_config_op_t op, void *arg, dev_info_t **childp);
185
186 /*
187 * SMP functions
188 */
189 static int mptsas_smp_start(struct smp_pkt *smp_pkt);
190
191 /*
192 * internal function prototypes.
193 */
194 static void mptsas_list_add(mptsas_t *mpt);
195 static void mptsas_list_del(mptsas_t *mpt);
196
197 static int mptsas_quiesce_bus(mptsas_t *mpt);
198 static int mptsas_unquiesce_bus(mptsas_t *mpt);
199
200 static int mptsas_alloc_handshake_msg(mptsas_t *mpt, size_t alloc_size);
201 static void mptsas_free_handshake_msg(mptsas_t *mpt);
202
203 static void mptsas_ncmds_checkdrain(void *arg);
204
205 static int mptsas_prepare_pkt(mptsas_cmd_t *cmd);
206 static int mptsas_accept_pkt(mptsas_t *mpt, mptsas_cmd_t *sp);
207 static int mptsas_accept_txwq_and_pkt(mptsas_t *mpt, mptsas_cmd_t *sp);
208 static void mptsas_accept_tx_waitq(mptsas_t *mpt);
209
210 static int mptsas_do_detach(dev_info_t *dev);
211 static int mptsas_do_scsi_reset(mptsas_t *mpt, uint16_t devhdl);
212 static int mptsas_do_scsi_abort(mptsas_t *mpt, int target, int lun,
213 struct scsi_pkt *pkt);
214 static int mptsas_scsi_capchk(char *cap, int tgtonly, int *cidxp);
215
216 static void mptsas_handle_qfull(mptsas_t *mpt, mptsas_cmd_t *cmd);
217 static void mptsas_handle_event(void *args);
218 static int mptsas_handle_event_sync(void *args);
219 static void mptsas_handle_dr(void *args);
220 static void mptsas_handle_topo_change(mptsas_topo_change_list_t *topo_node,
221 dev_info_t *pdip);
222
223 static void mptsas_restart_cmd(void *);
224
225 static void mptsas_flush_hba(mptsas_t *mpt);
226 static void mptsas_flush_target(mptsas_t *mpt, ushort_t target, int lun,
227 uint8_t tasktype);
228 static void mptsas_set_pkt_reason(mptsas_t *mpt, mptsas_cmd_t *cmd,
229 uchar_t reason, uint_t stat);
230
231 static uint_t mptsas_intr(caddr_t arg1, caddr_t arg2);
232 static void mptsas_process_intr(mptsas_t *mpt,
233 pMpi2ReplyDescriptorsUnion_t reply_desc_union);
234 static void mptsas_handle_scsi_io_success(mptsas_t *mpt,
235 pMpi2ReplyDescriptorsUnion_t reply_desc);
236 static void mptsas_handle_address_reply(mptsas_t *mpt,
237 pMpi2ReplyDescriptorsUnion_t reply_desc);
238 static int mptsas_wait_intr(mptsas_t *mpt, int polltime);
239 static void mptsas_sge_setup(mptsas_t *mpt, mptsas_cmd_t *cmd,
240 uint32_t *control, pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl);
241
242 static void mptsas_watch(void *arg);
243 static void mptsas_watchsubr(mptsas_t *mpt);
244 static void mptsas_cmd_timeout(mptsas_t *mpt, mptsas_target_t *ptgt);
245
246 static void mptsas_start_passthru(mptsas_t *mpt, mptsas_cmd_t *cmd);
247 static int mptsas_do_passthru(mptsas_t *mpt, uint8_t *request, uint8_t *reply,
248 uint8_t *data, uint32_t request_size, uint32_t reply_size,
249 uint32_t data_size, uint32_t direction, uint8_t *dataout,
250 uint32_t dataout_size, short timeout, int mode);
251 static int mptsas_free_devhdl(mptsas_t *mpt, uint16_t devhdl);
252
253 static uint8_t mptsas_get_fw_diag_buffer_number(mptsas_t *mpt,
254 uint32_t unique_id);
255 static void mptsas_start_diag(mptsas_t *mpt, mptsas_cmd_t *cmd);
256 static int mptsas_post_fw_diag_buffer(mptsas_t *mpt,
257 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code);
258 static int mptsas_release_fw_diag_buffer(mptsas_t *mpt,
259 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code,
260 uint32_t diag_type);
261 static int mptsas_diag_register(mptsas_t *mpt,
262 mptsas_fw_diag_register_t *diag_register, uint32_t *return_code);
263 static int mptsas_diag_unregister(mptsas_t *mpt,
264 mptsas_fw_diag_unregister_t *diag_unregister, uint32_t *return_code);
265 static int mptsas_diag_query(mptsas_t *mpt, mptsas_fw_diag_query_t *diag_query,
266 uint32_t *return_code);
267 static int mptsas_diag_read_buffer(mptsas_t *mpt,
268 mptsas_diag_read_buffer_t *diag_read_buffer, uint8_t *ioctl_buf,
269 uint32_t *return_code, int ioctl_mode);
270 static int mptsas_diag_release(mptsas_t *mpt,
271 mptsas_fw_diag_release_t *diag_release, uint32_t *return_code);
272 static int mptsas_do_diag_action(mptsas_t *mpt, uint32_t action,
273 uint8_t *diag_action, uint32_t length, uint32_t *return_code,
274 int ioctl_mode);
275 static int mptsas_diag_action(mptsas_t *mpt, mptsas_diag_action_t *data,
276 int mode);
277
278 static int mptsas_pkt_alloc_extern(mptsas_t *mpt, mptsas_cmd_t *cmd,
279 int cmdlen, int tgtlen, int statuslen, int kf);
280 static void mptsas_pkt_destroy_extern(mptsas_t *mpt, mptsas_cmd_t *cmd);
281
282 static int mptsas_kmem_cache_constructor(void *buf, void *cdrarg, int kmflags);
283 static void mptsas_kmem_cache_destructor(void *buf, void *cdrarg);
284
285 static int mptsas_cache_frames_constructor(void *buf, void *cdrarg,
286 int kmflags);
287 static void mptsas_cache_frames_destructor(void *buf, void *cdrarg);
288
289 static void mptsas_check_scsi_io_error(mptsas_t *mpt, pMpi2SCSIIOReply_t reply,
290 mptsas_cmd_t *cmd);
291 static void mptsas_check_task_mgt(mptsas_t *mpt,
292 pMpi2SCSIManagementReply_t reply, mptsas_cmd_t *cmd);
293 static int mptsas_send_scsi_cmd(mptsas_t *mpt, struct scsi_address *ap,
294 mptsas_target_t *ptgt, uchar_t *cdb, int cdblen, struct buf *data_bp,
295 int *resid);
296
297 static int mptsas_alloc_active_slots(mptsas_t *mpt, int flag);
298 static void mptsas_free_active_slots(mptsas_t *mpt);
299 static int mptsas_start_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd);
300
301 static void mptsas_restart_hba(mptsas_t *mpt);
302 static void mptsas_restart_waitq(mptsas_t *mpt);
303
304 static void mptsas_deliver_doneq_thread(mptsas_t *mpt);
305 static void mptsas_doneq_add(mptsas_t *mpt, mptsas_cmd_t *cmd);
306 static void mptsas_doneq_mv(mptsas_t *mpt, uint64_t t);
307
308 static mptsas_cmd_t *mptsas_doneq_thread_rm(mptsas_t *mpt, uint64_t t);
309 static void mptsas_doneq_empty(mptsas_t *mpt);
310 static void mptsas_doneq_thread(mptsas_doneq_thread_arg_t *arg);
311
312 static mptsas_cmd_t *mptsas_waitq_rm(mptsas_t *mpt);
313 static void mptsas_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd);
314 static mptsas_cmd_t *mptsas_tx_waitq_rm(mptsas_t *mpt);
315 static void mptsas_tx_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd);
316
317
318 static void mptsas_start_watch_reset_delay();
319 static void mptsas_setup_bus_reset_delay(mptsas_t *mpt);
320 static void mptsas_watch_reset_delay(void *arg);
321 static int mptsas_watch_reset_delay_subr(mptsas_t *mpt);
322
323 /*
324 * helper functions
325 */
326 static void mptsas_dump_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd);
327
328 static dev_info_t *mptsas_find_child(dev_info_t *pdip, char *name);
329 static dev_info_t *mptsas_find_child_phy(dev_info_t *pdip, uint8_t phy);
330 static dev_info_t *mptsas_find_child_addr(dev_info_t *pdip, uint64_t sasaddr,
331 int lun);
332 static mdi_pathinfo_t *mptsas_find_path_addr(dev_info_t *pdip, uint64_t sasaddr,
333 int lun);
334 static mdi_pathinfo_t *mptsas_find_path_phy(dev_info_t *pdip, uint8_t phy);
335 static dev_info_t *mptsas_find_smp_child(dev_info_t *pdip, char *str_wwn);
336
337 static int mptsas_parse_address(char *name, uint64_t *wwid, uint8_t *phy,
338 int *lun);
339 static int mptsas_parse_smp_name(char *name, uint64_t *wwn);
340
341 static mptsas_target_t *mptsas_phy_to_tgt(mptsas_t *mpt,
342 mptsas_phymask_t phymask, uint8_t phy);
343 static mptsas_target_t *mptsas_wwid_to_ptgt(mptsas_t *mpt,
344 mptsas_phymask_t phymask, uint64_t wwid);
345 static mptsas_smp_t *mptsas_wwid_to_psmp(mptsas_t *mpt,
346 mptsas_phymask_t phymask, uint64_t wwid);
347
348 static int mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun,
349 uchar_t page, unsigned char *buf, int len, int *rlen, uchar_t evpd);
350
351 static int mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address,
352 uint16_t *handle, mptsas_target_t **pptgt);
353 static void mptsas_update_phymask(mptsas_t *mpt);
354
355 static int mptsas_send_sep(mptsas_t *mpt, mptsas_target_t *ptgt,
356 uint32_t *status, uint8_t cmd);
357 static dev_info_t *mptsas_get_dip_from_dev(dev_t dev,
358 mptsas_phymask_t *phymask);
359 static mptsas_target_t *mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr,
360 mptsas_phymask_t phymask);
361 static int mptsas_flush_led_status(mptsas_t *mpt, mptsas_target_t *ptgt);
362
363
364 /*
365 * Enumeration / DR functions
366 */
367 static void mptsas_config_all(dev_info_t *pdip);
368 static int mptsas_config_one_addr(dev_info_t *pdip, uint64_t sasaddr, int lun,
369 dev_info_t **lundip);
370 static int mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun,
371 dev_info_t **lundip);
372
373 static int mptsas_config_target(dev_info_t *pdip, mptsas_target_t *ptgt);
374 static int mptsas_offline_target(dev_info_t *pdip, char *name);
375
376 static int mptsas_config_raid(dev_info_t *pdip, uint16_t target,
377 dev_info_t **dip);
378
379 static int mptsas_config_luns(dev_info_t *pdip, mptsas_target_t *ptgt);
380 static int mptsas_probe_lun(dev_info_t *pdip, int lun,
381 dev_info_t **dip, mptsas_target_t *ptgt);
382
383 static int mptsas_create_lun(dev_info_t *pdip, struct scsi_inquiry *sd_inq,
384 dev_info_t **dip, mptsas_target_t *ptgt, int lun);
385
386 static int mptsas_create_phys_lun(dev_info_t *pdip, struct scsi_inquiry *sd,
387 char *guid, dev_info_t **dip, mptsas_target_t *ptgt, int lun);
388 static int mptsas_create_virt_lun(dev_info_t *pdip, struct scsi_inquiry *sd,
389 char *guid, dev_info_t **dip, mdi_pathinfo_t **pip, mptsas_target_t *ptgt,
390 int lun);
391
392 static void mptsas_offline_missed_luns(dev_info_t *pdip,
393 uint16_t *repluns, int lun_cnt, mptsas_target_t *ptgt);
394 static int mptsas_offline_lun(dev_info_t *pdip, dev_info_t *rdip,
395 mdi_pathinfo_t *rpip, uint_t flags);
396
397 static int mptsas_config_smp(dev_info_t *pdip, uint64_t sas_wwn,
398 dev_info_t **smp_dip);
399 static int mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node,
400 uint_t flags);
401
402 static int mptsas_event_query(mptsas_t *mpt, mptsas_event_query_t *data,
403 int mode, int *rval);
404 static int mptsas_event_enable(mptsas_t *mpt, mptsas_event_enable_t *data,
405 int mode, int *rval);
406 static int mptsas_event_report(mptsas_t *mpt, mptsas_event_report_t *data,
407 int mode, int *rval);
408 static void mptsas_record_event(void *args);
409 static int mptsas_reg_access(mptsas_t *mpt, mptsas_reg_access_t *data,
410 int mode);
411
412 mptsas_target_t *mptsas_tgt_alloc(mptsas_t *, uint16_t, uint64_t,
413 uint32_t, mptsas_phymask_t, uint8_t);
414 static mptsas_smp_t *mptsas_smp_alloc(mptsas_t *, mptsas_smp_t *);
415 static int mptsas_online_smp(dev_info_t *pdip, mptsas_smp_t *smp_node,
416 dev_info_t **smp_dip);
417
418 /*
419 * Power management functions
420 */
421 static int mptsas_get_pci_cap(mptsas_t *mpt);
422 static int mptsas_init_pm(mptsas_t *mpt);
423
424 /*
425 * MPT MSI tunable:
426 *
427 * By default MSI is enabled on all supported platforms.
428 */
429 boolean_t mptsas_enable_msi = B_TRUE;
430 boolean_t mptsas_physical_bind_failed_page_83 = B_FALSE;
431
432 /*
433 * Global switch for use of MPI2.5 FAST PATH.
434 * We don't really know what FAST PATH actually does, so if it is suspected
435 * to cause problems it can be turned off by setting this variable to B_FALSE.
436 */
437 boolean_t mptsas_use_fastpath = B_TRUE;
438
439 static int mptsas_register_intrs(mptsas_t *);
440 static void mptsas_unregister_intrs(mptsas_t *);
441 static int mptsas_add_intrs(mptsas_t *, int);
442 static void mptsas_rem_intrs(mptsas_t *);
443
444 /*
445 * FMA Prototypes
446 */
447 static void mptsas_fm_init(mptsas_t *mpt);
448 static void mptsas_fm_fini(mptsas_t *mpt);
449 static int mptsas_fm_error_cb(dev_info_t *, ddi_fm_error_t *, const void *);
450
451 extern pri_t minclsyspri, maxclsyspri;
452
453 /*
454 * This device is created by the SCSI pseudo nexus driver (SCSI vHCI). It is
455 * under this device that the paths to a physical device are created when
456 * MPxIO is used.
457 */
458 extern dev_info_t *scsi_vhci_dip;
459
460 /*
461 * Tunable timeout value for Inquiry VPD page 0x83
462 * By default the value is 30 seconds.
463 */
464 int mptsas_inq83_retry_timeout = 30;
465
466 /*
467 * This is used to allocate memory for message frame storage, not for
468 * data I/O DMA. All message frames must be stored in the first 4G of
469 * physical memory.
470 */
471 ddi_dma_attr_t mptsas_dma_attrs = {
472 DMA_ATTR_V0, /* attribute layout version */
473 0x0ull, /* address low - should be 0 (longlong) */
474 0xffffffffull, /* address high - 32-bit max range */
475 0x00ffffffull, /* count max - max DMA object size */
476 4, /* allocation alignment requirements */
477 0x78, /* burstsizes - binary encoded values */
478 1, /* minxfer - gran. of DMA engine */
479 0x00ffffffull, /* maxxfer - gran. of DMA engine */
480 0xffffffffull, /* max segment size (DMA boundary) */
481 MPTSAS_MAX_DMA_SEGS, /* scatter/gather list length */
482 512, /* granularity - device transfer size */
483 0 /* flags, set to 0 */
484 };
485
486 /*
487 * This is used for data I/O DMA memory allocation. (full 64-bit DMA
488 * physical addresses are supported.)
489 */
490 ddi_dma_attr_t mptsas_dma_attrs64 = {
491 DMA_ATTR_V0, /* attribute layout version */
492 0x0ull, /* address low - should be 0 (longlong) */
493 0xffffffffffffffffull, /* address high - 64-bit max */
494 0x00ffffffull, /* count max - max DMA object size */
495 4, /* allocation alignment requirements */
496 0x78, /* burstsizes - binary encoded values */
497 1, /* minxfer - gran. of DMA engine */
498 0x00ffffffull, /* maxxfer - gran. of DMA engine */
499 0xffffffffull, /* max segment size (DMA boundary) */
500 MPTSAS_MAX_DMA_SEGS, /* scatter/gather list length */
501 512, /* granularity - device transfer size */
502 DDI_DMA_RELAXED_ORDERING /* flags, enable relaxed ordering */
503 };
504
505 ddi_device_acc_attr_t mptsas_dev_attr = {
506 DDI_DEVICE_ATTR_V1,
507 DDI_STRUCTURE_LE_ACC,
508 DDI_STRICTORDER_ACC,
509 DDI_DEFAULT_ACC
510 };
511
512 static struct cb_ops mptsas_cb_ops = {
513 scsi_hba_open, /* open */
514 scsi_hba_close, /* close */
515 nodev, /* strategy */
516 nodev, /* print */
517 nodev, /* dump */
518 nodev, /* read */
519 nodev, /* write */
520 mptsas_ioctl, /* ioctl */
521 nodev, /* devmap */
522 nodev, /* mmap */
523 nodev, /* segmap */
524 nochpoll, /* chpoll */
525 ddi_prop_op, /* cb_prop_op */
526 NULL, /* streamtab */
527 D_MP, /* cb_flag */
528 CB_REV, /* rev */
529 nodev, /* aread */
530 nodev /* awrite */
531 };
532
533 static struct dev_ops mptsas_ops = {
534 DEVO_REV, /* devo_rev, */
535 0, /* refcnt */
536 ddi_no_info, /* info */
537 nulldev, /* identify */
538 nulldev, /* probe */
539 mptsas_attach, /* attach */
540 mptsas_detach, /* detach */
541 #ifdef __sparc
542 mptsas_reset,
543 #else
544 nodev, /* reset */
545 #endif /* __sparc */
546 &mptsas_cb_ops, /* driver operations */
547 NULL, /* bus operations */
548 mptsas_power, /* power management */
549 #ifdef __sparc
550 ddi_quiesce_not_needed
551 #else
552 mptsas_quiesce /* quiesce */
553 #endif /* __sparc */
554 };
555
556
557 #define MPTSAS_MOD_STRING "MPTSAS HBA Driver 00.00.00.24"
558
559 static struct modldrv modldrv = {
560 &mod_driverops, /* Type of module. This one is a driver */
561 MPTSAS_MOD_STRING, /* Name of the module. */
562 &mptsas_ops, /* driver ops */
563 };
564
565 static struct modlinkage modlinkage = {
566 MODREV_1, &modldrv, NULL
567 };
568 #define TARGET_PROP "target"
569 #define LUN_PROP "lun"
570 #define LUN64_PROP "lun64"
571 #define SAS_PROP "sas-mpt"
572 #define MDI_GUID "wwn"
573 #define NDI_GUID "guid"
574 #define MPTSAS_DEV_GONE "mptsas_dev_gone"
575
576 /*
577 * Local static data
578 */
579 #if defined(MPTSAS_DEBUG)
580 /*
581 * Flags to indicate which debug messages are to be printed and which go to the
582 * debug log ring buffer. Default is to not print anything, and to log
583 * everything except the watchsubr() output which normally happens every second.
584 */
585 uint32_t mptsas_debugprt_flags = 0x0;
586 uint32_t mptsas_debuglog_flags = ~(1U << 30);
587 #endif /* defined(MPTSAS_DEBUG) */
588 uint32_t mptsas_debug_resets = 0;
589
590 static kmutex_t mptsas_global_mutex;
591 static void *mptsas_state; /* soft state ptr */
592 static krwlock_t mptsas_global_rwlock;
593
594 static kmutex_t mptsas_log_mutex;
595 static char mptsas_log_buf[256];
596 _NOTE(MUTEX_PROTECTS_DATA(mptsas_log_mutex, mptsas_log_buf))
597
598 static mptsas_t *mptsas_head, *mptsas_tail;
599 static clock_t mptsas_scsi_watchdog_tick;
600 static clock_t mptsas_tick;
601 static timeout_id_t mptsas_reset_watch;
602 static timeout_id_t mptsas_timeout_id;
603 static int mptsas_timeouts_enabled = 0;
604 /*
605 * warlock directives
606 */
607 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", scsi_pkt \
608 mptsas_cmd NcrTableIndirect buf scsi_cdb scsi_status))
609 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", smp_pkt))
610 _NOTE(SCHEME_PROTECTS_DATA("stable data", scsi_device scsi_address))
611 _NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", mptsas_tgt_private))
612 _NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", scsi_hba_tran::tran_tgt_private))
613
614 /*
615 * SM - HBA statics
616 */
617 char *mptsas_driver_rev = MPTSAS_MOD_STRING;
618
619 #ifdef MPTSAS_DEBUG
620 void debug_enter(char *);
621 #endif
622
623 /*
624 * Notes:
625 * - scsi_hba_init(9F) initializes SCSI HBA modules
626 * - must call scsi_hba_fini(9F) if modload() fails
627 */
628 int
629 _init(void)
630 {
631 int status;
632 /* CONSTCOND */
633 ASSERT(NO_COMPETING_THREADS);
634
635 NDBG0(("_init"));
636
637 status = ddi_soft_state_init(&mptsas_state, MPTSAS_SIZE,
638 MPTSAS_INITIAL_SOFT_SPACE);
639 if (status != 0) {
640 return (status);
641 }
642
643 if ((status = scsi_hba_init(&modlinkage)) != 0) {
644 ddi_soft_state_fini(&mptsas_state);
645 return (status);
646 }
647
648 mutex_init(&mptsas_global_mutex, NULL, MUTEX_DRIVER, NULL);
649 rw_init(&mptsas_global_rwlock, NULL, RW_DRIVER, NULL);
650 mutex_init(&mptsas_log_mutex, NULL, MUTEX_DRIVER, NULL);
651
652 if ((status = mod_install(&modlinkage)) != 0) {
653 mutex_destroy(&mptsas_log_mutex);
654 rw_destroy(&mptsas_global_rwlock);
655 mutex_destroy(&mptsas_global_mutex);
656 ddi_soft_state_fini(&mptsas_state);
657 scsi_hba_fini(&modlinkage);
658 }
659
660 return (status);
661 }
662
663 /*
664 * Notes:
665 * - scsi_hba_fini(9F) uninitializes SCSI HBA modules
666 */
667 int
668 _fini(void)
669 {
670 int status;
671 /* CONSTCOND */
672 ASSERT(NO_COMPETING_THREADS);
673
674 NDBG0(("_fini"));
675
676 if ((status = mod_remove(&modlinkage)) == 0) {
677 ddi_soft_state_fini(&mptsas_state);
678 scsi_hba_fini(&modlinkage);
679 mutex_destroy(&mptsas_global_mutex);
680 rw_destroy(&mptsas_global_rwlock);
681 mutex_destroy(&mptsas_log_mutex);
682 }
683 return (status);
684 }
685
686 /*
687 * The loadable-module _info(9E) entry point
688 */
689 int
690 _info(struct modinfo *modinfop)
691 {
692 /* CONSTCOND */
693 ASSERT(NO_COMPETING_THREADS);
694 NDBG0(("mptsas _info"));
695
696 return (mod_info(&modlinkage, modinfop));
697 }
698
699 static int
700 mptsas_target_eval_devhdl(const void *op, void *arg)
701 {
702 uint16_t dh = *(uint16_t *)arg;
703 const mptsas_target_t *tp = op;
704
705 return ((int)tp->m_devhdl - (int)dh);
706 }
707
708 static int
709 mptsas_target_eval_slot(const void *op, void *arg)
710 {
711 mptsas_led_control_t *lcp = arg;
712 const mptsas_target_t *tp = op;
713
714 if (tp->m_enclosure != lcp->Enclosure)
715 return ((int)tp->m_enclosure - (int)lcp->Enclosure);
716
717 return ((int)tp->m_slot_num - (int)lcp->Slot);
718 }
719
720 static int
721 mptsas_target_eval_nowwn(const void *op, void *arg)
722 {
723 uint8_t phy = *(uint8_t *)arg;
724 const mptsas_target_t *tp = op;
725
726 if (tp->m_addr.mta_wwn != 0)
727 return (-1);
728
729 return ((int)tp->m_phynum - (int)phy);
730 }
731
732 static int
733 mptsas_smp_eval_devhdl(const void *op, void *arg)
734 {
735 uint16_t dh = *(uint16_t *)arg;
736 const mptsas_smp_t *sp = op;
737
738 return ((int)sp->m_devhdl - (int)dh);
739 }
740
741 static uint64_t
742 mptsas_target_addr_hash(const void *tp)
743 {
744 const mptsas_target_addr_t *tap = tp;
745
746 return ((tap->mta_wwn & 0xffffffffffffULL) |
747 ((uint64_t)tap->mta_phymask << 48));
748 }
749
750 static int
751 mptsas_target_addr_cmp(const void *a, const void *b)
752 {
753 const mptsas_target_addr_t *aap = a;
754 const mptsas_target_addr_t *bap = b;
755
756 if (aap->mta_wwn < bap->mta_wwn)
757 return (-1);
758 if (aap->mta_wwn > bap->mta_wwn)
759 return (1);
760 return ((int)bap->mta_phymask - (int)aap->mta_phymask);
761 }
762
763 static void
764 mptsas_target_free(void *op)
765 {
766 kmem_free(op, sizeof (mptsas_target_t));
767 }
768
769 static void
770 mptsas_smp_free(void *op)
771 {
772 kmem_free(op, sizeof (mptsas_smp_t));
773 }
774
775 static void
776 mptsas_destroy_hashes(mptsas_t *mpt)
777 {
778 mptsas_target_t *tp;
779 mptsas_smp_t *sp;
780
781 for (tp = refhash_first(mpt->m_targets); tp != NULL;
782 tp = refhash_next(mpt->m_targets, tp)) {
783 refhash_remove(mpt->m_targets, tp);
784 }
785 for (sp = refhash_first(mpt->m_smp_targets); sp != NULL;
786 sp = refhash_next(mpt->m_smp_targets, sp)) {
787 refhash_remove(mpt->m_smp_targets, sp);
788 }
789 refhash_destroy(mpt->m_targets);
790 refhash_destroy(mpt->m_smp_targets);
791 mpt->m_targets = NULL;
792 mpt->m_smp_targets = NULL;
793 }
794
795 static int
796 mptsas_iport_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
797 {
798 dev_info_t *pdip;
799 mptsas_t *mpt;
800 scsi_hba_tran_t *hba_tran;
801 char *iport = NULL;
802 char phymask[MPTSAS_MAX_PHYS];
803 mptsas_phymask_t phy_mask = 0;
804 int dynamic_port = 0;
805 uint32_t page_address;
806 char initiator_wwnstr[MPTSAS_WWN_STRLEN];
807 int rval = DDI_FAILURE;
808 int i = 0;
809 uint8_t numphys = 0;
810 uint8_t phy_id;
811 uint8_t phy_port = 0;
812 uint16_t attached_devhdl = 0;
813 uint32_t dev_info;
814 uint64_t attached_sas_wwn;
815 uint16_t dev_hdl;
816 uint16_t pdev_hdl;
817 uint16_t bay_num, enclosure, io_flags;
818 char attached_wwnstr[MPTSAS_WWN_STRLEN];
819
820 /* CONSTCOND */
821 ASSERT(NO_COMPETING_THREADS);
822
823 switch (cmd) {
824 case DDI_ATTACH:
825 break;
826
827 case DDI_RESUME:
828 /*
829 * If this a scsi-iport node, nothing to do here.
830 */
831 return (DDI_SUCCESS);
832
833 default:
834 return (DDI_FAILURE);
835 }
836
837 pdip = ddi_get_parent(dip);
838
839 if ((hba_tran = ndi_flavorv_get(pdip, SCSA_FLAVOR_SCSI_DEVICE)) ==
840 NULL) {
841 cmn_err(CE_WARN, "Failed attach iport because fail to "
842 "get tran vector for the HBA node");
843 return (DDI_FAILURE);
844 }
845
846 mpt = TRAN2MPT(hba_tran);
847 ASSERT(mpt != NULL);
848 if (mpt == NULL)
849 return (DDI_FAILURE);
850
851 if ((hba_tran = ndi_flavorv_get(dip, SCSA_FLAVOR_SCSI_DEVICE)) ==
852 NULL) {
853 mptsas_log(mpt, CE_WARN, "Failed attach iport because fail to "
854 "get tran vector for the iport node");
855 return (DDI_FAILURE);
856 }
857
858 /*
859 * Overwrite parent's tran_hba_private to iport's tran vector
860 */
861 hba_tran->tran_hba_private = mpt;
862
863 ddi_report_dev(dip);
864
865 /*
866 * Get SAS address for initiator port according dev_handle
867 */
868 iport = ddi_get_name_addr(dip);
869 if (iport && strncmp(iport, "v0", 2) == 0) {
870 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip,
871 MPTSAS_VIRTUAL_PORT, 1) !=
872 DDI_PROP_SUCCESS) {
873 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip,
874 MPTSAS_VIRTUAL_PORT);
875 mptsas_log(mpt, CE_WARN, "mptsas virtual port "
876 "prop update failed");
877 return (DDI_FAILURE);
878 }
879 return (DDI_SUCCESS);
880 }
881
882 mutex_enter(&mpt->m_mutex);
883 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
884 bzero(phymask, sizeof (phymask));
885 (void) sprintf(phymask,
886 "%x", mpt->m_phy_info[i].phy_mask);
887 if (strcmp(phymask, iport) == 0) {
888 break;
889 }
890 }
891
892 if (i == MPTSAS_MAX_PHYS) {
893 mptsas_log(mpt, CE_WARN, "Failed attach port %s because port"
894 "seems not exist", iport);
895 mutex_exit(&mpt->m_mutex);
896 return (DDI_FAILURE);
897 }
898
899 phy_mask = mpt->m_phy_info[i].phy_mask;
900
901 if (mpt->m_phy_info[i].port_flags & AUTO_PORT_CONFIGURATION)
902 dynamic_port = 1;
903 else
904 dynamic_port = 0;
905
906 /*
907 * Update PHY info for smhba
908 */
909 if (mptsas_smhba_phy_init(mpt)) {
910 mutex_exit(&mpt->m_mutex);
911 mptsas_log(mpt, CE_WARN, "mptsas phy update "
912 "failed");
913 return (DDI_FAILURE);
914 }
915
916 mutex_exit(&mpt->m_mutex);
917
918 numphys = 0;
919 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
920 if ((phy_mask >> i) & 0x01) {
921 numphys++;
922 }
923 }
924
925 bzero(initiator_wwnstr, sizeof (initiator_wwnstr));
926 (void) sprintf(initiator_wwnstr, "w%016"PRIx64,
927 mpt->un.m_base_wwid);
928
929 if (ddi_prop_update_string(DDI_DEV_T_NONE, dip,
930 SCSI_ADDR_PROP_INITIATOR_PORT, initiator_wwnstr) !=
931 DDI_PROP_SUCCESS) {
932 (void) ddi_prop_remove(DDI_DEV_T_NONE,
933 dip, SCSI_ADDR_PROP_INITIATOR_PORT);
934 mptsas_log(mpt, CE_WARN, "mptsas Initiator port "
935 "prop update failed");
936 return (DDI_FAILURE);
937 }
938 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip,
939 MPTSAS_NUM_PHYS, numphys) !=
940 DDI_PROP_SUCCESS) {
941 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, MPTSAS_NUM_PHYS);
942 return (DDI_FAILURE);
943 }
944
945 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip,
946 "phymask", phy_mask) !=
947 DDI_PROP_SUCCESS) {
948 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "phymask");
949 mptsas_log(mpt, CE_WARN, "mptsas phy mask "
950 "prop update failed");
951 return (DDI_FAILURE);
952 }
953
954 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip,
955 "dynamic-port", dynamic_port) !=
956 DDI_PROP_SUCCESS) {
957 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "dynamic-port");
958 mptsas_log(mpt, CE_WARN, "mptsas dynamic port "
959 "prop update failed");
960 return (DDI_FAILURE);
961 }
962 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip,
963 MPTSAS_VIRTUAL_PORT, 0) !=
964 DDI_PROP_SUCCESS) {
965 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip,
966 MPTSAS_VIRTUAL_PORT);
967 mptsas_log(mpt, CE_WARN, "mptsas virtual port "
968 "prop update failed");
969 return (DDI_FAILURE);
970 }
971 mptsas_smhba_set_all_phy_props(mpt, dip, numphys, phy_mask,
972 &attached_devhdl);
973
974 mutex_enter(&mpt->m_mutex);
975 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
976 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)attached_devhdl;
977 rval = mptsas_get_sas_device_page0(mpt, page_address, &dev_hdl,
978 &attached_sas_wwn, &dev_info, &phy_port, &phy_id,
979 &pdev_hdl, &bay_num, &enclosure, &io_flags);
980 if (rval != DDI_SUCCESS) {
981 mptsas_log(mpt, CE_WARN,
982 "Failed to get device page0 for handle:%d",
983 attached_devhdl);
984 mutex_exit(&mpt->m_mutex);
985 return (DDI_FAILURE);
986 }
987
988 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
989 bzero(phymask, sizeof (phymask));
990 (void) sprintf(phymask, "%x", mpt->m_phy_info[i].phy_mask);
991 if (strcmp(phymask, iport) == 0) {
992 (void) sprintf(&mpt->m_phy_info[i].smhba_info.path[0],
993 "%x",
994 mpt->m_phy_info[i].phy_mask);
995 }
996 }
997 mutex_exit(&mpt->m_mutex);
998
999 bzero(attached_wwnstr, sizeof (attached_wwnstr));
1000 (void) sprintf(attached_wwnstr, "w%016"PRIx64,
1001 attached_sas_wwn);
1002 if (ddi_prop_update_string(DDI_DEV_T_NONE, dip,
1003 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) !=
1004 DDI_PROP_SUCCESS) {
1005 (void) ddi_prop_remove(DDI_DEV_T_NONE,
1006 dip, SCSI_ADDR_PROP_ATTACHED_PORT);
1007 return (DDI_FAILURE);
1008 }
1009
1010 /* Create kstats for each phy on this iport */
1011
1012 mptsas_create_phy_stats(mpt, iport, dip);
1013
1014 /*
1015 * register sas hba iport with mdi (MPxIO/vhci)
1016 */
1017 if (mdi_phci_register(MDI_HCI_CLASS_SCSI,
1018 dip, 0) == MDI_SUCCESS) {
1019 mpt->m_mpxio_enable = TRUE;
1020 }
1021 return (DDI_SUCCESS);
1022 }
1023
1024 /*
1025 * Notes:
1026 * Set up all device state and allocate data structures,
1027 * mutexes, condition variables, etc. for device operation.
1028 * Add interrupts needed.
1029 * Return DDI_SUCCESS if device is ready, else return DDI_FAILURE.
1030 */
1031 static int
1032 mptsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
1033 {
1034 mptsas_t *mpt = NULL;
1035 int instance, i, j;
1036 int doneq_thread_num;
1037 char intr_added = 0;
1038 char map_setup = 0;
1039 char config_setup = 0;
1040 char hba_attach_setup = 0;
1041 char smp_attach_setup = 0;
1042 char mutex_init_done = 0;
1043 char event_taskq_create = 0;
1044 char dr_taskq_create = 0;
1045 char doneq_thread_create = 0;
1046 char added_watchdog = 0;
1047 scsi_hba_tran_t *hba_tran;
1048 uint_t mem_bar = MEM_SPACE;
1049 int rval = DDI_FAILURE;
1050
1051 /* CONSTCOND */
1052 ASSERT(NO_COMPETING_THREADS);
1053
1054 if (scsi_hba_iport_unit_address(dip)) {
1055 return (mptsas_iport_attach(dip, cmd));
1056 }
1057
1058 switch (cmd) {
1059 case DDI_ATTACH:
1060 break;
1061
1062 case DDI_RESUME:
1063 if ((hba_tran = ddi_get_driver_private(dip)) == NULL)
1064 return (DDI_FAILURE);
1065
1066 mpt = TRAN2MPT(hba_tran);
1067
1068 if (!mpt) {
1069 return (DDI_FAILURE);
1070 }
1071
1072 /*
1073 * Reset hardware and softc to "no outstanding commands"
1074 * Note that a check condition can result on first command
1075 * to a target.
1076 */
1077 mutex_enter(&mpt->m_mutex);
1078
1079 /*
1080 * raise power.
1081 */
1082 if (mpt->m_options & MPTSAS_OPT_PM) {
1083 mutex_exit(&mpt->m_mutex);
1084 (void) pm_busy_component(dip, 0);
1085 rval = pm_power_has_changed(dip, 0, PM_LEVEL_D0);
1086 if (rval == DDI_SUCCESS) {
1087 mutex_enter(&mpt->m_mutex);
1088 } else {
1089 /*
1090 * The pm_raise_power() call above failed,
1091 * and that can only occur if we were unable
1092 * to reset the hardware. This is probably
1093 * due to unhealty hardware, and because
1094 * important filesystems(such as the root
1095 * filesystem) could be on the attached disks,
1096 * it would not be a good idea to continue,
1097 * as we won't be entirely certain we are
1098 * writing correct data. So we panic() here
1099 * to not only prevent possible data corruption,
1100 * but to give developers or end users a hope
1101 * of identifying and correcting any problems.
1102 */
1103 fm_panic("mptsas could not reset hardware "
1104 "during resume");
1105 }
1106 }
1107
1108 mpt->m_suspended = 0;
1109
1110 /*
1111 * Reinitialize ioc
1112 */
1113 mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET;
1114 if (mptsas_init_chip(mpt, FALSE) == DDI_FAILURE) {
1115 mutex_exit(&mpt->m_mutex);
1116 if (mpt->m_options & MPTSAS_OPT_PM) {
1117 (void) pm_idle_component(dip, 0);
1118 }
1119 fm_panic("mptsas init chip fail during resume");
1120 }
1121 /*
1122 * mptsas_update_driver_data needs interrupts so enable them
1123 * first.
1124 */
1125 MPTSAS_ENABLE_INTR(mpt);
1126 mptsas_update_driver_data(mpt);
1127
1128 /* start requests, if possible */
1129 mptsas_restart_hba(mpt);
1130
1131 mutex_exit(&mpt->m_mutex);
1132
1133 /*
1134 * Restart watch thread
1135 */
1136 mutex_enter(&mptsas_global_mutex);
1137 if (mptsas_timeout_id == 0) {
1138 mptsas_timeout_id = timeout(mptsas_watch, NULL,
1139 mptsas_tick);
1140 mptsas_timeouts_enabled = 1;
1141 }
1142 mutex_exit(&mptsas_global_mutex);
1143
1144 /* report idle status to pm framework */
1145 if (mpt->m_options & MPTSAS_OPT_PM) {
1146 (void) pm_idle_component(dip, 0);
1147 }
1148
1149 return (DDI_SUCCESS);
1150
1151 default:
1152 return (DDI_FAILURE);
1153
1154 }
1155
1156 instance = ddi_get_instance(dip);
1157
1158 /*
1159 * Allocate softc information.
1160 */
1161 if (ddi_soft_state_zalloc(mptsas_state, instance) != DDI_SUCCESS) {
1162 mptsas_log(NULL, CE_WARN,
1163 "mptsas%d: cannot allocate soft state", instance);
1164 goto fail;
1165 }
1166
1167 mpt = ddi_get_soft_state(mptsas_state, instance);
1168
1169 if (mpt == NULL) {
1170 mptsas_log(NULL, CE_WARN,
1171 "mptsas%d: cannot get soft state", instance);
1172 goto fail;
1173 }
1174
1175 /* Indicate that we are 'sizeof (scsi_*(9S))' clean. */
1176 scsi_size_clean(dip);
1177
1178 mpt->m_dip = dip;
1179 mpt->m_instance = instance;
1180
1181 /* Make a per-instance copy of the structures */
1182 mpt->m_io_dma_attr = mptsas_dma_attrs64;
1183 mpt->m_msg_dma_attr = mptsas_dma_attrs;
1184 mpt->m_reg_acc_attr = mptsas_dev_attr;
1185 mpt->m_dev_acc_attr = mptsas_dev_attr;
1186
1187 /*
1188 * Initialize FMA
1189 */
1190 mpt->m_fm_capabilities = ddi_getprop(DDI_DEV_T_ANY, mpt->m_dip,
1191 DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "fm-capable",
1192 DDI_FM_EREPORT_CAPABLE | DDI_FM_ACCCHK_CAPABLE |
1193 DDI_FM_DMACHK_CAPABLE | DDI_FM_ERRCB_CAPABLE);
1194
1195 mptsas_fm_init(mpt);
1196
1197 if (mptsas_alloc_handshake_msg(mpt,
1198 sizeof (Mpi2SCSITaskManagementRequest_t)) == DDI_FAILURE) {
1199 mptsas_log(mpt, CE_WARN, "cannot initialize handshake msg.");
1200 goto fail;
1201 }
1202
1203 /*
1204 * Setup configuration space
1205 */
1206 if (mptsas_config_space_init(mpt) == FALSE) {
1207 mptsas_log(mpt, CE_WARN, "mptsas_config_space_init failed");
1208 goto fail;
1209 }
1210 config_setup++;
1211
1212 if (ddi_regs_map_setup(dip, mem_bar, (caddr_t *)&mpt->m_reg,
1213 0, 0, &mpt->m_reg_acc_attr, &mpt->m_datap) != DDI_SUCCESS) {
1214 mptsas_log(mpt, CE_WARN, "map setup failed");
1215 goto fail;
1216 }
1217 map_setup++;
1218
1219 /*
1220 * A taskq is created for dealing with the event handler
1221 */
1222 if ((mpt->m_event_taskq = ddi_taskq_create(dip, "mptsas_event_taskq",
1223 1, TASKQ_DEFAULTPRI, 0)) == NULL) {
1224 mptsas_log(mpt, CE_NOTE, "ddi_taskq_create failed");
1225 goto fail;
1226 }
1227 event_taskq_create++;
1228
1229 /*
1230 * A taskq is created for dealing with dr events
1231 */
1232 if ((mpt->m_dr_taskq = ddi_taskq_create(dip,
1233 "mptsas_dr_taskq",
1234 1, TASKQ_DEFAULTPRI, 0)) == NULL) {
1235 mptsas_log(mpt, CE_NOTE, "ddi_taskq_create for discovery "
1236 "failed");
1237 goto fail;
1238 }
1239 dr_taskq_create++;
1240
1241 mpt->m_doneq_thread_threshold = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
1242 0, "mptsas_doneq_thread_threshold_prop", 10);
1243 mpt->m_doneq_length_threshold = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
1244 0, "mptsas_doneq_length_threshold_prop", 8);
1245 mpt->m_doneq_thread_n = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
1246 0, "mptsas_doneq_thread_n_prop", 8);
1247
1248 if (mpt->m_doneq_thread_n) {
1249 cv_init(&mpt->m_doneq_thread_cv, NULL, CV_DRIVER, NULL);
1250 mutex_init(&mpt->m_doneq_mutex, NULL, MUTEX_DRIVER, NULL);
1251
1252 mutex_enter(&mpt->m_doneq_mutex);
1253 mpt->m_doneq_thread_id =
1254 kmem_zalloc(sizeof (mptsas_doneq_thread_list_t)
1255 * mpt->m_doneq_thread_n, KM_SLEEP);
1256
1257 for (j = 0; j < mpt->m_doneq_thread_n; j++) {
1258 cv_init(&mpt->m_doneq_thread_id[j].cv, NULL,
1259 CV_DRIVER, NULL);
1260 mutex_init(&mpt->m_doneq_thread_id[j].mutex, NULL,
1261 MUTEX_DRIVER, NULL);
1262 mutex_enter(&mpt->m_doneq_thread_id[j].mutex);
1263 mpt->m_doneq_thread_id[j].flag |=
1264 MPTSAS_DONEQ_THREAD_ACTIVE;
1265 mpt->m_doneq_thread_id[j].arg.mpt = mpt;
1266 mpt->m_doneq_thread_id[j].arg.t = j;
1267 mpt->m_doneq_thread_id[j].threadp =
1268 thread_create(NULL, 0, mptsas_doneq_thread,
1269 &mpt->m_doneq_thread_id[j].arg,
1270 0, &p0, TS_RUN, minclsyspri);
1271 mpt->m_doneq_thread_id[j].donetail =
1272 &mpt->m_doneq_thread_id[j].doneq;
1273 mutex_exit(&mpt->m_doneq_thread_id[j].mutex);
1274 }
1275 mutex_exit(&mpt->m_doneq_mutex);
1276 doneq_thread_create++;
1277 }
1278
1279 /*
1280 * Disable hardware interrupt since we're not ready to
1281 * handle it yet.
1282 */
1283 MPTSAS_DISABLE_INTR(mpt);
1284 if (mptsas_register_intrs(mpt) == FALSE)
1285 goto fail;
1286 intr_added++;
1287
1288 /* Initialize mutex used in interrupt handler */
1289 mutex_init(&mpt->m_mutex, NULL, MUTEX_DRIVER,
1290 DDI_INTR_PRI(mpt->m_intr_pri));
1291 mutex_init(&mpt->m_passthru_mutex, NULL, MUTEX_DRIVER, NULL);
1292 mutex_init(&mpt->m_tx_waitq_mutex, NULL, MUTEX_DRIVER,
1293 DDI_INTR_PRI(mpt->m_intr_pri));
1294 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
1295 mutex_init(&mpt->m_phy_info[i].smhba_info.phy_mutex,
1296 NULL, MUTEX_DRIVER,
1297 DDI_INTR_PRI(mpt->m_intr_pri));
1298 }
1299
1300 cv_init(&mpt->m_cv, NULL, CV_DRIVER, NULL);
1301 cv_init(&mpt->m_passthru_cv, NULL, CV_DRIVER, NULL);
1302 cv_init(&mpt->m_fw_cv, NULL, CV_DRIVER, NULL);
1303 cv_init(&mpt->m_config_cv, NULL, CV_DRIVER, NULL);
1304 cv_init(&mpt->m_fw_diag_cv, NULL, CV_DRIVER, NULL);
1305 mutex_init_done++;
1306
1307 mutex_enter(&mpt->m_mutex);
1308 /*
1309 * Initialize power management component
1310 */
1311 if (mpt->m_options & MPTSAS_OPT_PM) {
1312 if (mptsas_init_pm(mpt)) {
1313 mutex_exit(&mpt->m_mutex);
1314 mptsas_log(mpt, CE_WARN, "mptsas pm initialization "
1315 "failed");
1316 goto fail;
1317 }
1318 }
1319
1320 /*
1321 * Initialize chip using Message Unit Reset, if allowed
1322 */
1323 mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET;
1324 if (mptsas_init_chip(mpt, TRUE) == DDI_FAILURE) {
1325 mutex_exit(&mpt->m_mutex);
1326 mptsas_log(mpt, CE_WARN, "mptsas chip initialization failed");
1327 goto fail;
1328 }
1329
1330 /*
1331 * Fill in the phy_info structure and get the base WWID
1332 */
1333 if (mptsas_get_manufacture_page5(mpt) == DDI_FAILURE) {
1334 mptsas_log(mpt, CE_WARN,
1335 "mptsas_get_manufacture_page5 failed!");
1336 goto fail;
1337 }
1338
1339 if (mptsas_get_sas_io_unit_page_hndshk(mpt)) {
1340 mptsas_log(mpt, CE_WARN,
1341 "mptsas_get_sas_io_unit_page_hndshk failed!");
1342 goto fail;
1343 }
1344
1345 if (mptsas_get_manufacture_page0(mpt) == DDI_FAILURE) {
1346 mptsas_log(mpt, CE_WARN,
1347 "mptsas_get_manufacture_page0 failed!");
1348 goto fail;
1349 }
1350
1351 mutex_exit(&mpt->m_mutex);
1352
1353 /*
1354 * Register the iport for multiple port HBA
1355 */
1356 mptsas_iport_register(mpt);
1357
1358 /*
1359 * initialize SCSI HBA transport structure
1360 */
1361 if (mptsas_hba_setup(mpt) == FALSE)
1362 goto fail;
1363 hba_attach_setup++;
1364
1365 if (mptsas_smp_setup(mpt) == FALSE)
1366 goto fail;
1367 smp_attach_setup++;
1368
1369 if (mptsas_cache_create(mpt) == FALSE)
1370 goto fail;
1371
1372 mpt->m_scsi_reset_delay = ddi_prop_get_int(DDI_DEV_T_ANY,
1373 dip, 0, "scsi-reset-delay", SCSI_DEFAULT_RESET_DELAY);
1374 if (mpt->m_scsi_reset_delay == 0) {
1375 mptsas_log(mpt, CE_NOTE,
1376 "scsi_reset_delay of 0 is not recommended,"
1377 " resetting to SCSI_DEFAULT_RESET_DELAY\n");
1378 mpt->m_scsi_reset_delay = SCSI_DEFAULT_RESET_DELAY;
1379 }
1380
1381 /*
1382 * Initialize the wait and done FIFO queue
1383 */
1384 mpt->m_donetail = &mpt->m_doneq;
1385 mpt->m_waitqtail = &mpt->m_waitq;
1386 mpt->m_tx_waitqtail = &mpt->m_tx_waitq;
1387 mpt->m_tx_draining = 0;
1388
1389 /*
1390 * ioc cmd queue initialize
1391 */
1392 mpt->m_ioc_event_cmdtail = &mpt->m_ioc_event_cmdq;
1393 mpt->m_dev_handle = 0xFFFF;
1394
1395 MPTSAS_ENABLE_INTR(mpt);
1396
1397 /*
1398 * enable event notification
1399 */
1400 mutex_enter(&mpt->m_mutex);
1401 if (mptsas_ioc_enable_event_notification(mpt)) {
1402 mutex_exit(&mpt->m_mutex);
1403 goto fail;
1404 }
1405 mutex_exit(&mpt->m_mutex);
1406
1407 /*
1408 * used for mptsas_watch
1409 */
1410 mptsas_list_add(mpt);
1411
1412 mutex_enter(&mptsas_global_mutex);
1413 if (mptsas_timeouts_enabled == 0) {
1414 mptsas_scsi_watchdog_tick = ddi_prop_get_int(DDI_DEV_T_ANY,
1415 dip, 0, "scsi-watchdog-tick", DEFAULT_WD_TICK);
1416
1417 mptsas_tick = mptsas_scsi_watchdog_tick *
1418 drv_usectohz((clock_t)1000000);
1419
1420 mptsas_timeout_id = timeout(mptsas_watch, NULL, mptsas_tick);
1421 mptsas_timeouts_enabled = 1;
1422 }
1423 mutex_exit(&mptsas_global_mutex);
1424 added_watchdog++;
1425
1426 /*
1427 * Initialize PHY info for smhba.
1428 * This requires watchdog to be enabled otherwise if interrupts
1429 * don't work the system will hang.
1430 */
1431 if (mptsas_smhba_setup(mpt)) {
1432 mptsas_log(mpt, CE_WARN, "mptsas phy initialization "
1433 "failed");
1434 goto fail;
1435 }
1436
1437 /* Check all dma handles allocated in attach */
1438 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl)
1439 != DDI_SUCCESS) ||
1440 (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl)
1441 != DDI_SUCCESS) ||
1442 (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl)
1443 != DDI_SUCCESS) ||
1444 (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl)
1445 != DDI_SUCCESS) ||
1446 (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl)
1447 != DDI_SUCCESS)) {
1448 goto fail;
1449 }
1450
1451 /* Check all acc handles allocated in attach */
1452 if ((mptsas_check_acc_handle(mpt->m_datap) != DDI_SUCCESS) ||
1453 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl)
1454 != DDI_SUCCESS) ||
1455 (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl)
1456 != DDI_SUCCESS) ||
1457 (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl)
1458 != DDI_SUCCESS) ||
1459 (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl)
1460 != DDI_SUCCESS) ||
1461 (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl)
1462 != DDI_SUCCESS) ||
1463 (mptsas_check_acc_handle(mpt->m_config_handle)
1464 != DDI_SUCCESS)) {
1465 goto fail;
1466 }
1467
1468 /*
1469 * After this point, we are not going to fail the attach.
1470 */
1471
1472 /* Print message of HBA present */
1473 ddi_report_dev(dip);
1474
1475 /* report idle status to pm framework */
1476 if (mpt->m_options & MPTSAS_OPT_PM) {
1477 (void) pm_idle_component(dip, 0);
1478 }
1479
1480 return (DDI_SUCCESS);
1481
1482 fail:
1483 mptsas_log(mpt, CE_WARN, "attach failed");
1484 mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE);
1485 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST);
1486 if (mpt) {
1487 /* deallocate in reverse order */
1488 if (added_watchdog) {
1489 mptsas_list_del(mpt);
1490 mutex_enter(&mptsas_global_mutex);
1491
1492 if (mptsas_timeout_id && (mptsas_head == NULL)) {
1493 timeout_id_t tid = mptsas_timeout_id;
1494 mptsas_timeouts_enabled = 0;
1495 mptsas_timeout_id = 0;
1496 mutex_exit(&mptsas_global_mutex);
1497 (void) untimeout(tid);
1498 mutex_enter(&mptsas_global_mutex);
1499 }
1500 mutex_exit(&mptsas_global_mutex);
1501 }
1502
1503 mptsas_cache_destroy(mpt);
1504
1505 if (smp_attach_setup) {
1506 mptsas_smp_teardown(mpt);
1507 }
1508 if (hba_attach_setup) {
1509 mptsas_hba_teardown(mpt);
1510 }
1511
1512 if (mpt->m_targets)
1513 refhash_destroy(mpt->m_targets);
1514 if (mpt->m_smp_targets)
1515 refhash_destroy(mpt->m_smp_targets);
1516
1517 if (mpt->m_active) {
1518 mptsas_free_active_slots(mpt);
1519 }
1520 if (intr_added) {
1521 mptsas_unregister_intrs(mpt);
1522 }
1523
1524 if (doneq_thread_create) {
1525 mutex_enter(&mpt->m_doneq_mutex);
1526 doneq_thread_num = mpt->m_doneq_thread_n;
1527 for (j = 0; j < mpt->m_doneq_thread_n; j++) {
1528 mutex_enter(&mpt->m_doneq_thread_id[j].mutex);
1529 mpt->m_doneq_thread_id[j].flag &=
1530 (~MPTSAS_DONEQ_THREAD_ACTIVE);
1531 cv_signal(&mpt->m_doneq_thread_id[j].cv);
1532 mutex_exit(&mpt->m_doneq_thread_id[j].mutex);
1533 }
1534 while (mpt->m_doneq_thread_n) {
1535 cv_wait(&mpt->m_doneq_thread_cv,
1536 &mpt->m_doneq_mutex);
1537 }
1538 for (j = 0; j < doneq_thread_num; j++) {
1539 cv_destroy(&mpt->m_doneq_thread_id[j].cv);
1540 mutex_destroy(&mpt->m_doneq_thread_id[j].mutex);
1541 }
1542 kmem_free(mpt->m_doneq_thread_id,
1543 sizeof (mptsas_doneq_thread_list_t)
1544 * doneq_thread_num);
1545 mutex_exit(&mpt->m_doneq_mutex);
1546 cv_destroy(&mpt->m_doneq_thread_cv);
1547 mutex_destroy(&mpt->m_doneq_mutex);
1548 }
1549 if (event_taskq_create) {
1550 ddi_taskq_destroy(mpt->m_event_taskq);
1551 }
1552 if (dr_taskq_create) {
1553 ddi_taskq_destroy(mpt->m_dr_taskq);
1554 }
1555 if (mutex_init_done) {
1556 mutex_destroy(&mpt->m_tx_waitq_mutex);
1557 mutex_destroy(&mpt->m_passthru_mutex);
1558 mutex_destroy(&mpt->m_mutex);
1559 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
1560 mutex_destroy(
1561 &mpt->m_phy_info[i].smhba_info.phy_mutex);
1562 }
1563 cv_destroy(&mpt->m_cv);
1564 cv_destroy(&mpt->m_passthru_cv);
1565 cv_destroy(&mpt->m_fw_cv);
1566 cv_destroy(&mpt->m_config_cv);
1567 cv_destroy(&mpt->m_fw_diag_cv);
1568 }
1569
1570 if (map_setup) {
1571 mptsas_cfg_fini(mpt);
1572 }
1573 if (config_setup) {
1574 mptsas_config_space_fini(mpt);
1575 }
1576 mptsas_free_handshake_msg(mpt);
1577 mptsas_hba_fini(mpt);
1578
1579 mptsas_fm_fini(mpt);
1580 ddi_soft_state_free(mptsas_state, instance);
1581 ddi_prop_remove_all(dip);
1582 }
1583 return (DDI_FAILURE);
1584 }
1585
1586 static int
1587 mptsas_suspend(dev_info_t *devi)
1588 {
1589 mptsas_t *mpt, *g;
1590 scsi_hba_tran_t *tran;
1591
1592 if (scsi_hba_iport_unit_address(devi)) {
1593 return (DDI_SUCCESS);
1594 }
1595
1596 if ((tran = ddi_get_driver_private(devi)) == NULL)
1597 return (DDI_SUCCESS);
1598
1599 mpt = TRAN2MPT(tran);
1600 if (!mpt) {
1601 return (DDI_SUCCESS);
1602 }
1603
1604 mutex_enter(&mpt->m_mutex);
1605
1606 if (mpt->m_suspended++) {
1607 mutex_exit(&mpt->m_mutex);
1608 return (DDI_SUCCESS);
1609 }
1610
1611 /*
1612 * Cancel timeout threads for this mpt
1613 */
1614 if (mpt->m_quiesce_timeid) {
1615 timeout_id_t tid = mpt->m_quiesce_timeid;
1616 mpt->m_quiesce_timeid = 0;
1617 mutex_exit(&mpt->m_mutex);
1618 (void) untimeout(tid);
1619 mutex_enter(&mpt->m_mutex);
1620 }
1621
1622 if (mpt->m_restart_cmd_timeid) {
1623 timeout_id_t tid = mpt->m_restart_cmd_timeid;
1624 mpt->m_restart_cmd_timeid = 0;
1625 mutex_exit(&mpt->m_mutex);
1626 (void) untimeout(tid);
1627 mutex_enter(&mpt->m_mutex);
1628 }
1629
1630 mutex_exit(&mpt->m_mutex);
1631
1632 (void) pm_idle_component(mpt->m_dip, 0);
1633
1634 /*
1635 * Cancel watch threads if all mpts suspended
1636 */
1637 rw_enter(&mptsas_global_rwlock, RW_WRITER);
1638 for (g = mptsas_head; g != NULL; g = g->m_next) {
1639 if (!g->m_suspended)
1640 break;
1641 }
1642 rw_exit(&mptsas_global_rwlock);
1643
1644 mutex_enter(&mptsas_global_mutex);
1645 if (g == NULL) {
1646 timeout_id_t tid;
1647
1648 mptsas_timeouts_enabled = 0;
1649 if (mptsas_timeout_id) {
1650 tid = mptsas_timeout_id;
1651 mptsas_timeout_id = 0;
1652 mutex_exit(&mptsas_global_mutex);
1653 (void) untimeout(tid);
1654 mutex_enter(&mptsas_global_mutex);
1655 }
1656 if (mptsas_reset_watch) {
1657 tid = mptsas_reset_watch;
1658 mptsas_reset_watch = 0;
1659 mutex_exit(&mptsas_global_mutex);
1660 (void) untimeout(tid);
1661 mutex_enter(&mptsas_global_mutex);
1662 }
1663 }
1664 mutex_exit(&mptsas_global_mutex);
1665
1666 mutex_enter(&mpt->m_mutex);
1667
1668 /*
1669 * If this mpt is not in full power(PM_LEVEL_D0), just return.
1670 */
1671 if ((mpt->m_options & MPTSAS_OPT_PM) &&
1672 (mpt->m_power_level != PM_LEVEL_D0)) {
1673 mutex_exit(&mpt->m_mutex);
1674 return (DDI_SUCCESS);
1675 }
1676
1677 /* Disable HBA interrupts in hardware */
1678 MPTSAS_DISABLE_INTR(mpt);
1679 /*
1680 * Send RAID action system shutdown to sync IR
1681 */
1682 mptsas_raid_action_system_shutdown(mpt);
1683
1684 mutex_exit(&mpt->m_mutex);
1685
1686 /* drain the taskq */
1687 ddi_taskq_wait(mpt->m_event_taskq);
1688 ddi_taskq_wait(mpt->m_dr_taskq);
1689
1690 return (DDI_SUCCESS);
1691 }
1692
1693 #ifdef __sparc
1694 /*ARGSUSED*/
1695 static int
1696 mptsas_reset(dev_info_t *devi, ddi_reset_cmd_t cmd)
1697 {
1698 mptsas_t *mpt;
1699 scsi_hba_tran_t *tran;
1700
1701 /*
1702 * If this call is for iport, just return.
1703 */
1704 if (scsi_hba_iport_unit_address(devi))
1705 return (DDI_SUCCESS);
1706
1707 if ((tran = ddi_get_driver_private(devi)) == NULL)
1708 return (DDI_SUCCESS);
1709
1710 if ((mpt = TRAN2MPT(tran)) == NULL)
1711 return (DDI_SUCCESS);
1712
1713 /*
1714 * Send RAID action system shutdown to sync IR. Disable HBA
1715 * interrupts in hardware first.
1716 */
1717 MPTSAS_DISABLE_INTR(mpt);
1718 mptsas_raid_action_system_shutdown(mpt);
1719
1720 return (DDI_SUCCESS);
1721 }
1722 #else /* __sparc */
1723 /*
1724 * quiesce(9E) entry point.
1725 *
1726 * This function is called when the system is single-threaded at high
1727 * PIL with preemption disabled. Therefore, this function must not be
1728 * blocked.
1729 *
1730 * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
1731 * DDI_FAILURE indicates an error condition and should almost never happen.
1732 */
1733 static int
1734 mptsas_quiesce(dev_info_t *devi)
1735 {
1736 mptsas_t *mpt;
1737 scsi_hba_tran_t *tran;
1738
1739 /*
1740 * If this call is for iport, just return.
1741 */
1742 if (scsi_hba_iport_unit_address(devi))
1743 return (DDI_SUCCESS);
1744
1745 if ((tran = ddi_get_driver_private(devi)) == NULL)
1746 return (DDI_SUCCESS);
1747
1748 if ((mpt = TRAN2MPT(tran)) == NULL)
1749 return (DDI_SUCCESS);
1750
1751 /* Disable HBA interrupts in hardware */
1752 MPTSAS_DISABLE_INTR(mpt);
1753 /* Send RAID action system shutdonw to sync IR */
1754 mptsas_raid_action_system_shutdown(mpt);
1755
1756 return (DDI_SUCCESS);
1757 }
1758 #endif /* __sparc */
1759
1760 /*
1761 * detach(9E). Remove all device allocations and system resources;
1762 * disable device interrupts.
1763 * Return DDI_SUCCESS if done; DDI_FAILURE if there's a problem.
1764 */
1765 static int
1766 mptsas_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
1767 {
1768 /* CONSTCOND */
1769 ASSERT(NO_COMPETING_THREADS);
1770 NDBG0(("mptsas_detach: dip=0x%p cmd=0x%p", (void *)devi, (void *)cmd));
1771
1772 switch (cmd) {
1773 case DDI_DETACH:
1774 return (mptsas_do_detach(devi));
1775
1776 case DDI_SUSPEND:
1777 return (mptsas_suspend(devi));
1778
1779 default:
1780 return (DDI_FAILURE);
1781 }
1782 /* NOTREACHED */
1783 }
1784
1785 static int
1786 mptsas_do_detach(dev_info_t *dip)
1787 {
1788 mptsas_t *mpt;
1789 scsi_hba_tran_t *tran;
1790 int circ = 0;
1791 int circ1 = 0;
1792 mdi_pathinfo_t *pip = NULL;
1793 int i;
1794 int doneq_thread_num = 0;
1795
1796 NDBG0(("mptsas_do_detach: dip=0x%p", (void *)dip));
1797
1798 if ((tran = ndi_flavorv_get(dip, SCSA_FLAVOR_SCSI_DEVICE)) == NULL)
1799 return (DDI_FAILURE);
1800
1801 mpt = TRAN2MPT(tran);
1802 if (!mpt) {
1803 return (DDI_FAILURE);
1804 }
1805 /*
1806 * Still have pathinfo child, should not detach mpt driver
1807 */
1808 if (scsi_hba_iport_unit_address(dip)) {
1809 if (mpt->m_mpxio_enable) {
1810 /*
1811 * MPxIO enabled for the iport
1812 */
1813 ndi_devi_enter(scsi_vhci_dip, &circ1);
1814 ndi_devi_enter(dip, &circ);
1815 while (pip = mdi_get_next_client_path(dip, NULL)) {
1816 if (mdi_pi_free(pip, 0) == MDI_SUCCESS) {
1817 continue;
1818 }
1819 ndi_devi_exit(dip, circ);
1820 ndi_devi_exit(scsi_vhci_dip, circ1);
1821 NDBG12(("detach failed because of "
1822 "outstanding path info"));
1823 return (DDI_FAILURE);
1824 }
1825 ndi_devi_exit(dip, circ);
1826 ndi_devi_exit(scsi_vhci_dip, circ1);
1827 (void) mdi_phci_unregister(dip, 0);
1828 }
1829
1830 ddi_prop_remove_all(dip);
1831
1832 return (DDI_SUCCESS);
1833 }
1834
1835 /* Make sure power level is D0 before accessing registers */
1836 if (mpt->m_options & MPTSAS_OPT_PM) {
1837 (void) pm_busy_component(dip, 0);
1838 if (mpt->m_power_level != PM_LEVEL_D0) {
1839 if (pm_raise_power(dip, 0, PM_LEVEL_D0) !=
1840 DDI_SUCCESS) {
1841 mptsas_log(mpt, CE_WARN,
1842 "mptsas%d: Raise power request failed.",
1843 mpt->m_instance);
1844 (void) pm_idle_component(dip, 0);
1845 return (DDI_FAILURE);
1846 }
1847 }
1848 }
1849
1850 /*
1851 * Send RAID action system shutdown to sync IR. After action, send a
1852 * Message Unit Reset. Since after that DMA resource will be freed,
1853 * set ioc to READY state will avoid HBA initiated DMA operation.
1854 */
1855 mutex_enter(&mpt->m_mutex);
1856 MPTSAS_DISABLE_INTR(mpt);
1857 mptsas_raid_action_system_shutdown(mpt);
1858 mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET;
1859 (void) mptsas_ioc_reset(mpt, FALSE);
1860 mutex_exit(&mpt->m_mutex);
1861 mptsas_rem_intrs(mpt);
1862 ddi_taskq_destroy(mpt->m_event_taskq);
1863 ddi_taskq_destroy(mpt->m_dr_taskq);
1864
1865 if (mpt->m_doneq_thread_n) {
1866 mutex_enter(&mpt->m_doneq_mutex);
1867 doneq_thread_num = mpt->m_doneq_thread_n;
1868 for (i = 0; i < mpt->m_doneq_thread_n; i++) {
1869 mutex_enter(&mpt->m_doneq_thread_id[i].mutex);
1870 mpt->m_doneq_thread_id[i].flag &=
1871 (~MPTSAS_DONEQ_THREAD_ACTIVE);
1872 cv_signal(&mpt->m_doneq_thread_id[i].cv);
1873 mutex_exit(&mpt->m_doneq_thread_id[i].mutex);
1874 }
1875 while (mpt->m_doneq_thread_n) {
1876 cv_wait(&mpt->m_doneq_thread_cv,
1877 &mpt->m_doneq_mutex);
1878 }
1879 for (i = 0; i < doneq_thread_num; i++) {
1880 cv_destroy(&mpt->m_doneq_thread_id[i].cv);
1881 mutex_destroy(&mpt->m_doneq_thread_id[i].mutex);
1882 }
1883 kmem_free(mpt->m_doneq_thread_id,
1884 sizeof (mptsas_doneq_thread_list_t)
1885 * doneq_thread_num);
1886 mutex_exit(&mpt->m_doneq_mutex);
1887 cv_destroy(&mpt->m_doneq_thread_cv);
1888 mutex_destroy(&mpt->m_doneq_mutex);
1889 }
1890
1891 scsi_hba_reset_notify_tear_down(mpt->m_reset_notify_listf);
1892
1893 mptsas_list_del(mpt);
1894
1895 /*
1896 * Cancel timeout threads for this mpt
1897 */
1898 mutex_enter(&mpt->m_mutex);
1899 if (mpt->m_quiesce_timeid) {
1900 timeout_id_t tid = mpt->m_quiesce_timeid;
1901 mpt->m_quiesce_timeid = 0;
1902 mutex_exit(&mpt->m_mutex);
1903 (void) untimeout(tid);
1904 mutex_enter(&mpt->m_mutex);
1905 }
1906
1907 if (mpt->m_restart_cmd_timeid) {
1908 timeout_id_t tid = mpt->m_restart_cmd_timeid;
1909 mpt->m_restart_cmd_timeid = 0;
1910 mutex_exit(&mpt->m_mutex);
1911 (void) untimeout(tid);
1912 mutex_enter(&mpt->m_mutex);
1913 }
1914
1915 mutex_exit(&mpt->m_mutex);
1916
1917 /*
1918 * last mpt? ... if active, CANCEL watch threads.
1919 */
1920 mutex_enter(&mptsas_global_mutex);
1921 if (mptsas_head == NULL) {
1922 timeout_id_t tid;
1923 /*
1924 * Clear mptsas_timeouts_enable so that the watch thread
1925 * gets restarted on DDI_ATTACH
1926 */
1927 mptsas_timeouts_enabled = 0;
1928 if (mptsas_timeout_id) {
1929 tid = mptsas_timeout_id;
1930 mptsas_timeout_id = 0;
1931 mutex_exit(&mptsas_global_mutex);
1932 (void) untimeout(tid);
1933 mutex_enter(&mptsas_global_mutex);
1934 }
1935 if (mptsas_reset_watch) {
1936 tid = mptsas_reset_watch;
1937 mptsas_reset_watch = 0;
1938 mutex_exit(&mptsas_global_mutex);
1939 (void) untimeout(tid);
1940 mutex_enter(&mptsas_global_mutex);
1941 }
1942 }
1943 mutex_exit(&mptsas_global_mutex);
1944
1945 /*
1946 * Delete Phy stats
1947 */
1948 mptsas_destroy_phy_stats(mpt);
1949
1950 mptsas_destroy_hashes(mpt);
1951
1952 /*
1953 * Delete nt_active.
1954 */
1955 mutex_enter(&mpt->m_mutex);
1956 mptsas_free_active_slots(mpt);
1957 mutex_exit(&mpt->m_mutex);
1958
1959 /* deallocate everything that was allocated in mptsas_attach */
1960 mptsas_cache_destroy(mpt);
1961
1962 mptsas_hba_fini(mpt);
1963 mptsas_cfg_fini(mpt);
1964
1965 /* Lower the power informing PM Framework */
1966 if (mpt->m_options & MPTSAS_OPT_PM) {
1967 if (pm_lower_power(dip, 0, PM_LEVEL_D3) != DDI_SUCCESS)
1968 mptsas_log(mpt, CE_WARN,
1969 "!mptsas%d: Lower power request failed "
1970 "during detach, ignoring.",
1971 mpt->m_instance);
1972 }
1973
1974 mutex_destroy(&mpt->m_tx_waitq_mutex);
1975 mutex_destroy(&mpt->m_passthru_mutex);
1976 mutex_destroy(&mpt->m_mutex);
1977 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
1978 mutex_destroy(&mpt->m_phy_info[i].smhba_info.phy_mutex);
1979 }
1980 cv_destroy(&mpt->m_cv);
1981 cv_destroy(&mpt->m_passthru_cv);
1982 cv_destroy(&mpt->m_fw_cv);
1983 cv_destroy(&mpt->m_config_cv);
1984 cv_destroy(&mpt->m_fw_diag_cv);
1985
1986
1987 mptsas_smp_teardown(mpt);
1988 mptsas_hba_teardown(mpt);
1989
1990 mptsas_config_space_fini(mpt);
1991
1992 mptsas_free_handshake_msg(mpt);
1993
1994 mptsas_fm_fini(mpt);
1995 ddi_soft_state_free(mptsas_state, ddi_get_instance(dip));
1996 ddi_prop_remove_all(dip);
1997
1998 return (DDI_SUCCESS);
1999 }
2000
2001 static void
2002 mptsas_list_add(mptsas_t *mpt)
2003 {
2004 rw_enter(&mptsas_global_rwlock, RW_WRITER);
2005
2006 if (mptsas_head == NULL) {
2007 mptsas_head = mpt;
2008 } else {
2009 mptsas_tail->m_next = mpt;
2010 }
2011 mptsas_tail = mpt;
2012 rw_exit(&mptsas_global_rwlock);
2013 }
2014
2015 static void
2016 mptsas_list_del(mptsas_t *mpt)
2017 {
2018 mptsas_t *m;
2019 /*
2020 * Remove device instance from the global linked list
2021 */
2022 rw_enter(&mptsas_global_rwlock, RW_WRITER);
2023 if (mptsas_head == mpt) {
2024 m = mptsas_head = mpt->m_next;
2025 } else {
2026 for (m = mptsas_head; m != NULL; m = m->m_next) {
2027 if (m->m_next == mpt) {
2028 m->m_next = mpt->m_next;
2029 break;
2030 }
2031 }
2032 if (m == NULL) {
2033 mptsas_log(mpt, CE_PANIC, "Not in softc list!");
2034 }
2035 }
2036
2037 if (mptsas_tail == mpt) {
2038 mptsas_tail = m;
2039 }
2040 rw_exit(&mptsas_global_rwlock);
2041 }
2042
2043 static int
2044 mptsas_alloc_handshake_msg(mptsas_t *mpt, size_t alloc_size)
2045 {
2046 ddi_dma_attr_t task_dma_attrs;
2047
2048 mpt->m_hshk_dma_size = 0;
2049 task_dma_attrs = mpt->m_msg_dma_attr;
2050 task_dma_attrs.dma_attr_sgllen = 1;
2051 task_dma_attrs.dma_attr_granular = (uint32_t)(alloc_size);
2052
2053 /* allocate Task Management ddi_dma resources */
2054 if (mptsas_dma_addr_create(mpt, task_dma_attrs,
2055 &mpt->m_hshk_dma_hdl, &mpt->m_hshk_acc_hdl, &mpt->m_hshk_memp,
2056 alloc_size, NULL) == FALSE) {
2057 return (DDI_FAILURE);
2058 }
2059 mpt->m_hshk_dma_size = alloc_size;
2060
2061 return (DDI_SUCCESS);
2062 }
2063
2064 static void
2065 mptsas_free_handshake_msg(mptsas_t *mpt)
2066 {
2067 if (mpt->m_hshk_dma_size == 0)
2068 return;
2069 mptsas_dma_addr_destroy(&mpt->m_hshk_dma_hdl, &mpt->m_hshk_acc_hdl);
2070 mpt->m_hshk_dma_size = 0;
2071 }
2072
2073 static int
2074 mptsas_hba_setup(mptsas_t *mpt)
2075 {
2076 scsi_hba_tran_t *hba_tran;
2077 int tran_flags;
2078
2079 /* Allocate a transport structure */
2080 hba_tran = mpt->m_tran = scsi_hba_tran_alloc(mpt->m_dip,
2081 SCSI_HBA_CANSLEEP);
2082 ASSERT(mpt->m_tran != NULL);
2083
2084 hba_tran->tran_hba_private = mpt;
2085 hba_tran->tran_tgt_private = NULL;
2086
2087 hba_tran->tran_tgt_init = mptsas_scsi_tgt_init;
2088 hba_tran->tran_tgt_free = mptsas_scsi_tgt_free;
2089
2090 hba_tran->tran_start = mptsas_scsi_start;
2091 hba_tran->tran_reset = mptsas_scsi_reset;
2092 hba_tran->tran_abort = mptsas_scsi_abort;
2093 hba_tran->tran_getcap = mptsas_scsi_getcap;
2094 hba_tran->tran_setcap = mptsas_scsi_setcap;
2095 hba_tran->tran_init_pkt = mptsas_scsi_init_pkt;
2096 hba_tran->tran_destroy_pkt = mptsas_scsi_destroy_pkt;
2097
2098 hba_tran->tran_dmafree = mptsas_scsi_dmafree;
2099 hba_tran->tran_sync_pkt = mptsas_scsi_sync_pkt;
2100 hba_tran->tran_reset_notify = mptsas_scsi_reset_notify;
2101
2102 hba_tran->tran_get_bus_addr = mptsas_get_bus_addr;
2103 hba_tran->tran_get_name = mptsas_get_name;
2104
2105 hba_tran->tran_quiesce = mptsas_scsi_quiesce;
2106 hba_tran->tran_unquiesce = mptsas_scsi_unquiesce;
2107 hba_tran->tran_bus_reset = NULL;
2108
2109 hba_tran->tran_add_eventcall = NULL;
2110 hba_tran->tran_get_eventcookie = NULL;
2111 hba_tran->tran_post_event = NULL;
2112 hba_tran->tran_remove_eventcall = NULL;
2113
2114 hba_tran->tran_bus_config = mptsas_bus_config;
2115
2116 hba_tran->tran_interconnect_type = INTERCONNECT_SAS;
2117
2118 /*
2119 * All children of the HBA are iports. We need tran was cloned.
2120 * So we pass the flags to SCSA. SCSI_HBA_TRAN_CLONE will be
2121 * inherited to iport's tran vector.
2122 */
2123 tran_flags = (SCSI_HBA_HBA | SCSI_HBA_TRAN_CLONE);
2124
2125 if (scsi_hba_attach_setup(mpt->m_dip, &mpt->m_msg_dma_attr,
2126 hba_tran, tran_flags) != DDI_SUCCESS) {
2127 mptsas_log(mpt, CE_WARN, "hba attach setup failed");
2128 scsi_hba_tran_free(hba_tran);
2129 mpt->m_tran = NULL;
2130 return (FALSE);
2131 }
2132 return (TRUE);
2133 }
2134
2135 static void
2136 mptsas_hba_teardown(mptsas_t *mpt)
2137 {
2138 (void) scsi_hba_detach(mpt->m_dip);
2139 if (mpt->m_tran != NULL) {
2140 scsi_hba_tran_free(mpt->m_tran);
2141 mpt->m_tran = NULL;
2142 }
2143 }
2144
2145 static void
2146 mptsas_iport_register(mptsas_t *mpt)
2147 {
2148 int i, j;
2149 mptsas_phymask_t mask = 0x0;
2150 /*
2151 * initial value of mask is 0
2152 */
2153 mutex_enter(&mpt->m_mutex);
2154 for (i = 0; i < mpt->m_num_phys; i++) {
2155 mptsas_phymask_t phy_mask = 0x0;
2156 char phy_mask_name[MPTSAS_MAX_PHYS];
2157 uint8_t current_port;
2158
2159 if (mpt->m_phy_info[i].attached_devhdl == 0)
2160 continue;
2161
2162 bzero(phy_mask_name, sizeof (phy_mask_name));
2163
2164 current_port = mpt->m_phy_info[i].port_num;
2165
2166 if ((mask & (1 << i)) != 0)
2167 continue;
2168
2169 for (j = 0; j < mpt->m_num_phys; j++) {
2170 if (mpt->m_phy_info[j].attached_devhdl &&
2171 (mpt->m_phy_info[j].port_num == current_port)) {
2172 phy_mask |= (1 << j);
2173 }
2174 }
2175 mask = mask | phy_mask;
2176
2177 for (j = 0; j < mpt->m_num_phys; j++) {
2178 if ((phy_mask >> j) & 0x01) {
2179 mpt->m_phy_info[j].phy_mask = phy_mask;
2180 }
2181 }
2182
2183 (void) sprintf(phy_mask_name, "%x", phy_mask);
2184
2185 mutex_exit(&mpt->m_mutex);
2186 /*
2187 * register a iport
2188 */
2189 (void) scsi_hba_iport_register(mpt->m_dip, phy_mask_name);
2190 mutex_enter(&mpt->m_mutex);
2191 }
2192 mutex_exit(&mpt->m_mutex);
2193 /*
2194 * register a virtual port for RAID volume always
2195 */
2196 (void) scsi_hba_iport_register(mpt->m_dip, "v0");
2197
2198 }
2199
2200 static int
2201 mptsas_smp_setup(mptsas_t *mpt)
2202 {
2203 mpt->m_smptran = smp_hba_tran_alloc(mpt->m_dip);
2204 ASSERT(mpt->m_smptran != NULL);
2205 mpt->m_smptran->smp_tran_hba_private = mpt;
2206 mpt->m_smptran->smp_tran_start = mptsas_smp_start;
2207 if (smp_hba_attach_setup(mpt->m_dip, mpt->m_smptran) != DDI_SUCCESS) {
2208 mptsas_log(mpt, CE_WARN, "smp attach setup failed");
2209 smp_hba_tran_free(mpt->m_smptran);
2210 mpt->m_smptran = NULL;
2211 return (FALSE);
2212 }
2213 /*
2214 * Initialize smp hash table
2215 */
2216 mpt->m_smp_targets = refhash_create(MPTSAS_SMP_BUCKET_COUNT,
2217 mptsas_target_addr_hash, mptsas_target_addr_cmp,
2218 mptsas_smp_free, sizeof (mptsas_smp_t),
2219 offsetof(mptsas_smp_t, m_link), offsetof(mptsas_smp_t, m_addr),
2220 KM_SLEEP);
2221 mpt->m_smp_devhdl = 0xFFFF;
2222
2223 return (TRUE);
2224 }
2225
2226 static void
2227 mptsas_smp_teardown(mptsas_t *mpt)
2228 {
2229 (void) smp_hba_detach(mpt->m_dip);
2230 if (mpt->m_smptran != NULL) {
2231 smp_hba_tran_free(mpt->m_smptran);
2232 mpt->m_smptran = NULL;
2233 }
2234 mpt->m_smp_devhdl = 0;
2235 }
2236
2237 static int
2238 mptsas_cache_create(mptsas_t *mpt)
2239 {
2240 int instance = mpt->m_instance;
2241 char buf[64];
2242
2243 /*
2244 * create kmem cache for packets
2245 */
2246 (void) sprintf(buf, "mptsas%d_cache", instance);
2247 mpt->m_kmem_cache = kmem_cache_create(buf,
2248 sizeof (struct mptsas_cmd) + scsi_pkt_size(), 8,
2249 mptsas_kmem_cache_constructor, mptsas_kmem_cache_destructor,
2250 NULL, (void *)mpt, NULL, 0);
2251
2252 if (mpt->m_kmem_cache == NULL) {
2253 mptsas_log(mpt, CE_WARN, "creating kmem cache failed");
2254 return (FALSE);
2255 }
2256
2257 /*
2258 * create kmem cache for extra SGL frames if SGL cannot
2259 * be accomodated into main request frame.
2260 */
2261 (void) sprintf(buf, "mptsas%d_cache_frames", instance);
2262 mpt->m_cache_frames = kmem_cache_create(buf,
2263 sizeof (mptsas_cache_frames_t), 8,
2264 mptsas_cache_frames_constructor, mptsas_cache_frames_destructor,
2265 NULL, (void *)mpt, NULL, 0);
2266
2267 if (mpt->m_cache_frames == NULL) {
2268 mptsas_log(mpt, CE_WARN, "creating cache for frames failed");
2269 return (FALSE);
2270 }
2271
2272 return (TRUE);
2273 }
2274
2275 static void
2276 mptsas_cache_destroy(mptsas_t *mpt)
2277 {
2278 /* deallocate in reverse order */
2279 if (mpt->m_cache_frames) {
2280 kmem_cache_destroy(mpt->m_cache_frames);
2281 mpt->m_cache_frames = NULL;
2282 }
2283 if (mpt->m_kmem_cache) {
2284 kmem_cache_destroy(mpt->m_kmem_cache);
2285 mpt->m_kmem_cache = NULL;
2286 }
2287 }
2288
2289 static int
2290 mptsas_power(dev_info_t *dip, int component, int level)
2291 {
2292 #ifndef __lock_lint
2293 _NOTE(ARGUNUSED(component))
2294 #endif
2295 mptsas_t *mpt;
2296 int rval = DDI_SUCCESS;
2297 int polls = 0;
2298 uint32_t ioc_status;
2299
2300 if (scsi_hba_iport_unit_address(dip) != 0)
2301 return (DDI_SUCCESS);
2302
2303 mpt = ddi_get_soft_state(mptsas_state, ddi_get_instance(dip));
2304 if (mpt == NULL) {
2305 return (DDI_FAILURE);
2306 }
2307
2308 mutex_enter(&mpt->m_mutex);
2309
2310 /*
2311 * If the device is busy, don't lower its power level
2312 */
2313 if (mpt->m_busy && (mpt->m_power_level > level)) {
2314 mutex_exit(&mpt->m_mutex);
2315 return (DDI_FAILURE);
2316 }
2317 switch (level) {
2318 case PM_LEVEL_D0:
2319 NDBG11(("mptsas%d: turning power ON.", mpt->m_instance));
2320 MPTSAS_POWER_ON(mpt);
2321 /*
2322 * Wait up to 30 seconds for IOC to come out of reset.
2323 */
2324 while (((ioc_status = ddi_get32(mpt->m_datap,
2325 &mpt->m_reg->Doorbell)) &
2326 MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_RESET) {
2327 if (polls++ > 3000) {
2328 break;
2329 }
2330 delay(drv_usectohz(10000));
2331 }
2332 /*
2333 * If IOC is not in operational state, try to hard reset it.
2334 */
2335 if ((ioc_status & MPI2_IOC_STATE_MASK) !=
2336 MPI2_IOC_STATE_OPERATIONAL) {
2337 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET;
2338 if (mptsas_restart_ioc(mpt) == DDI_FAILURE) {
2339 mptsas_log(mpt, CE_WARN,
2340 "mptsas_power: hard reset failed");
2341 mutex_exit(&mpt->m_mutex);
2342 return (DDI_FAILURE);
2343 }
2344 }
2345 mpt->m_power_level = PM_LEVEL_D0;
2346 break;
2347 case PM_LEVEL_D3:
2348 NDBG11(("mptsas%d: turning power OFF.", mpt->m_instance));
2349 MPTSAS_POWER_OFF(mpt);
2350 break;
2351 default:
2352 mptsas_log(mpt, CE_WARN, "mptsas%d: unknown power level <%x>.",
2353 mpt->m_instance, level);
2354 rval = DDI_FAILURE;
2355 break;
2356 }
2357 mutex_exit(&mpt->m_mutex);
2358 return (rval);
2359 }
2360
2361 /*
2362 * Initialize configuration space and figure out which
2363 * chip and revison of the chip the mpt driver is using.
2364 */
2365 static int
2366 mptsas_config_space_init(mptsas_t *mpt)
2367 {
2368 NDBG0(("mptsas_config_space_init"));
2369
2370 if (mpt->m_config_handle != NULL)
2371 return (TRUE);
2372
2373 if (pci_config_setup(mpt->m_dip,
2374 &mpt->m_config_handle) != DDI_SUCCESS) {
2375 mptsas_log(mpt, CE_WARN, "cannot map configuration space.");
2376 return (FALSE);
2377 }
2378
2379 /*
2380 * This is a workaround for a XMITS ASIC bug which does not
2381 * drive the CBE upper bits.
2382 */
2383 if (pci_config_get16(mpt->m_config_handle, PCI_CONF_STAT) &
2384 PCI_STAT_PERROR) {
2385 pci_config_put16(mpt->m_config_handle, PCI_CONF_STAT,
2386 PCI_STAT_PERROR);
2387 }
2388
2389 mptsas_setup_cmd_reg(mpt);
2390
2391 /*
2392 * Get the chip device id:
2393 */
2394 mpt->m_devid = pci_config_get16(mpt->m_config_handle, PCI_CONF_DEVID);
2395
2396 /*
2397 * Save the revision.
2398 */
2399 mpt->m_revid = pci_config_get8(mpt->m_config_handle, PCI_CONF_REVID);
2400
2401 /*
2402 * Save the SubSystem Vendor and Device IDs
2403 */
2404 mpt->m_svid = pci_config_get16(mpt->m_config_handle, PCI_CONF_SUBVENID);
2405 mpt->m_ssid = pci_config_get16(mpt->m_config_handle, PCI_CONF_SUBSYSID);
2406
2407 /*
2408 * Set the latency timer to 0x40 as specified by the upa -> pci
2409 * bridge chip design team. This may be done by the sparc pci
2410 * bus nexus driver, but the driver should make sure the latency
2411 * timer is correct for performance reasons.
2412 */
2413 pci_config_put8(mpt->m_config_handle, PCI_CONF_LATENCY_TIMER,
2414 MPTSAS_LATENCY_TIMER);
2415
2416 (void) mptsas_get_pci_cap(mpt);
2417 return (TRUE);
2418 }
2419
2420 static void
2421 mptsas_config_space_fini(mptsas_t *mpt)
2422 {
2423 if (mpt->m_config_handle != NULL) {
2424 mptsas_disable_bus_master(mpt);
2425 pci_config_teardown(&mpt->m_config_handle);
2426 mpt->m_config_handle = NULL;
2427 }
2428 }
2429
2430 static void
2431 mptsas_setup_cmd_reg(mptsas_t *mpt)
2432 {
2433 ushort_t cmdreg;
2434
2435 /*
2436 * Set the command register to the needed values.
2437 */
2438 cmdreg = pci_config_get16(mpt->m_config_handle, PCI_CONF_COMM);
2439 cmdreg |= (PCI_COMM_ME | PCI_COMM_SERR_ENABLE |
2440 PCI_COMM_PARITY_DETECT | PCI_COMM_MAE);
2441 cmdreg &= ~PCI_COMM_IO;
2442 pci_config_put16(mpt->m_config_handle, PCI_CONF_COMM, cmdreg);
2443 }
2444
2445 static void
2446 mptsas_disable_bus_master(mptsas_t *mpt)
2447 {
2448 ushort_t cmdreg;
2449
2450 /*
2451 * Clear the master enable bit in the PCI command register.
2452 * This prevents any bus mastering activity like DMA.
2453 */
2454 cmdreg = pci_config_get16(mpt->m_config_handle, PCI_CONF_COMM);
2455 cmdreg &= ~PCI_COMM_ME;
2456 pci_config_put16(mpt->m_config_handle, PCI_CONF_COMM, cmdreg);
2457 }
2458
2459 int
2460 mptsas_dma_alloc(mptsas_t *mpt, mptsas_dma_alloc_state_t *dma_statep)
2461 {
2462 ddi_dma_attr_t attrs;
2463
2464 attrs = mpt->m_io_dma_attr;
2465 attrs.dma_attr_sgllen = 1;
2466
2467 ASSERT(dma_statep != NULL);
2468
2469 if (mptsas_dma_addr_create(mpt, attrs, &dma_statep->handle,
2470 &dma_statep->accessp, &dma_statep->memp, dma_statep->size,
2471 &dma_statep->cookie) == FALSE) {
2472 return (DDI_FAILURE);
2473 }
2474
2475 return (DDI_SUCCESS);
2476 }
2477
2478 void
2479 mptsas_dma_free(mptsas_dma_alloc_state_t *dma_statep)
2480 {
2481 ASSERT(dma_statep != NULL);
2482 mptsas_dma_addr_destroy(&dma_statep->handle, &dma_statep->accessp);
2483 dma_statep->size = 0;
2484 }
2485
2486 int
2487 mptsas_do_dma(mptsas_t *mpt, uint32_t size, int var, int (*callback)())
2488 {
2489 ddi_dma_attr_t attrs;
2490 ddi_dma_handle_t dma_handle;
2491 caddr_t memp;
2492 ddi_acc_handle_t accessp;
2493 int rval;
2494
2495 ASSERT(mutex_owned(&mpt->m_mutex));
2496
2497 attrs = mpt->m_msg_dma_attr;
2498 attrs.dma_attr_sgllen = 1;
2499 attrs.dma_attr_granular = size;
2500
2501 if (mptsas_dma_addr_create(mpt, attrs, &dma_handle,
2502 &accessp, &memp, size, NULL) == FALSE) {
2503 return (DDI_FAILURE);
2504 }
2505
2506 rval = (*callback) (mpt, memp, var, accessp);
2507
2508 if ((mptsas_check_dma_handle(dma_handle) != DDI_SUCCESS) ||
2509 (mptsas_check_acc_handle(accessp) != DDI_SUCCESS)) {
2510 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
2511 rval = DDI_FAILURE;
2512 }
2513
2514 mptsas_dma_addr_destroy(&dma_handle, &accessp);
2515 return (rval);
2516
2517 }
2518
2519 static int
2520 mptsas_alloc_request_frames(mptsas_t *mpt)
2521 {
2522 ddi_dma_attr_t frame_dma_attrs;
2523 caddr_t memp;
2524 ddi_dma_cookie_t cookie;
2525 size_t mem_size;
2526
2527 /*
2528 * re-alloc when it has already alloced
2529 */
2530 mptsas_dma_addr_destroy(&mpt->m_dma_req_frame_hdl,
2531 &mpt->m_acc_req_frame_hdl);
2532
2533 /*
2534 * The size of the request frame pool is:
2535 * Number of Request Frames * Request Frame Size
2536 */
2537 mem_size = mpt->m_max_requests * mpt->m_req_frame_size;
2538
2539 /*
2540 * set the DMA attributes. System Request Message Frames must be
2541 * aligned on a 16-byte boundry.
2542 */
2543 frame_dma_attrs = mpt->m_msg_dma_attr;
2544 frame_dma_attrs.dma_attr_align = 16;
2545 frame_dma_attrs.dma_attr_sgllen = 1;
2546
2547 /*
2548 * allocate the request frame pool.
2549 */
2550 if (mptsas_dma_addr_create(mpt, frame_dma_attrs,
2551 &mpt->m_dma_req_frame_hdl, &mpt->m_acc_req_frame_hdl, &memp,
2552 mem_size, &cookie) == FALSE) {
2553 return (DDI_FAILURE);
2554 }
2555
2556 /*
2557 * Store the request frame memory address. This chip uses this
2558 * address to dma to and from the driver's frame. The second
2559 * address is the address mpt uses to fill in the frame.
2560 */
2561 mpt->m_req_frame_dma_addr = cookie.dmac_laddress;
2562 mpt->m_req_frame = memp;
2563
2564 /*
2565 * Clear the request frame pool.
2566 */
2567 bzero(mpt->m_req_frame, mem_size);
2568
2569 return (DDI_SUCCESS);
2570 }
2571
2572 static int
2573 mptsas_alloc_reply_frames(mptsas_t *mpt)
2574 {
2575 ddi_dma_attr_t frame_dma_attrs;
2576 caddr_t memp;
2577 ddi_dma_cookie_t cookie;
2578 size_t mem_size;
2579
2580 /*
2581 * re-alloc when it has already alloced
2582 */
2583 mptsas_dma_addr_destroy(&mpt->m_dma_reply_frame_hdl,
2584 &mpt->m_acc_reply_frame_hdl);
2585
2586 /*
2587 * The size of the reply frame pool is:
2588 * Number of Reply Frames * Reply Frame Size
2589 */
2590 mem_size = mpt->m_max_replies * mpt->m_reply_frame_size;
2591
2592 /*
2593 * set the DMA attributes. System Reply Message Frames must be
2594 * aligned on a 4-byte boundry. This is the default.
2595 */
2596 frame_dma_attrs = mpt->m_msg_dma_attr;
2597 frame_dma_attrs.dma_attr_sgllen = 1;
2598
2599 /*
2600 * allocate the reply frame pool
2601 */
2602 if (mptsas_dma_addr_create(mpt, frame_dma_attrs,
2603 &mpt->m_dma_reply_frame_hdl, &mpt->m_acc_reply_frame_hdl, &memp,
2604 mem_size, &cookie) == FALSE) {
2605 return (DDI_FAILURE);
2606 }
2607
2608 /*
2609 * Store the reply frame memory address. This chip uses this
2610 * address to dma to and from the driver's frame. The second
2611 * address is the address mpt uses to process the frame.
2612 */
2613 mpt->m_reply_frame_dma_addr = cookie.dmac_laddress;
2614 mpt->m_reply_frame = memp;
2615
2616 /*
2617 * Clear the reply frame pool.
2618 */
2619 bzero(mpt->m_reply_frame, mem_size);
2620
2621 return (DDI_SUCCESS);
2622 }
2623
2624 static int
2625 mptsas_alloc_free_queue(mptsas_t *mpt)
2626 {
2627 ddi_dma_attr_t frame_dma_attrs;
2628 caddr_t memp;
2629 ddi_dma_cookie_t cookie;
2630 size_t mem_size;
2631
2632 /*
2633 * re-alloc when it has already alloced
2634 */
2635 mptsas_dma_addr_destroy(&mpt->m_dma_free_queue_hdl,
2636 &mpt->m_acc_free_queue_hdl);
2637
2638 /*
2639 * The reply free queue size is:
2640 * Reply Free Queue Depth * 4
2641 * The "4" is the size of one 32 bit address (low part of 64-bit
2642 * address)
2643 */
2644 mem_size = mpt->m_free_queue_depth * 4;
2645
2646 /*
2647 * set the DMA attributes The Reply Free Queue must be aligned on a
2648 * 16-byte boundry.
2649 */
2650 frame_dma_attrs = mpt->m_msg_dma_attr;
2651 frame_dma_attrs.dma_attr_align = 16;
2652 frame_dma_attrs.dma_attr_sgllen = 1;
2653
2654 /*
2655 * allocate the reply free queue
2656 */
2657 if (mptsas_dma_addr_create(mpt, frame_dma_attrs,
2658 &mpt->m_dma_free_queue_hdl, &mpt->m_acc_free_queue_hdl, &memp,
2659 mem_size, &cookie) == FALSE) {
2660 return (DDI_FAILURE);
2661 }
2662
2663 /*
2664 * Store the reply free queue memory address. This chip uses this
2665 * address to read from the reply free queue. The second address
2666 * is the address mpt uses to manage the queue.
2667 */
2668 mpt->m_free_queue_dma_addr = cookie.dmac_laddress;
2669 mpt->m_free_queue = memp;
2670
2671 /*
2672 * Clear the reply free queue memory.
2673 */
2674 bzero(mpt->m_free_queue, mem_size);
2675
2676 return (DDI_SUCCESS);
2677 }
2678
2679 static int
2680 mptsas_alloc_post_queue(mptsas_t *mpt)
2681 {
2682 ddi_dma_attr_t frame_dma_attrs;
2683 caddr_t memp;
2684 ddi_dma_cookie_t cookie;
2685 size_t mem_size;
2686
2687 /*
2688 * re-alloc when it has already alloced
2689 */
2690 mptsas_dma_addr_destroy(&mpt->m_dma_post_queue_hdl,
2691 &mpt->m_acc_post_queue_hdl);
2692
2693 /*
2694 * The reply descriptor post queue size is:
2695 * Reply Descriptor Post Queue Depth * 8
2696 * The "8" is the size of each descriptor (8 bytes or 64 bits).
2697 */
2698 mem_size = mpt->m_post_queue_depth * 8;
2699
2700 /*
2701 * set the DMA attributes. The Reply Descriptor Post Queue must be
2702 * aligned on a 16-byte boundry.
2703 */
2704 frame_dma_attrs = mpt->m_msg_dma_attr;
2705 frame_dma_attrs.dma_attr_align = 16;
2706 frame_dma_attrs.dma_attr_sgllen = 1;
2707
2708 /*
2709 * allocate the reply post queue
2710 */
2711 if (mptsas_dma_addr_create(mpt, frame_dma_attrs,
2712 &mpt->m_dma_post_queue_hdl, &mpt->m_acc_post_queue_hdl, &memp,
2713 mem_size, &cookie) == FALSE) {
2714 return (DDI_FAILURE);
2715 }
2716
2717 /*
2718 * Store the reply descriptor post queue memory address. This chip
2719 * uses this address to write to the reply descriptor post queue. The
2720 * second address is the address mpt uses to manage the queue.
2721 */
2722 mpt->m_post_queue_dma_addr = cookie.dmac_laddress;
2723 mpt->m_post_queue = memp;
2724
2725 /*
2726 * Clear the reply post queue memory.
2727 */
2728 bzero(mpt->m_post_queue, mem_size);
2729
2730 return (DDI_SUCCESS);
2731 }
2732
2733 static void
2734 mptsas_alloc_reply_args(mptsas_t *mpt)
2735 {
2736 if (mpt->m_replyh_args == NULL) {
2737 mpt->m_replyh_args = kmem_zalloc(sizeof (m_replyh_arg_t) *
2738 mpt->m_max_replies, KM_SLEEP);
2739 }
2740 }
2741
2742 static int
2743 mptsas_alloc_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd)
2744 {
2745 mptsas_cache_frames_t *frames = NULL;
2746 if (cmd->cmd_extra_frames == NULL) {
2747 frames = kmem_cache_alloc(mpt->m_cache_frames, KM_NOSLEEP);
2748 if (frames == NULL) {
2749 return (DDI_FAILURE);
2750 }
2751 cmd->cmd_extra_frames = frames;
2752 }
2753 return (DDI_SUCCESS);
2754 }
2755
2756 static void
2757 mptsas_free_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd)
2758 {
2759 if (cmd->cmd_extra_frames) {
2760 kmem_cache_free(mpt->m_cache_frames,
2761 (void *)cmd->cmd_extra_frames);
2762 cmd->cmd_extra_frames = NULL;
2763 }
2764 }
2765
2766 static void
2767 mptsas_cfg_fini(mptsas_t *mpt)
2768 {
2769 NDBG0(("mptsas_cfg_fini"));
2770 ddi_regs_map_free(&mpt->m_datap);
2771 }
2772
2773 static void
2774 mptsas_hba_fini(mptsas_t *mpt)
2775 {
2776 NDBG0(("mptsas_hba_fini"));
2777
2778 /*
2779 * Free up any allocated memory
2780 */
2781 mptsas_dma_addr_destroy(&mpt->m_dma_req_frame_hdl,
2782 &mpt->m_acc_req_frame_hdl);
2783
2784 mptsas_dma_addr_destroy(&mpt->m_dma_reply_frame_hdl,
2785 &mpt->m_acc_reply_frame_hdl);
2786
2787 mptsas_dma_addr_destroy(&mpt->m_dma_free_queue_hdl,
2788 &mpt->m_acc_free_queue_hdl);
2789
2790 mptsas_dma_addr_destroy(&mpt->m_dma_post_queue_hdl,
2791 &mpt->m_acc_post_queue_hdl);
2792
2793 if (mpt->m_replyh_args != NULL) {
2794 kmem_free(mpt->m_replyh_args, sizeof (m_replyh_arg_t)
2795 * mpt->m_max_replies);
2796 }
2797 }
2798
2799 static int
2800 mptsas_name_child(dev_info_t *lun_dip, char *name, int len)
2801 {
2802 int lun = 0;
2803 char *sas_wwn = NULL;
2804 int phynum = -1;
2805 int reallen = 0;
2806
2807 /* Get the target num */
2808 lun = ddi_prop_get_int(DDI_DEV_T_ANY, lun_dip, DDI_PROP_DONTPASS,
2809 LUN_PROP, 0);
2810
2811 if ((phynum = ddi_prop_get_int(DDI_DEV_T_ANY, lun_dip,
2812 DDI_PROP_DONTPASS, "sata-phy", -1)) != -1) {
2813 /*
2814 * Stick in the address of form "pPHY,LUN"
2815 */
2816 reallen = snprintf(name, len, "p%x,%x", phynum, lun);
2817 } else if (ddi_prop_lookup_string(DDI_DEV_T_ANY, lun_dip,
2818 DDI_PROP_DONTPASS, SCSI_ADDR_PROP_TARGET_PORT, &sas_wwn)
2819 == DDI_PROP_SUCCESS) {
2820 /*
2821 * Stick in the address of the form "wWWN,LUN"
2822 */
2823 reallen = snprintf(name, len, "%s,%x", sas_wwn, lun);
2824 ddi_prop_free(sas_wwn);
2825 } else {
2826 return (DDI_FAILURE);
2827 }
2828
2829 ASSERT(reallen < len);
2830 if (reallen >= len) {
2831 mptsas_log(0, CE_WARN, "!mptsas_get_name: name parameter "
2832 "length too small, it needs to be %d bytes", reallen + 1);
2833 }
2834 return (DDI_SUCCESS);
2835 }
2836
2837 /*
2838 * tran_tgt_init(9E) - target device instance initialization
2839 */
2840 static int
2841 mptsas_scsi_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
2842 scsi_hba_tran_t *hba_tran, struct scsi_device *sd)
2843 {
2844 #ifndef __lock_lint
2845 _NOTE(ARGUNUSED(hba_tran))
2846 #endif
2847
2848 /*
2849 * At this point, the scsi_device structure already exists
2850 * and has been initialized.
2851 *
2852 * Use this function to allocate target-private data structures,
2853 * if needed by this HBA. Add revised flow-control and queue
2854 * properties for child here, if desired and if you can tell they
2855 * support tagged queueing by now.
2856 */
2857 mptsas_t *mpt;
2858 int lun = sd->sd_address.a_lun;
2859 mdi_pathinfo_t *pip = NULL;
2860 mptsas_tgt_private_t *tgt_private = NULL;
2861 mptsas_target_t *ptgt = NULL;
2862 char *psas_wwn = NULL;
2863 mptsas_phymask_t phymask = 0;
2864 uint64_t sas_wwn = 0;
2865 mptsas_target_addr_t addr;
2866 mpt = SDEV2MPT(sd);
2867
2868 ASSERT(scsi_hba_iport_unit_address(hba_dip) != 0);
2869
2870 NDBG0(("mptsas_scsi_tgt_init: hbadip=0x%p tgtdip=0x%p lun=%d",
2871 (void *)hba_dip, (void *)tgt_dip, lun));
2872
2873 if (ndi_dev_is_persistent_node(tgt_dip) == 0) {
2874 (void) ndi_merge_node(tgt_dip, mptsas_name_child);
2875 ddi_set_name_addr(tgt_dip, NULL);
2876 return (DDI_FAILURE);
2877 }
2878 /*
2879 * phymask is 0 means the virtual port for RAID
2880 */
2881 phymask = (mptsas_phymask_t)ddi_prop_get_int(DDI_DEV_T_ANY, hba_dip, 0,
2882 "phymask", 0);
2883 if (mdi_component_is_client(tgt_dip, NULL) == MDI_SUCCESS) {
2884 if ((pip = (void *)(sd->sd_private)) == NULL) {
2885 /*
2886 * Very bad news if this occurs. Somehow scsi_vhci has
2887 * lost the pathinfo node for this target.
2888 */
2889 return (DDI_NOT_WELL_FORMED);
2890 }
2891
2892 if (mdi_prop_lookup_int(pip, LUN_PROP, &lun) !=
2893 DDI_PROP_SUCCESS) {
2894 mptsas_log(mpt, CE_WARN, "Get lun property failed\n");
2895 return (DDI_FAILURE);
2896 }
2897
2898 if (mdi_prop_lookup_string(pip, SCSI_ADDR_PROP_TARGET_PORT,
2899 &psas_wwn) == MDI_SUCCESS) {
2900 if (scsi_wwnstr_to_wwn(psas_wwn, &sas_wwn)) {
2901 sas_wwn = 0;
2902 }
2903 (void) mdi_prop_free(psas_wwn);
2904 }
2905 } else {
2906 lun = ddi_prop_get_int(DDI_DEV_T_ANY, tgt_dip,
2907 DDI_PROP_DONTPASS, LUN_PROP, 0);
2908 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, tgt_dip,
2909 DDI_PROP_DONTPASS, SCSI_ADDR_PROP_TARGET_PORT, &psas_wwn) ==
2910 DDI_PROP_SUCCESS) {
2911 if (scsi_wwnstr_to_wwn(psas_wwn, &sas_wwn)) {
2912 sas_wwn = 0;
2913 }
2914 ddi_prop_free(psas_wwn);
2915 } else {
2916 sas_wwn = 0;
2917 }
2918 }
2919
2920 ASSERT((sas_wwn != 0) || (phymask != 0));
2921 addr.mta_wwn = sas_wwn;
2922 addr.mta_phymask = phymask;
2923 mutex_enter(&mpt->m_mutex);
2924 ptgt = refhash_lookup(mpt->m_targets, &addr);
2925 mutex_exit(&mpt->m_mutex);
2926 if (ptgt == NULL) {
2927 mptsas_log(mpt, CE_WARN, "!tgt_init: target doesn't exist or "
2928 "gone already! phymask:%x, saswwn %"PRIx64, phymask,
2929 sas_wwn);
2930 return (DDI_FAILURE);
2931 }
2932 if (hba_tran->tran_tgt_private == NULL) {
2933 tgt_private = kmem_zalloc(sizeof (mptsas_tgt_private_t),
2934 KM_SLEEP);
2935 tgt_private->t_lun = lun;
2936 tgt_private->t_private = ptgt;
2937 hba_tran->tran_tgt_private = tgt_private;
2938 }
2939
2940 if (mdi_component_is_client(tgt_dip, NULL) == MDI_SUCCESS) {
2941 return (DDI_SUCCESS);
2942 }
2943 mutex_enter(&mpt->m_mutex);
2944
2945 if (ptgt->m_deviceinfo &
2946 (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
2947 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
2948 uchar_t *inq89 = NULL;
2949 int inq89_len = 0x238;
2950 int reallen = 0;
2951 int rval = 0;
2952 struct sata_id *sid = NULL;
2953 char model[SATA_ID_MODEL_LEN + 1];
2954 char fw[SATA_ID_FW_LEN + 1];
2955 char *vid, *pid;
2956 int i;
2957
2958 mutex_exit(&mpt->m_mutex);
2959 /*
2960 * According SCSI/ATA Translation -2 (SAT-2) revision 01a
2961 * chapter 12.4.2 VPD page 89h includes 512 bytes ATA IDENTIFY
2962 * DEVICE data or ATA IDENTIFY PACKET DEVICE data.
2963 */
2964 inq89 = kmem_zalloc(inq89_len, KM_SLEEP);
2965 rval = mptsas_inquiry(mpt, ptgt, 0, 0x89,
2966 inq89, inq89_len, &reallen, 1);
2967
2968 if (rval != 0) {
2969 if (inq89 != NULL) {
2970 kmem_free(inq89, inq89_len);
2971 }
2972
2973 mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page "
2974 "0x89 for SATA target:%x failed!", ptgt->m_devhdl);
2975 return (DDI_SUCCESS);
2976 }
2977 sid = (void *)(&inq89[60]);
2978
2979 swab(sid->ai_model, model, SATA_ID_MODEL_LEN);
2980 swab(sid->ai_fw, fw, SATA_ID_FW_LEN);
2981
2982 model[SATA_ID_MODEL_LEN] = 0;
2983 fw[SATA_ID_FW_LEN] = 0;
2984
2985 /*
2986 * split model into into vid/pid
2987 */
2988 for (i = 0, pid = model; i < SATA_ID_MODEL_LEN; i++, pid++)
2989 if ((*pid == ' ') || (*pid == '\t'))
2990 break;
2991 if (i < SATA_ID_MODEL_LEN) {
2992 vid = model;
2993 /*
2994 * terminate vid, establish pid
2995 */
2996 *pid++ = 0;
2997 } else {
2998 /*
2999 * vid will stay "ATA ", the rule is same
3000 * as sata framework implementation.
3001 */
3002 vid = NULL;
3003 /*
3004 * model is all pid
3005 */
3006 pid = model;
3007 }
3008
3009 /*
3010 * override SCSA "inquiry-*" properties
3011 */
3012 if (vid)
3013 (void) scsi_device_prop_update_inqstring(sd,
3014 INQUIRY_VENDOR_ID, vid, strlen(vid));
3015 if (pid)
3016 (void) scsi_device_prop_update_inqstring(sd,
3017 INQUIRY_PRODUCT_ID, pid, strlen(pid));
3018 (void) scsi_device_prop_update_inqstring(sd,
3019 INQUIRY_REVISION_ID, fw, strlen(fw));
3020
3021 if (inq89 != NULL) {
3022 kmem_free(inq89, inq89_len);
3023 }
3024 } else {
3025 mutex_exit(&mpt->m_mutex);
3026 }
3027
3028 return (DDI_SUCCESS);
3029 }
3030 /*
3031 * tran_tgt_free(9E) - target device instance deallocation
3032 */
3033 static void
3034 mptsas_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip,
3035 scsi_hba_tran_t *hba_tran, struct scsi_device *sd)
3036 {
3037 #ifndef __lock_lint
3038 _NOTE(ARGUNUSED(hba_dip, tgt_dip, hba_tran, sd))
3039 #endif
3040
3041 mptsas_tgt_private_t *tgt_private = hba_tran->tran_tgt_private;
3042
3043 if (tgt_private != NULL) {
3044 kmem_free(tgt_private, sizeof (mptsas_tgt_private_t));
3045 hba_tran->tran_tgt_private = NULL;
3046 }
3047 }
3048
3049 /*
3050 * scsi_pkt handling
3051 *
3052 * Visible to the external world via the transport structure.
3053 */
3054
3055 /*
3056 * Notes:
3057 * - transport the command to the addressed SCSI target/lun device
3058 * - normal operation is to schedule the command to be transported,
3059 * and return TRAN_ACCEPT if this is successful.
3060 * - if NO_INTR, tran_start must poll device for command completion
3061 */
3062 static int
3063 mptsas_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt)
3064 {
3065 #ifndef __lock_lint
3066 _NOTE(ARGUNUSED(ap))
3067 #endif
3068 mptsas_t *mpt = PKT2MPT(pkt);
3069 mptsas_cmd_t *cmd = PKT2CMD(pkt);
3070 int rval;
3071 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
3072
3073 NDBG1(("mptsas_scsi_start: pkt=0x%p", (void *)pkt));
3074 ASSERT(ptgt);
3075 if (ptgt == NULL)
3076 return (TRAN_FATAL_ERROR);
3077
3078 /*
3079 * prepare the pkt before taking mutex.
3080 */
3081 rval = mptsas_prepare_pkt(cmd);
3082 if (rval != TRAN_ACCEPT) {
3083 return (rval);
3084 }
3085
3086 /*
3087 * Send the command to target/lun, however your HBA requires it.
3088 * If busy, return TRAN_BUSY; if there's some other formatting error
3089 * in the packet, return TRAN_BADPKT; otherwise, fall through to the
3090 * return of TRAN_ACCEPT.
3091 *
3092 * Remember that access to shared resources, including the mptsas_t
3093 * data structure and the HBA hardware registers, must be protected
3094 * with mutexes, here and everywhere.
3095 *
3096 * Also remember that at interrupt time, you'll get an argument
3097 * to the interrupt handler which is a pointer to your mptsas_t
3098 * structure; you'll have to remember which commands are outstanding
3099 * and which scsi_pkt is the currently-running command so the
3100 * interrupt handler can refer to the pkt to set completion
3101 * status, call the target driver back through pkt_comp, etc.
3102 *
3103 * If the instance lock is held by other thread, don't spin to wait
3104 * for it. Instead, queue the cmd and next time when the instance lock
3105 * is not held, accept all the queued cmd. A extra tx_waitq is
3106 * introduced to protect the queue.
3107 *
3108 * The polled cmd will not be queud and accepted as usual.
3109 *
3110 * Under the tx_waitq mutex, record whether a thread is draining
3111 * the tx_waitq. An IO requesting thread that finds the instance
3112 * mutex contended appends to the tx_waitq and while holding the
3113 * tx_wait mutex, if the draining flag is not set, sets it and then
3114 * proceeds to spin for the instance mutex. This scheme ensures that
3115 * the last cmd in a burst be processed.
3116 *
3117 * we enable this feature only when the helper threads are enabled,
3118 * at which we think the loads are heavy.
3119 *
3120 * per instance mutex m_tx_waitq_mutex is introduced to protect the
3121 * m_tx_waitqtail, m_tx_waitq, m_tx_draining.
3122 */
3123
3124 if (mpt->m_doneq_thread_n) {
3125 if (mutex_tryenter(&mpt->m_mutex) != 0) {
3126 rval = mptsas_accept_txwq_and_pkt(mpt, cmd);
3127 mutex_exit(&mpt->m_mutex);
3128 } else if (cmd->cmd_pkt_flags & FLAG_NOINTR) {
3129 mutex_enter(&mpt->m_mutex);
3130 rval = mptsas_accept_txwq_and_pkt(mpt, cmd);
3131 mutex_exit(&mpt->m_mutex);
3132 } else {
3133 mutex_enter(&mpt->m_tx_waitq_mutex);
3134 /*
3135 * ptgt->m_dr_flag is protected by m_mutex or
3136 * m_tx_waitq_mutex. In this case, m_tx_waitq_mutex
3137 * is acquired.
3138 */
3139 if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) {
3140 if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) {
3141 /*
3142 * The command should be allowed to
3143 * retry by returning TRAN_BUSY to
3144 * to stall the I/O's which come from
3145 * scsi_vhci since the device/path is
3146 * in unstable state now.
3147 */
3148 mutex_exit(&mpt->m_tx_waitq_mutex);
3149 return (TRAN_BUSY);
3150 } else {
3151 /*
3152 * The device is offline, just fail the
3153 * command by returning
3154 * TRAN_FATAL_ERROR.
3155 */
3156 mutex_exit(&mpt->m_tx_waitq_mutex);
3157 return (TRAN_FATAL_ERROR);
3158 }
3159 }
3160 if (mpt->m_tx_draining) {
3161 cmd->cmd_flags |= CFLAG_TXQ;
3162 *mpt->m_tx_waitqtail = cmd;
3163 mpt->m_tx_waitqtail = &cmd->cmd_linkp;
3164 mutex_exit(&mpt->m_tx_waitq_mutex);
3165 } else { /* drain the queue */
3166 mpt->m_tx_draining = 1;
3167 mutex_exit(&mpt->m_tx_waitq_mutex);
3168 mutex_enter(&mpt->m_mutex);
3169 rval = mptsas_accept_txwq_and_pkt(mpt, cmd);
3170 mutex_exit(&mpt->m_mutex);
3171 }
3172 }
3173 } else {
3174 mutex_enter(&mpt->m_mutex);
3175 /*
3176 * ptgt->m_dr_flag is protected by m_mutex or m_tx_waitq_mutex
3177 * in this case, m_mutex is acquired.
3178 */
3179 if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) {
3180 if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) {
3181 /*
3182 * commands should be allowed to retry by
3183 * returning TRAN_BUSY to stall the I/O's
3184 * which come from scsi_vhci since the device/
3185 * path is in unstable state now.
3186 */
3187 mutex_exit(&mpt->m_mutex);
3188 return (TRAN_BUSY);
3189 } else {
3190 /*
3191 * The device is offline, just fail the
3192 * command by returning TRAN_FATAL_ERROR.
3193 */
3194 mutex_exit(&mpt->m_mutex);
3195 return (TRAN_FATAL_ERROR);
3196 }
3197 }
3198 rval = mptsas_accept_pkt(mpt, cmd);
3199 mutex_exit(&mpt->m_mutex);
3200 }
3201
3202 return (rval);
3203 }
3204
3205 /*
3206 * Accept all the queued cmds(if any) before accept the current one.
3207 */
3208 static int
3209 mptsas_accept_txwq_and_pkt(mptsas_t *mpt, mptsas_cmd_t *cmd)
3210 {
3211 int rval;
3212 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
3213
3214 ASSERT(mutex_owned(&mpt->m_mutex));
3215 /*
3216 * The call to mptsas_accept_tx_waitq() must always be performed
3217 * because that is where mpt->m_tx_draining is cleared.
3218 */
3219 mutex_enter(&mpt->m_tx_waitq_mutex);
3220 mptsas_accept_tx_waitq(mpt);
3221 mutex_exit(&mpt->m_tx_waitq_mutex);
3222 /*
3223 * ptgt->m_dr_flag is protected by m_mutex or m_tx_waitq_mutex
3224 * in this case, m_mutex is acquired.
3225 */
3226 if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) {
3227 if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) {
3228 /*
3229 * The command should be allowed to retry by returning
3230 * TRAN_BUSY to stall the I/O's which come from
3231 * scsi_vhci since the device/path is in unstable state
3232 * now.
3233 */
3234 return (TRAN_BUSY);
3235 } else {
3236 /*
3237 * The device is offline, just fail the command by
3238 * return TRAN_FATAL_ERROR.
3239 */
3240 return (TRAN_FATAL_ERROR);
3241 }
3242 }
3243 rval = mptsas_accept_pkt(mpt, cmd);
3244
3245 return (rval);
3246 }
3247
3248 static int
3249 mptsas_accept_pkt(mptsas_t *mpt, mptsas_cmd_t *cmd)
3250 {
3251 int rval = TRAN_ACCEPT;
3252 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
3253
3254 NDBG1(("mptsas_accept_pkt: cmd=0x%p", (void *)cmd));
3255
3256 ASSERT(mutex_owned(&mpt->m_mutex));
3257
3258 if ((cmd->cmd_flags & CFLAG_PREPARED) == 0) {
3259 rval = mptsas_prepare_pkt(cmd);
3260 if (rval != TRAN_ACCEPT) {
3261 cmd->cmd_flags &= ~CFLAG_TRANFLAG;
3262 return (rval);
3263 }
3264 }
3265
3266 /*
3267 * reset the throttle if we were draining
3268 */
3269 if ((ptgt->m_t_ncmds == 0) &&
3270 (ptgt->m_t_throttle == DRAIN_THROTTLE)) {
3271 NDBG23(("reset throttle"));
3272 ASSERT(ptgt->m_reset_delay == 0);
3273 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
3274 }
3275
3276 /*
3277 * If HBA is being reset, the DevHandles are being re-initialized,
3278 * which means that they could be invalid even if the target is still
3279 * attached. Check if being reset and if DevHandle is being
3280 * re-initialized. If this is the case, return BUSY so the I/O can be
3281 * retried later.
3282 */
3283 if ((ptgt->m_devhdl == MPTSAS_INVALID_DEVHDL) && mpt->m_in_reset) {
3284 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET);
3285 if (cmd->cmd_flags & CFLAG_TXQ) {
3286 mptsas_doneq_add(mpt, cmd);
3287 mptsas_doneq_empty(mpt);
3288 return (rval);
3289 } else {
3290 return (TRAN_BUSY);
3291 }
3292 }
3293
3294 /*
3295 * If device handle has already been invalidated, just
3296 * fail the command. In theory, command from scsi_vhci
3297 * client is impossible send down command with invalid
3298 * devhdl since devhdl is set after path offline, target
3299 * driver is not suppose to select a offlined path.
3300 */
3301 if (ptgt->m_devhdl == MPTSAS_INVALID_DEVHDL) {
3302 NDBG3(("rejecting command, it might because invalid devhdl "
3303 "request."));
3304 mptsas_set_pkt_reason(mpt, cmd, CMD_DEV_GONE, STAT_TERMINATED);
3305 if (cmd->cmd_flags & CFLAG_TXQ) {
3306 mptsas_doneq_add(mpt, cmd);
3307 mptsas_doneq_empty(mpt);
3308 return (rval);
3309 } else {
3310 return (TRAN_FATAL_ERROR);
3311 }
3312 }
3313 /*
3314 * The first case is the normal case. mpt gets a command from the
3315 * target driver and starts it.
3316 * Since SMID 0 is reserved and the TM slot is reserved, the actual max
3317 * commands is m_max_requests - 2.
3318 */
3319 if ((mpt->m_ncmds <= (mpt->m_max_requests - 2)) &&
3320 (ptgt->m_t_throttle > HOLD_THROTTLE) &&
3321 (ptgt->m_t_ncmds < ptgt->m_t_throttle) &&
3322 (ptgt->m_reset_delay == 0) &&
3323 (ptgt->m_t_nwait == 0) &&
3324 ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0)) {
3325 if (mptsas_save_cmd(mpt, cmd) == TRUE) {
3326 (void) mptsas_start_cmd(mpt, cmd);
3327 } else {
3328 mptsas_waitq_add(mpt, cmd);
3329 }
3330 } else {
3331 /*
3332 * Add this pkt to the work queue
3333 */
3334 mptsas_waitq_add(mpt, cmd);
3335
3336 if (cmd->cmd_pkt_flags & FLAG_NOINTR) {
3337 (void) mptsas_poll(mpt, cmd, MPTSAS_POLL_TIME);
3338
3339 /*
3340 * Only flush the doneq if this is not a TM
3341 * cmd. For TM cmds the flushing of the
3342 * doneq will be done in those routines.
3343 */
3344 if ((cmd->cmd_flags & CFLAG_TM_CMD) == 0) {
3345 mptsas_doneq_empty(mpt);
3346 }
3347 }
3348 }
3349 return (rval);
3350 }
3351
3352 int
3353 mptsas_save_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
3354 {
3355 mptsas_slots_t *slots = mpt->m_active;
3356 uint_t slot, start_rotor;
3357 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
3358
3359 ASSERT(MUTEX_HELD(&mpt->m_mutex));
3360
3361 /*
3362 * Account for reserved TM request slot and reserved SMID of 0.
3363 */
3364 ASSERT(slots->m_n_normal == (mpt->m_max_requests - 2));
3365
3366 /*
3367 * Find the next available slot, beginning at m_rotor. If no slot is
3368 * available, we'll return FALSE to indicate that. This mechanism
3369 * considers only the normal slots, not the reserved slot 0 nor the
3370 * task management slot m_n_normal + 1. The rotor is left to point to
3371 * the normal slot after the one we select, unless we select the last
3372 * normal slot in which case it returns to slot 1.
3373 */
3374 start_rotor = slots->m_rotor;
3375 do {
3376 slot = slots->m_rotor++;
3377 if (slots->m_rotor > slots->m_n_normal)
3378 slots->m_rotor = 1;
3379
3380 if (slots->m_rotor == start_rotor)
3381 break;
3382 } while (slots->m_slot[slot] != NULL);
3383
3384 if (slots->m_slot[slot] != NULL)
3385 return (FALSE);
3386
3387 ASSERT(slot != 0 && slot <= slots->m_n_normal);
3388
3389 cmd->cmd_slot = slot;
3390 slots->m_slot[slot] = cmd;
3391 mpt->m_ncmds++;
3392
3393 /*
3394 * only increment per target ncmds if this is not a
3395 * command that has no target associated with it (i.e. a
3396 * event acknoledgment)
3397 */
3398 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) {
3399 /*
3400 * Expiration time is set in mptsas_start_cmd
3401 */
3402 ptgt->m_t_ncmds++;
3403 cmd->cmd_active_expiration = 0;
3404 } else {
3405 /*
3406 * Initialize expiration time for passthrough commands,
3407 */
3408 cmd->cmd_active_expiration = gethrtime() +
3409 (hrtime_t)cmd->cmd_pkt->pkt_time * NANOSEC;
3410 }
3411 return (TRUE);
3412 }
3413
3414 /*
3415 * prepare the pkt:
3416 * the pkt may have been resubmitted or just reused so
3417 * initialize some fields and do some checks.
3418 */
3419 static int
3420 mptsas_prepare_pkt(mptsas_cmd_t *cmd)
3421 {
3422 struct scsi_pkt *pkt = CMD2PKT(cmd);
3423
3424 NDBG1(("mptsas_prepare_pkt: cmd=0x%p", (void *)cmd));
3425
3426 /*
3427 * Reinitialize some fields that need it; the packet may
3428 * have been resubmitted
3429 */
3430 pkt->pkt_reason = CMD_CMPLT;
3431 pkt->pkt_state = 0;
3432 pkt->pkt_statistics = 0;
3433 pkt->pkt_resid = 0;
3434 cmd->cmd_age = 0;
3435 cmd->cmd_pkt_flags = pkt->pkt_flags;
3436
3437 /*
3438 * zero status byte.
3439 */
3440 *(pkt->pkt_scbp) = 0;
3441
3442 if (cmd->cmd_flags & CFLAG_DMAVALID) {
3443 pkt->pkt_resid = cmd->cmd_dmacount;
3444
3445 /*
3446 * consistent packets need to be sync'ed first
3447 * (only for data going out)
3448 */
3449 if ((cmd->cmd_flags & CFLAG_CMDIOPB) &&
3450 (cmd->cmd_flags & CFLAG_DMASEND)) {
3451 (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0,
3452 DDI_DMA_SYNC_FORDEV);
3453 }
3454 }
3455
3456 cmd->cmd_flags =
3457 (cmd->cmd_flags & ~(CFLAG_TRANFLAG)) |
3458 CFLAG_PREPARED | CFLAG_IN_TRANSPORT;
3459
3460 return (TRAN_ACCEPT);
3461 }
3462
3463 /*
3464 * tran_init_pkt(9E) - allocate scsi_pkt(9S) for command
3465 *
3466 * One of three possibilities:
3467 * - allocate scsi_pkt
3468 * - allocate scsi_pkt and DMA resources
3469 * - allocate DMA resources to an already-allocated pkt
3470 */
3471 static struct scsi_pkt *
3472 mptsas_scsi_init_pkt(struct scsi_address *ap, struct scsi_pkt *pkt,
3473 struct buf *bp, int cmdlen, int statuslen, int tgtlen, int flags,
3474 int (*callback)(), caddr_t arg)
3475 {
3476 mptsas_cmd_t *cmd, *new_cmd;
3477 mptsas_t *mpt = ADDR2MPT(ap);
3478 int failure = 1;
3479 uint_t oldcookiec;
3480 mptsas_target_t *ptgt = NULL;
3481 int rval;
3482 mptsas_tgt_private_t *tgt_private;
3483 int kf;
3484
3485 kf = (callback == SLEEP_FUNC)? KM_SLEEP: KM_NOSLEEP;
3486
3487 tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran->
3488 tran_tgt_private;
3489 ASSERT(tgt_private != NULL);
3490 if (tgt_private == NULL) {
3491 return (NULL);
3492 }
3493 ptgt = tgt_private->t_private;
3494 ASSERT(ptgt != NULL);
3495 if (ptgt == NULL)
3496 return (NULL);
3497 ap->a_target = ptgt->m_devhdl;
3498 ap->a_lun = tgt_private->t_lun;
3499
3500 ASSERT(callback == NULL_FUNC || callback == SLEEP_FUNC);
3501 #ifdef MPTSAS_TEST_EXTRN_ALLOC
3502 statuslen *= 100; tgtlen *= 4;
3503 #endif
3504 NDBG3(("mptsas_scsi_init_pkt:\n"
3505 "\ttgt=%d in=0x%p bp=0x%p clen=%d slen=%d tlen=%d flags=%x",
3506 ap->a_target, (void *)pkt, (void *)bp,
3507 cmdlen, statuslen, tgtlen, flags));
3508
3509 /*
3510 * Allocate the new packet.
3511 */
3512 if (pkt == NULL) {
3513 ddi_dma_handle_t save_dma_handle;
3514 ddi_dma_handle_t save_arq_dma_handle;
3515 struct buf *save_arq_bp;
3516 ddi_dma_cookie_t save_arqcookie;
3517
3518 cmd = kmem_cache_alloc(mpt->m_kmem_cache, kf);
3519
3520 if (cmd) {
3521 save_dma_handle = cmd->cmd_dmahandle;
3522 save_arq_dma_handle = cmd->cmd_arqhandle;
3523 save_arq_bp = cmd->cmd_arq_buf;
3524 save_arqcookie = cmd->cmd_arqcookie;
3525 bzero(cmd, sizeof (*cmd) + scsi_pkt_size());
3526 cmd->cmd_dmahandle = save_dma_handle;
3527 cmd->cmd_arqhandle = save_arq_dma_handle;
3528 cmd->cmd_arq_buf = save_arq_bp;
3529 cmd->cmd_arqcookie = save_arqcookie;
3530
3531 pkt = (void *)((uchar_t *)cmd +
3532 sizeof (struct mptsas_cmd));
3533 pkt->pkt_ha_private = (opaque_t)cmd;
3534 pkt->pkt_address = *ap;
3535 pkt->pkt_private = (opaque_t)cmd->cmd_pkt_private;
3536 pkt->pkt_scbp = (opaque_t)&cmd->cmd_scb;
3537 pkt->pkt_cdbp = (opaque_t)&cmd->cmd_cdb;
3538 cmd->cmd_pkt = (struct scsi_pkt *)pkt;
3539 cmd->cmd_cdblen = (uchar_t)cmdlen;
3540 cmd->cmd_scblen = statuslen;
3541 cmd->cmd_rqslen = SENSE_LENGTH;
3542 cmd->cmd_tgt_addr = ptgt;
3543 failure = 0;
3544 }
3545
3546 if (failure || (cmdlen > sizeof (cmd->cmd_cdb)) ||
3547 (tgtlen > PKT_PRIV_LEN) ||
3548 (statuslen > EXTCMDS_STATUS_SIZE)) {
3549 if (failure == 0) {
3550 /*
3551 * if extern alloc fails, all will be
3552 * deallocated, including cmd
3553 */
3554 failure = mptsas_pkt_alloc_extern(mpt, cmd,
3555 cmdlen, tgtlen, statuslen, kf);
3556 }
3557 if (failure) {
3558 /*
3559 * if extern allocation fails, it will
3560 * deallocate the new pkt as well
3561 */
3562 return (NULL);
3563 }
3564 }
3565 new_cmd = cmd;
3566
3567 } else {
3568 cmd = PKT2CMD(pkt);
3569 new_cmd = NULL;
3570 }
3571
3572
3573 /* grab cmd->cmd_cookiec here as oldcookiec */
3574
3575 oldcookiec = cmd->cmd_cookiec;
3576
3577 /*
3578 * If the dma was broken up into PARTIAL transfers cmd_nwin will be
3579 * greater than 0 and we'll need to grab the next dma window
3580 */
3581 /*
3582 * SLM-not doing extra command frame right now; may add later
3583 */
3584
3585 if (cmd->cmd_nwin > 0) {
3586
3587 /*
3588 * Make sure we havn't gone past the the total number
3589 * of windows
3590 */
3591 if (++cmd->cmd_winindex >= cmd->cmd_nwin) {
3592 return (NULL);
3593 }
3594 if (ddi_dma_getwin(cmd->cmd_dmahandle, cmd->cmd_winindex,
3595 &cmd->cmd_dma_offset, &cmd->cmd_dma_len,
3596 &cmd->cmd_cookie, &cmd->cmd_cookiec) == DDI_FAILURE) {
3597 return (NULL);
3598 }
3599 goto get_dma_cookies;
3600 }
3601
3602
3603 if (flags & PKT_XARQ) {
3604 cmd->cmd_flags |= CFLAG_XARQ;
3605 }
3606
3607 /*
3608 * DMA resource allocation. This version assumes your
3609 * HBA has some sort of bus-mastering or onboard DMA capability, with a
3610 * scatter-gather list of length MPTSAS_MAX_DMA_SEGS, as given in the
3611 * ddi_dma_attr_t structure and passed to scsi_impl_dmaget.
3612 */
3613 if (bp && (bp->b_bcount != 0) &&
3614 (cmd->cmd_flags & CFLAG_DMAVALID) == 0) {
3615
3616 int cnt, dma_flags;
3617 mptti_t *dmap; /* ptr to the S/G list */
3618
3619 /*
3620 * Set up DMA memory and position to the next DMA segment.
3621 */
3622 ASSERT(cmd->cmd_dmahandle != NULL);
3623
3624 if (bp->b_flags & B_READ) {
3625 dma_flags = DDI_DMA_READ;
3626 cmd->cmd_flags &= ~CFLAG_DMASEND;
3627 } else {
3628 dma_flags = DDI_DMA_WRITE;
3629 cmd->cmd_flags |= CFLAG_DMASEND;
3630 }
3631 if (flags & PKT_CONSISTENT) {
3632 cmd->cmd_flags |= CFLAG_CMDIOPB;
3633 dma_flags |= DDI_DMA_CONSISTENT;
3634 }
3635
3636 if (flags & PKT_DMA_PARTIAL) {
3637 dma_flags |= DDI_DMA_PARTIAL;
3638 }
3639
3640 /*
3641 * workaround for byte hole issue on psycho and
3642 * schizo pre 2.1
3643 */
3644 if ((bp->b_flags & B_READ) && ((bp->b_flags &
3645 (B_PAGEIO|B_REMAPPED)) != B_PAGEIO) &&
3646 ((uintptr_t)bp->b_un.b_addr & 0x7)) {
3647 dma_flags |= DDI_DMA_CONSISTENT;
3648 }
3649
3650 rval = ddi_dma_buf_bind_handle(cmd->cmd_dmahandle, bp,
3651 dma_flags, callback, arg,
3652 &cmd->cmd_cookie, &cmd->cmd_cookiec);
3653 if (rval == DDI_DMA_PARTIAL_MAP) {
3654 (void) ddi_dma_numwin(cmd->cmd_dmahandle,
3655 &cmd->cmd_nwin);
3656 cmd->cmd_winindex = 0;
3657 (void) ddi_dma_getwin(cmd->cmd_dmahandle,
3658 cmd->cmd_winindex, &cmd->cmd_dma_offset,
3659 &cmd->cmd_dma_len, &cmd->cmd_cookie,
3660 &cmd->cmd_cookiec);
3661 } else if (rval && (rval != DDI_DMA_MAPPED)) {
3662 switch (rval) {
3663 case DDI_DMA_NORESOURCES:
3664 bioerror(bp, 0);
3665 break;
3666 case DDI_DMA_BADATTR:
3667 case DDI_DMA_NOMAPPING:
3668 bioerror(bp, EFAULT);
3669 break;
3670 case DDI_DMA_TOOBIG:
3671 default:
3672 bioerror(bp, EINVAL);
3673 break;
3674 }
3675 cmd->cmd_flags &= ~CFLAG_DMAVALID;
3676 if (new_cmd) {
3677 mptsas_scsi_destroy_pkt(ap, pkt);
3678 }
3679 return ((struct scsi_pkt *)NULL);
3680 }
3681
3682 get_dma_cookies:
3683 cmd->cmd_flags |= CFLAG_DMAVALID;
3684 ASSERT(cmd->cmd_cookiec > 0);
3685
3686 if (cmd->cmd_cookiec > MPTSAS_MAX_CMD_SEGS) {
3687 mptsas_log(mpt, CE_NOTE, "large cookiec received %d\n",
3688 cmd->cmd_cookiec);
3689 bioerror(bp, EINVAL);
3690 if (new_cmd) {
3691 mptsas_scsi_destroy_pkt(ap, pkt);
3692 }
3693 return ((struct scsi_pkt *)NULL);
3694 }
3695
3696 /*
3697 * Allocate extra SGL buffer if needed.
3698 */
3699 if ((cmd->cmd_cookiec > MPTSAS_MAX_FRAME_SGES64(mpt)) &&
3700 (cmd->cmd_extra_frames == NULL)) {
3701 if (mptsas_alloc_extra_sgl_frame(mpt, cmd) ==
3702 DDI_FAILURE) {
3703 mptsas_log(mpt, CE_WARN, "MPT SGL mem alloc "
3704 "failed");
3705 bioerror(bp, ENOMEM);
3706 if (new_cmd) {
3707 mptsas_scsi_destroy_pkt(ap, pkt);
3708 }
3709 return ((struct scsi_pkt *)NULL);
3710 }
3711 }
3712
3713 /*
3714 * Always use scatter-gather transfer
3715 * Use the loop below to store physical addresses of
3716 * DMA segments, from the DMA cookies, into your HBA's
3717 * scatter-gather list.
3718 * We need to ensure we have enough kmem alloc'd
3719 * for the sg entries since we are no longer using an
3720 * array inside mptsas_cmd_t.
3721 *
3722 * We check cmd->cmd_cookiec against oldcookiec so
3723 * the scatter-gather list is correctly allocated
3724 */
3725
3726 if (oldcookiec != cmd->cmd_cookiec) {
3727 if (cmd->cmd_sg != (mptti_t *)NULL) {
3728 kmem_free(cmd->cmd_sg, sizeof (mptti_t) *
3729 oldcookiec);
3730 cmd->cmd_sg = NULL;
3731 }
3732 }
3733
3734 if (cmd->cmd_sg == (mptti_t *)NULL) {
3735 cmd->cmd_sg = kmem_alloc((size_t)(sizeof (mptti_t)*
3736 cmd->cmd_cookiec), kf);
3737
3738 if (cmd->cmd_sg == (mptti_t *)NULL) {
3739 mptsas_log(mpt, CE_WARN,
3740 "unable to kmem_alloc enough memory "
3741 "for scatter/gather list");
3742 /*
3743 * if we have an ENOMEM condition we need to behave
3744 * the same way as the rest of this routine
3745 */
3746
3747 bioerror(bp, ENOMEM);
3748 if (new_cmd) {
3749 mptsas_scsi_destroy_pkt(ap, pkt);
3750 }
3751 return ((struct scsi_pkt *)NULL);
3752 }
3753 }
3754
3755 dmap = cmd->cmd_sg;
3756
3757 ASSERT(cmd->cmd_cookie.dmac_size != 0);
3758
3759 /*
3760 * store the first segment into the S/G list
3761 */
3762 dmap->count = cmd->cmd_cookie.dmac_size;
3763 dmap->addr.address64.Low = (uint32_t)
3764 (cmd->cmd_cookie.dmac_laddress & 0xffffffffull);
3765 dmap->addr.address64.High = (uint32_t)
3766 (cmd->cmd_cookie.dmac_laddress >> 32);
3767
3768 /*
3769 * dmacount counts the size of the dma for this window
3770 * (if partial dma is being used). totaldmacount
3771 * keeps track of the total amount of dma we have
3772 * transferred for all the windows (needed to calculate
3773 * the resid value below).
3774 */
3775 cmd->cmd_dmacount = cmd->cmd_cookie.dmac_size;
3776 cmd->cmd_totaldmacount += cmd->cmd_cookie.dmac_size;
3777
3778 /*
3779 * We already stored the first DMA scatter gather segment,
3780 * start at 1 if we need to store more.
3781 */
3782 for (cnt = 1; cnt < cmd->cmd_cookiec; cnt++) {
3783 /*
3784 * Get next DMA cookie
3785 */
3786 ddi_dma_nextcookie(cmd->cmd_dmahandle,
3787 &cmd->cmd_cookie);
3788 dmap++;
3789
3790 cmd->cmd_dmacount += cmd->cmd_cookie.dmac_size;
3791 cmd->cmd_totaldmacount += cmd->cmd_cookie.dmac_size;
3792
3793 /*
3794 * store the segment parms into the S/G list
3795 */
3796 dmap->count = cmd->cmd_cookie.dmac_size;
3797 dmap->addr.address64.Low = (uint32_t)
3798 (cmd->cmd_cookie.dmac_laddress & 0xffffffffull);
3799 dmap->addr.address64.High = (uint32_t)
3800 (cmd->cmd_cookie.dmac_laddress >> 32);
3801 }
3802
3803 /*
3804 * If this was partially allocated we set the resid
3805 * the amount of data NOT transferred in this window
3806 * If there is only one window, the resid will be 0
3807 */
3808 pkt->pkt_resid = (bp->b_bcount - cmd->cmd_totaldmacount);
3809 NDBG3(("mptsas_scsi_init_pkt: cmd_dmacount=%d.",
3810 cmd->cmd_dmacount));
3811 }
3812 return (pkt);
3813 }
3814
3815 /*
3816 * tran_destroy_pkt(9E) - scsi_pkt(9s) deallocation
3817 *
3818 * Notes:
3819 * - also frees DMA resources if allocated
3820 * - implicit DMA synchonization
3821 */
3822 static void
3823 mptsas_scsi_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
3824 {
3825 mptsas_cmd_t *cmd = PKT2CMD(pkt);
3826 mptsas_t *mpt = ADDR2MPT(ap);
3827
3828 NDBG3(("mptsas_scsi_destroy_pkt: target=%d pkt=0x%p",
3829 ap->a_target, (void *)pkt));
3830
3831 if (cmd->cmd_flags & CFLAG_DMAVALID) {
3832 (void) ddi_dma_unbind_handle(cmd->cmd_dmahandle);
3833 cmd->cmd_flags &= ~CFLAG_DMAVALID;
3834 }
3835
3836 if (cmd->cmd_sg) {
3837 kmem_free(cmd->cmd_sg, sizeof (mptti_t) * cmd->cmd_cookiec);
3838 cmd->cmd_sg = NULL;
3839 }
3840
3841 mptsas_free_extra_sgl_frame(mpt, cmd);
3842
3843 if ((cmd->cmd_flags &
3844 (CFLAG_FREE | CFLAG_CDBEXTERN | CFLAG_PRIVEXTERN |
3845 CFLAG_SCBEXTERN)) == 0) {
3846 cmd->cmd_flags = CFLAG_FREE;
3847 kmem_cache_free(mpt->m_kmem_cache, (void *)cmd);
3848 } else {
3849 mptsas_pkt_destroy_extern(mpt, cmd);
3850 }
3851 }
3852
3853 /*
3854 * kmem cache constructor and destructor:
3855 * When constructing, we bzero the cmd and allocate the dma handle
3856 * When destructing, just free the dma handle
3857 */
3858 static int
3859 mptsas_kmem_cache_constructor(void *buf, void *cdrarg, int kmflags)
3860 {
3861 mptsas_cmd_t *cmd = buf;
3862 mptsas_t *mpt = cdrarg;
3863 struct scsi_address ap;
3864 uint_t cookiec;
3865 ddi_dma_attr_t arq_dma_attr;
3866 int (*callback)(caddr_t);
3867
3868 callback = (kmflags == KM_SLEEP)? DDI_DMA_SLEEP: DDI_DMA_DONTWAIT;
3869
3870 NDBG4(("mptsas_kmem_cache_constructor"));
3871
3872 ap.a_hba_tran = mpt->m_tran;
3873 ap.a_target = 0;
3874 ap.a_lun = 0;
3875
3876 /*
3877 * allocate a dma handle
3878 */
3879 if ((ddi_dma_alloc_handle(mpt->m_dip, &mpt->m_io_dma_attr, callback,
3880 NULL, &cmd->cmd_dmahandle)) != DDI_SUCCESS) {
3881 cmd->cmd_dmahandle = NULL;
3882 return (-1);
3883 }
3884
3885 cmd->cmd_arq_buf = scsi_alloc_consistent_buf(&ap, (struct buf *)NULL,
3886 SENSE_LENGTH, B_READ, callback, NULL);
3887 if (cmd->cmd_arq_buf == NULL) {
3888 ddi_dma_free_handle(&cmd->cmd_dmahandle);
3889 cmd->cmd_dmahandle = NULL;
3890 return (-1);
3891 }
3892
3893 /*
3894 * allocate a arq handle
3895 */
3896 arq_dma_attr = mpt->m_msg_dma_attr;
3897 arq_dma_attr.dma_attr_sgllen = 1;
3898 if ((ddi_dma_alloc_handle(mpt->m_dip, &arq_dma_attr, callback,
3899 NULL, &cmd->cmd_arqhandle)) != DDI_SUCCESS) {
3900 ddi_dma_free_handle(&cmd->cmd_dmahandle);
3901 scsi_free_consistent_buf(cmd->cmd_arq_buf);
3902 cmd->cmd_dmahandle = NULL;
3903 cmd->cmd_arqhandle = NULL;
3904 return (-1);
3905 }
3906
3907 if (ddi_dma_buf_bind_handle(cmd->cmd_arqhandle,
3908 cmd->cmd_arq_buf, (DDI_DMA_READ | DDI_DMA_CONSISTENT),
3909 callback, NULL, &cmd->cmd_arqcookie, &cookiec) != DDI_SUCCESS) {
3910 ddi_dma_free_handle(&cmd->cmd_dmahandle);
3911 ddi_dma_free_handle(&cmd->cmd_arqhandle);
3912 scsi_free_consistent_buf(cmd->cmd_arq_buf);
3913 cmd->cmd_dmahandle = NULL;
3914 cmd->cmd_arqhandle = NULL;
3915 cmd->cmd_arq_buf = NULL;
3916 return (-1);
3917 }
3918
3919 return (0);
3920 }
3921
3922 static void
3923 mptsas_kmem_cache_destructor(void *buf, void *cdrarg)
3924 {
3925 #ifndef __lock_lint
3926 _NOTE(ARGUNUSED(cdrarg))
3927 #endif
3928 mptsas_cmd_t *cmd = buf;
3929
3930 NDBG4(("mptsas_kmem_cache_destructor"));
3931
3932 if (cmd->cmd_arqhandle) {
3933 (void) ddi_dma_unbind_handle(cmd->cmd_arqhandle);
3934 ddi_dma_free_handle(&cmd->cmd_arqhandle);
3935 cmd->cmd_arqhandle = NULL;
3936 }
3937 if (cmd->cmd_arq_buf) {
3938 scsi_free_consistent_buf(cmd->cmd_arq_buf);
3939 cmd->cmd_arq_buf = NULL;
3940 }
3941 if (cmd->cmd_dmahandle) {
3942 ddi_dma_free_handle(&cmd->cmd_dmahandle);
3943 cmd->cmd_dmahandle = NULL;
3944 }
3945 }
3946
3947 static int
3948 mptsas_cache_frames_constructor(void *buf, void *cdrarg, int kmflags)
3949 {
3950 mptsas_cache_frames_t *p = buf;
3951 mptsas_t *mpt = cdrarg;
3952 ddi_dma_attr_t frame_dma_attr;
3953 size_t mem_size, alloc_len;
3954 ddi_dma_cookie_t cookie;
3955 uint_t ncookie;
3956 int (*callback)(caddr_t) = (kmflags == KM_SLEEP)
3957 ? DDI_DMA_SLEEP: DDI_DMA_DONTWAIT;
3958
3959 frame_dma_attr = mpt->m_msg_dma_attr;
3960 frame_dma_attr.dma_attr_align = 0x10;
3961 frame_dma_attr.dma_attr_sgllen = 1;
3962
3963 if (ddi_dma_alloc_handle(mpt->m_dip, &frame_dma_attr, callback, NULL,
3964 &p->m_dma_hdl) != DDI_SUCCESS) {
3965 mptsas_log(mpt, CE_WARN, "Unable to allocate dma handle for"
3966 " extra SGL.");
3967 return (DDI_FAILURE);
3968 }
3969
3970 mem_size = (mpt->m_max_request_frames - 1) * mpt->m_req_frame_size;
3971
3972 if (ddi_dma_mem_alloc(p->m_dma_hdl, mem_size, &mpt->m_dev_acc_attr,
3973 DDI_DMA_CONSISTENT, callback, NULL, (caddr_t *)&p->m_frames_addr,
3974 &alloc_len, &p->m_acc_hdl) != DDI_SUCCESS) {
3975 ddi_dma_free_handle(&p->m_dma_hdl);
3976 p->m_dma_hdl = NULL;
3977 mptsas_log(mpt, CE_WARN, "Unable to allocate dma memory for"
3978 " extra SGL.");
3979 return (DDI_FAILURE);
3980 }
3981
3982 if (ddi_dma_addr_bind_handle(p->m_dma_hdl, NULL, p->m_frames_addr,
3983 alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, callback, NULL,
3984 &cookie, &ncookie) != DDI_DMA_MAPPED) {
3985 (void) ddi_dma_mem_free(&p->m_acc_hdl);
3986 ddi_dma_free_handle(&p->m_dma_hdl);
3987 p->m_dma_hdl = NULL;
3988 mptsas_log(mpt, CE_WARN, "Unable to bind DMA resources for"
3989 " extra SGL");
3990 return (DDI_FAILURE);
3991 }
3992
3993 /*
3994 * Store the SGL memory address. This chip uses this
3995 * address to dma to and from the driver. The second
3996 * address is the address mpt uses to fill in the SGL.
3997 */
3998 p->m_phys_addr = cookie.dmac_address;
3999
4000 return (DDI_SUCCESS);
4001 }
4002
4003 static void
4004 mptsas_cache_frames_destructor(void *buf, void *cdrarg)
4005 {
4006 #ifndef __lock_lint
4007 _NOTE(ARGUNUSED(cdrarg))
4008 #endif
4009 mptsas_cache_frames_t *p = buf;
4010 if (p->m_dma_hdl != NULL) {
4011 (void) ddi_dma_unbind_handle(p->m_dma_hdl);
4012 (void) ddi_dma_mem_free(&p->m_acc_hdl);
4013 ddi_dma_free_handle(&p->m_dma_hdl);
4014 p->m_phys_addr = NULL;
4015 p->m_frames_addr = NULL;
4016 p->m_dma_hdl = NULL;
4017 p->m_acc_hdl = NULL;
4018 }
4019
4020 }
4021
4022 /*
4023 * allocate and deallocate external pkt space (ie. not part of mptsas_cmd)
4024 * for non-standard length cdb, pkt_private, status areas
4025 * if allocation fails, then deallocate all external space and the pkt
4026 */
4027 /* ARGSUSED */
4028 static int
4029 mptsas_pkt_alloc_extern(mptsas_t *mpt, mptsas_cmd_t *cmd,
4030 int cmdlen, int tgtlen, int statuslen, int kf)
4031 {
4032 caddr_t cdbp, scbp, tgt;
4033 int (*callback)(caddr_t) = (kf == KM_SLEEP) ?
4034 DDI_DMA_SLEEP : DDI_DMA_DONTWAIT;
4035 struct scsi_address ap;
4036 size_t senselength;
4037 ddi_dma_attr_t ext_arq_dma_attr;
4038 uint_t cookiec;
4039
4040 NDBG3(("mptsas_pkt_alloc_extern: "
4041 "cmd=0x%p cmdlen=%d tgtlen=%d statuslen=%d kf=%x",
4042 (void *)cmd, cmdlen, tgtlen, statuslen, kf));
4043
4044 tgt = cdbp = scbp = NULL;
4045 cmd->cmd_scblen = statuslen;
4046 cmd->cmd_privlen = (uchar_t)tgtlen;
4047
4048 if (cmdlen > sizeof (cmd->cmd_cdb)) {
4049 if ((cdbp = kmem_zalloc((size_t)cmdlen, kf)) == NULL) {
4050 goto fail;
4051 }
4052 cmd->cmd_pkt->pkt_cdbp = (opaque_t)cdbp;
4053 cmd->cmd_flags |= CFLAG_CDBEXTERN;
4054 }
4055 if (tgtlen > PKT_PRIV_LEN) {
4056 if ((tgt = kmem_zalloc((size_t)tgtlen, kf)) == NULL) {
4057 goto fail;
4058 }
4059 cmd->cmd_flags |= CFLAG_PRIVEXTERN;
4060 cmd->cmd_pkt->pkt_private = tgt;
4061 }
4062 if (statuslen > EXTCMDS_STATUS_SIZE) {
4063 if ((scbp = kmem_zalloc((size_t)statuslen, kf)) == NULL) {
4064 goto fail;
4065 }
4066 cmd->cmd_flags |= CFLAG_SCBEXTERN;
4067 cmd->cmd_pkt->pkt_scbp = (opaque_t)scbp;
4068
4069 /* allocate sense data buf for DMA */
4070
4071 senselength = statuslen - MPTSAS_GET_ITEM_OFF(
4072 struct scsi_arq_status, sts_sensedata);
4073 cmd->cmd_rqslen = (uchar_t)senselength;
4074
4075 ap.a_hba_tran = mpt->m_tran;
4076 ap.a_target = 0;
4077 ap.a_lun = 0;
4078
4079 cmd->cmd_ext_arq_buf = scsi_alloc_consistent_buf(&ap,
4080 (struct buf *)NULL, senselength, B_READ,
4081 callback, NULL);
4082
4083 if (cmd->cmd_ext_arq_buf == NULL) {
4084 goto fail;
4085 }
4086 /*
4087 * allocate a extern arq handle and bind the buf
4088 */
4089 ext_arq_dma_attr = mpt->m_msg_dma_attr;
4090 ext_arq_dma_attr.dma_attr_sgllen = 1;
4091 if ((ddi_dma_alloc_handle(mpt->m_dip,
4092 &ext_arq_dma_attr, callback,
4093 NULL, &cmd->cmd_ext_arqhandle)) != DDI_SUCCESS) {
4094 goto fail;
4095 }
4096
4097 if (ddi_dma_buf_bind_handle(cmd->cmd_ext_arqhandle,
4098 cmd->cmd_ext_arq_buf, (DDI_DMA_READ | DDI_DMA_CONSISTENT),
4099 callback, NULL, &cmd->cmd_ext_arqcookie,
4100 &cookiec)
4101 != DDI_SUCCESS) {
4102 goto fail;
4103 }
4104 cmd->cmd_flags |= CFLAG_EXTARQBUFVALID;
4105 }
4106 return (0);
4107 fail:
4108 mptsas_pkt_destroy_extern(mpt, cmd);
4109 return (1);
4110 }
4111
4112 /*
4113 * deallocate external pkt space and deallocate the pkt
4114 */
4115 static void
4116 mptsas_pkt_destroy_extern(mptsas_t *mpt, mptsas_cmd_t *cmd)
4117 {
4118 NDBG3(("mptsas_pkt_destroy_extern: cmd=0x%p", (void *)cmd));
4119
4120 if (cmd->cmd_flags & CFLAG_FREE) {
4121 mptsas_log(mpt, CE_PANIC,
4122 "mptsas_pkt_destroy_extern: freeing free packet");
4123 _NOTE(NOT_REACHED)
4124 /* NOTREACHED */
4125 }
4126 if (cmd->cmd_flags & CFLAG_CDBEXTERN) {
4127 kmem_free(cmd->cmd_pkt->pkt_cdbp, (size_t)cmd->cmd_cdblen);
4128 }
4129 if (cmd->cmd_flags & CFLAG_SCBEXTERN) {
4130 kmem_free(cmd->cmd_pkt->pkt_scbp, (size_t)cmd->cmd_scblen);
4131 if (cmd->cmd_flags & CFLAG_EXTARQBUFVALID) {
4132 (void) ddi_dma_unbind_handle(cmd->cmd_ext_arqhandle);
4133 }
4134 if (cmd->cmd_ext_arqhandle) {
4135 ddi_dma_free_handle(&cmd->cmd_ext_arqhandle);
4136 cmd->cmd_ext_arqhandle = NULL;
4137 }
4138 if (cmd->cmd_ext_arq_buf)
4139 scsi_free_consistent_buf(cmd->cmd_ext_arq_buf);
4140 }
4141 if (cmd->cmd_flags & CFLAG_PRIVEXTERN) {
4142 kmem_free(cmd->cmd_pkt->pkt_private, (size_t)cmd->cmd_privlen);
4143 }
4144 cmd->cmd_flags = CFLAG_FREE;
4145 kmem_cache_free(mpt->m_kmem_cache, (void *)cmd);
4146 }
4147
4148 /*
4149 * tran_sync_pkt(9E) - explicit DMA synchronization
4150 */
4151 /*ARGSUSED*/
4152 static void
4153 mptsas_scsi_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
4154 {
4155 mptsas_cmd_t *cmd = PKT2CMD(pkt);
4156
4157 NDBG3(("mptsas_scsi_sync_pkt: target=%d, pkt=0x%p",
4158 ap->a_target, (void *)pkt));
4159
4160 if (cmd->cmd_dmahandle) {
4161 (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0,
4162 (cmd->cmd_flags & CFLAG_DMASEND) ?
4163 DDI_DMA_SYNC_FORDEV : DDI_DMA_SYNC_FORCPU);
4164 }
4165 }
4166
4167 /*
4168 * tran_dmafree(9E) - deallocate DMA resources allocated for command
4169 */
4170 /*ARGSUSED*/
4171 static void
4172 mptsas_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt)
4173 {
4174 mptsas_cmd_t *cmd = PKT2CMD(pkt);
4175 mptsas_t *mpt = ADDR2MPT(ap);
4176
4177 NDBG3(("mptsas_scsi_dmafree: target=%d pkt=0x%p",
4178 ap->a_target, (void *)pkt));
4179
4180 if (cmd->cmd_flags & CFLAG_DMAVALID) {
4181 (void) ddi_dma_unbind_handle(cmd->cmd_dmahandle);
4182 cmd->cmd_flags &= ~CFLAG_DMAVALID;
4183 }
4184
4185 if (cmd->cmd_flags & CFLAG_EXTARQBUFVALID) {
4186 (void) ddi_dma_unbind_handle(cmd->cmd_ext_arqhandle);
4187 cmd->cmd_flags &= ~CFLAG_EXTARQBUFVALID;
4188 }
4189
4190 mptsas_free_extra_sgl_frame(mpt, cmd);
4191 }
4192
4193 static void
4194 mptsas_pkt_comp(struct scsi_pkt *pkt, mptsas_cmd_t *cmd)
4195 {
4196 if ((cmd->cmd_flags & CFLAG_CMDIOPB) &&
4197 (!(cmd->cmd_flags & CFLAG_DMASEND))) {
4198 (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0,
4199 DDI_DMA_SYNC_FORCPU);
4200 }
4201 (*pkt->pkt_comp)(pkt);
4202 }
4203
4204 static void
4205 mptsas_sge_mainframe(mptsas_cmd_t *cmd, pMpi2SCSIIORequest_t frame,
4206 ddi_acc_handle_t acc_hdl, uint_t cookiec, uint32_t end_flags)
4207 {
4208 pMpi2SGESimple64_t sge;
4209 mptti_t *dmap;
4210 uint32_t flags;
4211
4212 dmap = cmd->cmd_sg;
4213
4214 sge = (pMpi2SGESimple64_t)(&frame->SGL);
4215 while (cookiec--) {
4216 ddi_put32(acc_hdl,
4217 &sge->Address.Low, dmap->addr.address64.Low);
4218 ddi_put32(acc_hdl,
4219 &sge->Address.High, dmap->addr.address64.High);
4220 ddi_put32(acc_hdl, &sge->FlagsLength,
4221 dmap->count);
4222 flags = ddi_get32(acc_hdl, &sge->FlagsLength);
4223 flags |= ((uint32_t)
4224 (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
4225 MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
4226 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
4227 MPI2_SGE_FLAGS_SHIFT);
4228
4229 /*
4230 * If this is the last cookie, we set the flags
4231 * to indicate so
4232 */
4233 if (cookiec == 0) {
4234 flags |= end_flags;
4235 }
4236 if (cmd->cmd_flags & CFLAG_DMASEND) {
4237 flags |= (MPI2_SGE_FLAGS_HOST_TO_IOC <<
4238 MPI2_SGE_FLAGS_SHIFT);
4239 } else {
4240 flags |= (MPI2_SGE_FLAGS_IOC_TO_HOST <<
4241 MPI2_SGE_FLAGS_SHIFT);
4242 }
4243 ddi_put32(acc_hdl, &sge->FlagsLength, flags);
4244 dmap++;
4245 sge++;
4246 }
4247 }
4248
4249 static void
4250 mptsas_sge_chain(mptsas_t *mpt, mptsas_cmd_t *cmd,
4251 pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl)
4252 {
4253 pMpi2SGESimple64_t sge;
4254 pMpi2SGEChain64_t sgechain;
4255 uint_t cookiec;
4256 mptti_t *dmap;
4257 uint32_t flags;
4258
4259 /*
4260 * Save the number of entries in the DMA
4261 * Scatter/Gather list
4262 */
4263 cookiec = cmd->cmd_cookiec;
4264
4265 /*
4266 * Hereby we start to deal with multiple frames.
4267 * The process is as follows:
4268 * 1. Determine how many frames are needed for SGL element
4269 * storage; Note that all frames are stored in contiguous
4270 * memory space and in 64-bit DMA mode each element is
4271 * 3 double-words (12 bytes) long.
4272 * 2. Fill up the main frame. We need to do this separately
4273 * since it contains the SCSI IO request header and needs
4274 * dedicated processing. Note that the last 4 double-words
4275 * of the SCSI IO header is for SGL element storage
4276 * (MPI2_SGE_IO_UNION).
4277 * 3. Fill the chain element in the main frame, so the DMA
4278 * engine can use the following frames.
4279 * 4. Enter a loop to fill the remaining frames. Note that the
4280 * last frame contains no chain element. The remaining
4281 * frames go into the mpt SGL buffer allocated on the fly,
4282 * not immediately following the main message frame, as in
4283 * Gen1.
4284 * Some restrictions:
4285 * 1. For 64-bit DMA, the simple element and chain element
4286 * are both of 3 double-words (12 bytes) in size, even
4287 * though all frames are stored in the first 4G of mem
4288 * range and the higher 32-bits of the address are always 0.
4289 * 2. On some controllers (like the 1064/1068), a frame can
4290 * hold SGL elements with the last 1 or 2 double-words
4291 * (4 or 8 bytes) un-used. On these controllers, we should
4292 * recognize that there's not enough room for another SGL
4293 * element and move the sge pointer to the next frame.
4294 */
4295 int i, j, k, l, frames, sgemax;
4296 int temp;
4297 uint8_t chainflags;
4298 uint16_t chainlength;
4299 mptsas_cache_frames_t *p;
4300
4301 /*
4302 * Sgemax is the number of SGE's that will fit
4303 * each extra frame and frames is total
4304 * number of frames we'll need. 1 sge entry per
4305 * frame is reseverd for the chain element thus the -1 below.
4306 */
4307 sgemax = ((mpt->m_req_frame_size / sizeof (MPI2_SGE_SIMPLE64))
4308 - 1);
4309 temp = (cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) / sgemax;
4310
4311 /*
4312 * A little check to see if we need to round up the number
4313 * of frames we need
4314 */
4315 if ((cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) - (temp *
4316 sgemax) > 1) {
4317 frames = (temp + 1);
4318 } else {
4319 frames = temp;
4320 }
4321 dmap = cmd->cmd_sg;
4322 sge = (pMpi2SGESimple64_t)(&frame->SGL);
4323
4324 /*
4325 * First fill in the main frame
4326 */
4327 j = MPTSAS_MAX_FRAME_SGES64(mpt) - 1;
4328 mptsas_sge_mainframe(cmd, frame, acc_hdl, j,
4329 ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT) <<
4330 MPI2_SGE_FLAGS_SHIFT));
4331 dmap += j;
4332 sge += j;
4333 j++;
4334
4335 /*
4336 * Fill in the chain element in the main frame.
4337 * About calculation on ChainOffset:
4338 * 1. Struct msg_scsi_io_request has 4 double-words (16 bytes)
4339 * in the end reserved for SGL element storage
4340 * (MPI2_SGE_IO_UNION); we should count it in our
4341 * calculation. See its definition in the header file.
4342 * 2. Constant j is the counter of the current SGL element
4343 * that will be processed, and (j - 1) is the number of
4344 * SGL elements that have been processed (stored in the
4345 * main frame).
4346 * 3. ChainOffset value should be in units of double-words (4
4347 * bytes) so the last value should be divided by 4.
4348 */
4349 ddi_put8(acc_hdl, &frame->ChainOffset,
4350 (sizeof (MPI2_SCSI_IO_REQUEST) -
4351 sizeof (MPI2_SGE_IO_UNION) +
4352 (j - 1) * sizeof (MPI2_SGE_SIMPLE64)) >> 2);
4353 sgechain = (pMpi2SGEChain64_t)sge;
4354 chainflags = (MPI2_SGE_FLAGS_CHAIN_ELEMENT |
4355 MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
4356 MPI2_SGE_FLAGS_64_BIT_ADDRESSING);
4357 ddi_put8(acc_hdl, &sgechain->Flags, chainflags);
4358
4359 /*
4360 * The size of the next frame is the accurate size of space
4361 * (in bytes) used to store the SGL elements. j is the counter
4362 * of SGL elements. (j - 1) is the number of SGL elements that
4363 * have been processed (stored in frames).
4364 */
4365 if (frames >= 2) {
4366 ASSERT(mpt->m_req_frame_size >= sizeof (MPI2_SGE_SIMPLE64));
4367 chainlength = mpt->m_req_frame_size /
4368 sizeof (MPI2_SGE_SIMPLE64) *
4369 sizeof (MPI2_SGE_SIMPLE64);
4370 } else {
4371 chainlength = ((cookiec - (j - 1)) *
4372 sizeof (MPI2_SGE_SIMPLE64));
4373 }
4374
4375 p = cmd->cmd_extra_frames;
4376
4377 ddi_put16(acc_hdl, &sgechain->Length, chainlength);
4378 ddi_put32(acc_hdl, &sgechain->Address.Low,
4379 p->m_phys_addr);
4380 /* SGL is allocated in the first 4G mem range */
4381 ddi_put32(acc_hdl, &sgechain->Address.High, 0);
4382
4383 /*
4384 * If there are more than 2 frames left we have to
4385 * fill in the next chain offset to the location of
4386 * the chain element in the next frame.
4387 * sgemax is the number of simple elements in an extra
4388 * frame. Note that the value NextChainOffset should be
4389 * in double-words (4 bytes).
4390 */
4391 if (frames >= 2) {
4392 ddi_put8(acc_hdl, &sgechain->NextChainOffset,
4393 (sgemax * sizeof (MPI2_SGE_SIMPLE64)) >> 2);
4394 } else {
4395 ddi_put8(acc_hdl, &sgechain->NextChainOffset, 0);
4396 }
4397
4398 /*
4399 * Jump to next frame;
4400 * Starting here, chain buffers go into the per command SGL.
4401 * This buffer is allocated when chain buffers are needed.
4402 */
4403 sge = (pMpi2SGESimple64_t)p->m_frames_addr;
4404 i = cookiec;
4405
4406 /*
4407 * Start filling in frames with SGE's. If we
4408 * reach the end of frame and still have SGE's
4409 * to fill we need to add a chain element and
4410 * use another frame. j will be our counter
4411 * for what cookie we are at and i will be
4412 * the total cookiec. k is the current frame
4413 */
4414 for (k = 1; k <= frames; k++) {
4415 for (l = 1; (l <= (sgemax + 1)) && (j <= i); j++, l++) {
4416
4417 /*
4418 * If we have reached the end of frame
4419 * and we have more SGE's to fill in
4420 * we have to fill the final entry
4421 * with a chain element and then
4422 * continue to the next frame
4423 */
4424 if ((l == (sgemax + 1)) && (k != frames)) {
4425 sgechain = (pMpi2SGEChain64_t)sge;
4426 j--;
4427 chainflags = (
4428 MPI2_SGE_FLAGS_CHAIN_ELEMENT |
4429 MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
4430 MPI2_SGE_FLAGS_64_BIT_ADDRESSING);
4431 ddi_put8(p->m_acc_hdl,
4432 &sgechain->Flags, chainflags);
4433 /*
4434 * k is the frame counter and (k + 1)
4435 * is the number of the next frame.
4436 * Note that frames are in contiguous
4437 * memory space.
4438 */
4439 ddi_put32(p->m_acc_hdl,
4440 &sgechain->Address.Low,
4441 (p->m_phys_addr +
4442 (mpt->m_req_frame_size * k)));
4443 ddi_put32(p->m_acc_hdl,
4444 &sgechain->Address.High, 0);
4445
4446 /*
4447 * If there are more than 2 frames left
4448 * we have to next chain offset to
4449 * the location of the chain element
4450 * in the next frame and fill in the
4451 * length of the next chain
4452 */
4453 if ((frames - k) >= 2) {
4454 ddi_put8(p->m_acc_hdl,
4455 &sgechain->NextChainOffset,
4456 (sgemax *
4457 sizeof (MPI2_SGE_SIMPLE64))
4458 >> 2);
4459 ddi_put16(p->m_acc_hdl,
4460 &sgechain->Length,
4461 mpt->m_req_frame_size /
4462 sizeof (MPI2_SGE_SIMPLE64) *
4463 sizeof (MPI2_SGE_SIMPLE64));
4464 } else {
4465 /*
4466 * This is the last frame. Set
4467 * the NextChainOffset to 0 and
4468 * Length is the total size of
4469 * all remaining simple elements
4470 */
4471 ddi_put8(p->m_acc_hdl,
4472 &sgechain->NextChainOffset,
4473 0);
4474 ddi_put16(p->m_acc_hdl,
4475 &sgechain->Length,
4476 (cookiec - j) *
4477 sizeof (MPI2_SGE_SIMPLE64));
4478 }
4479
4480 /* Jump to the next frame */
4481 sge = (pMpi2SGESimple64_t)
4482 ((char *)p->m_frames_addr +
4483 (int)mpt->m_req_frame_size * k);
4484
4485 continue;
4486 }
4487
4488 ddi_put32(p->m_acc_hdl,
4489 &sge->Address.Low,
4490 dmap->addr.address64.Low);
4491 ddi_put32(p->m_acc_hdl,
4492 &sge->Address.High,
4493 dmap->addr.address64.High);
4494 ddi_put32(p->m_acc_hdl,
4495 &sge->FlagsLength, dmap->count);
4496 flags = ddi_get32(p->m_acc_hdl,
4497 &sge->FlagsLength);
4498 flags |= ((uint32_t)(
4499 MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
4500 MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
4501 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
4502 MPI2_SGE_FLAGS_SHIFT);
4503
4504 /*
4505 * If we are at the end of the frame and
4506 * there is another frame to fill in
4507 * we set the last simple element as last
4508 * element
4509 */
4510 if ((l == sgemax) && (k != frames)) {
4511 flags |= ((uint32_t)
4512 (MPI2_SGE_FLAGS_LAST_ELEMENT) <<
4513 MPI2_SGE_FLAGS_SHIFT);
4514 }
4515
4516 /*
4517 * If this is the final cookie we
4518 * indicate it by setting the flags
4519 */
4520 if (j == i) {
4521 flags |= ((uint32_t)
4522 (MPI2_SGE_FLAGS_LAST_ELEMENT |
4523 MPI2_SGE_FLAGS_END_OF_BUFFER |
4524 MPI2_SGE_FLAGS_END_OF_LIST) <<
4525 MPI2_SGE_FLAGS_SHIFT);
4526 }
4527 if (cmd->cmd_flags & CFLAG_DMASEND) {
4528 flags |=
4529 (MPI2_SGE_FLAGS_HOST_TO_IOC <<
4530 MPI2_SGE_FLAGS_SHIFT);
4531 } else {
4532 flags |=
4533 (MPI2_SGE_FLAGS_IOC_TO_HOST <<
4534 MPI2_SGE_FLAGS_SHIFT);
4535 }
4536 ddi_put32(p->m_acc_hdl,
4537 &sge->FlagsLength, flags);
4538 dmap++;
4539 sge++;
4540 }
4541 }
4542
4543 /*
4544 * Sync DMA with the chain buffers that were just created
4545 */
4546 (void) ddi_dma_sync(p->m_dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
4547 }
4548
4549 static void
4550 mptsas_ieee_sge_mainframe(mptsas_cmd_t *cmd, pMpi2SCSIIORequest_t frame,
4551 ddi_acc_handle_t acc_hdl, uint_t cookiec, uint8_t end_flag)
4552 {
4553 pMpi2IeeeSgeSimple64_t ieeesge;
4554 mptti_t *dmap;
4555 uint8_t flags;
4556
4557 dmap = cmd->cmd_sg;
4558
4559 NDBG1(("mptsas_ieee_sge_mainframe: cookiec=%d, %s", cookiec,
4560 cmd->cmd_flags & CFLAG_DMASEND?"Out":"In"));
4561
4562 ieeesge = (pMpi2IeeeSgeSimple64_t)(&frame->SGL);
4563 while (cookiec--) {
4564 ddi_put32(acc_hdl,
4565 &ieeesge->Address.Low, dmap->addr.address64.Low);
4566 ddi_put32(acc_hdl,
4567 &ieeesge->Address.High, dmap->addr.address64.High);
4568 ddi_put32(acc_hdl, &ieeesge->Length,
4569 dmap->count);
4570 NDBG1(("mptsas_ieee_sge_mainframe: len=%d", dmap->count));
4571 flags = (MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT |
4572 MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR);
4573
4574 /*
4575 * If this is the last cookie, we set the flags
4576 * to indicate so
4577 */
4578 if (cookiec == 0) {
4579 flags |= end_flag;
4580 }
4581
4582 ddi_put8(acc_hdl, &ieeesge->Flags, flags);
4583 dmap++;
4584 ieeesge++;
4585 }
4586 }
4587
4588 static void
4589 mptsas_ieee_sge_chain(mptsas_t *mpt, mptsas_cmd_t *cmd,
4590 pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl)
4591 {
4592 pMpi2IeeeSgeSimple64_t ieeesge;
4593 pMpi25IeeeSgeChain64_t ieeesgechain;
4594 uint_t cookiec;
4595 mptti_t *dmap;
4596 uint8_t flags;
4597
4598 /*
4599 * Save the number of entries in the DMA
4600 * Scatter/Gather list
4601 */
4602 cookiec = cmd->cmd_cookiec;
4603
4604 NDBG1(("mptsas_ieee_sge_chain: cookiec=%d", cookiec));
4605
4606 /*
4607 * Hereby we start to deal with multiple frames.
4608 * The process is as follows:
4609 * 1. Determine how many frames are needed for SGL element
4610 * storage; Note that all frames are stored in contiguous
4611 * memory space and in 64-bit DMA mode each element is
4612 * 4 double-words (16 bytes) long.
4613 * 2. Fill up the main frame. We need to do this separately
4614 * since it contains the SCSI IO request header and needs
4615 * dedicated processing. Note that the last 4 double-words
4616 * of the SCSI IO header is for SGL element storage
4617 * (MPI2_SGE_IO_UNION).
4618 * 3. Fill the chain element in the main frame, so the DMA
4619 * engine can use the following frames.
4620 * 4. Enter a loop to fill the remaining frames. Note that the
4621 * last frame contains no chain element. The remaining
4622 * frames go into the mpt SGL buffer allocated on the fly,
4623 * not immediately following the main message frame, as in
4624 * Gen1.
4625 * Restrictions:
4626 * For 64-bit DMA, the simple element and chain element
4627 * are both of 4 double-words (16 bytes) in size, even
4628 * though all frames are stored in the first 4G of mem
4629 * range and the higher 32-bits of the address are always 0.
4630 */
4631 int i, j, k, l, frames, sgemax;
4632 int temp;
4633 uint8_t chainflags;
4634 uint32_t chainlength;
4635 mptsas_cache_frames_t *p;
4636
4637 /*
4638 * Sgemax is the number of SGE's that will fit
4639 * each extra frame and frames is total
4640 * number of frames we'll need. 1 sge entry per
4641 * frame is reseverd for the chain element thus the -1 below.
4642 */
4643 sgemax = ((mpt->m_req_frame_size / sizeof (MPI2_IEEE_SGE_SIMPLE64))
4644 - 1);
4645 temp = (cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) / sgemax;
4646
4647 /*
4648 * A little check to see if we need to round up the number
4649 * of frames we need
4650 */
4651 if ((cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) - (temp *
4652 sgemax) > 1) {
4653 frames = (temp + 1);
4654 } else {
4655 frames = temp;
4656 }
4657 NDBG1(("mptsas_ieee_sge_chain: temp=%d, frames=%d", temp, frames));
4658 dmap = cmd->cmd_sg;
4659 ieeesge = (pMpi2IeeeSgeSimple64_t)(&frame->SGL);
4660
4661 /*
4662 * First fill in the main frame
4663 */
4664 j = MPTSAS_MAX_FRAME_SGES64(mpt) - 1;
4665 mptsas_ieee_sge_mainframe(cmd, frame, acc_hdl, j, 0);
4666 dmap += j;
4667 ieeesge += j;
4668 j++;
4669
4670 /*
4671 * Fill in the chain element in the main frame.
4672 * About calculation on ChainOffset:
4673 * 1. Struct msg_scsi_io_request has 4 double-words (16 bytes)
4674 * in the end reserved for SGL element storage
4675 * (MPI2_SGE_IO_UNION); we should count it in our
4676 * calculation. See its definition in the header file.
4677 * 2. Constant j is the counter of the current SGL element
4678 * that will be processed, and (j - 1) is the number of
4679 * SGL elements that have been processed (stored in the
4680 * main frame).
4681 * 3. ChainOffset value should be in units of quad-words (16
4682 * bytes) so the last value should be divided by 16.
4683 */
4684 ddi_put8(acc_hdl, &frame->ChainOffset,
4685 (sizeof (MPI2_SCSI_IO_REQUEST) -
4686 sizeof (MPI2_SGE_IO_UNION) +
4687 (j - 1) * sizeof (MPI2_IEEE_SGE_SIMPLE64)) >> 4);
4688 ieeesgechain = (pMpi25IeeeSgeChain64_t)ieeesge;
4689 chainflags = (MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT |
4690 MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR);
4691 ddi_put8(acc_hdl, &ieeesgechain->Flags, chainflags);
4692
4693 /*
4694 * The size of the next frame is the accurate size of space
4695 * (in bytes) used to store the SGL elements. j is the counter
4696 * of SGL elements. (j - 1) is the number of SGL elements that
4697 * have been processed (stored in frames).
4698 */
4699 if (frames >= 2) {
4700 ASSERT(mpt->m_req_frame_size >=
4701 sizeof (MPI2_IEEE_SGE_SIMPLE64));
4702 chainlength = mpt->m_req_frame_size /
4703 sizeof (MPI2_IEEE_SGE_SIMPLE64) *
4704 sizeof (MPI2_IEEE_SGE_SIMPLE64);
4705 } else {
4706 chainlength = ((cookiec - (j - 1)) *
4707 sizeof (MPI2_IEEE_SGE_SIMPLE64));
4708 }
4709
4710 p = cmd->cmd_extra_frames;
4711
4712 ddi_put32(acc_hdl, &ieeesgechain->Length, chainlength);
4713 ddi_put32(acc_hdl, &ieeesgechain->Address.Low,
4714 p->m_phys_addr);
4715 /* SGL is allocated in the first 4G mem range */
4716 ddi_put32(acc_hdl, &ieeesgechain->Address.High, 0);
4717
4718 /*
4719 * If there are more than 2 frames left we have to
4720 * fill in the next chain offset to the location of
4721 * the chain element in the next frame.
4722 * sgemax is the number of simple elements in an extra
4723 * frame. Note that the value NextChainOffset should be
4724 * in double-words (4 bytes).
4725 */
4726 if (frames >= 2) {
4727 ddi_put8(acc_hdl, &ieeesgechain->NextChainOffset,
4728 (sgemax * sizeof (MPI2_IEEE_SGE_SIMPLE64)) >> 4);
4729 } else {
4730 ddi_put8(acc_hdl, &ieeesgechain->NextChainOffset, 0);
4731 }
4732
4733 /*
4734 * Jump to next frame;
4735 * Starting here, chain buffers go into the per command SGL.
4736 * This buffer is allocated when chain buffers are needed.
4737 */
4738 ieeesge = (pMpi2IeeeSgeSimple64_t)p->m_frames_addr;
4739 i = cookiec;
4740
4741 /*
4742 * Start filling in frames with SGE's. If we
4743 * reach the end of frame and still have SGE's
4744 * to fill we need to add a chain element and
4745 * use another frame. j will be our counter
4746 * for what cookie we are at and i will be
4747 * the total cookiec. k is the current frame
4748 */
4749 for (k = 1; k <= frames; k++) {
4750 for (l = 1; (l <= (sgemax + 1)) && (j <= i); j++, l++) {
4751
4752 /*
4753 * If we have reached the end of frame
4754 * and we have more SGE's to fill in
4755 * we have to fill the final entry
4756 * with a chain element and then
4757 * continue to the next frame
4758 */
4759 if ((l == (sgemax + 1)) && (k != frames)) {
4760 ieeesgechain = (pMpi25IeeeSgeChain64_t)ieeesge;
4761 j--;
4762 chainflags =
4763 MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT |
4764 MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR;
4765 ddi_put8(p->m_acc_hdl,
4766 &ieeesgechain->Flags, chainflags);
4767 /*
4768 * k is the frame counter and (k + 1)
4769 * is the number of the next frame.
4770 * Note that frames are in contiguous
4771 * memory space.
4772 */
4773 ddi_put32(p->m_acc_hdl,
4774 &ieeesgechain->Address.Low,
4775 (p->m_phys_addr +
4776 (mpt->m_req_frame_size * k)));
4777 ddi_put32(p->m_acc_hdl,
4778 &ieeesgechain->Address.High, 0);
4779
4780 /*
4781 * If there are more than 2 frames left
4782 * we have to next chain offset to
4783 * the location of the chain element
4784 * in the next frame and fill in the
4785 * length of the next chain
4786 */
4787 if ((frames - k) >= 2) {
4788 ddi_put8(p->m_acc_hdl,
4789 &ieeesgechain->NextChainOffset,
4790 (sgemax *
4791 sizeof (MPI2_IEEE_SGE_SIMPLE64))
4792 >> 4);
4793 ASSERT(mpt->m_req_frame_size >=
4794 sizeof (MPI2_IEEE_SGE_SIMPLE64));
4795 ddi_put32(p->m_acc_hdl,
4796 &ieeesgechain->Length,
4797 mpt->m_req_frame_size /
4798 sizeof (MPI2_IEEE_SGE_SIMPLE64) *
4799 sizeof (MPI2_IEEE_SGE_SIMPLE64));
4800 } else {
4801 /*
4802 * This is the last frame. Set
4803 * the NextChainOffset to 0 and
4804 * Length is the total size of
4805 * all remaining simple elements
4806 */
4807 ddi_put8(p->m_acc_hdl,
4808 &ieeesgechain->NextChainOffset,
4809 0);
4810 ddi_put32(p->m_acc_hdl,
4811 &ieeesgechain->Length,
4812 (cookiec - j) *
4813 sizeof (MPI2_IEEE_SGE_SIMPLE64));
4814 }
4815
4816 /* Jump to the next frame */
4817 ieeesge = (pMpi2IeeeSgeSimple64_t)
4818 ((char *)p->m_frames_addr +
4819 (int)mpt->m_req_frame_size * k);
4820
4821 continue;
4822 }
4823
4824 ddi_put32(p->m_acc_hdl,
4825 &ieeesge->Address.Low,
4826 dmap->addr.address64.Low);
4827 ddi_put32(p->m_acc_hdl,
4828 &ieeesge->Address.High,
4829 dmap->addr.address64.High);
4830 ddi_put32(p->m_acc_hdl,
4831 &ieeesge->Length, dmap->count);
4832 flags = (MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT |
4833 MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR);
4834
4835 /*
4836 * If we are at the end of the frame and
4837 * there is another frame to fill in
4838 * do we need to do anything?
4839 * if ((l == sgemax) && (k != frames)) {
4840 * }
4841 */
4842
4843 /*
4844 * If this is the final cookie set end of list.
4845 */
4846 if (j == i) {
4847 flags |= MPI25_IEEE_SGE_FLAGS_END_OF_LIST;
4848 }
4849
4850 ddi_put8(p->m_acc_hdl, &ieeesge->Flags, flags);
4851 dmap++;
4852 ieeesge++;
4853 }
4854 }
4855
4856 /*
4857 * Sync DMA with the chain buffers that were just created
4858 */
4859 (void) ddi_dma_sync(p->m_dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
4860 }
4861
4862 static void
4863 mptsas_sge_setup(mptsas_t *mpt, mptsas_cmd_t *cmd, uint32_t *control,
4864 pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl)
4865 {
4866 ASSERT(cmd->cmd_flags & CFLAG_DMAVALID);
4867
4868 NDBG1(("mptsas_sge_setup: cookiec=%d", cmd->cmd_cookiec));
4869
4870 /*
4871 * Set read/write bit in control.
4872 */
4873 if (cmd->cmd_flags & CFLAG_DMASEND) {
4874 *control |= MPI2_SCSIIO_CONTROL_WRITE;
4875 } else {
4876 *control |= MPI2_SCSIIO_CONTROL_READ;
4877 }
4878
4879 ddi_put32(acc_hdl, &frame->DataLength, cmd->cmd_dmacount);
4880
4881 /*
4882 * We have 4 cases here. First where we can fit all the
4883 * SG elements into the main frame, and the case
4884 * where we can't. The SG element is also different when using
4885 * MPI2.5 interface.
4886 * If we have more cookies than we can attach to a frame
4887 * we will need to use a chain element to point
4888 * a location of memory where the rest of the S/G
4889 * elements reside.
4890 */
4891 if (cmd->cmd_cookiec <= MPTSAS_MAX_FRAME_SGES64(mpt)) {
4892 if (mpt->m_MPI25) {
4893 mptsas_ieee_sge_mainframe(cmd, frame, acc_hdl,
4894 cmd->cmd_cookiec,
4895 MPI25_IEEE_SGE_FLAGS_END_OF_LIST);
4896 } else {
4897 mptsas_sge_mainframe(cmd, frame, acc_hdl,
4898 cmd->cmd_cookiec,
4899 ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT
4900 | MPI2_SGE_FLAGS_END_OF_BUFFER
4901 | MPI2_SGE_FLAGS_END_OF_LIST) <<
4902 MPI2_SGE_FLAGS_SHIFT));
4903 }
4904 } else {
4905 if (mpt->m_MPI25) {
4906 mptsas_ieee_sge_chain(mpt, cmd, frame, acc_hdl);
4907 } else {
4908 mptsas_sge_chain(mpt, cmd, frame, acc_hdl);
4909 }
4910 }
4911 }
4912
4913 /*
4914 * Interrupt handling
4915 * Utility routine. Poll for status of a command sent to HBA
4916 * without interrupts (a FLAG_NOINTR command).
4917 */
4918 int
4919 mptsas_poll(mptsas_t *mpt, mptsas_cmd_t *poll_cmd, int polltime)
4920 {
4921 int rval = TRUE;
4922
4923 NDBG5(("mptsas_poll: cmd=0x%p", (void *)poll_cmd));
4924
4925 if ((poll_cmd->cmd_flags & CFLAG_TM_CMD) == 0) {
4926 mptsas_restart_hba(mpt);
4927 }
4928
4929 /*
4930 * Wait, using drv_usecwait(), long enough for the command to
4931 * reasonably return from the target if the target isn't
4932 * "dead". A polled command may well be sent from scsi_poll, and
4933 * there are retries built in to scsi_poll if the transport
4934 * accepted the packet (TRAN_ACCEPT). scsi_poll waits 1 second
4935 * and retries the transport up to scsi_poll_busycnt times
4936 * (currently 60) if
4937 * 1. pkt_reason is CMD_INCOMPLETE and pkt_state is 0, or
4938 * 2. pkt_reason is CMD_CMPLT and *pkt_scbp has STATUS_BUSY
4939 *
4940 * limit the waiting to avoid a hang in the event that the
4941 * cmd never gets started but we are still receiving interrupts
4942 */
4943 while (!(poll_cmd->cmd_flags & CFLAG_FINISHED)) {
4944 if (mptsas_wait_intr(mpt, polltime) == FALSE) {
4945 NDBG5(("mptsas_poll: command incomplete"));
4946 rval = FALSE;
4947 break;
4948 }
4949 }
4950
4951 if (rval == FALSE) {
4952
4953 /*
4954 * this isn't supposed to happen, the hba must be wedged
4955 * Mark this cmd as a timeout.
4956 */
4957 mptsas_set_pkt_reason(mpt, poll_cmd, CMD_TIMEOUT,
4958 (STAT_TIMEOUT|STAT_ABORTED));
4959
4960 if (poll_cmd->cmd_queued == FALSE) {
4961
4962 NDBG5(("mptsas_poll: not on waitq"));
4963
4964 poll_cmd->cmd_pkt->pkt_state |=
4965 (STATE_GOT_BUS|STATE_GOT_TARGET|STATE_SENT_CMD);
4966 } else {
4967
4968 /* find and remove it from the waitq */
4969 NDBG5(("mptsas_poll: delete from waitq"));
4970 mptsas_waitq_delete(mpt, poll_cmd);
4971 }
4972
4973 }
4974 mptsas_fma_check(mpt, poll_cmd);
4975 NDBG5(("mptsas_poll: done"));
4976 return (rval);
4977 }
4978
4979 /*
4980 * Used for polling cmds and TM function
4981 */
4982 static int
4983 mptsas_wait_intr(mptsas_t *mpt, int polltime)
4984 {
4985 int cnt;
4986 pMpi2ReplyDescriptorsUnion_t reply_desc_union;
4987 uint32_t int_mask;
4988
4989 NDBG5(("mptsas_wait_intr"));
4990
4991 mpt->m_polled_intr = 1;
4992
4993 /*
4994 * Get the current interrupt mask and disable interrupts. When
4995 * re-enabling ints, set mask to saved value.
4996 */
4997 int_mask = ddi_get32(mpt->m_datap, &mpt->m_reg->HostInterruptMask);
4998 MPTSAS_DISABLE_INTR(mpt);
4999
5000 /*
5001 * Keep polling for at least (polltime * 1000) seconds
5002 */
5003 for (cnt = 0; cnt < polltime; cnt++) {
5004 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0,
5005 DDI_DMA_SYNC_FORCPU);
5006
5007 reply_desc_union = (pMpi2ReplyDescriptorsUnion_t)
5008 MPTSAS_GET_NEXT_REPLY(mpt, mpt->m_post_index);
5009
5010 if (ddi_get32(mpt->m_acc_post_queue_hdl,
5011 &reply_desc_union->Words.Low) == 0xFFFFFFFF ||
5012 ddi_get32(mpt->m_acc_post_queue_hdl,
5013 &reply_desc_union->Words.High) == 0xFFFFFFFF) {
5014 drv_usecwait(1000);
5015 continue;
5016 }
5017
5018 /*
5019 * The reply is valid, process it according to its
5020 * type.
5021 */
5022 mptsas_process_intr(mpt, reply_desc_union);
5023
5024 if (++mpt->m_post_index == mpt->m_post_queue_depth) {
5025 mpt->m_post_index = 0;
5026 }
5027
5028 /*
5029 * Update the global reply index
5030 */
5031 ddi_put32(mpt->m_datap,
5032 &mpt->m_reg->ReplyPostHostIndex, mpt->m_post_index);
5033 mpt->m_polled_intr = 0;
5034
5035 /*
5036 * Re-enable interrupts and quit.
5037 */
5038 ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptMask,
5039 int_mask);
5040 return (TRUE);
5041
5042 }
5043
5044 /*
5045 * Clear polling flag, re-enable interrupts and quit.
5046 */
5047 mpt->m_polled_intr = 0;
5048 ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptMask, int_mask);
5049 return (FALSE);
5050 }
5051
5052 static void
5053 mptsas_handle_scsi_io_success(mptsas_t *mpt,
5054 pMpi2ReplyDescriptorsUnion_t reply_desc)
5055 {
5056 pMpi2SCSIIOSuccessReplyDescriptor_t scsi_io_success;
5057 uint16_t SMID;
5058 mptsas_slots_t *slots = mpt->m_active;
5059 mptsas_cmd_t *cmd = NULL;
5060 struct scsi_pkt *pkt;
5061
5062 ASSERT(mutex_owned(&mpt->m_mutex));
5063
5064 scsi_io_success = (pMpi2SCSIIOSuccessReplyDescriptor_t)reply_desc;
5065 SMID = ddi_get16(mpt->m_acc_post_queue_hdl, &scsi_io_success->SMID);
5066
5067 /*
5068 * This is a success reply so just complete the IO. First, do a sanity
5069 * check on the SMID. The final slot is used for TM requests, which
5070 * would not come into this reply handler.
5071 */
5072 if ((SMID == 0) || (SMID > slots->m_n_normal)) {
5073 mptsas_log(mpt, CE_WARN, "?Received invalid SMID of %d\n",
5074 SMID);
5075 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
5076 return;
5077 }
5078
5079 cmd = slots->m_slot[SMID];
5080
5081 /*
5082 * print warning and return if the slot is empty
5083 */
5084 if (cmd == NULL) {
5085 mptsas_log(mpt, CE_WARN, "?NULL command for successful SCSI IO "
5086 "in slot %d", SMID);
5087 return;
5088 }
5089
5090 pkt = CMD2PKT(cmd);
5091 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD |
5092 STATE_GOT_STATUS);
5093 if (cmd->cmd_flags & CFLAG_DMAVALID) {
5094 pkt->pkt_state |= STATE_XFERRED_DATA;
5095 }
5096 pkt->pkt_resid = 0;
5097
5098 if (cmd->cmd_flags & CFLAG_PASSTHRU) {
5099 cmd->cmd_flags |= CFLAG_FINISHED;
5100 cv_broadcast(&mpt->m_passthru_cv);
5101 return;
5102 } else {
5103 mptsas_remove_cmd(mpt, cmd);
5104 }
5105
5106 if (cmd->cmd_flags & CFLAG_RETRY) {
5107 /*
5108 * The target returned QFULL or busy, do not add tihs
5109 * pkt to the doneq since the hba will retry
5110 * this cmd.
5111 *
5112 * The pkt has already been resubmitted in
5113 * mptsas_handle_qfull() or in mptsas_check_scsi_io_error().
5114 * Remove this cmd_flag here.
5115 */
5116 cmd->cmd_flags &= ~CFLAG_RETRY;
5117 } else {
5118 mptsas_doneq_add(mpt, cmd);
5119 }
5120 }
5121
5122 static void
5123 mptsas_handle_address_reply(mptsas_t *mpt,
5124 pMpi2ReplyDescriptorsUnion_t reply_desc)
5125 {
5126 pMpi2AddressReplyDescriptor_t address_reply;
5127 pMPI2DefaultReply_t reply;
5128 mptsas_fw_diagnostic_buffer_t *pBuffer;
5129 uint32_t reply_addr;
5130 uint16_t SMID, iocstatus;
5131 mptsas_slots_t *slots = mpt->m_active;
5132 mptsas_cmd_t *cmd = NULL;
5133 uint8_t function, buffer_type;
5134 m_replyh_arg_t *args;
5135 int reply_frame_no;
5136
5137 ASSERT(mutex_owned(&mpt->m_mutex));
5138
5139 address_reply = (pMpi2AddressReplyDescriptor_t)reply_desc;
5140 reply_addr = ddi_get32(mpt->m_acc_post_queue_hdl,
5141 &address_reply->ReplyFrameAddress);
5142 SMID = ddi_get16(mpt->m_acc_post_queue_hdl, &address_reply->SMID);
5143
5144 /*
5145 * If reply frame is not in the proper range we should ignore this
5146 * message and exit the interrupt handler.
5147 */
5148 if ((reply_addr < mpt->m_reply_frame_dma_addr) ||
5149 (reply_addr >= (mpt->m_reply_frame_dma_addr +
5150 (mpt->m_reply_frame_size * mpt->m_max_replies))) ||
5151 ((reply_addr - mpt->m_reply_frame_dma_addr) %
5152 mpt->m_reply_frame_size != 0)) {
5153 mptsas_log(mpt, CE_WARN, "?Received invalid reply frame "
5154 "address 0x%x\n", reply_addr);
5155 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
5156 return;
5157 }
5158
5159 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
5160 DDI_DMA_SYNC_FORCPU);
5161 reply = (pMPI2DefaultReply_t)(mpt->m_reply_frame + (reply_addr -
5162 mpt->m_reply_frame_dma_addr));
5163 function = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->Function);
5164
5165 NDBG31(("mptsas_handle_address_reply: function 0x%x, reply_addr=0x%x",
5166 function, reply_addr));
5167
5168 /*
5169 * don't get slot information and command for events since these values
5170 * don't exist
5171 */
5172 if ((function != MPI2_FUNCTION_EVENT_NOTIFICATION) &&
5173 (function != MPI2_FUNCTION_DIAG_BUFFER_POST)) {
5174 /*
5175 * This could be a TM reply, which use the last allocated SMID,
5176 * so allow for that.
5177 */
5178 if ((SMID == 0) || (SMID > (slots->m_n_normal + 1))) {
5179 mptsas_log(mpt, CE_WARN, "?Received invalid SMID of "
5180 "%d\n", SMID);
5181 ddi_fm_service_impact(mpt->m_dip,
5182 DDI_SERVICE_UNAFFECTED);
5183 return;
5184 }
5185
5186 cmd = slots->m_slot[SMID];
5187
5188 /*
5189 * print warning and return if the slot is empty
5190 */
5191 if (cmd == NULL) {
5192 mptsas_log(mpt, CE_WARN, "?NULL command for address "
5193 "reply in slot %d", SMID);
5194 return;
5195 }
5196 if ((cmd->cmd_flags &
5197 (CFLAG_PASSTHRU | CFLAG_CONFIG | CFLAG_FW_DIAG))) {
5198 cmd->cmd_rfm = reply_addr;
5199 cmd->cmd_flags |= CFLAG_FINISHED;
5200 cv_broadcast(&mpt->m_passthru_cv);
5201 cv_broadcast(&mpt->m_config_cv);
5202 cv_broadcast(&mpt->m_fw_diag_cv);
5203 return;
5204 } else if (!(cmd->cmd_flags & CFLAG_FW_CMD)) {
5205 mptsas_remove_cmd(mpt, cmd);
5206 }
5207 NDBG31(("\t\tmptsas_process_intr: slot=%d", SMID));
5208 }
5209 /*
5210 * Depending on the function, we need to handle
5211 * the reply frame (and cmd) differently.
5212 */
5213 switch (function) {
5214 case MPI2_FUNCTION_SCSI_IO_REQUEST:
5215 mptsas_check_scsi_io_error(mpt, (pMpi2SCSIIOReply_t)reply, cmd);
5216 break;
5217 case MPI2_FUNCTION_SCSI_TASK_MGMT:
5218 cmd->cmd_rfm = reply_addr;
5219 mptsas_check_task_mgt(mpt, (pMpi2SCSIManagementReply_t)reply,
5220 cmd);
5221 break;
5222 case MPI2_FUNCTION_FW_DOWNLOAD:
5223 cmd->cmd_flags |= CFLAG_FINISHED;
5224 cv_signal(&mpt->m_fw_cv);
5225 break;
5226 case MPI2_FUNCTION_EVENT_NOTIFICATION:
5227 reply_frame_no = (reply_addr - mpt->m_reply_frame_dma_addr) /
5228 mpt->m_reply_frame_size;
5229 args = &mpt->m_replyh_args[reply_frame_no];
5230 args->mpt = (void *)mpt;
5231 args->rfm = reply_addr;
5232
5233 /*
5234 * Record the event if its type is enabled in
5235 * this mpt instance by ioctl.
5236 */
5237 mptsas_record_event(args);
5238
5239 /*
5240 * Handle time critical events
5241 * NOT_RESPONDING/ADDED only now
5242 */
5243 if (mptsas_handle_event_sync(args) == DDI_SUCCESS) {
5244 /*
5245 * Would not return main process,
5246 * just let taskq resolve ack action
5247 * and ack would be sent in taskq thread
5248 */
5249 NDBG20(("send mptsas_handle_event_sync success"));
5250 }
5251
5252 if (mpt->m_in_reset) {
5253 NDBG20(("dropping event received during reset"));
5254 return;
5255 }
5256
5257 if ((ddi_taskq_dispatch(mpt->m_event_taskq, mptsas_handle_event,
5258 (void *)args, DDI_NOSLEEP)) != DDI_SUCCESS) {
5259 mptsas_log(mpt, CE_WARN, "No memory available"
5260 "for dispatch taskq");
5261 /*
5262 * Return the reply frame to the free queue.
5263 */
5264 ddi_put32(mpt->m_acc_free_queue_hdl,
5265 &((uint32_t *)(void *)
5266 mpt->m_free_queue)[mpt->m_free_index], reply_addr);
5267 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
5268 DDI_DMA_SYNC_FORDEV);
5269 if (++mpt->m_free_index == mpt->m_free_queue_depth) {
5270 mpt->m_free_index = 0;
5271 }
5272
5273 ddi_put32(mpt->m_datap,
5274 &mpt->m_reg->ReplyFreeHostIndex, mpt->m_free_index);
5275 }
5276 return;
5277 case MPI2_FUNCTION_DIAG_BUFFER_POST:
5278 /*
5279 * If SMID is 0, this implies that the reply is due to a
5280 * release function with a status that the buffer has been
5281 * released. Set the buffer flags accordingly.
5282 */
5283 if (SMID == 0) {
5284 iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
5285 &reply->IOCStatus);
5286 buffer_type = ddi_get8(mpt->m_acc_reply_frame_hdl,
5287 &(((pMpi2DiagBufferPostReply_t)reply)->BufferType));
5288 if (iocstatus == MPI2_IOCSTATUS_DIAGNOSTIC_RELEASED) {
5289 pBuffer =
5290 &mpt->m_fw_diag_buffer_list[buffer_type];
5291 pBuffer->valid_data = TRUE;
5292 pBuffer->owned_by_firmware = FALSE;
5293 pBuffer->immediate = FALSE;
5294 }
5295 } else {
5296 /*
5297 * Normal handling of diag post reply with SMID.
5298 */
5299 cmd = slots->m_slot[SMID];
5300
5301 /*
5302 * print warning and return if the slot is empty
5303 */
5304 if (cmd == NULL) {
5305 mptsas_log(mpt, CE_WARN, "?NULL command for "
5306 "address reply in slot %d", SMID);
5307 return;
5308 }
5309 cmd->cmd_rfm = reply_addr;
5310 cmd->cmd_flags |= CFLAG_FINISHED;
5311 cv_broadcast(&mpt->m_fw_diag_cv);
5312 }
5313 return;
5314 default:
5315 mptsas_log(mpt, CE_WARN, "Unknown function 0x%x ", function);
5316 break;
5317 }
5318
5319 /*
5320 * Return the reply frame to the free queue.
5321 */
5322 ddi_put32(mpt->m_acc_free_queue_hdl,
5323 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index],
5324 reply_addr);
5325 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
5326 DDI_DMA_SYNC_FORDEV);
5327 if (++mpt->m_free_index == mpt->m_free_queue_depth) {
5328 mpt->m_free_index = 0;
5329 }
5330 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
5331 mpt->m_free_index);
5332
5333 if (cmd->cmd_flags & CFLAG_FW_CMD)
5334 return;
5335
5336 if (cmd->cmd_flags & CFLAG_RETRY) {
5337 /*
5338 * The target returned QFULL or busy, do not add this
5339 * pkt to the doneq since the hba will retry
5340 * this cmd.
5341 *
5342 * The pkt has already been resubmitted in
5343 * mptsas_handle_qfull() or in mptsas_check_scsi_io_error().
5344 * Remove this cmd_flag here.
5345 */
5346 cmd->cmd_flags &= ~CFLAG_RETRY;
5347 } else {
5348 mptsas_doneq_add(mpt, cmd);
5349 }
5350 }
5351
5352 static void
5353 mptsas_check_scsi_io_error(mptsas_t *mpt, pMpi2SCSIIOReply_t reply,
5354 mptsas_cmd_t *cmd)
5355 {
5356 uint8_t scsi_status, scsi_state;
5357 uint16_t ioc_status;
5358 uint32_t xferred, sensecount, responsedata, loginfo = 0;
5359 struct scsi_pkt *pkt;
5360 struct scsi_arq_status *arqstat;
5361 struct buf *bp;
5362 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
5363 uint8_t *sensedata = NULL;
5364 uint64_t sas_wwn;
5365 uint8_t phy;
5366 char wwn_str[MPTSAS_WWN_STRLEN];
5367
5368 if ((cmd->cmd_flags & (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) ==
5369 (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) {
5370 bp = cmd->cmd_ext_arq_buf;
5371 } else {
5372 bp = cmd->cmd_arq_buf;
5373 }
5374
5375 scsi_status = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->SCSIStatus);
5376 ioc_status = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->IOCStatus);
5377 scsi_state = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->SCSIState);
5378 xferred = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->TransferCount);
5379 sensecount = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->SenseCount);
5380 responsedata = ddi_get32(mpt->m_acc_reply_frame_hdl,
5381 &reply->ResponseInfo);
5382
5383 if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
5384 sas_wwn = ptgt->m_addr.mta_wwn;
5385 phy = ptgt->m_phynum;
5386 if (sas_wwn == 0) {
5387 (void) sprintf(wwn_str, "p%x", phy);
5388 } else {
5389 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn);
5390 }
5391 loginfo = ddi_get32(mpt->m_acc_reply_frame_hdl,
5392 &reply->IOCLogInfo);
5393 mptsas_log(mpt, CE_NOTE,
5394 "?Log info 0x%x received for target %d %s.\n"
5395 "\tscsi_status=0x%x, ioc_status=0x%x, scsi_state=0x%x",
5396 loginfo, Tgt(cmd), wwn_str, scsi_status, ioc_status,
5397 scsi_state);
5398 }
5399
5400 NDBG31(("\t\tscsi_status=0x%x, ioc_status=0x%x, scsi_state=0x%x",
5401 scsi_status, ioc_status, scsi_state));
5402
5403 pkt = CMD2PKT(cmd);
5404 *(pkt->pkt_scbp) = scsi_status;
5405
5406 if (loginfo == 0x31170000) {
5407 /*
5408 * if loginfo PL_LOGINFO_CODE_IO_DEVICE_MISSING_DELAY_RETRY
5409 * 0x31170000 comes, that means the device missing delay
5410 * is in progressing, the command need retry later.
5411 */
5412 *(pkt->pkt_scbp) = STATUS_BUSY;
5413 return;
5414 }
5415
5416 if ((scsi_state & MPI2_SCSI_STATE_NO_SCSI_STATUS) &&
5417 ((ioc_status & MPI2_IOCSTATUS_MASK) ==
5418 MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE)) {
5419 pkt->pkt_reason = CMD_INCOMPLETE;
5420 pkt->pkt_state |= STATE_GOT_BUS;
5421 if (ptgt->m_reset_delay == 0) {
5422 mptsas_set_throttle(mpt, ptgt,
5423 DRAIN_THROTTLE);
5424 }
5425 return;
5426 }
5427
5428 if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) {
5429 responsedata &= 0x000000FF;
5430 if (responsedata & MPTSAS_SCSI_RESPONSE_CODE_TLR_OFF) {
5431 mptsas_log(mpt, CE_NOTE, "Do not support the TLR\n");
5432 pkt->pkt_reason = CMD_TLR_OFF;
5433 return;
5434 }
5435 }
5436
5437
5438 switch (scsi_status) {
5439 case MPI2_SCSI_STATUS_CHECK_CONDITION:
5440 pkt->pkt_resid = (cmd->cmd_dmacount - xferred);
5441 arqstat = (void*)(pkt->pkt_scbp);
5442 arqstat->sts_rqpkt_status = *((struct scsi_status *)
5443 (pkt->pkt_scbp));
5444 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET |
5445 STATE_SENT_CMD | STATE_GOT_STATUS | STATE_ARQ_DONE);
5446 if (cmd->cmd_flags & CFLAG_XARQ) {
5447 pkt->pkt_state |= STATE_XARQ_DONE;
5448 }
5449 if (pkt->pkt_resid != cmd->cmd_dmacount) {
5450 pkt->pkt_state |= STATE_XFERRED_DATA;
5451 }
5452 arqstat->sts_rqpkt_reason = pkt->pkt_reason;
5453 arqstat->sts_rqpkt_state = pkt->pkt_state;
5454 arqstat->sts_rqpkt_state |= STATE_XFERRED_DATA;
5455 arqstat->sts_rqpkt_statistics = pkt->pkt_statistics;
5456 sensedata = (uint8_t *)&arqstat->sts_sensedata;
5457
5458 bcopy((uchar_t *)bp->b_un.b_addr, sensedata,
5459 ((cmd->cmd_rqslen >= sensecount) ? sensecount :
5460 cmd->cmd_rqslen));
5461 arqstat->sts_rqpkt_resid = (cmd->cmd_rqslen - sensecount);
5462 cmd->cmd_flags |= CFLAG_CMDARQ;
5463 /*
5464 * Set proper status for pkt if autosense was valid
5465 */
5466 if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) {
5467 struct scsi_status zero_status = { 0 };
5468 arqstat->sts_rqpkt_status = zero_status;
5469 }
5470
5471 /*
5472 * ASC=0x47 is parity error
5473 * ASC=0x48 is initiator detected error received
5474 */
5475 if ((scsi_sense_key(sensedata) == KEY_ABORTED_COMMAND) &&
5476 ((scsi_sense_asc(sensedata) == 0x47) ||
5477 (scsi_sense_asc(sensedata) == 0x48))) {
5478 mptsas_log(mpt, CE_NOTE, "Aborted_command!");
5479 }
5480
5481 /*
5482 * ASC/ASCQ=0x3F/0x0E means report_luns data changed
5483 * ASC/ASCQ=0x25/0x00 means invalid lun
5484 */
5485 if (((scsi_sense_key(sensedata) == KEY_UNIT_ATTENTION) &&
5486 (scsi_sense_asc(sensedata) == 0x3F) &&
5487 (scsi_sense_ascq(sensedata) == 0x0E)) ||
5488 ((scsi_sense_key(sensedata) == KEY_ILLEGAL_REQUEST) &&
5489 (scsi_sense_asc(sensedata) == 0x25) &&
5490 (scsi_sense_ascq(sensedata) == 0x00))) {
5491 mptsas_topo_change_list_t *topo_node = NULL;
5492
5493 topo_node = kmem_zalloc(
5494 sizeof (mptsas_topo_change_list_t),
5495 KM_NOSLEEP);
5496 if (topo_node == NULL) {
5497 mptsas_log(mpt, CE_NOTE, "No memory"
5498 "resource for handle SAS dynamic"
5499 "reconfigure.\n");
5500 break;
5501 }
5502 topo_node->mpt = mpt;
5503 topo_node->event = MPTSAS_DR_EVENT_RECONFIG_TARGET;
5504 topo_node->un.phymask = ptgt->m_addr.mta_phymask;
5505 topo_node->devhdl = ptgt->m_devhdl;
5506 topo_node->object = (void *)ptgt;
5507 topo_node->flags = MPTSAS_TOPO_FLAG_LUN_ASSOCIATED;
5508
5509 if ((ddi_taskq_dispatch(mpt->m_dr_taskq,
5510 mptsas_handle_dr,
5511 (void *)topo_node,
5512 DDI_NOSLEEP)) != DDI_SUCCESS) {
5513 kmem_free(topo_node,
5514 sizeof (mptsas_topo_change_list_t));
5515 mptsas_log(mpt, CE_NOTE, "mptsas start taskq"
5516 "for handle SAS dynamic reconfigure"
5517 "failed. \n");
5518 }
5519 }
5520 break;
5521 case MPI2_SCSI_STATUS_GOOD:
5522 switch (ioc_status & MPI2_IOCSTATUS_MASK) {
5523 case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
5524 pkt->pkt_reason = CMD_DEV_GONE;
5525 pkt->pkt_state |= STATE_GOT_BUS;
5526 if (ptgt->m_reset_delay == 0) {
5527 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
5528 }
5529 NDBG31(("lost disk for target%d, command:%x",
5530 Tgt(cmd), pkt->pkt_cdbp[0]));
5531 break;
5532 case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN:
5533 NDBG31(("data overrun: xferred=%d", xferred));
5534 NDBG31(("dmacount=%d", cmd->cmd_dmacount));
5535 pkt->pkt_reason = CMD_DATA_OVR;
5536 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET
5537 | STATE_SENT_CMD | STATE_GOT_STATUS
5538 | STATE_XFERRED_DATA);
5539 pkt->pkt_resid = 0;
5540 break;
5541 case MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:
5542 case MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN:
5543 NDBG31(("data underrun: xferred=%d", xferred));
5544 NDBG31(("dmacount=%d", cmd->cmd_dmacount));
5545 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET
5546 | STATE_SENT_CMD | STATE_GOT_STATUS);
5547 pkt->pkt_resid = (cmd->cmd_dmacount - xferred);
5548 if (pkt->pkt_resid != cmd->cmd_dmacount) {
5549 pkt->pkt_state |= STATE_XFERRED_DATA;
5550 }
5551 break;
5552 case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED:
5553 if (cmd->cmd_active_expiration <= gethrtime()) {
5554 /*
5555 * When timeout requested, propagate
5556 * proper reason and statistics to
5557 * target drivers.
5558 */
5559 mptsas_set_pkt_reason(mpt, cmd, CMD_TIMEOUT,
5560 STAT_BUS_RESET | STAT_TIMEOUT);
5561 } else {
5562 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET,
5563 STAT_BUS_RESET);
5564 }
5565 break;
5566 case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED:
5567 case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED:
5568 mptsas_set_pkt_reason(mpt,
5569 cmd, CMD_RESET, STAT_DEV_RESET);
5570 break;
5571 case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR:
5572 case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR:
5573 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET);
5574 mptsas_set_pkt_reason(mpt,
5575 cmd, CMD_TERMINATED, STAT_TERMINATED);
5576 break;
5577 case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES:
5578 case MPI2_IOCSTATUS_BUSY:
5579 /*
5580 * set throttles to drain
5581 */
5582 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
5583 ptgt = refhash_next(mpt->m_targets, ptgt)) {
5584 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
5585 }
5586
5587 /*
5588 * retry command
5589 */
5590 cmd->cmd_flags |= CFLAG_RETRY;
5591 cmd->cmd_pkt_flags |= FLAG_HEAD;
5592
5593 (void) mptsas_accept_pkt(mpt, cmd);
5594 break;
5595 default:
5596 mptsas_log(mpt, CE_WARN,
5597 "unknown ioc_status = %x\n", ioc_status);
5598 mptsas_log(mpt, CE_CONT, "scsi_state = %x, transfer "
5599 "count = %x, scsi_status = %x", scsi_state,
5600 xferred, scsi_status);
5601 break;
5602 }
5603 break;
5604 case MPI2_SCSI_STATUS_TASK_SET_FULL:
5605 mptsas_handle_qfull(mpt, cmd);
5606 break;
5607 case MPI2_SCSI_STATUS_BUSY:
5608 NDBG31(("scsi_status busy received"));
5609 break;
5610 case MPI2_SCSI_STATUS_RESERVATION_CONFLICT:
5611 NDBG31(("scsi_status reservation conflict received"));
5612 break;
5613 default:
5614 mptsas_log(mpt, CE_WARN, "scsi_status=%x, ioc_status=%x\n",
5615 scsi_status, ioc_status);
5616 mptsas_log(mpt, CE_WARN,
5617 "mptsas_process_intr: invalid scsi status\n");
5618 break;
5619 }
5620 }
5621
5622 static void
5623 mptsas_check_task_mgt(mptsas_t *mpt, pMpi2SCSIManagementReply_t reply,
5624 mptsas_cmd_t *cmd)
5625 {
5626 uint8_t task_type;
5627 uint16_t ioc_status;
5628 uint32_t log_info;
5629 uint16_t dev_handle;
5630 struct scsi_pkt *pkt = CMD2PKT(cmd);
5631
5632 task_type = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->TaskType);
5633 ioc_status = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->IOCStatus);
5634 log_info = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->IOCLogInfo);
5635 dev_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->DevHandle);
5636
5637 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
5638 mptsas_log(mpt, CE_WARN, "mptsas_check_task_mgt: Task 0x%x "
5639 "failed. IOCStatus=0x%x IOCLogInfo=0x%x target=%d\n",
5640 task_type, ioc_status, log_info, dev_handle);
5641 pkt->pkt_reason = CMD_INCOMPLETE;
5642 return;
5643 }
5644
5645 switch (task_type) {
5646 case MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK:
5647 case MPI2_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET:
5648 case MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK:
5649 case MPI2_SCSITASKMGMT_TASKTYPE_CLR_ACA:
5650 case MPI2_SCSITASKMGMT_TASKTYPE_QRY_TASK_SET:
5651 case MPI2_SCSITASKMGMT_TASKTYPE_QRY_UNIT_ATTENTION:
5652 break;
5653 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
5654 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
5655 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
5656 /*
5657 * Check for invalid DevHandle of 0 in case application
5658 * sends bad command. DevHandle of 0 could cause problems.
5659 */
5660 if (dev_handle == 0) {
5661 mptsas_log(mpt, CE_WARN, "!Can't flush target with"
5662 " DevHandle of 0.");
5663 } else {
5664 mptsas_flush_target(mpt, dev_handle, Lun(cmd),
5665 task_type);
5666 }
5667 break;
5668 default:
5669 mptsas_log(mpt, CE_WARN, "Unknown task management type %d.",
5670 task_type);
5671 mptsas_log(mpt, CE_WARN, "ioc status = %x", ioc_status);
5672 break;
5673 }
5674 }
5675
5676 static void
5677 mptsas_doneq_thread(mptsas_doneq_thread_arg_t *arg)
5678 {
5679 mptsas_t *mpt = arg->mpt;
5680 uint64_t t = arg->t;
5681 mptsas_cmd_t *cmd;
5682 struct scsi_pkt *pkt;
5683 mptsas_doneq_thread_list_t *item = &mpt->m_doneq_thread_id[t];
5684
5685 mutex_enter(&item->mutex);
5686 while (item->flag & MPTSAS_DONEQ_THREAD_ACTIVE) {
5687 if (!item->doneq) {
5688 cv_wait(&item->cv, &item->mutex);
5689 }
5690 pkt = NULL;
5691 if ((cmd = mptsas_doneq_thread_rm(mpt, t)) != NULL) {
5692 cmd->cmd_flags |= CFLAG_COMPLETED;
5693 pkt = CMD2PKT(cmd);
5694 }
5695 mutex_exit(&item->mutex);
5696 if (pkt) {
5697 mptsas_pkt_comp(pkt, cmd);
5698 }
5699 mutex_enter(&item->mutex);
5700 }
5701 mutex_exit(&item->mutex);
5702 mutex_enter(&mpt->m_doneq_mutex);
5703 mpt->m_doneq_thread_n--;
5704 cv_broadcast(&mpt->m_doneq_thread_cv);
5705 mutex_exit(&mpt->m_doneq_mutex);
5706 }
5707
5708
5709 /*
5710 * mpt interrupt handler.
5711 */
5712 static uint_t
5713 mptsas_intr(caddr_t arg1, caddr_t arg2)
5714 {
5715 mptsas_t *mpt = (void *)arg1;
5716 pMpi2ReplyDescriptorsUnion_t reply_desc_union;
5717 uchar_t did_reply = FALSE;
5718
5719 NDBG1(("mptsas_intr: arg1 0x%p arg2 0x%p", (void *)arg1, (void *)arg2));
5720
5721 mutex_enter(&mpt->m_mutex);
5722
5723 /*
5724 * If interrupts are shared by two channels then check whether this
5725 * interrupt is genuinely for this channel by making sure first the
5726 * chip is in high power state.
5727 */
5728 if ((mpt->m_options & MPTSAS_OPT_PM) &&
5729 (mpt->m_power_level != PM_LEVEL_D0)) {
5730 mutex_exit(&mpt->m_mutex);
5731 return (DDI_INTR_UNCLAIMED);
5732 }
5733
5734 /*
5735 * If polling, interrupt was triggered by some shared interrupt because
5736 * IOC interrupts are disabled during polling, so polling routine will
5737 * handle any replies. Considering this, if polling is happening,
5738 * return with interrupt unclaimed.
5739 */
5740 if (mpt->m_polled_intr) {
5741 mutex_exit(&mpt->m_mutex);
5742 mptsas_log(mpt, CE_WARN, "mpt_sas: Unclaimed interrupt");
5743 return (DDI_INTR_UNCLAIMED);
5744 }
5745
5746 /*
5747 * Read the istat register.
5748 */
5749 if ((INTPENDING(mpt)) != 0) {
5750 /*
5751 * read fifo until empty.
5752 */
5753 #ifndef __lock_lint
5754 _NOTE(CONSTCOND)
5755 #endif
5756 while (TRUE) {
5757 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0,
5758 DDI_DMA_SYNC_FORCPU);
5759 reply_desc_union = (pMpi2ReplyDescriptorsUnion_t)
5760 MPTSAS_GET_NEXT_REPLY(mpt, mpt->m_post_index);
5761
5762 if (ddi_get32(mpt->m_acc_post_queue_hdl,
5763 &reply_desc_union->Words.Low) == 0xFFFFFFFF ||
5764 ddi_get32(mpt->m_acc_post_queue_hdl,
5765 &reply_desc_union->Words.High) == 0xFFFFFFFF) {
5766 break;
5767 }
5768
5769 /*
5770 * The reply is valid, process it according to its
5771 * type. Also, set a flag for updating the reply index
5772 * after they've all been processed.
5773 */
5774 did_reply = TRUE;
5775
5776 mptsas_process_intr(mpt, reply_desc_union);
5777
5778 /*
5779 * Increment post index and roll over if needed.
5780 */
5781 if (++mpt->m_post_index == mpt->m_post_queue_depth) {
5782 mpt->m_post_index = 0;
5783 }
5784 }
5785
5786 /*
5787 * Update the global reply index if at least one reply was
5788 * processed.
5789 */
5790 if (did_reply) {
5791 ddi_put32(mpt->m_datap,
5792 &mpt->m_reg->ReplyPostHostIndex, mpt->m_post_index);
5793 }
5794 } else {
5795 mutex_exit(&mpt->m_mutex);
5796 return (DDI_INTR_UNCLAIMED);
5797 }
5798 NDBG1(("mptsas_intr complete"));
5799
5800 /*
5801 * If no helper threads are created, process the doneq in ISR. If
5802 * helpers are created, use the doneq length as a metric to measure the
5803 * load on the interrupt CPU. If it is long enough, which indicates the
5804 * load is heavy, then we deliver the IO completions to the helpers.
5805 * This measurement has some limitations, although it is simple and
5806 * straightforward and works well for most of the cases at present.
5807 */
5808 if (!mpt->m_doneq_thread_n ||
5809 (mpt->m_doneq_len <= mpt->m_doneq_length_threshold)) {
5810 mptsas_doneq_empty(mpt);
5811 } else {
5812 mptsas_deliver_doneq_thread(mpt);
5813 }
5814
5815 /*
5816 * If there are queued cmd, start them now.
5817 */
5818 if (mpt->m_waitq != NULL) {
5819 mptsas_restart_waitq(mpt);
5820 }
5821
5822 mutex_exit(&mpt->m_mutex);
5823 return (DDI_INTR_CLAIMED);
5824 }
5825
5826 static void
5827 mptsas_process_intr(mptsas_t *mpt,
5828 pMpi2ReplyDescriptorsUnion_t reply_desc_union)
5829 {
5830 uint8_t reply_type;
5831
5832 ASSERT(mutex_owned(&mpt->m_mutex));
5833
5834 /*
5835 * The reply is valid, process it according to its
5836 * type. Also, set a flag for updated the reply index
5837 * after they've all been processed.
5838 */
5839 reply_type = ddi_get8(mpt->m_acc_post_queue_hdl,
5840 &reply_desc_union->Default.ReplyFlags);
5841 reply_type &= MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
5842 if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS ||
5843 reply_type == MPI25_RPY_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO_SUCCESS) {
5844 mptsas_handle_scsi_io_success(mpt, reply_desc_union);
5845 } else if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) {
5846 mptsas_handle_address_reply(mpt, reply_desc_union);
5847 } else {
5848 mptsas_log(mpt, CE_WARN, "?Bad reply type %x", reply_type);
5849 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
5850 }
5851
5852 /*
5853 * Clear the reply descriptor for re-use and increment
5854 * index.
5855 */
5856 ddi_put64(mpt->m_acc_post_queue_hdl,
5857 &((uint64_t *)(void *)mpt->m_post_queue)[mpt->m_post_index],
5858 0xFFFFFFFFFFFFFFFF);
5859 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0,
5860 DDI_DMA_SYNC_FORDEV);
5861 }
5862
5863 /*
5864 * handle qfull condition
5865 */
5866 static void
5867 mptsas_handle_qfull(mptsas_t *mpt, mptsas_cmd_t *cmd)
5868 {
5869 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
5870
5871 if ((++cmd->cmd_qfull_retries > ptgt->m_qfull_retries) ||
5872 (ptgt->m_qfull_retries == 0)) {
5873 /*
5874 * We have exhausted the retries on QFULL, or,
5875 * the target driver has indicated that it
5876 * wants to handle QFULL itself by setting
5877 * qfull-retries capability to 0. In either case
5878 * we want the target driver's QFULL handling
5879 * to kick in. We do this by having pkt_reason
5880 * as CMD_CMPLT and pkt_scbp as STATUS_QFULL.
5881 */
5882 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
5883 } else {
5884 if (ptgt->m_reset_delay == 0) {
5885 ptgt->m_t_throttle =
5886 max((ptgt->m_t_ncmds - 2), 0);
5887 }
5888
5889 cmd->cmd_pkt_flags |= FLAG_HEAD;
5890 cmd->cmd_flags &= ~(CFLAG_TRANFLAG);
5891 cmd->cmd_flags |= CFLAG_RETRY;
5892
5893 (void) mptsas_accept_pkt(mpt, cmd);
5894
5895 /*
5896 * when target gives queue full status with no commands
5897 * outstanding (m_t_ncmds == 0), throttle is set to 0
5898 * (HOLD_THROTTLE), and the queue full handling start
5899 * (see psarc/1994/313); if there are commands outstanding,
5900 * throttle is set to (m_t_ncmds - 2)
5901 */
5902 if (ptgt->m_t_throttle == HOLD_THROTTLE) {
5903 /*
5904 * By setting throttle to QFULL_THROTTLE, we
5905 * avoid submitting new commands and in
5906 * mptsas_restart_cmd find out slots which need
5907 * their throttles to be cleared.
5908 */
5909 mptsas_set_throttle(mpt, ptgt, QFULL_THROTTLE);
5910 if (mpt->m_restart_cmd_timeid == 0) {
5911 mpt->m_restart_cmd_timeid =
5912 timeout(mptsas_restart_cmd, mpt,
5913 ptgt->m_qfull_retry_interval);
5914 }
5915 }
5916 }
5917 }
5918
5919 mptsas_phymask_t
5920 mptsas_physport_to_phymask(mptsas_t *mpt, uint8_t physport)
5921 {
5922 mptsas_phymask_t phy_mask = 0;
5923 uint8_t i = 0;
5924
5925 NDBG20(("mptsas%d physport_to_phymask enter", mpt->m_instance));
5926
5927 ASSERT(mutex_owned(&mpt->m_mutex));
5928
5929 /*
5930 * If physport is 0xFF, this is a RAID volume. Use phymask of 0.
5931 */
5932 if (physport == 0xFF) {
5933 return (0);
5934 }
5935
5936 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
5937 if (mpt->m_phy_info[i].attached_devhdl &&
5938 (mpt->m_phy_info[i].phy_mask != 0) &&
5939 (mpt->m_phy_info[i].port_num == physport)) {
5940 phy_mask = mpt->m_phy_info[i].phy_mask;
5941 break;
5942 }
5943 }
5944 NDBG20(("mptsas%d physport_to_phymask:physport :%x phymask :%x, ",
5945 mpt->m_instance, physport, phy_mask));
5946 return (phy_mask);
5947 }
5948
5949 /*
5950 * mpt free device handle after device gone, by use of passthrough
5951 */
5952 static int
5953 mptsas_free_devhdl(mptsas_t *mpt, uint16_t devhdl)
5954 {
5955 Mpi2SasIoUnitControlRequest_t req;
5956 Mpi2SasIoUnitControlReply_t rep;
5957 int ret;
5958
5959 ASSERT(mutex_owned(&mpt->m_mutex));
5960
5961 /*
5962 * Need to compose a SAS IO Unit Control request message
5963 * and call mptsas_do_passthru() function
5964 */
5965 bzero(&req, sizeof (req));
5966 bzero(&rep, sizeof (rep));
5967
5968 req.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
5969 req.Operation = MPI2_SAS_OP_REMOVE_DEVICE;
5970 req.DevHandle = LE_16(devhdl);
5971
5972 ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, NULL,
5973 sizeof (req), sizeof (rep), NULL, 0, NULL, 0, 60, FKIOCTL);
5974 if (ret != 0) {
5975 cmn_err(CE_WARN, "mptsas_free_devhdl: passthru SAS IO Unit "
5976 "Control error %d", ret);
5977 return (DDI_FAILURE);
5978 }
5979
5980 /* do passthrough success, check the ioc status */
5981 if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) {
5982 cmn_err(CE_WARN, "mptsas_free_devhdl: passthru SAS IO Unit "
5983 "Control IOCStatus %d", LE_16(rep.IOCStatus));
5984 return (DDI_FAILURE);
5985 }
5986
5987 return (DDI_SUCCESS);
5988 }
5989
5990 static void
5991 mptsas_update_phymask(mptsas_t *mpt)
5992 {
5993 mptsas_phymask_t mask = 0, phy_mask;
5994 char *phy_mask_name;
5995 uint8_t current_port;
5996 int i, j;
5997
5998 NDBG20(("mptsas%d update phymask ", mpt->m_instance));
5999
6000 ASSERT(mutex_owned(&mpt->m_mutex));
6001
6002 (void) mptsas_get_sas_io_unit_page(mpt);
6003
6004 phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP);
6005
6006 for (i = 0; i < mpt->m_num_phys; i++) {
6007 phy_mask = 0x00;
6008
6009 if (mpt->m_phy_info[i].attached_devhdl == 0)
6010 continue;
6011
6012 bzero(phy_mask_name, sizeof (phy_mask_name));
6013
6014 current_port = mpt->m_phy_info[i].port_num;
6015
6016 if ((mask & (1 << i)) != 0)
6017 continue;
6018
6019 for (j = 0; j < mpt->m_num_phys; j++) {
6020 if (mpt->m_phy_info[j].attached_devhdl &&
6021 (mpt->m_phy_info[j].port_num == current_port)) {
6022 phy_mask |= (1 << j);
6023 }
6024 }
6025 mask = mask | phy_mask;
6026
6027 for (j = 0; j < mpt->m_num_phys; j++) {
6028 if ((phy_mask >> j) & 0x01) {
6029 mpt->m_phy_info[j].phy_mask = phy_mask;
6030 }
6031 }
6032
6033 (void) sprintf(phy_mask_name, "%x", phy_mask);
6034
6035 mutex_exit(&mpt->m_mutex);
6036 /*
6037 * register a iport, if the port has already been existed
6038 * SCSA will do nothing and just return.
6039 */
6040 (void) scsi_hba_iport_register(mpt->m_dip, phy_mask_name);
6041 mutex_enter(&mpt->m_mutex);
6042 }
6043 kmem_free(phy_mask_name, MPTSAS_MAX_PHYS);
6044 NDBG20(("mptsas%d update phymask return", mpt->m_instance));
6045 }
6046
6047 /*
6048 * mptsas_handle_dr is a task handler for DR, the DR action includes:
6049 * 1. Directly attched Device Added/Removed.
6050 * 2. Expander Device Added/Removed.
6051 * 3. Indirectly Attached Device Added/Expander.
6052 * 4. LUNs of a existing device status change.
6053 * 5. RAID volume created/deleted.
6054 * 6. Member of RAID volume is released because of RAID deletion.
6055 * 7. Physical disks are removed because of RAID creation.
6056 */
6057 static void
6058 mptsas_handle_dr(void *args) {
6059 mptsas_topo_change_list_t *topo_node = NULL;
6060 mptsas_topo_change_list_t *save_node = NULL;
6061 mptsas_t *mpt;
6062 dev_info_t *parent = NULL;
6063 mptsas_phymask_t phymask = 0;
6064 char *phy_mask_name;
6065 uint8_t flags = 0, physport = 0xff;
6066 uint8_t port_update = 0;
6067 uint_t event;
6068
6069 topo_node = (mptsas_topo_change_list_t *)args;
6070
6071 mpt = topo_node->mpt;
6072 event = topo_node->event;
6073 flags = topo_node->flags;
6074
6075 phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP);
6076
6077 NDBG20(("mptsas%d handle_dr enter", mpt->m_instance));
6078
6079 switch (event) {
6080 case MPTSAS_DR_EVENT_RECONFIG_TARGET:
6081 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) ||
6082 (flags == MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE) ||
6083 (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED)) {
6084 /*
6085 * Direct attached or expander attached device added
6086 * into system or a Phys Disk that is being unhidden.
6087 */
6088 port_update = 1;
6089 }
6090 break;
6091 case MPTSAS_DR_EVENT_RECONFIG_SMP:
6092 /*
6093 * New expander added into system, it must be the head
6094 * of topo_change_list_t
6095 */
6096 port_update = 1;
6097 break;
6098 default:
6099 port_update = 0;
6100 break;
6101 }
6102 /*
6103 * All cases port_update == 1 may cause initiator port form change
6104 */
6105 mutex_enter(&mpt->m_mutex);
6106 if (mpt->m_port_chng && port_update) {
6107 /*
6108 * mpt->m_port_chng flag indicates some PHYs of initiator
6109 * port have changed to online. So when expander added or
6110 * directly attached device online event come, we force to
6111 * update port information by issueing SAS IO Unit Page and
6112 * update PHYMASKs.
6113 */
6114 (void) mptsas_update_phymask(mpt);
6115 mpt->m_port_chng = 0;
6116
6117 }
6118 mutex_exit(&mpt->m_mutex);
6119 while (topo_node) {
6120 phymask = 0;
6121 if (parent == NULL) {
6122 physport = topo_node->un.physport;
6123 event = topo_node->event;
6124 flags = topo_node->flags;
6125 if (event & (MPTSAS_DR_EVENT_OFFLINE_TARGET |
6126 MPTSAS_DR_EVENT_OFFLINE_SMP)) {
6127 /*
6128 * For all offline events, phymask is known
6129 */
6130 phymask = topo_node->un.phymask;
6131 goto find_parent;
6132 }
6133 if (event & MPTSAS_TOPO_FLAG_REMOVE_HANDLE) {
6134 goto handle_topo_change;
6135 }
6136 if (flags & MPTSAS_TOPO_FLAG_LUN_ASSOCIATED) {
6137 phymask = topo_node->un.phymask;
6138 goto find_parent;
6139 }
6140
6141 if ((flags ==
6142 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) &&
6143 (event == MPTSAS_DR_EVENT_RECONFIG_TARGET)) {
6144 /*
6145 * There is no any field in IR_CONFIG_CHANGE
6146 * event indicate physport/phynum, let's get
6147 * parent after SAS Device Page0 request.
6148 */
6149 goto handle_topo_change;
6150 }
6151
6152 mutex_enter(&mpt->m_mutex);
6153 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) {
6154 /*
6155 * If the direct attached device added or a
6156 * phys disk is being unhidden, argument
6157 * physport actually is PHY#, so we have to get
6158 * phymask according PHY#.
6159 */
6160 physport = mpt->m_phy_info[physport].port_num;
6161 }
6162
6163 /*
6164 * Translate physport to phymask so that we can search
6165 * parent dip.
6166 */
6167 phymask = mptsas_physport_to_phymask(mpt,
6168 physport);
6169 mutex_exit(&mpt->m_mutex);
6170
6171 find_parent:
6172 bzero(phy_mask_name, MPTSAS_MAX_PHYS);
6173 /*
6174 * For RAID topology change node, write the iport name
6175 * as v0.
6176 */
6177 if (flags & MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) {
6178 (void) sprintf(phy_mask_name, "v0");
6179 } else {
6180 /*
6181 * phymask can bo 0 if the drive has been
6182 * pulled by the time an add event is
6183 * processed. If phymask is 0, just skip this
6184 * event and continue.
6185 */
6186 if (phymask == 0) {
6187 mutex_enter(&mpt->m_mutex);
6188 save_node = topo_node;
6189 topo_node = topo_node->next;
6190 ASSERT(save_node);
6191 kmem_free(save_node,
6192 sizeof (mptsas_topo_change_list_t));
6193 mutex_exit(&mpt->m_mutex);
6194
6195 parent = NULL;
6196 continue;
6197 }
6198 (void) sprintf(phy_mask_name, "%x", phymask);
6199 }
6200 parent = scsi_hba_iport_find(mpt->m_dip,
6201 phy_mask_name);
6202 if (parent == NULL) {
6203 mptsas_log(mpt, CE_WARN, "Failed to find an "
6204 "iport, should not happen!");
6205 goto out;
6206 }
6207
6208 }
6209 ASSERT(parent);
6210 handle_topo_change:
6211
6212 mutex_enter(&mpt->m_mutex);
6213 /*
6214 * If HBA is being reset, don't perform operations depending
6215 * on the IOC. We must free the topo list, however.
6216 */
6217 if (!mpt->m_in_reset)
6218 mptsas_handle_topo_change(topo_node, parent);
6219 else
6220 NDBG20(("skipping topo change received during reset"));
6221 save_node = topo_node;
6222 topo_node = topo_node->next;
6223 ASSERT(save_node);
6224 kmem_free(save_node, sizeof (mptsas_topo_change_list_t));
6225 mutex_exit(&mpt->m_mutex);
6226
6227 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) ||
6228 (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) ||
6229 (flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED)) {
6230 /*
6231 * If direct attached device associated, make sure
6232 * reset the parent before start the next one. But
6233 * all devices associated with expander shares the
6234 * parent. Also, reset parent if this is for RAID.
6235 */
6236 parent = NULL;
6237 }
6238 }
6239 out:
6240 kmem_free(phy_mask_name, MPTSAS_MAX_PHYS);
6241 }
6242
6243 static void
6244 mptsas_handle_topo_change(mptsas_topo_change_list_t *topo_node,
6245 dev_info_t *parent)
6246 {
6247 mptsas_target_t *ptgt = NULL;
6248 mptsas_smp_t *psmp = NULL;
6249 mptsas_t *mpt = (void *)topo_node->mpt;
6250 uint16_t devhdl;
6251 uint16_t attached_devhdl;
6252 uint64_t sas_wwn = 0;
6253 int rval = 0;
6254 uint32_t page_address;
6255 uint8_t phy, flags;
6256 char *addr = NULL;
6257 dev_info_t *lundip;
6258 int circ = 0, circ1 = 0;
6259 char attached_wwnstr[MPTSAS_WWN_STRLEN];
6260
6261 NDBG20(("mptsas%d handle_topo_change enter, devhdl 0x%x,"
6262 "event 0x%x, flags 0x%x", mpt->m_instance, topo_node->devhdl,
6263 topo_node->event, topo_node->flags));
6264
6265 ASSERT(mutex_owned(&mpt->m_mutex));
6266
6267 switch (topo_node->event) {
6268 case MPTSAS_DR_EVENT_RECONFIG_TARGET:
6269 {
6270 char *phy_mask_name;
6271 mptsas_phymask_t phymask = 0;
6272
6273 if (topo_node->flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) {
6274 /*
6275 * Get latest RAID info.
6276 */
6277 (void) mptsas_get_raid_info(mpt);
6278 ptgt = refhash_linear_search(mpt->m_targets,
6279 mptsas_target_eval_devhdl, &topo_node->devhdl);
6280 if (ptgt == NULL)
6281 break;
6282 } else {
6283 ptgt = (void *)topo_node->object;
6284 }
6285
6286 if (ptgt == NULL) {
6287 /*
6288 * If a Phys Disk was deleted, RAID info needs to be
6289 * updated to reflect the new topology.
6290 */
6291 (void) mptsas_get_raid_info(mpt);
6292
6293 /*
6294 * Get sas device page 0 by DevHandle to make sure if
6295 * SSP/SATA end device exist.
6296 */
6297 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
6298 MPI2_SAS_DEVICE_PGAD_FORM_MASK) |
6299 topo_node->devhdl;
6300
6301 rval = mptsas_get_target_device_info(mpt, page_address,
6302 &devhdl, &ptgt);
6303 if (rval == DEV_INFO_WRONG_DEVICE_TYPE) {
6304 mptsas_log(mpt, CE_NOTE,
6305 "mptsas_handle_topo_change: target %d is "
6306 "not a SAS/SATA device. \n",
6307 topo_node->devhdl);
6308 } else if (rval == DEV_INFO_FAIL_ALLOC) {
6309 mptsas_log(mpt, CE_NOTE,
6310 "mptsas_handle_topo_change: could not "
6311 "allocate memory. \n");
6312 }
6313 /*
6314 * If rval is DEV_INFO_PHYS_DISK than there is nothing
6315 * else to do, just leave.
6316 */
6317 if (rval != DEV_INFO_SUCCESS) {
6318 return;
6319 }
6320 }
6321
6322 ASSERT(ptgt->m_devhdl == topo_node->devhdl);
6323
6324 mutex_exit(&mpt->m_mutex);
6325 flags = topo_node->flags;
6326
6327 if (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) {
6328 phymask = ptgt->m_addr.mta_phymask;
6329 phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP);
6330 (void) sprintf(phy_mask_name, "%x", phymask);
6331 parent = scsi_hba_iport_find(mpt->m_dip,
6332 phy_mask_name);
6333 kmem_free(phy_mask_name, MPTSAS_MAX_PHYS);
6334 if (parent == NULL) {
6335 mptsas_log(mpt, CE_WARN, "Failed to find a "
6336 "iport for PD, should not happen!");
6337 mutex_enter(&mpt->m_mutex);
6338 break;
6339 }
6340 }
6341
6342 if (flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) {
6343 ndi_devi_enter(parent, &circ1);
6344 (void) mptsas_config_raid(parent, topo_node->devhdl,
6345 &lundip);
6346 ndi_devi_exit(parent, circ1);
6347 } else {
6348 /*
6349 * hold nexus for bus configure
6350 */
6351 ndi_devi_enter(scsi_vhci_dip, &circ);
6352 ndi_devi_enter(parent, &circ1);
6353 rval = mptsas_config_target(parent, ptgt);
6354 /*
6355 * release nexus for bus configure
6356 */
6357 ndi_devi_exit(parent, circ1);
6358 ndi_devi_exit(scsi_vhci_dip, circ);
6359
6360 /*
6361 * Add parent's props for SMHBA support
6362 */
6363 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) {
6364 bzero(attached_wwnstr,
6365 sizeof (attached_wwnstr));
6366 (void) sprintf(attached_wwnstr, "w%016"PRIx64,
6367 ptgt->m_addr.mta_wwn);
6368 if (ddi_prop_update_string(DDI_DEV_T_NONE,
6369 parent,
6370 SCSI_ADDR_PROP_ATTACHED_PORT,
6371 attached_wwnstr)
6372 != DDI_PROP_SUCCESS) {
6373 (void) ddi_prop_remove(DDI_DEV_T_NONE,
6374 parent,
6375 SCSI_ADDR_PROP_ATTACHED_PORT);
6376 mptsas_log(mpt, CE_WARN, "Failed to"
6377 "attached-port props");
6378 return;
6379 }
6380 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6381 MPTSAS_NUM_PHYS, 1) !=
6382 DDI_PROP_SUCCESS) {
6383 (void) ddi_prop_remove(DDI_DEV_T_NONE,
6384 parent, MPTSAS_NUM_PHYS);
6385 mptsas_log(mpt, CE_WARN, "Failed to"
6386 " create num-phys props");
6387 return;
6388 }
6389
6390 /*
6391 * Update PHY info for smhba
6392 */
6393 mutex_enter(&mpt->m_mutex);
6394 if (mptsas_smhba_phy_init(mpt)) {
6395 mutex_exit(&mpt->m_mutex);
6396 mptsas_log(mpt, CE_WARN, "mptsas phy"
6397 " update failed");
6398 return;
6399 }
6400 mutex_exit(&mpt->m_mutex);
6401
6402 /*
6403 * topo_node->un.physport is really the PHY#
6404 * for direct attached devices
6405 */
6406 mptsas_smhba_set_one_phy_props(mpt, parent,
6407 topo_node->un.physport, &attached_devhdl);
6408
6409 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6410 MPTSAS_VIRTUAL_PORT, 0) !=
6411 DDI_PROP_SUCCESS) {
6412 (void) ddi_prop_remove(DDI_DEV_T_NONE,
6413 parent, MPTSAS_VIRTUAL_PORT);
6414 mptsas_log(mpt, CE_WARN,
6415 "mptsas virtual-port"
6416 "port prop update failed");
6417 return;
6418 }
6419 }
6420 }
6421 mutex_enter(&mpt->m_mutex);
6422
6423 NDBG20(("mptsas%d handle_topo_change to online devhdl:%x, "
6424 "phymask:%x.", mpt->m_instance, ptgt->m_devhdl,
6425 ptgt->m_addr.mta_phymask));
6426 break;
6427 }
6428 case MPTSAS_DR_EVENT_OFFLINE_TARGET:
6429 {
6430 devhdl = topo_node->devhdl;
6431 ptgt = refhash_linear_search(mpt->m_targets,
6432 mptsas_target_eval_devhdl, &devhdl);
6433 if (ptgt == NULL)
6434 break;
6435
6436 sas_wwn = ptgt->m_addr.mta_wwn;
6437 phy = ptgt->m_phynum;
6438
6439 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
6440
6441 if (sas_wwn) {
6442 (void) sprintf(addr, "w%016"PRIx64, sas_wwn);
6443 } else {
6444 (void) sprintf(addr, "p%x", phy);
6445 }
6446 ASSERT(ptgt->m_devhdl == devhdl);
6447
6448 if ((topo_node->flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) ||
6449 (topo_node->flags ==
6450 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED)) {
6451 /*
6452 * Get latest RAID info if RAID volume status changes
6453 * or Phys Disk status changes
6454 */
6455 (void) mptsas_get_raid_info(mpt);
6456 }
6457 /*
6458 * Abort all outstanding command on the device
6459 */
6460 rval = mptsas_do_scsi_reset(mpt, devhdl);
6461 if (rval) {
6462 NDBG20(("mptsas%d handle_topo_change to reset target "
6463 "before offline devhdl:%x, phymask:%x, rval:%x",
6464 mpt->m_instance, ptgt->m_devhdl,
6465 ptgt->m_addr.mta_phymask, rval));
6466 }
6467
6468 mutex_exit(&mpt->m_mutex);
6469
6470 ndi_devi_enter(scsi_vhci_dip, &circ);
6471 ndi_devi_enter(parent, &circ1);
6472 rval = mptsas_offline_target(parent, addr);
6473 ndi_devi_exit(parent, circ1);
6474 ndi_devi_exit(scsi_vhci_dip, circ);
6475 NDBG20(("mptsas%d handle_topo_change to offline devhdl:%x, "
6476 "phymask:%x, rval:%x", mpt->m_instance,
6477 ptgt->m_devhdl, ptgt->m_addr.mta_phymask, rval));
6478
6479 kmem_free(addr, SCSI_MAXNAMELEN);
6480
6481 /*
6482 * Clear parent's props for SMHBA support
6483 */
6484 flags = topo_node->flags;
6485 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) {
6486 bzero(attached_wwnstr, sizeof (attached_wwnstr));
6487 if (ddi_prop_update_string(DDI_DEV_T_NONE, parent,
6488 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) !=
6489 DDI_PROP_SUCCESS) {
6490 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6491 SCSI_ADDR_PROP_ATTACHED_PORT);
6492 mptsas_log(mpt, CE_WARN, "mptsas attached port "
6493 "prop update failed");
6494 break;
6495 }
6496 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6497 MPTSAS_NUM_PHYS, 0) !=
6498 DDI_PROP_SUCCESS) {
6499 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6500 MPTSAS_NUM_PHYS);
6501 mptsas_log(mpt, CE_WARN, "mptsas num phys "
6502 "prop update failed");
6503 break;
6504 }
6505 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6506 MPTSAS_VIRTUAL_PORT, 1) !=
6507 DDI_PROP_SUCCESS) {
6508 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6509 MPTSAS_VIRTUAL_PORT);
6510 mptsas_log(mpt, CE_WARN, "mptsas virtual port "
6511 "prop update failed");
6512 break;
6513 }
6514 }
6515
6516 mutex_enter(&mpt->m_mutex);
6517 ptgt->m_led_status = 0;
6518 (void) mptsas_flush_led_status(mpt, ptgt);
6519 if (rval == DDI_SUCCESS) {
6520 refhash_remove(mpt->m_targets, ptgt);
6521 ptgt = NULL;
6522 } else {
6523 /*
6524 * clean DR_INTRANSITION flag to allow I/O down to
6525 * PHCI driver since failover finished.
6526 * Invalidate the devhdl
6527 */
6528 ptgt->m_devhdl = MPTSAS_INVALID_DEVHDL;
6529 ptgt->m_tgt_unconfigured = 0;
6530 mutex_enter(&mpt->m_tx_waitq_mutex);
6531 ptgt->m_dr_flag = MPTSAS_DR_INACTIVE;
6532 mutex_exit(&mpt->m_tx_waitq_mutex);
6533 }
6534
6535 /*
6536 * Send SAS IO Unit Control to free the dev handle
6537 */
6538 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) ||
6539 (flags == MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE)) {
6540 rval = mptsas_free_devhdl(mpt, devhdl);
6541
6542 NDBG20(("mptsas%d handle_topo_change to remove "
6543 "devhdl:%x, rval:%x", mpt->m_instance, devhdl,
6544 rval));
6545 }
6546
6547 break;
6548 }
6549 case MPTSAS_TOPO_FLAG_REMOVE_HANDLE:
6550 {
6551 devhdl = topo_node->devhdl;
6552 /*
6553 * If this is the remove handle event, do a reset first.
6554 */
6555 if (topo_node->event == MPTSAS_TOPO_FLAG_REMOVE_HANDLE) {
6556 rval = mptsas_do_scsi_reset(mpt, devhdl);
6557 if (rval) {
6558 NDBG20(("mpt%d reset target before remove "
6559 "devhdl:%x, rval:%x", mpt->m_instance,
6560 devhdl, rval));
6561 }
6562 }
6563
6564 /*
6565 * Send SAS IO Unit Control to free the dev handle
6566 */
6567 rval = mptsas_free_devhdl(mpt, devhdl);
6568 NDBG20(("mptsas%d handle_topo_change to remove "
6569 "devhdl:%x, rval:%x", mpt->m_instance, devhdl,
6570 rval));
6571 break;
6572 }
6573 case MPTSAS_DR_EVENT_RECONFIG_SMP:
6574 {
6575 mptsas_smp_t smp;
6576 dev_info_t *smpdip;
6577
6578 devhdl = topo_node->devhdl;
6579
6580 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_HNDL &
6581 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)devhdl;
6582 rval = mptsas_get_sas_expander_page0(mpt, page_address, &smp);
6583 if (rval != DDI_SUCCESS) {
6584 mptsas_log(mpt, CE_WARN, "failed to online smp, "
6585 "handle %x", devhdl);
6586 return;
6587 }
6588
6589 psmp = mptsas_smp_alloc(mpt, &smp);
6590 if (psmp == NULL) {
6591 return;
6592 }
6593
6594 mutex_exit(&mpt->m_mutex);
6595 ndi_devi_enter(parent, &circ1);
6596 (void) mptsas_online_smp(parent, psmp, &smpdip);
6597 ndi_devi_exit(parent, circ1);
6598
6599 mutex_enter(&mpt->m_mutex);
6600 break;
6601 }
6602 case MPTSAS_DR_EVENT_OFFLINE_SMP:
6603 {
6604 devhdl = topo_node->devhdl;
6605 uint32_t dev_info;
6606
6607 psmp = refhash_linear_search(mpt->m_smp_targets,
6608 mptsas_smp_eval_devhdl, &devhdl);
6609 if (psmp == NULL)
6610 break;
6611 /*
6612 * The mptsas_smp_t data is released only if the dip is offlined
6613 * successfully.
6614 */
6615 mutex_exit(&mpt->m_mutex);
6616
6617 ndi_devi_enter(parent, &circ1);
6618 rval = mptsas_offline_smp(parent, psmp, NDI_DEVI_REMOVE);
6619 ndi_devi_exit(parent, circ1);
6620
6621 dev_info = psmp->m_deviceinfo;
6622 if ((dev_info & DEVINFO_DIRECT_ATTACHED) ==
6623 DEVINFO_DIRECT_ATTACHED) {
6624 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6625 MPTSAS_VIRTUAL_PORT, 1) !=
6626 DDI_PROP_SUCCESS) {
6627 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6628 MPTSAS_VIRTUAL_PORT);
6629 mptsas_log(mpt, CE_WARN, "mptsas virtual port "
6630 "prop update failed");
6631 return;
6632 }
6633 /*
6634 * Check whether the smp connected to the iport,
6635 */
6636 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6637 MPTSAS_NUM_PHYS, 0) !=
6638 DDI_PROP_SUCCESS) {
6639 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6640 MPTSAS_NUM_PHYS);
6641 mptsas_log(mpt, CE_WARN, "mptsas num phys"
6642 "prop update failed");
6643 return;
6644 }
6645 /*
6646 * Clear parent's attached-port props
6647 */
6648 bzero(attached_wwnstr, sizeof (attached_wwnstr));
6649 if (ddi_prop_update_string(DDI_DEV_T_NONE, parent,
6650 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) !=
6651 DDI_PROP_SUCCESS) {
6652 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6653 SCSI_ADDR_PROP_ATTACHED_PORT);
6654 mptsas_log(mpt, CE_WARN, "mptsas attached port "
6655 "prop update failed");
6656 return;
6657 }
6658 }
6659
6660 mutex_enter(&mpt->m_mutex);
6661 NDBG20(("mptsas%d handle_topo_change to remove devhdl:%x, "
6662 "rval:%x", mpt->m_instance, psmp->m_devhdl, rval));
6663 if (rval == DDI_SUCCESS) {
6664 refhash_remove(mpt->m_smp_targets, psmp);
6665 } else {
6666 psmp->m_devhdl = MPTSAS_INVALID_DEVHDL;
6667 }
6668
6669 bzero(attached_wwnstr, sizeof (attached_wwnstr));
6670
6671 break;
6672 }
6673 default:
6674 return;
6675 }
6676 }
6677
6678 /*
6679 * Record the event if its type is enabled in mpt instance by ioctl.
6680 */
6681 static void
6682 mptsas_record_event(void *args)
6683 {
6684 m_replyh_arg_t *replyh_arg;
6685 pMpi2EventNotificationReply_t eventreply;
6686 uint32_t event, rfm;
6687 mptsas_t *mpt;
6688 int i, j;
6689 uint16_t event_data_len;
6690 boolean_t sendAEN = FALSE;
6691
6692 replyh_arg = (m_replyh_arg_t *)args;
6693 rfm = replyh_arg->rfm;
6694 mpt = replyh_arg->mpt;
6695
6696 eventreply = (pMpi2EventNotificationReply_t)
6697 (mpt->m_reply_frame + (rfm - mpt->m_reply_frame_dma_addr));
6698 event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event);
6699
6700
6701 /*
6702 * Generate a system event to let anyone who cares know that a
6703 * LOG_ENTRY_ADDED event has occurred. This is sent no matter what the
6704 * event mask is set to.
6705 */
6706 if (event == MPI2_EVENT_LOG_ENTRY_ADDED) {
6707 sendAEN = TRUE;
6708 }
6709
6710 /*
6711 * Record the event only if it is not masked. Determine which dword
6712 * and bit of event mask to test.
6713 */
6714 i = (uint8_t)(event / 32);
6715 j = (uint8_t)(event % 32);
6716 if ((i < 4) && ((1 << j) & mpt->m_event_mask[i])) {
6717 i = mpt->m_event_index;
6718 mpt->m_events[i].Type = event;
6719 mpt->m_events[i].Number = ++mpt->m_event_number;
6720 bzero(mpt->m_events[i].Data, MPTSAS_MAX_EVENT_DATA_LENGTH * 4);
6721 event_data_len = ddi_get16(mpt->m_acc_reply_frame_hdl,
6722 &eventreply->EventDataLength);
6723
6724 if (event_data_len > 0) {
6725 /*
6726 * Limit data to size in m_event entry
6727 */
6728 if (event_data_len > MPTSAS_MAX_EVENT_DATA_LENGTH) {
6729 event_data_len = MPTSAS_MAX_EVENT_DATA_LENGTH;
6730 }
6731 for (j = 0; j < event_data_len; j++) {
6732 mpt->m_events[i].Data[j] =
6733 ddi_get32(mpt->m_acc_reply_frame_hdl,
6734 &(eventreply->EventData[j]));
6735 }
6736
6737 /*
6738 * check for index wrap-around
6739 */
6740 if (++i == MPTSAS_EVENT_QUEUE_SIZE) {
6741 i = 0;
6742 }
6743 mpt->m_event_index = (uint8_t)i;
6744
6745 /*
6746 * Set flag to send the event.
6747 */
6748 sendAEN = TRUE;
6749 }
6750 }
6751
6752 /*
6753 * Generate a system event if flag is set to let anyone who cares know
6754 * that an event has occurred.
6755 */
6756 if (sendAEN) {
6757 (void) ddi_log_sysevent(mpt->m_dip, DDI_VENDOR_LSI, "MPT_SAS",
6758 "SAS", NULL, NULL, DDI_NOSLEEP);
6759 }
6760 }
6761
6762 #define SMP_RESET_IN_PROGRESS MPI2_EVENT_SAS_TOPO_LR_SMP_RESET_IN_PROGRESS
6763 /*
6764 * handle sync events from ioc in interrupt
6765 * return value:
6766 * DDI_SUCCESS: The event is handled by this func
6767 * DDI_FAILURE: Event is not handled
6768 */
6769 static int
6770 mptsas_handle_event_sync(void *args)
6771 {
6772 m_replyh_arg_t *replyh_arg;
6773 pMpi2EventNotificationReply_t eventreply;
6774 uint32_t event, rfm;
6775 mptsas_t *mpt;
6776 uint_t iocstatus;
6777
6778 replyh_arg = (m_replyh_arg_t *)args;
6779 rfm = replyh_arg->rfm;
6780 mpt = replyh_arg->mpt;
6781
6782 ASSERT(mutex_owned(&mpt->m_mutex));
6783
6784 eventreply = (pMpi2EventNotificationReply_t)
6785 (mpt->m_reply_frame + (rfm - mpt->m_reply_frame_dma_addr));
6786 event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event);
6787
6788 if (iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
6789 &eventreply->IOCStatus)) {
6790 if (iocstatus == MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
6791 mptsas_log(mpt, CE_WARN,
6792 "!mptsas_handle_event_sync: event 0x%x, "
6793 "IOCStatus=0x%x, "
6794 "IOCLogInfo=0x%x", event, iocstatus,
6795 ddi_get32(mpt->m_acc_reply_frame_hdl,
6796 &eventreply->IOCLogInfo));
6797 } else {
6798 mptsas_log(mpt, CE_WARN,
6799 "mptsas_handle_event_sync: event 0x%x, "
6800 "IOCStatus=0x%x, "
6801 "(IOCLogInfo=0x%x)", event, iocstatus,
6802 ddi_get32(mpt->m_acc_reply_frame_hdl,
6803 &eventreply->IOCLogInfo));
6804 }
6805 }
6806
6807 /*
6808 * figure out what kind of event we got and handle accordingly
6809 */
6810 switch (event) {
6811 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
6812 {
6813 pMpi2EventDataSasTopologyChangeList_t sas_topo_change_list;
6814 uint8_t num_entries, expstatus, phy;
6815 uint8_t phystatus, physport, state, i;
6816 uint8_t start_phy_num, link_rate;
6817 uint16_t dev_handle, reason_code;
6818 uint16_t enc_handle, expd_handle;
6819 char string[80], curr[80], prev[80];
6820 mptsas_topo_change_list_t *topo_head = NULL;
6821 mptsas_topo_change_list_t *topo_tail = NULL;
6822 mptsas_topo_change_list_t *topo_node = NULL;
6823 mptsas_target_t *ptgt;
6824 mptsas_smp_t *psmp;
6825 uint8_t flags = 0, exp_flag;
6826 smhba_info_t *pSmhba = NULL;
6827
6828 NDBG20(("mptsas_handle_event_sync: SAS topology change"));
6829
6830 sas_topo_change_list = (pMpi2EventDataSasTopologyChangeList_t)
6831 eventreply->EventData;
6832
6833 enc_handle = ddi_get16(mpt->m_acc_reply_frame_hdl,
6834 &sas_topo_change_list->EnclosureHandle);
6835 expd_handle = ddi_get16(mpt->m_acc_reply_frame_hdl,
6836 &sas_topo_change_list->ExpanderDevHandle);
6837 num_entries = ddi_get8(mpt->m_acc_reply_frame_hdl,
6838 &sas_topo_change_list->NumEntries);
6839 start_phy_num = ddi_get8(mpt->m_acc_reply_frame_hdl,
6840 &sas_topo_change_list->StartPhyNum);
6841 expstatus = ddi_get8(mpt->m_acc_reply_frame_hdl,
6842 &sas_topo_change_list->ExpStatus);
6843 physport = ddi_get8(mpt->m_acc_reply_frame_hdl,
6844 &sas_topo_change_list->PhysicalPort);
6845
6846 string[0] = 0;
6847 if (expd_handle) {
6848 flags = MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED;
6849 switch (expstatus) {
6850 case MPI2_EVENT_SAS_TOPO_ES_ADDED:
6851 (void) sprintf(string, " added");
6852 /*
6853 * New expander device added
6854 */
6855 mpt->m_port_chng = 1;
6856 topo_node = kmem_zalloc(
6857 sizeof (mptsas_topo_change_list_t),
6858 KM_SLEEP);
6859 topo_node->mpt = mpt;
6860 topo_node->event = MPTSAS_DR_EVENT_RECONFIG_SMP;
6861 topo_node->un.physport = physport;
6862 topo_node->devhdl = expd_handle;
6863 topo_node->flags = flags;
6864 topo_node->object = NULL;
6865 if (topo_head == NULL) {
6866 topo_head = topo_tail = topo_node;
6867 } else {
6868 topo_tail->next = topo_node;
6869 topo_tail = topo_node;
6870 }
6871 break;
6872 case MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING:
6873 (void) sprintf(string, " not responding, "
6874 "removed");
6875 psmp = refhash_linear_search(mpt->m_smp_targets,
6876 mptsas_smp_eval_devhdl, &expd_handle);
6877 if (psmp == NULL)
6878 break;
6879
6880 topo_node = kmem_zalloc(
6881 sizeof (mptsas_topo_change_list_t),
6882 KM_SLEEP);
6883 topo_node->mpt = mpt;
6884 topo_node->un.phymask =
6885 psmp->m_addr.mta_phymask;
6886 topo_node->event = MPTSAS_DR_EVENT_OFFLINE_SMP;
6887 topo_node->devhdl = expd_handle;
6888 topo_node->flags = flags;
6889 topo_node->object = NULL;
6890 if (topo_head == NULL) {
6891 topo_head = topo_tail = topo_node;
6892 } else {
6893 topo_tail->next = topo_node;
6894 topo_tail = topo_node;
6895 }
6896 break;
6897 case MPI2_EVENT_SAS_TOPO_ES_RESPONDING:
6898 break;
6899 case MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING:
6900 (void) sprintf(string, " not responding, "
6901 "delaying removal");
6902 break;
6903 default:
6904 break;
6905 }
6906 } else {
6907 flags = MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE;
6908 }
6909
6910 NDBG20(("SAS TOPOLOGY CHANGE for enclosure %x expander %x%s\n",
6911 enc_handle, expd_handle, string));
6912 for (i = 0; i < num_entries; i++) {
6913 phy = i + start_phy_num;
6914 phystatus = ddi_get8(mpt->m_acc_reply_frame_hdl,
6915 &sas_topo_change_list->PHY[i].PhyStatus);
6916 dev_handle = ddi_get16(mpt->m_acc_reply_frame_hdl,
6917 &sas_topo_change_list->PHY[i].AttachedDevHandle);
6918 reason_code = phystatus & MPI2_EVENT_SAS_TOPO_RC_MASK;
6919 /*
6920 * Filter out processing of Phy Vacant Status unless
6921 * the reason code is "Not Responding". Process all
6922 * other combinations of Phy Status and Reason Codes.
6923 */
6924 if ((phystatus &
6925 MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT) &&
6926 (reason_code !=
6927 MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING)) {
6928 continue;
6929 }
6930 curr[0] = 0;
6931 prev[0] = 0;
6932 string[0] = 0;
6933 switch (reason_code) {
6934 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
6935 {
6936 NDBG20(("mptsas%d phy %d physical_port %d "
6937 "dev_handle %d added", mpt->m_instance, phy,
6938 physport, dev_handle));
6939 link_rate = ddi_get8(mpt->m_acc_reply_frame_hdl,
6940 &sas_topo_change_list->PHY[i].LinkRate);
6941 state = (link_rate &
6942 MPI2_EVENT_SAS_TOPO_LR_CURRENT_MASK) >>
6943 MPI2_EVENT_SAS_TOPO_LR_CURRENT_SHIFT;
6944 switch (state) {
6945 case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED:
6946 (void) sprintf(curr, "is disabled");
6947 break;
6948 case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED:
6949 (void) sprintf(curr, "is offline, "
6950 "failed speed negotiation");
6951 break;
6952 case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE:
6953 (void) sprintf(curr, "SATA OOB "
6954 "complete");
6955 break;
6956 case SMP_RESET_IN_PROGRESS:
6957 (void) sprintf(curr, "SMP reset in "
6958 "progress");
6959 break;
6960 case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5:
6961 (void) sprintf(curr, "is online at "
6962 "1.5 Gbps");
6963 break;
6964 case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0:
6965 (void) sprintf(curr, "is online at 3.0 "
6966 "Gbps");
6967 break;
6968 case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0:
6969 (void) sprintf(curr, "is online at 6.0 "
6970 "Gbps");
6971 break;
6972 case MPI25_EVENT_SAS_TOPO_LR_RATE_12_0:
6973 (void) sprintf(curr,
6974 "is online at 12.0 Gbps");
6975 break;
6976 default:
6977 (void) sprintf(curr, "state is "
6978 "unknown");
6979 break;
6980 }
6981 /*
6982 * New target device added into the system.
6983 * Set association flag according to if an
6984 * expander is used or not.
6985 */
6986 exp_flag =
6987 MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE;
6988 if (flags ==
6989 MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED) {
6990 flags = exp_flag;
6991 }
6992 topo_node = kmem_zalloc(
6993 sizeof (mptsas_topo_change_list_t),
6994 KM_SLEEP);
6995 topo_node->mpt = mpt;
6996 topo_node->event =
6997 MPTSAS_DR_EVENT_RECONFIG_TARGET;
6998 if (expd_handle == 0) {
6999 /*
7000 * Per MPI 2, if expander dev handle
7001 * is 0, it's a directly attached
7002 * device. So driver use PHY to decide
7003 * which iport is associated
7004 */
7005 physport = phy;
7006 mpt->m_port_chng = 1;
7007 }
7008 topo_node->un.physport = physport;
7009 topo_node->devhdl = dev_handle;
7010 topo_node->flags = flags;
7011 topo_node->object = NULL;
7012 if (topo_head == NULL) {
7013 topo_head = topo_tail = topo_node;
7014 } else {
7015 topo_tail->next = topo_node;
7016 topo_tail = topo_node;
7017 }
7018 break;
7019 }
7020 case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING:
7021 {
7022 NDBG20(("mptsas%d phy %d physical_port %d "
7023 "dev_handle %d removed", mpt->m_instance,
7024 phy, physport, dev_handle));
7025 /*
7026 * Set association flag according to if an
7027 * expander is used or not.
7028 */
7029 exp_flag =
7030 MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE;
7031 if (flags ==
7032 MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED) {
7033 flags = exp_flag;
7034 }
7035 /*
7036 * Target device is removed from the system
7037 * Before the device is really offline from
7038 * from system.
7039 */
7040 ptgt = refhash_linear_search(mpt->m_targets,
7041 mptsas_target_eval_devhdl, &dev_handle);
7042 /*
7043 * If ptgt is NULL here, it means that the
7044 * DevHandle is not in the hash table. This is
7045 * reasonable sometimes. For example, if a
7046 * disk was pulled, then added, then pulled
7047 * again, the disk will not have been put into
7048 * the hash table because the add event will
7049 * have an invalid phymask. BUT, this does not
7050 * mean that the DevHandle is invalid. The
7051 * controller will still have a valid DevHandle
7052 * that must be removed. To do this, use the
7053 * MPTSAS_TOPO_FLAG_REMOVE_HANDLE event.
7054 */
7055 if (ptgt == NULL) {
7056 topo_node = kmem_zalloc(
7057 sizeof (mptsas_topo_change_list_t),
7058 KM_SLEEP);
7059 topo_node->mpt = mpt;
7060 topo_node->un.phymask = 0;
7061 topo_node->event =
7062 MPTSAS_TOPO_FLAG_REMOVE_HANDLE;
7063 topo_node->devhdl = dev_handle;
7064 topo_node->flags = flags;
7065 topo_node->object = NULL;
7066 if (topo_head == NULL) {
7067 topo_head = topo_tail =
7068 topo_node;
7069 } else {
7070 topo_tail->next = topo_node;
7071 topo_tail = topo_node;
7072 }
7073 break;
7074 }
7075
7076 /*
7077 * Update DR flag immediately avoid I/O failure
7078 * before failover finish. Pay attention to the
7079 * mutex protect, we need grab m_tx_waitq_mutex
7080 * during set m_dr_flag because we won't add
7081 * the following command into waitq, instead,
7082 * we need return TRAN_BUSY in the tran_start
7083 * context.
7084 */
7085 mutex_enter(&mpt->m_tx_waitq_mutex);
7086 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION;
7087 mutex_exit(&mpt->m_tx_waitq_mutex);
7088
7089 topo_node = kmem_zalloc(
7090 sizeof (mptsas_topo_change_list_t),
7091 KM_SLEEP);
7092 topo_node->mpt = mpt;
7093 topo_node->un.phymask =
7094 ptgt->m_addr.mta_phymask;
7095 topo_node->event =
7096 MPTSAS_DR_EVENT_OFFLINE_TARGET;
7097 topo_node->devhdl = dev_handle;
7098 topo_node->flags = flags;
7099 topo_node->object = NULL;
7100 if (topo_head == NULL) {
7101 topo_head = topo_tail = topo_node;
7102 } else {
7103 topo_tail->next = topo_node;
7104 topo_tail = topo_node;
7105 }
7106 break;
7107 }
7108 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
7109 link_rate = ddi_get8(mpt->m_acc_reply_frame_hdl,
7110 &sas_topo_change_list->PHY[i].LinkRate);
7111 state = (link_rate &
7112 MPI2_EVENT_SAS_TOPO_LR_CURRENT_MASK) >>
7113 MPI2_EVENT_SAS_TOPO_LR_CURRENT_SHIFT;
7114 pSmhba = &mpt->m_phy_info[i].smhba_info;
7115 pSmhba->negotiated_link_rate = state;
7116 switch (state) {
7117 case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED:
7118 (void) sprintf(curr, "is disabled");
7119 mptsas_smhba_log_sysevent(mpt,
7120 ESC_SAS_PHY_EVENT,
7121 SAS_PHY_REMOVE,
7122 &mpt->m_phy_info[i].smhba_info);
7123 mpt->m_phy_info[i].smhba_info.
7124 negotiated_link_rate
7125 = 0x1;
7126 break;
7127 case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED:
7128 (void) sprintf(curr, "is offline, "
7129 "failed speed negotiation");
7130 mptsas_smhba_log_sysevent(mpt,
7131 ESC_SAS_PHY_EVENT,
7132 SAS_PHY_OFFLINE,
7133 &mpt->m_phy_info[i].smhba_info);
7134 break;
7135 case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE:
7136 (void) sprintf(curr, "SATA OOB "
7137 "complete");
7138 break;
7139 case SMP_RESET_IN_PROGRESS:
7140 (void) sprintf(curr, "SMP reset in "
7141 "progress");
7142 break;
7143 case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5:
7144 (void) sprintf(curr, "is online at "
7145 "1.5 Gbps");
7146 if ((expd_handle == 0) &&
7147 (enc_handle == 1)) {
7148 mpt->m_port_chng = 1;
7149 }
7150 mptsas_smhba_log_sysevent(mpt,
7151 ESC_SAS_PHY_EVENT,
7152 SAS_PHY_ONLINE,
7153 &mpt->m_phy_info[i].smhba_info);
7154 break;
7155 case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0:
7156 (void) sprintf(curr, "is online at 3.0 "
7157 "Gbps");
7158 if ((expd_handle == 0) &&
7159 (enc_handle == 1)) {
7160 mpt->m_port_chng = 1;
7161 }
7162 mptsas_smhba_log_sysevent(mpt,
7163 ESC_SAS_PHY_EVENT,
7164 SAS_PHY_ONLINE,
7165 &mpt->m_phy_info[i].smhba_info);
7166 break;
7167 case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0:
7168 (void) sprintf(curr, "is online at "
7169 "6.0 Gbps");
7170 if ((expd_handle == 0) &&
7171 (enc_handle == 1)) {
7172 mpt->m_port_chng = 1;
7173 }
7174 mptsas_smhba_log_sysevent(mpt,
7175 ESC_SAS_PHY_EVENT,
7176 SAS_PHY_ONLINE,
7177 &mpt->m_phy_info[i].smhba_info);
7178 break;
7179 case MPI25_EVENT_SAS_TOPO_LR_RATE_12_0:
7180 (void) sprintf(curr, "is online at "
7181 "12.0 Gbps");
7182 if ((expd_handle == 0) &&
7183 (enc_handle == 1)) {
7184 mpt->m_port_chng = 1;
7185 }
7186 mptsas_smhba_log_sysevent(mpt,
7187 ESC_SAS_PHY_EVENT,
7188 SAS_PHY_ONLINE,
7189 &mpt->m_phy_info[i].smhba_info);
7190 break;
7191 default:
7192 (void) sprintf(curr, "state is "
7193 "unknown");
7194 break;
7195 }
7196
7197 state = (link_rate &
7198 MPI2_EVENT_SAS_TOPO_LR_PREV_MASK) >>
7199 MPI2_EVENT_SAS_TOPO_LR_PREV_SHIFT;
7200 switch (state) {
7201 case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED:
7202 (void) sprintf(prev, ", was disabled");
7203 break;
7204 case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED:
7205 (void) sprintf(prev, ", was offline, "
7206 "failed speed negotiation");
7207 break;
7208 case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE:
7209 (void) sprintf(prev, ", was SATA OOB "
7210 "complete");
7211 break;
7212 case SMP_RESET_IN_PROGRESS:
7213 (void) sprintf(prev, ", was SMP reset "
7214 "in progress");
7215 break;
7216 case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5:
7217 (void) sprintf(prev, ", was online at "
7218 "1.5 Gbps");
7219 break;
7220 case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0:
7221 (void) sprintf(prev, ", was online at "
7222 "3.0 Gbps");
7223 break;
7224 case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0:
7225 (void) sprintf(prev, ", was online at "
7226 "6.0 Gbps");
7227 break;
7228 case MPI25_EVENT_SAS_TOPO_LR_RATE_12_0:
7229 (void) sprintf(prev, ", was online at "
7230 "12.0 Gbps");
7231 break;
7232 default:
7233 break;
7234 }
7235 (void) sprintf(&string[strlen(string)], "link "
7236 "changed, ");
7237 break;
7238 case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE:
7239 continue;
7240 case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING:
7241 (void) sprintf(&string[strlen(string)],
7242 "target not responding, delaying "
7243 "removal");
7244 break;
7245 }
7246 NDBG20(("mptsas%d phy %d DevHandle %x, %s%s%s\n",
7247 mpt->m_instance, phy, dev_handle, string, curr,
7248 prev));
7249 }
7250 if (topo_head != NULL) {
7251 /*
7252 * Launch DR taskq to handle topology change
7253 */
7254 if ((ddi_taskq_dispatch(mpt->m_dr_taskq,
7255 mptsas_handle_dr, (void *)topo_head,
7256 DDI_NOSLEEP)) != DDI_SUCCESS) {
7257 while (topo_head != NULL) {
7258 topo_node = topo_head;
7259 topo_head = topo_head->next;
7260 kmem_free(topo_node,
7261 sizeof (mptsas_topo_change_list_t));
7262 }
7263 mptsas_log(mpt, CE_NOTE, "mptsas start taskq "
7264 "for handle SAS DR event failed. \n");
7265 }
7266 }
7267 break;
7268 }
7269 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
7270 {
7271 Mpi2EventDataIrConfigChangeList_t *irChangeList;
7272 mptsas_topo_change_list_t *topo_head = NULL;
7273 mptsas_topo_change_list_t *topo_tail = NULL;
7274 mptsas_topo_change_list_t *topo_node = NULL;
7275 mptsas_target_t *ptgt;
7276 uint8_t num_entries, i, reason;
7277 uint16_t volhandle, diskhandle;
7278
7279 irChangeList = (pMpi2EventDataIrConfigChangeList_t)
7280 eventreply->EventData;
7281 num_entries = ddi_get8(mpt->m_acc_reply_frame_hdl,
7282 &irChangeList->NumElements);
7283
7284 NDBG20(("mptsas%d IR_CONFIGURATION_CHANGE_LIST event received",
7285 mpt->m_instance));
7286
7287 for (i = 0; i < num_entries; i++) {
7288 reason = ddi_get8(mpt->m_acc_reply_frame_hdl,
7289 &irChangeList->ConfigElement[i].ReasonCode);
7290 volhandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
7291 &irChangeList->ConfigElement[i].VolDevHandle);
7292 diskhandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
7293 &irChangeList->ConfigElement[i].PhysDiskDevHandle);
7294
7295 switch (reason) {
7296 case MPI2_EVENT_IR_CHANGE_RC_ADDED:
7297 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED:
7298 {
7299 NDBG20(("mptsas %d volume added\n",
7300 mpt->m_instance));
7301
7302 topo_node = kmem_zalloc(
7303 sizeof (mptsas_topo_change_list_t),
7304 KM_SLEEP);
7305
7306 topo_node->mpt = mpt;
7307 topo_node->event =
7308 MPTSAS_DR_EVENT_RECONFIG_TARGET;
7309 topo_node->un.physport = 0xff;
7310 topo_node->devhdl = volhandle;
7311 topo_node->flags =
7312 MPTSAS_TOPO_FLAG_RAID_ASSOCIATED;
7313 topo_node->object = NULL;
7314 if (topo_head == NULL) {
7315 topo_head = topo_tail = topo_node;
7316 } else {
7317 topo_tail->next = topo_node;
7318 topo_tail = topo_node;
7319 }
7320 break;
7321 }
7322 case MPI2_EVENT_IR_CHANGE_RC_REMOVED:
7323 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED:
7324 {
7325 NDBG20(("mptsas %d volume deleted\n",
7326 mpt->m_instance));
7327 ptgt = refhash_linear_search(mpt->m_targets,
7328 mptsas_target_eval_devhdl, &volhandle);
7329 if (ptgt == NULL)
7330 break;
7331
7332 /*
7333 * Clear any flags related to volume
7334 */
7335 (void) mptsas_delete_volume(mpt, volhandle);
7336
7337 /*
7338 * Update DR flag immediately avoid I/O failure
7339 */
7340 mutex_enter(&mpt->m_tx_waitq_mutex);
7341 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION;
7342 mutex_exit(&mpt->m_tx_waitq_mutex);
7343
7344 topo_node = kmem_zalloc(
7345 sizeof (mptsas_topo_change_list_t),
7346 KM_SLEEP);
7347 topo_node->mpt = mpt;
7348 topo_node->un.phymask =
7349 ptgt->m_addr.mta_phymask;
7350 topo_node->event =
7351 MPTSAS_DR_EVENT_OFFLINE_TARGET;
7352 topo_node->devhdl = volhandle;
7353 topo_node->flags =
7354 MPTSAS_TOPO_FLAG_RAID_ASSOCIATED;
7355 topo_node->object = (void *)ptgt;
7356 if (topo_head == NULL) {
7357 topo_head = topo_tail = topo_node;
7358 } else {
7359 topo_tail->next = topo_node;
7360 topo_tail = topo_node;
7361 }
7362 break;
7363 }
7364 case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED:
7365 case MPI2_EVENT_IR_CHANGE_RC_HIDE:
7366 {
7367 ptgt = refhash_linear_search(mpt->m_targets,
7368 mptsas_target_eval_devhdl, &diskhandle);
7369 if (ptgt == NULL)
7370 break;
7371
7372 /*
7373 * Update DR flag immediately avoid I/O failure
7374 */
7375 mutex_enter(&mpt->m_tx_waitq_mutex);
7376 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION;
7377 mutex_exit(&mpt->m_tx_waitq_mutex);
7378
7379 topo_node = kmem_zalloc(
7380 sizeof (mptsas_topo_change_list_t),
7381 KM_SLEEP);
7382 topo_node->mpt = mpt;
7383 topo_node->un.phymask =
7384 ptgt->m_addr.mta_phymask;
7385 topo_node->event =
7386 MPTSAS_DR_EVENT_OFFLINE_TARGET;
7387 topo_node->devhdl = diskhandle;
7388 topo_node->flags =
7389 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED;
7390 topo_node->object = (void *)ptgt;
7391 if (topo_head == NULL) {
7392 topo_head = topo_tail = topo_node;
7393 } else {
7394 topo_tail->next = topo_node;
7395 topo_tail = topo_node;
7396 }
7397 break;
7398 }
7399 case MPI2_EVENT_IR_CHANGE_RC_UNHIDE:
7400 case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED:
7401 {
7402 /*
7403 * The physical drive is released by a IR
7404 * volume. But we cannot get the the physport
7405 * or phynum from the event data, so we only
7406 * can get the physport/phynum after SAS
7407 * Device Page0 request for the devhdl.
7408 */
7409 topo_node = kmem_zalloc(
7410 sizeof (mptsas_topo_change_list_t),
7411 KM_SLEEP);
7412 topo_node->mpt = mpt;
7413 topo_node->un.phymask = 0;
7414 topo_node->event =
7415 MPTSAS_DR_EVENT_RECONFIG_TARGET;
7416 topo_node->devhdl = diskhandle;
7417 topo_node->flags =
7418 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED;
7419 topo_node->object = NULL;
7420 mpt->m_port_chng = 1;
7421 if (topo_head == NULL) {
7422 topo_head = topo_tail = topo_node;
7423 } else {
7424 topo_tail->next = topo_node;
7425 topo_tail = topo_node;
7426 }
7427 break;
7428 }
7429 default:
7430 break;
7431 }
7432 }
7433
7434 if (topo_head != NULL) {
7435 /*
7436 * Launch DR taskq to handle topology change
7437 */
7438 if ((ddi_taskq_dispatch(mpt->m_dr_taskq,
7439 mptsas_handle_dr, (void *)topo_head,
7440 DDI_NOSLEEP)) != DDI_SUCCESS) {
7441 while (topo_head != NULL) {
7442 topo_node = topo_head;
7443 topo_head = topo_head->next;
7444 kmem_free(topo_node,
7445 sizeof (mptsas_topo_change_list_t));
7446 }
7447 mptsas_log(mpt, CE_NOTE, "mptsas start taskq "
7448 "for handle SAS DR event failed. \n");
7449 }
7450 }
7451 break;
7452 }
7453 default:
7454 return (DDI_FAILURE);
7455 }
7456
7457 return (DDI_SUCCESS);
7458 }
7459
7460 /*
7461 * handle events from ioc
7462 */
7463 static void
7464 mptsas_handle_event(void *args)
7465 {
7466 m_replyh_arg_t *replyh_arg;
7467 pMpi2EventNotificationReply_t eventreply;
7468 uint32_t event, iocloginfo, rfm;
7469 uint32_t status;
7470 uint8_t port;
7471 mptsas_t *mpt;
7472 uint_t iocstatus;
7473
7474 replyh_arg = (m_replyh_arg_t *)args;
7475 rfm = replyh_arg->rfm;
7476 mpt = replyh_arg->mpt;
7477
7478 mutex_enter(&mpt->m_mutex);
7479 /*
7480 * If HBA is being reset, drop incoming event.
7481 */
7482 if (mpt->m_in_reset) {
7483 NDBG20(("dropping event received prior to reset"));
7484 mutex_exit(&mpt->m_mutex);
7485 return;
7486 }
7487
7488 eventreply = (pMpi2EventNotificationReply_t)
7489 (mpt->m_reply_frame + (rfm - mpt->m_reply_frame_dma_addr));
7490 event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event);
7491
7492 if (iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
7493 &eventreply->IOCStatus)) {
7494 if (iocstatus == MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
7495 mptsas_log(mpt, CE_WARN,
7496 "!mptsas_handle_event: IOCStatus=0x%x, "
7497 "IOCLogInfo=0x%x", iocstatus,
7498 ddi_get32(mpt->m_acc_reply_frame_hdl,
7499 &eventreply->IOCLogInfo));
7500 } else {
7501 mptsas_log(mpt, CE_WARN,
7502 "mptsas_handle_event: IOCStatus=0x%x, "
7503 "IOCLogInfo=0x%x", iocstatus,
7504 ddi_get32(mpt->m_acc_reply_frame_hdl,
7505 &eventreply->IOCLogInfo));
7506 }
7507 }
7508
7509 /*
7510 * figure out what kind of event we got and handle accordingly
7511 */
7512 switch (event) {
7513 case MPI2_EVENT_LOG_ENTRY_ADDED:
7514 break;
7515 case MPI2_EVENT_LOG_DATA:
7516 iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl,
7517 &eventreply->IOCLogInfo);
7518 NDBG20(("mptsas %d log info %x received.\n", mpt->m_instance,
7519 iocloginfo));
7520 break;
7521 case MPI2_EVENT_STATE_CHANGE:
7522 NDBG20(("mptsas%d state change.", mpt->m_instance));
7523 break;
7524 case MPI2_EVENT_HARD_RESET_RECEIVED:
7525 NDBG20(("mptsas%d event change.", mpt->m_instance));
7526 break;
7527 case MPI2_EVENT_SAS_DISCOVERY:
7528 {
7529 MPI2_EVENT_DATA_SAS_DISCOVERY *sasdiscovery;
7530 char string[80];
7531 uint8_t rc;
7532
7533 sasdiscovery =
7534 (pMpi2EventDataSasDiscovery_t)eventreply->EventData;
7535
7536 rc = ddi_get8(mpt->m_acc_reply_frame_hdl,
7537 &sasdiscovery->ReasonCode);
7538 port = ddi_get8(mpt->m_acc_reply_frame_hdl,
7539 &sasdiscovery->PhysicalPort);
7540 status = ddi_get32(mpt->m_acc_reply_frame_hdl,
7541 &sasdiscovery->DiscoveryStatus);
7542
7543 string[0] = 0;
7544 switch (rc) {
7545 case MPI2_EVENT_SAS_DISC_RC_STARTED:
7546 (void) sprintf(string, "STARTING");
7547 break;
7548 case MPI2_EVENT_SAS_DISC_RC_COMPLETED:
7549 (void) sprintf(string, "COMPLETED");
7550 break;
7551 default:
7552 (void) sprintf(string, "UNKNOWN");
7553 break;
7554 }
7555
7556 NDBG20(("SAS DISCOVERY is %s for port %d, status %x", string,
7557 port, status));
7558
7559 break;
7560 }
7561 case MPI2_EVENT_EVENT_CHANGE:
7562 NDBG20(("mptsas%d event change.", mpt->m_instance));
7563 break;
7564 case MPI2_EVENT_TASK_SET_FULL:
7565 {
7566 pMpi2EventDataTaskSetFull_t taskfull;
7567
7568 taskfull = (pMpi2EventDataTaskSetFull_t)eventreply->EventData;
7569
7570 NDBG20(("TASK_SET_FULL received for mptsas%d, depth %d\n",
7571 mpt->m_instance, ddi_get16(mpt->m_acc_reply_frame_hdl,
7572 &taskfull->CurrentDepth)));
7573 break;
7574 }
7575 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
7576 {
7577 /*
7578 * SAS TOPOLOGY CHANGE LIST Event has already been handled
7579 * in mptsas_handle_event_sync() of interrupt context
7580 */
7581 break;
7582 }
7583 case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
7584 {
7585 pMpi2EventDataSasEnclDevStatusChange_t encstatus;
7586 uint8_t rc;
7587 char string[80];
7588
7589 encstatus = (pMpi2EventDataSasEnclDevStatusChange_t)
7590 eventreply->EventData;
7591
7592 rc = ddi_get8(mpt->m_acc_reply_frame_hdl,
7593 &encstatus->ReasonCode);
7594 switch (rc) {
7595 case MPI2_EVENT_SAS_ENCL_RC_ADDED:
7596 (void) sprintf(string, "added");
7597 break;
7598 case MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING:
7599 (void) sprintf(string, ", not responding");
7600 break;
7601 default:
7602 break;
7603 }
7604 NDBG20(("mptsas%d ENCLOSURE STATUS CHANGE for enclosure "
7605 "%x%s\n", mpt->m_instance,
7606 ddi_get16(mpt->m_acc_reply_frame_hdl,
7607 &encstatus->EnclosureHandle), string));
7608 break;
7609 }
7610
7611 /*
7612 * MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE is handled by
7613 * mptsas_handle_event_sync,in here just send ack message.
7614 */
7615 case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
7616 {
7617 pMpi2EventDataSasDeviceStatusChange_t statuschange;
7618 uint8_t rc;
7619 uint16_t devhdl;
7620 uint64_t wwn = 0;
7621 uint32_t wwn_lo, wwn_hi;
7622
7623 statuschange = (pMpi2EventDataSasDeviceStatusChange_t)
7624 eventreply->EventData;
7625 rc = ddi_get8(mpt->m_acc_reply_frame_hdl,
7626 &statuschange->ReasonCode);
7627 wwn_lo = ddi_get32(mpt->m_acc_reply_frame_hdl,
7628 (uint32_t *)(void *)&statuschange->SASAddress);
7629 wwn_hi = ddi_get32(mpt->m_acc_reply_frame_hdl,
7630 (uint32_t *)(void *)&statuschange->SASAddress + 1);
7631 wwn = ((uint64_t)wwn_hi << 32) | wwn_lo;
7632 devhdl = ddi_get16(mpt->m_acc_reply_frame_hdl,
7633 &statuschange->DevHandle);
7634
7635 NDBG13(("MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE wwn is %"PRIx64,
7636 wwn));
7637
7638 switch (rc) {
7639 case MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
7640 NDBG20(("SMART data received, ASC/ASCQ = %02x/%02x",
7641 ddi_get8(mpt->m_acc_reply_frame_hdl,
7642 &statuschange->ASC),
7643 ddi_get8(mpt->m_acc_reply_frame_hdl,
7644 &statuschange->ASCQ)));
7645 break;
7646
7647 case MPI2_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
7648 NDBG20(("Device not supported"));
7649 break;
7650
7651 case MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
7652 NDBG20(("IOC internally generated the Target Reset "
7653 "for devhdl:%x", devhdl));
7654 break;
7655
7656 case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET:
7657 NDBG20(("IOC's internally generated Target Reset "
7658 "completed for devhdl:%x", devhdl));
7659 break;
7660
7661 case MPI2_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
7662 NDBG20(("IOC internally generated Abort Task"));
7663 break;
7664
7665 case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_TASK_ABORT_INTERNAL:
7666 NDBG20(("IOC's internally generated Abort Task "
7667 "completed"));
7668 break;
7669
7670 case MPI2_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
7671 NDBG20(("IOC internally generated Abort Task Set"));
7672 break;
7673
7674 case MPI2_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
7675 NDBG20(("IOC internally generated Clear Task Set"));
7676 break;
7677
7678 case MPI2_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
7679 NDBG20(("IOC internally generated Query Task"));
7680 break;
7681
7682 case MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION:
7683 NDBG20(("Device sent an Asynchronous Notification"));
7684 break;
7685
7686 default:
7687 break;
7688 }
7689 break;
7690 }
7691 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
7692 {
7693 /*
7694 * IR TOPOLOGY CHANGE LIST Event has already been handled
7695 * in mpt_handle_event_sync() of interrupt context
7696 */
7697 break;
7698 }
7699 case MPI2_EVENT_IR_OPERATION_STATUS:
7700 {
7701 Mpi2EventDataIrOperationStatus_t *irOpStatus;
7702 char reason_str[80];
7703 uint8_t rc, percent;
7704 uint16_t handle;
7705
7706 irOpStatus = (pMpi2EventDataIrOperationStatus_t)
7707 eventreply->EventData;
7708 rc = ddi_get8(mpt->m_acc_reply_frame_hdl,
7709 &irOpStatus->RAIDOperation);
7710 percent = ddi_get8(mpt->m_acc_reply_frame_hdl,
7711 &irOpStatus->PercentComplete);
7712 handle = ddi_get16(mpt->m_acc_reply_frame_hdl,
7713 &irOpStatus->VolDevHandle);
7714
7715 switch (rc) {
7716 case MPI2_EVENT_IR_RAIDOP_RESYNC:
7717 (void) sprintf(reason_str, "resync");
7718 break;
7719 case MPI2_EVENT_IR_RAIDOP_ONLINE_CAP_EXPANSION:
7720 (void) sprintf(reason_str, "online capacity "
7721 "expansion");
7722 break;
7723 case MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK:
7724 (void) sprintf(reason_str, "consistency check");
7725 break;
7726 default:
7727 (void) sprintf(reason_str, "unknown reason %x",
7728 rc);
7729 }
7730
7731 NDBG20(("mptsas%d raid operational status: (%s)"
7732 "\thandle(0x%04x), percent complete(%d)\n",
7733 mpt->m_instance, reason_str, handle, percent));
7734 break;
7735 }
7736 case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE:
7737 {
7738 pMpi2EventDataSasBroadcastPrimitive_t sas_broadcast;
7739 uint8_t phy_num;
7740 uint8_t primitive;
7741
7742 sas_broadcast = (pMpi2EventDataSasBroadcastPrimitive_t)
7743 eventreply->EventData;
7744
7745 phy_num = ddi_get8(mpt->m_acc_reply_frame_hdl,
7746 &sas_broadcast->PhyNum);
7747 primitive = ddi_get8(mpt->m_acc_reply_frame_hdl,
7748 &sas_broadcast->Primitive);
7749
7750 switch (primitive) {
7751 case MPI2_EVENT_PRIMITIVE_CHANGE:
7752 mptsas_smhba_log_sysevent(mpt,
7753 ESC_SAS_HBA_PORT_BROADCAST,
7754 SAS_PORT_BROADCAST_CHANGE,
7755 &mpt->m_phy_info[phy_num].smhba_info);
7756 break;
7757 case MPI2_EVENT_PRIMITIVE_SES:
7758 mptsas_smhba_log_sysevent(mpt,
7759 ESC_SAS_HBA_PORT_BROADCAST,
7760 SAS_PORT_BROADCAST_SES,
7761 &mpt->m_phy_info[phy_num].smhba_info);
7762 break;
7763 case MPI2_EVENT_PRIMITIVE_EXPANDER:
7764 mptsas_smhba_log_sysevent(mpt,
7765 ESC_SAS_HBA_PORT_BROADCAST,
7766 SAS_PORT_BROADCAST_D01_4,
7767 &mpt->m_phy_info[phy_num].smhba_info);
7768 break;
7769 case MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT:
7770 mptsas_smhba_log_sysevent(mpt,
7771 ESC_SAS_HBA_PORT_BROADCAST,
7772 SAS_PORT_BROADCAST_D04_7,
7773 &mpt->m_phy_info[phy_num].smhba_info);
7774 break;
7775 case MPI2_EVENT_PRIMITIVE_RESERVED3:
7776 mptsas_smhba_log_sysevent(mpt,
7777 ESC_SAS_HBA_PORT_BROADCAST,
7778 SAS_PORT_BROADCAST_D16_7,
7779 &mpt->m_phy_info[phy_num].smhba_info);
7780 break;
7781 case MPI2_EVENT_PRIMITIVE_RESERVED4:
7782 mptsas_smhba_log_sysevent(mpt,
7783 ESC_SAS_HBA_PORT_BROADCAST,
7784 SAS_PORT_BROADCAST_D29_7,
7785 &mpt->m_phy_info[phy_num].smhba_info);
7786 break;
7787 case MPI2_EVENT_PRIMITIVE_CHANGE0_RESERVED:
7788 mptsas_smhba_log_sysevent(mpt,
7789 ESC_SAS_HBA_PORT_BROADCAST,
7790 SAS_PORT_BROADCAST_D24_0,
7791 &mpt->m_phy_info[phy_num].smhba_info);
7792 break;
7793 case MPI2_EVENT_PRIMITIVE_CHANGE1_RESERVED:
7794 mptsas_smhba_log_sysevent(mpt,
7795 ESC_SAS_HBA_PORT_BROADCAST,
7796 SAS_PORT_BROADCAST_D27_4,
7797 &mpt->m_phy_info[phy_num].smhba_info);
7798 break;
7799 default:
7800 NDBG16(("mptsas%d: unknown BROADCAST PRIMITIVE"
7801 " %x received",
7802 mpt->m_instance, primitive));
7803 break;
7804 }
7805 NDBG16(("mptsas%d sas broadcast primitive: "
7806 "\tprimitive(0x%04x), phy(%d) complete\n",
7807 mpt->m_instance, primitive, phy_num));
7808 break;
7809 }
7810 case MPI2_EVENT_IR_VOLUME:
7811 {
7812 Mpi2EventDataIrVolume_t *irVolume;
7813 uint16_t devhandle;
7814 uint32_t state;
7815 int config, vol;
7816 uint8_t found = FALSE;
7817
7818 irVolume = (pMpi2EventDataIrVolume_t)eventreply->EventData;
7819 state = ddi_get32(mpt->m_acc_reply_frame_hdl,
7820 &irVolume->NewValue);
7821 devhandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
7822 &irVolume->VolDevHandle);
7823
7824 NDBG20(("EVENT_IR_VOLUME event is received"));
7825
7826 /*
7827 * Get latest RAID info and then find the DevHandle for this
7828 * event in the configuration. If the DevHandle is not found
7829 * just exit the event.
7830 */
7831 (void) mptsas_get_raid_info(mpt);
7832 for (config = 0; (config < mpt->m_num_raid_configs) &&
7833 (!found); config++) {
7834 for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) {
7835 if (mpt->m_raidconfig[config].m_raidvol[vol].
7836 m_raidhandle == devhandle) {
7837 found = TRUE;
7838 break;
7839 }
7840 }
7841 }
7842 if (!found) {
7843 break;
7844 }
7845
7846 switch (irVolume->ReasonCode) {
7847 case MPI2_EVENT_IR_VOLUME_RC_SETTINGS_CHANGED:
7848 {
7849 uint32_t i;
7850 mpt->m_raidconfig[config].m_raidvol[vol].m_settings =
7851 state;
7852
7853 i = state & MPI2_RAIDVOL0_SETTING_MASK_WRITE_CACHING;
7854 mptsas_log(mpt, CE_NOTE, " Volume %d settings changed"
7855 ", auto-config of hot-swap drives is %s"
7856 ", write caching is %s"
7857 ", hot-spare pool mask is %02x\n",
7858 vol, state &
7859 MPI2_RAIDVOL0_SETTING_AUTO_CONFIG_HSWAP_DISABLE
7860 ? "disabled" : "enabled",
7861 i == MPI2_RAIDVOL0_SETTING_UNCHANGED
7862 ? "controlled by member disks" :
7863 i == MPI2_RAIDVOL0_SETTING_DISABLE_WRITE_CACHING
7864 ? "disabled" :
7865 i == MPI2_RAIDVOL0_SETTING_ENABLE_WRITE_CACHING
7866 ? "enabled" :
7867 "incorrectly set",
7868 (state >> 16) & 0xff);
7869 break;
7870 }
7871 case MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED:
7872 {
7873 mpt->m_raidconfig[config].m_raidvol[vol].m_state =
7874 (uint8_t)state;
7875
7876 mptsas_log(mpt, CE_NOTE,
7877 "Volume %d is now %s\n", vol,
7878 state == MPI2_RAID_VOL_STATE_OPTIMAL
7879 ? "optimal" :
7880 state == MPI2_RAID_VOL_STATE_DEGRADED
7881 ? "degraded" :
7882 state == MPI2_RAID_VOL_STATE_ONLINE
7883 ? "online" :
7884 state == MPI2_RAID_VOL_STATE_INITIALIZING
7885 ? "initializing" :
7886 state == MPI2_RAID_VOL_STATE_FAILED
7887 ? "failed" :
7888 state == MPI2_RAID_VOL_STATE_MISSING
7889 ? "missing" :
7890 "state unknown");
7891 break;
7892 }
7893 case MPI2_EVENT_IR_VOLUME_RC_STATUS_FLAGS_CHANGED:
7894 {
7895 mpt->m_raidconfig[config].m_raidvol[vol].
7896 m_statusflags = state;
7897
7898 mptsas_log(mpt, CE_NOTE,
7899 " Volume %d is now %s%s%s%s%s%s%s%s%s\n",
7900 vol,
7901 state & MPI2_RAIDVOL0_STATUS_FLAG_ENABLED
7902 ? ", enabled" : ", disabled",
7903 state & MPI2_RAIDVOL0_STATUS_FLAG_QUIESCED
7904 ? ", quiesced" : "",
7905 state & MPI2_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE
7906 ? ", inactive" : ", active",
7907 state &
7908 MPI2_RAIDVOL0_STATUS_FLAG_BAD_BLOCK_TABLE_FULL
7909 ? ", bad block table is full" : "",
7910 state &
7911 MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
7912 ? ", resync in progress" : "",
7913 state & MPI2_RAIDVOL0_STATUS_FLAG_BACKGROUND_INIT
7914 ? ", background initialization in progress" : "",
7915 state &
7916 MPI2_RAIDVOL0_STATUS_FLAG_CAPACITY_EXPANSION
7917 ? ", capacity expansion in progress" : "",
7918 state &
7919 MPI2_RAIDVOL0_STATUS_FLAG_CONSISTENCY_CHECK
7920 ? ", consistency check in progress" : "",
7921 state & MPI2_RAIDVOL0_STATUS_FLAG_DATA_SCRUB
7922 ? ", data scrub in progress" : "");
7923 break;
7924 }
7925 default:
7926 break;
7927 }
7928 break;
7929 }
7930 case MPI2_EVENT_IR_PHYSICAL_DISK:
7931 {
7932 Mpi2EventDataIrPhysicalDisk_t *irPhysDisk;
7933 uint16_t devhandle, enchandle, slot;
7934 uint32_t status, state;
7935 uint8_t physdisknum, reason;
7936
7937 irPhysDisk = (Mpi2EventDataIrPhysicalDisk_t *)
7938 eventreply->EventData;
7939 physdisknum = ddi_get8(mpt->m_acc_reply_frame_hdl,
7940 &irPhysDisk->PhysDiskNum);
7941 devhandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
7942 &irPhysDisk->PhysDiskDevHandle);
7943 enchandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
7944 &irPhysDisk->EnclosureHandle);
7945 slot = ddi_get16(mpt->m_acc_reply_frame_hdl,
7946 &irPhysDisk->Slot);
7947 state = ddi_get32(mpt->m_acc_reply_frame_hdl,
7948 &irPhysDisk->NewValue);
7949 reason = ddi_get8(mpt->m_acc_reply_frame_hdl,
7950 &irPhysDisk->ReasonCode);
7951
7952 NDBG20(("EVENT_IR_PHYSICAL_DISK event is received"));
7953
7954 switch (reason) {
7955 case MPI2_EVENT_IR_PHYSDISK_RC_SETTINGS_CHANGED:
7956 mptsas_log(mpt, CE_NOTE,
7957 " PhysDiskNum %d with DevHandle 0x%x in slot %d "
7958 "for enclosure with handle 0x%x is now in hot "
7959 "spare pool %d",
7960 physdisknum, devhandle, slot, enchandle,
7961 (state >> 16) & 0xff);
7962 break;
7963
7964 case MPI2_EVENT_IR_PHYSDISK_RC_STATUS_FLAGS_CHANGED:
7965 status = state;
7966 mptsas_log(mpt, CE_NOTE,
7967 " PhysDiskNum %d with DevHandle 0x%x in slot %d "
7968 "for enclosure with handle 0x%x is now "
7969 "%s%s%s%s%s\n", physdisknum, devhandle, slot,
7970 enchandle,
7971 status & MPI2_PHYSDISK0_STATUS_FLAG_INACTIVE_VOLUME
7972 ? ", inactive" : ", active",
7973 status & MPI2_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
7974 ? ", out of sync" : "",
7975 status & MPI2_PHYSDISK0_STATUS_FLAG_QUIESCED
7976 ? ", quiesced" : "",
7977 status &
7978 MPI2_PHYSDISK0_STATUS_FLAG_WRITE_CACHE_ENABLED
7979 ? ", write cache enabled" : "",
7980 status & MPI2_PHYSDISK0_STATUS_FLAG_OCE_TARGET
7981 ? ", capacity expansion target" : "");
7982 break;
7983
7984 case MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED:
7985 mptsas_log(mpt, CE_NOTE,
7986 " PhysDiskNum %d with DevHandle 0x%x in slot %d "
7987 "for enclosure with handle 0x%x is now %s\n",
7988 physdisknum, devhandle, slot, enchandle,
7989 state == MPI2_RAID_PD_STATE_OPTIMAL
7990 ? "optimal" :
7991 state == MPI2_RAID_PD_STATE_REBUILDING
7992 ? "rebuilding" :
7993 state == MPI2_RAID_PD_STATE_DEGRADED
7994 ? "degraded" :
7995 state == MPI2_RAID_PD_STATE_HOT_SPARE
7996 ? "a hot spare" :
7997 state == MPI2_RAID_PD_STATE_ONLINE
7998 ? "online" :
7999 state == MPI2_RAID_PD_STATE_OFFLINE
8000 ? "offline" :
8001 state == MPI2_RAID_PD_STATE_NOT_COMPATIBLE
8002 ? "not compatible" :
8003 state == MPI2_RAID_PD_STATE_NOT_CONFIGURED
8004 ? "not configured" :
8005 "state unknown");
8006 break;
8007 }
8008 break;
8009 }
8010 default:
8011 NDBG20(("mptsas%d: unknown event %x received",
8012 mpt->m_instance, event));
8013 break;
8014 }
8015
8016 /*
8017 * Return the reply frame to the free queue.
8018 */
8019 ddi_put32(mpt->m_acc_free_queue_hdl,
8020 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], rfm);
8021 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
8022 DDI_DMA_SYNC_FORDEV);
8023 if (++mpt->m_free_index == mpt->m_free_queue_depth) {
8024 mpt->m_free_index = 0;
8025 }
8026 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
8027 mpt->m_free_index);
8028 mutex_exit(&mpt->m_mutex);
8029 }
8030
8031 /*
8032 * invoked from timeout() to restart qfull cmds with throttle == 0
8033 */
8034 static void
8035 mptsas_restart_cmd(void *arg)
8036 {
8037 mptsas_t *mpt = arg;
8038 mptsas_target_t *ptgt = NULL;
8039
8040 mutex_enter(&mpt->m_mutex);
8041
8042 mpt->m_restart_cmd_timeid = 0;
8043
8044 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
8045 ptgt = refhash_next(mpt->m_targets, ptgt)) {
8046 if (ptgt->m_reset_delay == 0) {
8047 if (ptgt->m_t_throttle == QFULL_THROTTLE) {
8048 mptsas_set_throttle(mpt, ptgt,
8049 MAX_THROTTLE);
8050 }
8051 }
8052 }
8053 mptsas_restart_hba(mpt);
8054 mutex_exit(&mpt->m_mutex);
8055 }
8056
8057 void
8058 mptsas_remove_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
8059 {
8060 int slot;
8061 mptsas_slots_t *slots = mpt->m_active;
8062 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
8063
8064 ASSERT(cmd != NULL);
8065 ASSERT(cmd->cmd_queued == FALSE);
8066
8067 /*
8068 * Task Management cmds are removed in their own routines. Also,
8069 * we don't want to modify timeout based on TM cmds.
8070 */
8071 if (cmd->cmd_flags & CFLAG_TM_CMD) {
8072 return;
8073 }
8074
8075 slot = cmd->cmd_slot;
8076
8077 /*
8078 * remove the cmd.
8079 */
8080 if (cmd == slots->m_slot[slot]) {
8081 NDBG31(("mptsas_remove_cmd: removing cmd=0x%p, flags "
8082 "0x%x", (void *)cmd, cmd->cmd_flags));
8083 slots->m_slot[slot] = NULL;
8084 mpt->m_ncmds--;
8085
8086 /*
8087 * only decrement per target ncmds if command
8088 * has a target associated with it.
8089 */
8090 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) {
8091 ptgt->m_t_ncmds--;
8092 /*
8093 * reset throttle if we just ran an untagged command
8094 * to a tagged target
8095 */
8096 if ((ptgt->m_t_ncmds == 0) &&
8097 ((cmd->cmd_pkt_flags & FLAG_TAGMASK) == 0)) {
8098 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
8099 }
8100
8101 /*
8102 * Remove this command from the active queue.
8103 */
8104 if (cmd->cmd_active_expiration != 0) {
8105 TAILQ_REMOVE(&ptgt->m_active_cmdq, cmd,
8106 cmd_active_link);
8107 cmd->cmd_active_expiration = 0;
8108 }
8109 }
8110 }
8111
8112 /*
8113 * This is all we need to do for ioc commands.
8114 */
8115 if (cmd->cmd_flags & CFLAG_CMDIOC) {
8116 mptsas_return_to_pool(mpt, cmd);
8117 return;
8118 }
8119
8120 ASSERT(cmd != slots->m_slot[cmd->cmd_slot]);
8121 }
8122
8123 /*
8124 * accept all cmds on the tx_waitq if any and then
8125 * start a fresh request from the top of the device queue.
8126 *
8127 * since there are always cmds queued on the tx_waitq, and rare cmds on
8128 * the instance waitq, so this function should not be invoked in the ISR,
8129 * the mptsas_restart_waitq() is invoked in the ISR instead. otherwise, the
8130 * burden belongs to the IO dispatch CPUs is moved the interrupt CPU.
8131 */
8132 static void
8133 mptsas_restart_hba(mptsas_t *mpt)
8134 {
8135 ASSERT(mutex_owned(&mpt->m_mutex));
8136
8137 mutex_enter(&mpt->m_tx_waitq_mutex);
8138 if (mpt->m_tx_waitq) {
8139 mptsas_accept_tx_waitq(mpt);
8140 }
8141 mutex_exit(&mpt->m_tx_waitq_mutex);
8142 mptsas_restart_waitq(mpt);
8143 }
8144
8145 /*
8146 * start a fresh request from the top of the device queue
8147 */
8148 static void
8149 mptsas_restart_waitq(mptsas_t *mpt)
8150 {
8151 mptsas_cmd_t *cmd, *next_cmd;
8152 mptsas_target_t *ptgt = NULL;
8153
8154 NDBG1(("mptsas_restart_waitq: mpt=0x%p", (void *)mpt));
8155
8156 ASSERT(mutex_owned(&mpt->m_mutex));
8157
8158 /*
8159 * If there is a reset delay, don't start any cmds. Otherwise, start
8160 * as many cmds as possible.
8161 * Since SMID 0 is reserved and the TM slot is reserved, the actual max
8162 * commands is m_max_requests - 2.
8163 */
8164 cmd = mpt->m_waitq;
8165
8166 while (cmd != NULL) {
8167 next_cmd = cmd->cmd_linkp;
8168 if (cmd->cmd_flags & CFLAG_PASSTHRU) {
8169 if (mptsas_save_cmd(mpt, cmd) == TRUE) {
8170 /*
8171 * passthru command get slot need
8172 * set CFLAG_PREPARED.
8173 */
8174 cmd->cmd_flags |= CFLAG_PREPARED;
8175 mptsas_waitq_delete(mpt, cmd);
8176 mptsas_start_passthru(mpt, cmd);
8177 }
8178 cmd = next_cmd;
8179 continue;
8180 }
8181 if (cmd->cmd_flags & CFLAG_CONFIG) {
8182 if (mptsas_save_cmd(mpt, cmd) == TRUE) {
8183 /*
8184 * Send the config page request and delete it
8185 * from the waitq.
8186 */
8187 cmd->cmd_flags |= CFLAG_PREPARED;
8188 mptsas_waitq_delete(mpt, cmd);
8189 mptsas_start_config_page_access(mpt, cmd);
8190 }
8191 cmd = next_cmd;
8192 continue;
8193 }
8194 if (cmd->cmd_flags & CFLAG_FW_DIAG) {
8195 if (mptsas_save_cmd(mpt, cmd) == TRUE) {
8196 /*
8197 * Send the FW Diag request and delete if from
8198 * the waitq.
8199 */
8200 cmd->cmd_flags |= CFLAG_PREPARED;
8201 mptsas_waitq_delete(mpt, cmd);
8202 mptsas_start_diag(mpt, cmd);
8203 }
8204 cmd = next_cmd;
8205 continue;
8206 }
8207
8208 ptgt = cmd->cmd_tgt_addr;
8209 if (ptgt && (ptgt->m_t_throttle == DRAIN_THROTTLE) &&
8210 (ptgt->m_t_ncmds == 0)) {
8211 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
8212 }
8213 if ((mpt->m_ncmds <= (mpt->m_max_requests - 2)) &&
8214 (ptgt && (ptgt->m_reset_delay == 0)) &&
8215 (ptgt && (ptgt->m_t_ncmds <
8216 ptgt->m_t_throttle))) {
8217 if (mptsas_save_cmd(mpt, cmd) == TRUE) {
8218 mptsas_waitq_delete(mpt, cmd);
8219 (void) mptsas_start_cmd(mpt, cmd);
8220 }
8221 }
8222 cmd = next_cmd;
8223 }
8224 }
8225 /*
8226 * Cmds are queued if tran_start() doesn't get the m_mutexlock(no wait).
8227 * Accept all those queued cmds before new cmd is accept so that the
8228 * cmds are sent in order.
8229 */
8230 static void
8231 mptsas_accept_tx_waitq(mptsas_t *mpt)
8232 {
8233 mptsas_cmd_t *cmd;
8234
8235 ASSERT(mutex_owned(&mpt->m_mutex));
8236 ASSERT(mutex_owned(&mpt->m_tx_waitq_mutex));
8237
8238 /*
8239 * A Bus Reset could occur at any time and flush the tx_waitq,
8240 * so we cannot count on the tx_waitq to contain even one cmd.
8241 * And when the m_tx_waitq_mutex is released and run
8242 * mptsas_accept_pkt(), the tx_waitq may be flushed.
8243 */
8244 cmd = mpt->m_tx_waitq;
8245 for (;;) {
8246 if ((cmd = mpt->m_tx_waitq) == NULL) {
8247 mpt->m_tx_draining = 0;
8248 break;
8249 }
8250 if ((mpt->m_tx_waitq = cmd->cmd_linkp) == NULL) {
8251 mpt->m_tx_waitqtail = &mpt->m_tx_waitq;
8252 }
8253 cmd->cmd_linkp = NULL;
8254 mutex_exit(&mpt->m_tx_waitq_mutex);
8255 if (mptsas_accept_pkt(mpt, cmd) != TRAN_ACCEPT)
8256 cmn_err(CE_WARN, "mpt: mptsas_accept_tx_waitq: failed "
8257 "to accept cmd on queue\n");
8258 mutex_enter(&mpt->m_tx_waitq_mutex);
8259 }
8260 }
8261
8262
8263 /*
8264 * mpt tag type lookup
8265 */
8266 static char mptsas_tag_lookup[] =
8267 {0, MSG_HEAD_QTAG, MSG_ORDERED_QTAG, 0, MSG_SIMPLE_QTAG};
8268
8269 static int
8270 mptsas_start_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
8271 {
8272 struct scsi_pkt *pkt = CMD2PKT(cmd);
8273 uint32_t control = 0;
8274 caddr_t mem;
8275 pMpi2SCSIIORequest_t io_request;
8276 ddi_dma_handle_t dma_hdl = mpt->m_dma_req_frame_hdl;
8277 ddi_acc_handle_t acc_hdl = mpt->m_acc_req_frame_hdl;
8278 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
8279 uint16_t SMID, io_flags = 0;
8280 uint32_t request_desc_low, request_desc_high;
8281 mptsas_cmd_t *c;
8282
8283 NDBG1(("mptsas_start_cmd: cmd=0x%p, flags 0x%x", (void *)cmd,
8284 cmd->cmd_flags));
8285
8286 /*
8287 * Set SMID and increment index. Rollover to 1 instead of 0 if index
8288 * is at the max. 0 is an invalid SMID, so we call the first index 1.
8289 */
8290 SMID = cmd->cmd_slot;
8291
8292 /*
8293 * It is possible for back to back device reset to
8294 * happen before the reset delay has expired. That's
8295 * ok, just let the device reset go out on the bus.
8296 */
8297 if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) {
8298 ASSERT(ptgt->m_reset_delay == 0);
8299 }
8300
8301 /*
8302 * if a non-tagged cmd is submitted to an active tagged target
8303 * then drain before submitting this cmd; SCSI-2 allows RQSENSE
8304 * to be untagged
8305 */
8306 if (((cmd->cmd_pkt_flags & FLAG_TAGMASK) == 0) &&
8307 (ptgt->m_t_ncmds > 1) &&
8308 ((cmd->cmd_flags & CFLAG_TM_CMD) == 0) &&
8309 (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE)) {
8310 if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) {
8311 NDBG23(("target=%d, untagged cmd, start draining\n",
8312 ptgt->m_devhdl));
8313
8314 if (ptgt->m_reset_delay == 0) {
8315 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
8316 }
8317
8318 mptsas_remove_cmd(mpt, cmd);
8319 cmd->cmd_pkt_flags |= FLAG_HEAD;
8320 mptsas_waitq_add(mpt, cmd);
8321 }
8322 return (DDI_FAILURE);
8323 }
8324
8325 /*
8326 * Set correct tag bits.
8327 */
8328 if (cmd->cmd_pkt_flags & FLAG_TAGMASK) {
8329 switch (mptsas_tag_lookup[((cmd->cmd_pkt_flags &
8330 FLAG_TAGMASK) >> 12)]) {
8331 case MSG_SIMPLE_QTAG:
8332 control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
8333 break;
8334 case MSG_HEAD_QTAG:
8335 control |= MPI2_SCSIIO_CONTROL_HEADOFQ;
8336 break;
8337 case MSG_ORDERED_QTAG:
8338 control |= MPI2_SCSIIO_CONTROL_ORDEREDQ;
8339 break;
8340 default:
8341 mptsas_log(mpt, CE_WARN, "mpt: Invalid tag type\n");
8342 break;
8343 }
8344 } else {
8345 if (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE) {
8346 ptgt->m_t_throttle = 1;
8347 }
8348 control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
8349 }
8350
8351 if (cmd->cmd_pkt_flags & FLAG_TLR) {
8352 control |= MPI2_SCSIIO_CONTROL_TLR_ON;
8353 }
8354
8355 mem = mpt->m_req_frame + (mpt->m_req_frame_size * SMID);
8356 io_request = (pMpi2SCSIIORequest_t)mem;
8357
8358 bzero(io_request, sizeof (Mpi2SCSIIORequest_t));
8359 ddi_put8(acc_hdl, &io_request->SGLOffset0, offsetof
8360 (MPI2_SCSI_IO_REQUEST, SGL) / 4);
8361 mptsas_init_std_hdr(acc_hdl, io_request, ptgt->m_devhdl, Lun(cmd), 0,
8362 MPI2_FUNCTION_SCSI_IO_REQUEST);
8363
8364 (void) ddi_rep_put8(acc_hdl, (uint8_t *)pkt->pkt_cdbp,
8365 io_request->CDB.CDB32, cmd->cmd_cdblen, DDI_DEV_AUTOINCR);
8366
8367 io_flags = cmd->cmd_cdblen;
8368 if (mptsas_use_fastpath &&
8369 ptgt->m_io_flags & MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH) {
8370 io_flags |= MPI25_SCSIIO_IOFLAGS_FAST_PATH;
8371 request_desc_low = MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO;
8372 } else {
8373 request_desc_low = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO;
8374 }
8375 ddi_put16(acc_hdl, &io_request->IoFlags, io_flags);
8376 /*
8377 * setup the Scatter/Gather DMA list for this request
8378 */
8379 if (cmd->cmd_cookiec > 0) {
8380 mptsas_sge_setup(mpt, cmd, &control, io_request, acc_hdl);
8381 } else {
8382 ddi_put32(acc_hdl, &io_request->SGL.MpiSimple.FlagsLength,
8383 ((uint32_t)MPI2_SGE_FLAGS_LAST_ELEMENT |
8384 MPI2_SGE_FLAGS_END_OF_BUFFER |
8385 MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
8386 MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT);
8387 }
8388
8389 /*
8390 * save ARQ information
8391 */
8392 ddi_put8(acc_hdl, &io_request->SenseBufferLength, cmd->cmd_rqslen);
8393 if ((cmd->cmd_flags & (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) ==
8394 (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) {
8395 ddi_put32(acc_hdl, &io_request->SenseBufferLowAddress,
8396 cmd->cmd_ext_arqcookie.dmac_address);
8397 } else {
8398 ddi_put32(acc_hdl, &io_request->SenseBufferLowAddress,
8399 cmd->cmd_arqcookie.dmac_address);
8400 }
8401
8402 ddi_put32(acc_hdl, &io_request->Control, control);
8403
8404 NDBG31(("starting message=%d(0x%p), with cmd=0x%p",
8405 SMID, (void *)io_request, (void *)cmd));
8406
8407 (void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
8408
8409 /*
8410 * Build request descriptor and write it to the request desc post reg.
8411 */
8412 request_desc_low |= (SMID << 16);
8413 request_desc_high = ptgt->m_devhdl << 16;
8414 MPTSAS_START_CMD(mpt, request_desc_low, request_desc_high);
8415
8416 /*
8417 * Start timeout.
8418 */
8419 cmd->cmd_active_expiration =
8420 gethrtime() + (hrtime_t)pkt->pkt_time * NANOSEC;
8421 #ifdef MPTSAS_TEST
8422 /*
8423 * Force timeouts to happen immediately.
8424 */
8425 if (mptsas_test_timeouts)
8426 cmd->cmd_active_expiration = gethrtime();
8427 #endif
8428 c = TAILQ_FIRST(&ptgt->m_active_cmdq);
8429 if (c == NULL ||
8430 c->cmd_active_expiration < cmd->cmd_active_expiration) {
8431 /*
8432 * Common case is that this is the last pending expiration
8433 * (or queue is empty). Insert at head of the queue.
8434 */
8435 TAILQ_INSERT_HEAD(&ptgt->m_active_cmdq, cmd, cmd_active_link);
8436 } else {
8437 /*
8438 * Queue is not empty and first element expires later than
8439 * this command. Search for element expiring sooner.
8440 */
8441 while ((c = TAILQ_NEXT(c, cmd_active_link)) != NULL) {
8442 if (c->cmd_active_expiration <
8443 cmd->cmd_active_expiration) {
8444 TAILQ_INSERT_BEFORE(c, cmd, cmd_active_link);
8445 break;
8446 }
8447 }
8448 if (c == NULL) {
8449 /*
8450 * No element found expiring sooner, append to
8451 * non-empty queue.
8452 */
8453 TAILQ_INSERT_TAIL(&ptgt->m_active_cmdq, cmd,
8454 cmd_active_link);
8455 }
8456 }
8457
8458 if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) ||
8459 (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) {
8460 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
8461 return (DDI_FAILURE);
8462 }
8463 return (DDI_SUCCESS);
8464 }
8465
8466 /*
8467 * Select a helper thread to handle current doneq
8468 */
8469 static void
8470 mptsas_deliver_doneq_thread(mptsas_t *mpt)
8471 {
8472 uint64_t t, i;
8473 uint32_t min = 0xffffffff;
8474 mptsas_doneq_thread_list_t *item;
8475
8476 for (i = 0; i < mpt->m_doneq_thread_n; i++) {
8477 item = &mpt->m_doneq_thread_id[i];
8478 /*
8479 * If the completed command on help thread[i] less than
8480 * doneq_thread_threshold, then pick the thread[i]. Otherwise
8481 * pick a thread which has least completed command.
8482 */
8483
8484 mutex_enter(&item->mutex);
8485 if (item->len < mpt->m_doneq_thread_threshold) {
8486 t = i;
8487 mutex_exit(&item->mutex);
8488 break;
8489 }
8490 if (item->len < min) {
8491 min = item->len;
8492 t = i;
8493 }
8494 mutex_exit(&item->mutex);
8495 }
8496 mutex_enter(&mpt->m_doneq_thread_id[t].mutex);
8497 mptsas_doneq_mv(mpt, t);
8498 cv_signal(&mpt->m_doneq_thread_id[t].cv);
8499 mutex_exit(&mpt->m_doneq_thread_id[t].mutex);
8500 }
8501
8502 /*
8503 * move the current global doneq to the doneq of thead[t]
8504 */
8505 static void
8506 mptsas_doneq_mv(mptsas_t *mpt, uint64_t t)
8507 {
8508 mptsas_cmd_t *cmd;
8509 mptsas_doneq_thread_list_t *item = &mpt->m_doneq_thread_id[t];
8510
8511 ASSERT(mutex_owned(&item->mutex));
8512 while ((cmd = mpt->m_doneq) != NULL) {
8513 if ((mpt->m_doneq = cmd->cmd_linkp) == NULL) {
8514 mpt->m_donetail = &mpt->m_doneq;
8515 }
8516 cmd->cmd_linkp = NULL;
8517 *item->donetail = cmd;
8518 item->donetail = &cmd->cmd_linkp;
8519 mpt->m_doneq_len--;
8520 item->len++;
8521 }
8522 }
8523
8524 void
8525 mptsas_fma_check(mptsas_t *mpt, mptsas_cmd_t *cmd)
8526 {
8527 struct scsi_pkt *pkt = CMD2PKT(cmd);
8528
8529 /* Check all acc and dma handles */
8530 if ((mptsas_check_acc_handle(mpt->m_datap) !=
8531 DDI_SUCCESS) ||
8532 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) !=
8533 DDI_SUCCESS) ||
8534 (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl) !=
8535 DDI_SUCCESS) ||
8536 (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl) !=
8537 DDI_SUCCESS) ||
8538 (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl) !=
8539 DDI_SUCCESS) ||
8540 (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl) !=
8541 DDI_SUCCESS) ||
8542 (mptsas_check_acc_handle(mpt->m_config_handle) !=
8543 DDI_SUCCESS)) {
8544 ddi_fm_service_impact(mpt->m_dip,
8545 DDI_SERVICE_UNAFFECTED);
8546 ddi_fm_acc_err_clear(mpt->m_config_handle,
8547 DDI_FME_VER0);
8548 pkt->pkt_reason = CMD_TRAN_ERR;
8549 pkt->pkt_statistics = 0;
8550 }
8551 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) !=
8552 DDI_SUCCESS) ||
8553 (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl) !=
8554 DDI_SUCCESS) ||
8555 (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl) !=
8556 DDI_SUCCESS) ||
8557 (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) !=
8558 DDI_SUCCESS) ||
8559 (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl) !=
8560 DDI_SUCCESS)) {
8561 ddi_fm_service_impact(mpt->m_dip,
8562 DDI_SERVICE_UNAFFECTED);
8563 pkt->pkt_reason = CMD_TRAN_ERR;
8564 pkt->pkt_statistics = 0;
8565 }
8566 if (cmd->cmd_dmahandle &&
8567 (mptsas_check_dma_handle(cmd->cmd_dmahandle) != DDI_SUCCESS)) {
8568 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
8569 pkt->pkt_reason = CMD_TRAN_ERR;
8570 pkt->pkt_statistics = 0;
8571 }
8572 if ((cmd->cmd_extra_frames &&
8573 ((mptsas_check_dma_handle(cmd->cmd_extra_frames->m_dma_hdl) !=
8574 DDI_SUCCESS) ||
8575 (mptsas_check_acc_handle(cmd->cmd_extra_frames->m_acc_hdl) !=
8576 DDI_SUCCESS)))) {
8577 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
8578 pkt->pkt_reason = CMD_TRAN_ERR;
8579 pkt->pkt_statistics = 0;
8580 }
8581 if (cmd->cmd_arqhandle &&
8582 (mptsas_check_dma_handle(cmd->cmd_arqhandle) != DDI_SUCCESS)) {
8583 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
8584 pkt->pkt_reason = CMD_TRAN_ERR;
8585 pkt->pkt_statistics = 0;
8586 }
8587 if (cmd->cmd_ext_arqhandle &&
8588 (mptsas_check_dma_handle(cmd->cmd_ext_arqhandle) != DDI_SUCCESS)) {
8589 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
8590 pkt->pkt_reason = CMD_TRAN_ERR;
8591 pkt->pkt_statistics = 0;
8592 }
8593 }
8594
8595 /*
8596 * These routines manipulate the queue of commands that
8597 * are waiting for their completion routines to be called.
8598 * The queue is usually in FIFO order but on an MP system
8599 * it's possible for the completion routines to get out
8600 * of order. If that's a problem you need to add a global
8601 * mutex around the code that calls the completion routine
8602 * in the interrupt handler.
8603 */
8604 static void
8605 mptsas_doneq_add(mptsas_t *mpt, mptsas_cmd_t *cmd)
8606 {
8607 struct scsi_pkt *pkt = CMD2PKT(cmd);
8608
8609 NDBG31(("mptsas_doneq_add: cmd=0x%p", (void *)cmd));
8610
8611 ASSERT((cmd->cmd_flags & CFLAG_COMPLETED) == 0);
8612 cmd->cmd_linkp = NULL;
8613 cmd->cmd_flags |= CFLAG_FINISHED;
8614 cmd->cmd_flags &= ~CFLAG_IN_TRANSPORT;
8615
8616 mptsas_fma_check(mpt, cmd);
8617
8618 /*
8619 * only add scsi pkts that have completion routines to
8620 * the doneq. no intr cmds do not have callbacks.
8621 */
8622 if (pkt && (pkt->pkt_comp)) {
8623 *mpt->m_donetail = cmd;
8624 mpt->m_donetail = &cmd->cmd_linkp;
8625 mpt->m_doneq_len++;
8626 }
8627 }
8628
8629 static mptsas_cmd_t *
8630 mptsas_doneq_thread_rm(mptsas_t *mpt, uint64_t t)
8631 {
8632 mptsas_cmd_t *cmd;
8633 mptsas_doneq_thread_list_t *item = &mpt->m_doneq_thread_id[t];
8634
8635 /* pop one off the done queue */
8636 if ((cmd = item->doneq) != NULL) {
8637 /* if the queue is now empty fix the tail pointer */
8638 NDBG31(("mptsas_doneq_thread_rm: cmd=0x%p", (void *)cmd));
8639 if ((item->doneq = cmd->cmd_linkp) == NULL) {
8640 item->donetail = &item->doneq;
8641 }
8642 cmd->cmd_linkp = NULL;
8643 item->len--;
8644 }
8645 return (cmd);
8646 }
8647
8648 static void
8649 mptsas_doneq_empty(mptsas_t *mpt)
8650 {
8651 if (mpt->m_doneq && !mpt->m_in_callback) {
8652 mptsas_cmd_t *cmd, *next;
8653 struct scsi_pkt *pkt;
8654
8655 mpt->m_in_callback = 1;
8656 cmd = mpt->m_doneq;
8657 mpt->m_doneq = NULL;
8658 mpt->m_donetail = &mpt->m_doneq;
8659 mpt->m_doneq_len = 0;
8660
8661 mutex_exit(&mpt->m_mutex);
8662 /*
8663 * run the completion routines of all the
8664 * completed commands
8665 */
8666 while (cmd != NULL) {
8667 next = cmd->cmd_linkp;
8668 cmd->cmd_linkp = NULL;
8669 /* run this command's completion routine */
8670 cmd->cmd_flags |= CFLAG_COMPLETED;
8671 pkt = CMD2PKT(cmd);
8672 mptsas_pkt_comp(pkt, cmd);
8673 cmd = next;
8674 }
8675 mutex_enter(&mpt->m_mutex);
8676 mpt->m_in_callback = 0;
8677 }
8678 }
8679
8680 /*
8681 * These routines manipulate the target's queue of pending requests
8682 */
8683 void
8684 mptsas_waitq_add(mptsas_t *mpt, mptsas_cmd_t *cmd)
8685 {
8686 NDBG7(("mptsas_waitq_add: cmd=0x%p", (void *)cmd));
8687 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
8688 cmd->cmd_queued = TRUE;
8689 if (ptgt)
8690 ptgt->m_t_nwait++;
8691 if (cmd->cmd_pkt_flags & FLAG_HEAD) {
8692 if ((cmd->cmd_linkp = mpt->m_waitq) == NULL) {
8693 mpt->m_waitqtail = &cmd->cmd_linkp;
8694 }
8695 mpt->m_waitq = cmd;
8696 } else {
8697 cmd->cmd_linkp = NULL;
8698 *(mpt->m_waitqtail) = cmd;
8699 mpt->m_waitqtail = &cmd->cmd_linkp;
8700 }
8701 }
8702
8703 static mptsas_cmd_t *
8704 mptsas_waitq_rm(mptsas_t *mpt)
8705 {
8706 mptsas_cmd_t *cmd;
8707 mptsas_target_t *ptgt;
8708 NDBG7(("mptsas_waitq_rm"));
8709
8710 MPTSAS_WAITQ_RM(mpt, cmd);
8711
8712 NDBG7(("mptsas_waitq_rm: cmd=0x%p", (void *)cmd));
8713 if (cmd) {
8714 ptgt = cmd->cmd_tgt_addr;
8715 if (ptgt) {
8716 ptgt->m_t_nwait--;
8717 ASSERT(ptgt->m_t_nwait >= 0);
8718 }
8719 }
8720 return (cmd);
8721 }
8722
8723 /*
8724 * remove specified cmd from the middle of the wait queue.
8725 */
8726 static void
8727 mptsas_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd)
8728 {
8729 mptsas_cmd_t *prevp = mpt->m_waitq;
8730 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
8731
8732 NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p",
8733 (void *)mpt, (void *)cmd));
8734 if (ptgt) {
8735 ptgt->m_t_nwait--;
8736 ASSERT(ptgt->m_t_nwait >= 0);
8737 }
8738
8739 if (prevp == cmd) {
8740 if ((mpt->m_waitq = cmd->cmd_linkp) == NULL)
8741 mpt->m_waitqtail = &mpt->m_waitq;
8742
8743 cmd->cmd_linkp = NULL;
8744 cmd->cmd_queued = FALSE;
8745 NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p",
8746 (void *)mpt, (void *)cmd));
8747 return;
8748 }
8749
8750 while (prevp != NULL) {
8751 if (prevp->cmd_linkp == cmd) {
8752 if ((prevp->cmd_linkp = cmd->cmd_linkp) == NULL)
8753 mpt->m_waitqtail = &prevp->cmd_linkp;
8754
8755 cmd->cmd_linkp = NULL;
8756 cmd->cmd_queued = FALSE;
8757 NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p",
8758 (void *)mpt, (void *)cmd));
8759 return;
8760 }
8761 prevp = prevp->cmd_linkp;
8762 }
8763 cmn_err(CE_PANIC, "mpt: mptsas_waitq_delete: queue botch");
8764 }
8765
8766 static mptsas_cmd_t *
8767 mptsas_tx_waitq_rm(mptsas_t *mpt)
8768 {
8769 mptsas_cmd_t *cmd;
8770 NDBG7(("mptsas_tx_waitq_rm"));
8771
8772 MPTSAS_TX_WAITQ_RM(mpt, cmd);
8773
8774 NDBG7(("mptsas_tx_waitq_rm: cmd=0x%p", (void *)cmd));
8775
8776 return (cmd);
8777 }
8778
8779 /*
8780 * remove specified cmd from the middle of the tx_waitq.
8781 */
8782 static void
8783 mptsas_tx_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd)
8784 {
8785 mptsas_cmd_t *prevp = mpt->m_tx_waitq;
8786
8787 NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p",
8788 (void *)mpt, (void *)cmd));
8789
8790 if (prevp == cmd) {
8791 if ((mpt->m_tx_waitq = cmd->cmd_linkp) == NULL)
8792 mpt->m_tx_waitqtail = &mpt->m_tx_waitq;
8793
8794 cmd->cmd_linkp = NULL;
8795 cmd->cmd_queued = FALSE;
8796 NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p",
8797 (void *)mpt, (void *)cmd));
8798 return;
8799 }
8800
8801 while (prevp != NULL) {
8802 if (prevp->cmd_linkp == cmd) {
8803 if ((prevp->cmd_linkp = cmd->cmd_linkp) == NULL)
8804 mpt->m_tx_waitqtail = &prevp->cmd_linkp;
8805
8806 cmd->cmd_linkp = NULL;
8807 cmd->cmd_queued = FALSE;
8808 NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p",
8809 (void *)mpt, (void *)cmd));
8810 return;
8811 }
8812 prevp = prevp->cmd_linkp;
8813 }
8814 cmn_err(CE_PANIC, "mpt: mptsas_tx_waitq_delete: queue botch");
8815 }
8816
8817 /*
8818 * device and bus reset handling
8819 *
8820 * Notes:
8821 * - RESET_ALL: reset the controller
8822 * - RESET_TARGET: reset the target specified in scsi_address
8823 */
8824 static int
8825 mptsas_scsi_reset(struct scsi_address *ap, int level)
8826 {
8827 mptsas_t *mpt = ADDR2MPT(ap);
8828 int rval;
8829 mptsas_tgt_private_t *tgt_private;
8830 mptsas_target_t *ptgt = NULL;
8831
8832 tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran->tran_tgt_private;
8833 ptgt = tgt_private->t_private;
8834 if (ptgt == NULL) {
8835 return (FALSE);
8836 }
8837 NDBG22(("mptsas_scsi_reset: target=%d level=%d", ptgt->m_devhdl,
8838 level));
8839
8840 mutex_enter(&mpt->m_mutex);
8841 /*
8842 * if we are not in panic set up a reset delay for this target
8843 */
8844 if (!ddi_in_panic()) {
8845 mptsas_setup_bus_reset_delay(mpt);
8846 } else {
8847 drv_usecwait(mpt->m_scsi_reset_delay * 1000);
8848 }
8849 rval = mptsas_do_scsi_reset(mpt, ptgt->m_devhdl);
8850 mutex_exit(&mpt->m_mutex);
8851
8852 /*
8853 * The transport layer expect to only see TRUE and
8854 * FALSE. Therefore, we will adjust the return value
8855 * if mptsas_do_scsi_reset returns FAILED.
8856 */
8857 if (rval == FAILED)
8858 rval = FALSE;
8859 return (rval);
8860 }
8861
8862 static int
8863 mptsas_do_scsi_reset(mptsas_t *mpt, uint16_t devhdl)
8864 {
8865 int rval = FALSE;
8866 uint8_t config, disk;
8867
8868 ASSERT(mutex_owned(&mpt->m_mutex));
8869
8870 if (mptsas_debug_resets) {
8871 mptsas_log(mpt, CE_WARN, "mptsas_do_scsi_reset: target=%d",
8872 devhdl);
8873 }
8874
8875 /*
8876 * Issue a Target Reset message to the target specified but not to a
8877 * disk making up a raid volume. Just look through the RAID config
8878 * Phys Disk list of DevHandles. If the target's DevHandle is in this
8879 * list, then don't reset this target.
8880 */
8881 for (config = 0; config < mpt->m_num_raid_configs; config++) {
8882 for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) {
8883 if (devhdl == mpt->m_raidconfig[config].
8884 m_physdisk_devhdl[disk]) {
8885 return (TRUE);
8886 }
8887 }
8888 }
8889
8890 rval = mptsas_ioc_task_management(mpt,
8891 MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, devhdl, 0, NULL, 0, 0);
8892
8893 mptsas_doneq_empty(mpt);
8894 return (rval);
8895 }
8896
8897 static int
8898 mptsas_scsi_reset_notify(struct scsi_address *ap, int flag,
8899 void (*callback)(caddr_t), caddr_t arg)
8900 {
8901 mptsas_t *mpt = ADDR2MPT(ap);
8902
8903 NDBG22(("mptsas_scsi_reset_notify: tgt=%d", ap->a_target));
8904
8905 return (scsi_hba_reset_notify_setup(ap, flag, callback, arg,
8906 &mpt->m_mutex, &mpt->m_reset_notify_listf));
8907 }
8908
8909 static int
8910 mptsas_get_name(struct scsi_device *sd, char *name, int len)
8911 {
8912 dev_info_t *lun_dip = NULL;
8913
8914 ASSERT(sd != NULL);
8915 ASSERT(name != NULL);
8916 lun_dip = sd->sd_dev;
8917 ASSERT(lun_dip != NULL);
8918
8919 if (mptsas_name_child(lun_dip, name, len) == DDI_SUCCESS) {
8920 return (1);
8921 } else {
8922 return (0);
8923 }
8924 }
8925
8926 static int
8927 mptsas_get_bus_addr(struct scsi_device *sd, char *name, int len)
8928 {
8929 return (mptsas_get_name(sd, name, len));
8930 }
8931
8932 void
8933 mptsas_set_throttle(mptsas_t *mpt, mptsas_target_t *ptgt, int what)
8934 {
8935
8936 NDBG25(("mptsas_set_throttle: throttle=%x", what));
8937
8938 /*
8939 * if the bus is draining/quiesced, no changes to the throttles
8940 * are allowed. Not allowing change of throttles during draining
8941 * limits error recovery but will reduce draining time
8942 *
8943 * all throttles should have been set to HOLD_THROTTLE
8944 */
8945 if (mpt->m_softstate & (MPTSAS_SS_QUIESCED | MPTSAS_SS_DRAINING)) {
8946 return;
8947 }
8948
8949 if (what == HOLD_THROTTLE) {
8950 ptgt->m_t_throttle = HOLD_THROTTLE;
8951 } else if (ptgt->m_reset_delay == 0) {
8952 ptgt->m_t_throttle = what;
8953 }
8954 }
8955
8956 /*
8957 * Clean up from a device reset.
8958 * For the case of target reset, this function clears the waitq of all
8959 * commands for a particular target. For the case of abort task set, this
8960 * function clears the waitq of all commonds for a particular target/lun.
8961 */
8962 static void
8963 mptsas_flush_target(mptsas_t *mpt, ushort_t target, int lun, uint8_t tasktype)
8964 {
8965 mptsas_slots_t *slots = mpt->m_active;
8966 mptsas_cmd_t *cmd, *next_cmd;
8967 int slot;
8968 uchar_t reason;
8969 uint_t stat;
8970 hrtime_t timestamp;
8971
8972 NDBG25(("mptsas_flush_target: target=%d lun=%d", target, lun));
8973
8974 timestamp = gethrtime();
8975
8976 /*
8977 * Make sure the I/O Controller has flushed all cmds
8978 * that are associated with this target for a target reset
8979 * and target/lun for abort task set.
8980 * Account for TM requests, which use the last SMID.
8981 */
8982 for (slot = 0; slot <= mpt->m_active->m_n_normal; slot++) {
8983 if ((cmd = slots->m_slot[slot]) == NULL)
8984 continue;
8985 reason = CMD_RESET;
8986 stat = STAT_DEV_RESET;
8987 switch (tasktype) {
8988 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
8989 if (Tgt(cmd) == target) {
8990 if (cmd->cmd_active_expiration <= timestamp) {
8991 /*
8992 * When timeout requested, propagate
8993 * proper reason and statistics to
8994 * target drivers.
8995 */
8996 reason = CMD_TIMEOUT;
8997 stat |= STAT_TIMEOUT;
8998 }
8999 NDBG25(("mptsas_flush_target discovered non-"
9000 "NULL cmd in slot %d, tasktype 0x%x", slot,
9001 tasktype));
9002 mptsas_dump_cmd(mpt, cmd);
9003 mptsas_remove_cmd(mpt, cmd);
9004 mptsas_set_pkt_reason(mpt, cmd, reason, stat);
9005 mptsas_doneq_add(mpt, cmd);
9006 }
9007 break;
9008 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
9009 reason = CMD_ABORTED;
9010 stat = STAT_ABORTED;
9011 /*FALLTHROUGH*/
9012 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
9013 if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) {
9014
9015 NDBG25(("mptsas_flush_target discovered non-"
9016 "NULL cmd in slot %d, tasktype 0x%x", slot,
9017 tasktype));
9018 mptsas_dump_cmd(mpt, cmd);
9019 mptsas_remove_cmd(mpt, cmd);
9020 mptsas_set_pkt_reason(mpt, cmd, reason,
9021 stat);
9022 mptsas_doneq_add(mpt, cmd);
9023 }
9024 break;
9025 default:
9026 break;
9027 }
9028 }
9029
9030 /*
9031 * Flush the waitq and tx_waitq of this target's cmds
9032 */
9033 cmd = mpt->m_waitq;
9034
9035 reason = CMD_RESET;
9036 stat = STAT_DEV_RESET;
9037
9038 switch (tasktype) {
9039 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
9040 while (cmd != NULL) {
9041 next_cmd = cmd->cmd_linkp;
9042 if (Tgt(cmd) == target) {
9043 mptsas_waitq_delete(mpt, cmd);
9044 mptsas_set_pkt_reason(mpt, cmd,
9045 reason, stat);
9046 mptsas_doneq_add(mpt, cmd);
9047 }
9048 cmd = next_cmd;
9049 }
9050 mutex_enter(&mpt->m_tx_waitq_mutex);
9051 cmd = mpt->m_tx_waitq;
9052 while (cmd != NULL) {
9053 next_cmd = cmd->cmd_linkp;
9054 if (Tgt(cmd) == target) {
9055 mptsas_tx_waitq_delete(mpt, cmd);
9056 mutex_exit(&mpt->m_tx_waitq_mutex);
9057 mptsas_set_pkt_reason(mpt, cmd,
9058 reason, stat);
9059 mptsas_doneq_add(mpt, cmd);
9060 mutex_enter(&mpt->m_tx_waitq_mutex);
9061 }
9062 cmd = next_cmd;
9063 }
9064 mutex_exit(&mpt->m_tx_waitq_mutex);
9065 break;
9066 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
9067 reason = CMD_ABORTED;
9068 stat = STAT_ABORTED;
9069 /*FALLTHROUGH*/
9070 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
9071 while (cmd != NULL) {
9072 next_cmd = cmd->cmd_linkp;
9073 if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) {
9074 mptsas_waitq_delete(mpt, cmd);
9075 mptsas_set_pkt_reason(mpt, cmd,
9076 reason, stat);
9077 mptsas_doneq_add(mpt, cmd);
9078 }
9079 cmd = next_cmd;
9080 }
9081 mutex_enter(&mpt->m_tx_waitq_mutex);
9082 cmd = mpt->m_tx_waitq;
9083 while (cmd != NULL) {
9084 next_cmd = cmd->cmd_linkp;
9085 if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) {
9086 mptsas_tx_waitq_delete(mpt, cmd);
9087 mutex_exit(&mpt->m_tx_waitq_mutex);
9088 mptsas_set_pkt_reason(mpt, cmd,
9089 reason, stat);
9090 mptsas_doneq_add(mpt, cmd);
9091 mutex_enter(&mpt->m_tx_waitq_mutex);
9092 }
9093 cmd = next_cmd;
9094 }
9095 mutex_exit(&mpt->m_tx_waitq_mutex);
9096 break;
9097 default:
9098 mptsas_log(mpt, CE_WARN, "Unknown task management type %d.",
9099 tasktype);
9100 break;
9101 }
9102 }
9103
9104 /*
9105 * Clean up hba state, abort all outstanding command and commands in waitq
9106 * reset timeout of all targets.
9107 */
9108 static void
9109 mptsas_flush_hba(mptsas_t *mpt)
9110 {
9111 mptsas_slots_t *slots = mpt->m_active;
9112 mptsas_cmd_t *cmd;
9113 int slot;
9114
9115 NDBG25(("mptsas_flush_hba"));
9116
9117 /*
9118 * The I/O Controller should have already sent back
9119 * all commands via the scsi I/O reply frame. Make
9120 * sure all commands have been flushed.
9121 * Account for TM request, which use the last SMID.
9122 */
9123 for (slot = 0; slot <= mpt->m_active->m_n_normal; slot++) {
9124 if ((cmd = slots->m_slot[slot]) == NULL)
9125 continue;
9126
9127 if (cmd->cmd_flags & CFLAG_CMDIOC) {
9128 /*
9129 * Need to make sure to tell everyone that might be
9130 * waiting on this command that it's going to fail. If
9131 * we get here, this command will never timeout because
9132 * the active command table is going to be re-allocated,
9133 * so there will be nothing to check against a time out.
9134 * Instead, mark the command as failed due to reset.
9135 */
9136 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET,
9137 STAT_BUS_RESET);
9138 if ((cmd->cmd_flags &
9139 (CFLAG_PASSTHRU | CFLAG_CONFIG | CFLAG_FW_DIAG))) {
9140 cmd->cmd_flags |= CFLAG_FINISHED;
9141 cv_broadcast(&mpt->m_passthru_cv);
9142 cv_broadcast(&mpt->m_config_cv);
9143 cv_broadcast(&mpt->m_fw_diag_cv);
9144 }
9145 continue;
9146 }
9147
9148 NDBG25(("mptsas_flush_hba discovered non-NULL cmd in slot %d",
9149 slot));
9150 mptsas_dump_cmd(mpt, cmd);
9151
9152 mptsas_remove_cmd(mpt, cmd);
9153 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET);
9154 mptsas_doneq_add(mpt, cmd);
9155 }
9156
9157 /*
9158 * Flush the waitq.
9159 */
9160 while ((cmd = mptsas_waitq_rm(mpt)) != NULL) {
9161 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET);
9162 if ((cmd->cmd_flags & CFLAG_PASSTHRU) ||
9163 (cmd->cmd_flags & CFLAG_CONFIG) ||
9164 (cmd->cmd_flags & CFLAG_FW_DIAG)) {
9165 cmd->cmd_flags |= CFLAG_FINISHED;
9166 cv_broadcast(&mpt->m_passthru_cv);
9167 cv_broadcast(&mpt->m_config_cv);
9168 cv_broadcast(&mpt->m_fw_diag_cv);
9169 } else {
9170 mptsas_doneq_add(mpt, cmd);
9171 }
9172 }
9173
9174 /*
9175 * Flush the tx_waitq
9176 */
9177 mutex_enter(&mpt->m_tx_waitq_mutex);
9178 while ((cmd = mptsas_tx_waitq_rm(mpt)) != NULL) {
9179 mutex_exit(&mpt->m_tx_waitq_mutex);
9180 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET);
9181 mptsas_doneq_add(mpt, cmd);
9182 mutex_enter(&mpt->m_tx_waitq_mutex);
9183 }
9184 mutex_exit(&mpt->m_tx_waitq_mutex);
9185
9186 /*
9187 * Drain the taskqs prior to reallocating resources.
9188 */
9189 mutex_exit(&mpt->m_mutex);
9190 ddi_taskq_wait(mpt->m_event_taskq);
9191 ddi_taskq_wait(mpt->m_dr_taskq);
9192 mutex_enter(&mpt->m_mutex);
9193 }
9194
9195 /*
9196 * set pkt_reason and OR in pkt_statistics flag
9197 */
9198 static void
9199 mptsas_set_pkt_reason(mptsas_t *mpt, mptsas_cmd_t *cmd, uchar_t reason,
9200 uint_t stat)
9201 {
9202 #ifndef __lock_lint
9203 _NOTE(ARGUNUSED(mpt))
9204 #endif
9205
9206 NDBG25(("mptsas_set_pkt_reason: cmd=0x%p reason=%x stat=%x",
9207 (void *)cmd, reason, stat));
9208
9209 if (cmd) {
9210 if (cmd->cmd_pkt->pkt_reason == CMD_CMPLT) {
9211 cmd->cmd_pkt->pkt_reason = reason;
9212 }
9213 cmd->cmd_pkt->pkt_statistics |= stat;
9214 }
9215 }
9216
9217 static void
9218 mptsas_start_watch_reset_delay()
9219 {
9220 NDBG22(("mptsas_start_watch_reset_delay"));
9221
9222 mutex_enter(&mptsas_global_mutex);
9223 if (mptsas_reset_watch == NULL && mptsas_timeouts_enabled) {
9224 mptsas_reset_watch = timeout(mptsas_watch_reset_delay, NULL,
9225 drv_usectohz((clock_t)
9226 MPTSAS_WATCH_RESET_DELAY_TICK * 1000));
9227 ASSERT(mptsas_reset_watch != NULL);
9228 }
9229 mutex_exit(&mptsas_global_mutex);
9230 }
9231
9232 static void
9233 mptsas_setup_bus_reset_delay(mptsas_t *mpt)
9234 {
9235 mptsas_target_t *ptgt = NULL;
9236
9237 ASSERT(MUTEX_HELD(&mpt->m_mutex));
9238
9239 NDBG22(("mptsas_setup_bus_reset_delay"));
9240 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
9241 ptgt = refhash_next(mpt->m_targets, ptgt)) {
9242 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
9243 ptgt->m_reset_delay = mpt->m_scsi_reset_delay;
9244 }
9245
9246 mptsas_start_watch_reset_delay();
9247 }
9248
9249 /*
9250 * mptsas_watch_reset_delay(_subr) is invoked by timeout() and checks every
9251 * mpt instance for active reset delays
9252 */
9253 static void
9254 mptsas_watch_reset_delay(void *arg)
9255 {
9256 #ifndef __lock_lint
9257 _NOTE(ARGUNUSED(arg))
9258 #endif
9259
9260 mptsas_t *mpt;
9261 int not_done = 0;
9262
9263 NDBG22(("mptsas_watch_reset_delay"));
9264
9265 mutex_enter(&mptsas_global_mutex);
9266 mptsas_reset_watch = 0;
9267 mutex_exit(&mptsas_global_mutex);
9268 rw_enter(&mptsas_global_rwlock, RW_READER);
9269 for (mpt = mptsas_head; mpt != NULL; mpt = mpt->m_next) {
9270 if (mpt->m_tran == 0) {
9271 continue;
9272 }
9273 mutex_enter(&mpt->m_mutex);
9274 not_done += mptsas_watch_reset_delay_subr(mpt);
9275 mutex_exit(&mpt->m_mutex);
9276 }
9277 rw_exit(&mptsas_global_rwlock);
9278
9279 if (not_done) {
9280 mptsas_start_watch_reset_delay();
9281 }
9282 }
9283
9284 static int
9285 mptsas_watch_reset_delay_subr(mptsas_t *mpt)
9286 {
9287 int done = 0;
9288 int restart = 0;
9289 mptsas_target_t *ptgt = NULL;
9290
9291 NDBG22(("mptsas_watch_reset_delay_subr: mpt=0x%p", (void *)mpt));
9292
9293 ASSERT(mutex_owned(&mpt->m_mutex));
9294
9295 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
9296 ptgt = refhash_next(mpt->m_targets, ptgt)) {
9297 if (ptgt->m_reset_delay != 0) {
9298 ptgt->m_reset_delay -=
9299 MPTSAS_WATCH_RESET_DELAY_TICK;
9300 if (ptgt->m_reset_delay <= 0) {
9301 ptgt->m_reset_delay = 0;
9302 mptsas_set_throttle(mpt, ptgt,
9303 MAX_THROTTLE);
9304 restart++;
9305 } else {
9306 done = -1;
9307 }
9308 }
9309 }
9310
9311 if (restart > 0) {
9312 mptsas_restart_hba(mpt);
9313 }
9314 return (done);
9315 }
9316
9317 #ifdef MPTSAS_TEST
9318 static void
9319 mptsas_test_reset(mptsas_t *mpt, int target)
9320 {
9321 mptsas_target_t *ptgt = NULL;
9322
9323 if (mptsas_rtest == target) {
9324 if (mptsas_do_scsi_reset(mpt, target) == TRUE) {
9325 mptsas_rtest = -1;
9326 }
9327 if (mptsas_rtest == -1) {
9328 NDBG22(("mptsas_test_reset success"));
9329 }
9330 }
9331 }
9332 #endif
9333
9334 /*
9335 * abort handling:
9336 *
9337 * Notes:
9338 * - if pkt is not NULL, abort just that command
9339 * - if pkt is NULL, abort all outstanding commands for target
9340 */
9341 static int
9342 mptsas_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt)
9343 {
9344 mptsas_t *mpt = ADDR2MPT(ap);
9345 int rval;
9346 mptsas_tgt_private_t *tgt_private;
9347 int target, lun;
9348
9349 tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran->
9350 tran_tgt_private;
9351 ASSERT(tgt_private != NULL);
9352 target = tgt_private->t_private->m_devhdl;
9353 lun = tgt_private->t_lun;
9354
9355 NDBG23(("mptsas_scsi_abort: target=%d.%d", target, lun));
9356
9357 mutex_enter(&mpt->m_mutex);
9358 rval = mptsas_do_scsi_abort(mpt, target, lun, pkt);
9359 mutex_exit(&mpt->m_mutex);
9360 return (rval);
9361 }
9362
9363 static int
9364 mptsas_do_scsi_abort(mptsas_t *mpt, int target, int lun, struct scsi_pkt *pkt)
9365 {
9366 mptsas_cmd_t *sp = NULL;
9367 mptsas_slots_t *slots = mpt->m_active;
9368 int rval = FALSE;
9369
9370 ASSERT(mutex_owned(&mpt->m_mutex));
9371
9372 /*
9373 * Abort the command pkt on the target/lun in ap. If pkt is
9374 * NULL, abort all outstanding commands on that target/lun.
9375 * If you can abort them, return 1, else return 0.
9376 * Each packet that's aborted should be sent back to the target
9377 * driver through the callback routine, with pkt_reason set to
9378 * CMD_ABORTED.
9379 *
9380 * abort cmd pkt on HBA hardware; clean out of outstanding
9381 * command lists, etc.
9382 */
9383 if (pkt != NULL) {
9384 /* abort the specified packet */
9385 sp = PKT2CMD(pkt);
9386
9387 if (sp->cmd_queued) {
9388 NDBG23(("mptsas_do_scsi_abort: queued sp=0x%p aborted",
9389 (void *)sp));
9390 mptsas_waitq_delete(mpt, sp);
9391 mptsas_set_pkt_reason(mpt, sp, CMD_ABORTED,
9392 STAT_ABORTED);
9393 mptsas_doneq_add(mpt, sp);
9394 rval = TRUE;
9395 goto done;
9396 }
9397
9398 /*
9399 * Have mpt firmware abort this command
9400 */
9401
9402 if (slots->m_slot[sp->cmd_slot] != NULL) {
9403 rval = mptsas_ioc_task_management(mpt,
9404 MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, target,
9405 lun, NULL, 0, 0);
9406
9407 /*
9408 * The transport layer expects only TRUE and FALSE.
9409 * Therefore, if mptsas_ioc_task_management returns
9410 * FAILED we will return FALSE.
9411 */
9412 if (rval == FAILED)
9413 rval = FALSE;
9414 goto done;
9415 }
9416 }
9417
9418 /*
9419 * If pkt is NULL then abort task set
9420 */
9421 rval = mptsas_ioc_task_management(mpt,
9422 MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET, target, lun, NULL, 0, 0);
9423
9424 /*
9425 * The transport layer expects only TRUE and FALSE.
9426 * Therefore, if mptsas_ioc_task_management returns
9427 * FAILED we will return FALSE.
9428 */
9429 if (rval == FAILED)
9430 rval = FALSE;
9431
9432 #ifdef MPTSAS_TEST
9433 if (rval && mptsas_test_stop) {
9434 debug_enter("mptsas_do_scsi_abort");
9435 }
9436 #endif
9437
9438 done:
9439 mptsas_doneq_empty(mpt);
9440 return (rval);
9441 }
9442
9443 /*
9444 * capability handling:
9445 * (*tran_getcap). Get the capability named, and return its value.
9446 */
9447 static int
9448 mptsas_scsi_getcap(struct scsi_address *ap, char *cap, int tgtonly)
9449 {
9450 mptsas_t *mpt = ADDR2MPT(ap);
9451 int ckey;
9452 int rval = FALSE;
9453
9454 NDBG24(("mptsas_scsi_getcap: target=%d, cap=%s tgtonly=%x",
9455 ap->a_target, cap, tgtonly));
9456
9457 mutex_enter(&mpt->m_mutex);
9458
9459 if ((mptsas_scsi_capchk(cap, tgtonly, &ckey)) != TRUE) {
9460 mutex_exit(&mpt->m_mutex);
9461 return (UNDEFINED);
9462 }
9463
9464 switch (ckey) {
9465 case SCSI_CAP_DMA_MAX:
9466 rval = (int)mpt->m_msg_dma_attr.dma_attr_maxxfer;
9467 break;
9468 case SCSI_CAP_ARQ:
9469 rval = TRUE;
9470 break;
9471 case SCSI_CAP_MSG_OUT:
9472 case SCSI_CAP_PARITY:
9473 case SCSI_CAP_UNTAGGED_QING:
9474 rval = TRUE;
9475 break;
9476 case SCSI_CAP_TAGGED_QING:
9477 rval = TRUE;
9478 break;
9479 case SCSI_CAP_RESET_NOTIFICATION:
9480 rval = TRUE;
9481 break;
9482 case SCSI_CAP_LINKED_CMDS:
9483 rval = FALSE;
9484 break;
9485 case SCSI_CAP_QFULL_RETRIES:
9486 rval = ((mptsas_tgt_private_t *)(ap->a_hba_tran->
9487 tran_tgt_private))->t_private->m_qfull_retries;
9488 break;
9489 case SCSI_CAP_QFULL_RETRY_INTERVAL:
9490 rval = drv_hztousec(((mptsas_tgt_private_t *)
9491 (ap->a_hba_tran->tran_tgt_private))->
9492 t_private->m_qfull_retry_interval) / 1000;
9493 break;
9494 case SCSI_CAP_CDB_LEN:
9495 rval = CDB_GROUP4;
9496 break;
9497 case SCSI_CAP_INTERCONNECT_TYPE:
9498 rval = INTERCONNECT_SAS;
9499 break;
9500 case SCSI_CAP_TRAN_LAYER_RETRIES:
9501 if (mpt->m_ioc_capabilities &
9502 MPI2_IOCFACTS_CAPABILITY_TLR)
9503 rval = TRUE;
9504 else
9505 rval = FALSE;
9506 break;
9507 default:
9508 rval = UNDEFINED;
9509 break;
9510 }
9511
9512 NDBG24(("mptsas_scsi_getcap: %s, rval=%x", cap, rval));
9513
9514 mutex_exit(&mpt->m_mutex);
9515 return (rval);
9516 }
9517
9518 /*
9519 * (*tran_setcap). Set the capability named to the value given.
9520 */
9521 static int
9522 mptsas_scsi_setcap(struct scsi_address *ap, char *cap, int value, int tgtonly)
9523 {
9524 mptsas_t *mpt = ADDR2MPT(ap);
9525 int ckey;
9526 int rval = FALSE;
9527
9528 NDBG24(("mptsas_scsi_setcap: target=%d, cap=%s value=%x tgtonly=%x",
9529 ap->a_target, cap, value, tgtonly));
9530
9531 if (!tgtonly) {
9532 return (rval);
9533 }
9534
9535 mutex_enter(&mpt->m_mutex);
9536
9537 if ((mptsas_scsi_capchk(cap, tgtonly, &ckey)) != TRUE) {
9538 mutex_exit(&mpt->m_mutex);
9539 return (UNDEFINED);
9540 }
9541
9542 switch (ckey) {
9543 case SCSI_CAP_DMA_MAX:
9544 case SCSI_CAP_MSG_OUT:
9545 case SCSI_CAP_PARITY:
9546 case SCSI_CAP_INITIATOR_ID:
9547 case SCSI_CAP_LINKED_CMDS:
9548 case SCSI_CAP_UNTAGGED_QING:
9549 case SCSI_CAP_RESET_NOTIFICATION:
9550 /*
9551 * None of these are settable via
9552 * the capability interface.
9553 */
9554 break;
9555 case SCSI_CAP_ARQ:
9556 /*
9557 * We cannot turn off arq so return false if asked to
9558 */
9559 if (value) {
9560 rval = TRUE;
9561 } else {
9562 rval = FALSE;
9563 }
9564 break;
9565 case SCSI_CAP_TAGGED_QING:
9566 mptsas_set_throttle(mpt, ((mptsas_tgt_private_t *)
9567 (ap->a_hba_tran->tran_tgt_private))->t_private,
9568 MAX_THROTTLE);
9569 rval = TRUE;
9570 break;
9571 case SCSI_CAP_QFULL_RETRIES:
9572 ((mptsas_tgt_private_t *)(ap->a_hba_tran->tran_tgt_private))->
9573 t_private->m_qfull_retries = (uchar_t)value;
9574 rval = TRUE;
9575 break;
9576 case SCSI_CAP_QFULL_RETRY_INTERVAL:
9577 ((mptsas_tgt_private_t *)(ap->a_hba_tran->tran_tgt_private))->
9578 t_private->m_qfull_retry_interval =
9579 drv_usectohz(value * 1000);
9580 rval = TRUE;
9581 break;
9582 default:
9583 rval = UNDEFINED;
9584 break;
9585 }
9586 mutex_exit(&mpt->m_mutex);
9587 return (rval);
9588 }
9589
9590 /*
9591 * Utility routine for mptsas_ifsetcap/ifgetcap
9592 */
9593 /*ARGSUSED*/
9594 static int
9595 mptsas_scsi_capchk(char *cap, int tgtonly, int *cidxp)
9596 {
9597 NDBG24(("mptsas_scsi_capchk: cap=%s", cap));
9598
9599 if (!cap)
9600 return (FALSE);
9601
9602 *cidxp = scsi_hba_lookup_capstr(cap);
9603 return (TRUE);
9604 }
9605
9606 static int
9607 mptsas_alloc_active_slots(mptsas_t *mpt, int flag)
9608 {
9609 mptsas_slots_t *old_active = mpt->m_active;
9610 mptsas_slots_t *new_active;
9611 size_t size;
9612
9613 /*
9614 * if there are active commands, then we cannot
9615 * change size of active slots array.
9616 */
9617 ASSERT(mpt->m_ncmds == 0);
9618
9619 size = MPTSAS_SLOTS_SIZE(mpt);
9620 new_active = kmem_zalloc(size, flag);
9621 if (new_active == NULL) {
9622 NDBG1(("new active alloc failed"));
9623 return (-1);
9624 }
9625 /*
9626 * Since SMID 0 is reserved and the TM slot is reserved, the
9627 * number of slots that can be used at any one time is
9628 * m_max_requests - 2.
9629 */
9630 new_active->m_n_normal = (mpt->m_max_requests - 2);
9631 new_active->m_size = size;
9632 new_active->m_rotor = 1;
9633 if (old_active)
9634 mptsas_free_active_slots(mpt);
9635 mpt->m_active = new_active;
9636
9637 return (0);
9638 }
9639
9640 static void
9641 mptsas_free_active_slots(mptsas_t *mpt)
9642 {
9643 mptsas_slots_t *active = mpt->m_active;
9644 size_t size;
9645
9646 if (active == NULL)
9647 return;
9648 size = active->m_size;
9649 kmem_free(active, size);
9650 mpt->m_active = NULL;
9651 }
9652
9653 /*
9654 * Error logging, printing, and debug print routines.
9655 */
9656 static char *mptsas_label = "mpt_sas";
9657
9658 /*PRINTFLIKE3*/
9659 void
9660 mptsas_log(mptsas_t *mpt, int level, char *fmt, ...)
9661 {
9662 dev_info_t *dev;
9663 va_list ap;
9664
9665 if (mpt) {
9666 dev = mpt->m_dip;
9667 } else {
9668 dev = 0;
9669 }
9670
9671 mutex_enter(&mptsas_log_mutex);
9672
9673 va_start(ap, fmt);
9674 (void) vsprintf(mptsas_log_buf, fmt, ap);
9675 va_end(ap);
9676
9677 if (level == CE_CONT) {
9678 scsi_log(dev, mptsas_label, level, "%s\n", mptsas_log_buf);
9679 } else {
9680 scsi_log(dev, mptsas_label, level, "%s", mptsas_log_buf);
9681 }
9682
9683 mutex_exit(&mptsas_log_mutex);
9684 }
9685
9686 #ifdef MPTSAS_DEBUG
9687 /*
9688 * Use a circular buffer to log messages to private memory.
9689 * Increment idx atomically to minimize risk to miss lines.
9690 * It's fast and does not hold up the proceedings too much.
9691 */
9692 static const size_t mptsas_dbglog_linecnt = MPTSAS_DBGLOG_LINECNT;
9693 static const size_t mptsas_dbglog_linelen = MPTSAS_DBGLOG_LINELEN;
9694 static char mptsas_dbglog_bufs[MPTSAS_DBGLOG_LINECNT][MPTSAS_DBGLOG_LINELEN];
9695 static uint32_t mptsas_dbglog_idx = 0;
9696
9697 /*PRINTFLIKE1*/
9698 void
9699 mptsas_debug_log(char *fmt, ...)
9700 {
9701 va_list ap;
9702 uint32_t idx;
9703
9704 idx = atomic_inc_32_nv(&mptsas_dbglog_idx) &
9705 (mptsas_dbglog_linecnt - 1);
9706
9707 va_start(ap, fmt);
9708 (void) vsnprintf(mptsas_dbglog_bufs[idx],
9709 mptsas_dbglog_linelen, fmt, ap);
9710 va_end(ap);
9711 }
9712
9713 /*PRINTFLIKE1*/
9714 void
9715 mptsas_printf(char *fmt, ...)
9716 {
9717 dev_info_t *dev = 0;
9718 va_list ap;
9719
9720 mutex_enter(&mptsas_log_mutex);
9721
9722 va_start(ap, fmt);
9723 (void) vsprintf(mptsas_log_buf, fmt, ap);
9724 va_end(ap);
9725
9726 #ifdef PROM_PRINTF
9727 prom_printf("%s:\t%s\n", mptsas_label, mptsas_log_buf);
9728 #else
9729 scsi_log(dev, mptsas_label, CE_CONT, "!%s\n", mptsas_log_buf);
9730 #endif
9731 mutex_exit(&mptsas_log_mutex);
9732 }
9733 #endif
9734
9735 /*
9736 * timeout handling
9737 */
9738 static void
9739 mptsas_watch(void *arg)
9740 {
9741 #ifndef __lock_lint
9742 _NOTE(ARGUNUSED(arg))
9743 #endif
9744
9745 mptsas_t *mpt;
9746 uint32_t doorbell;
9747
9748 NDBG30(("mptsas_watch"));
9749
9750 rw_enter(&mptsas_global_rwlock, RW_READER);
9751 for (mpt = mptsas_head; mpt != (mptsas_t *)NULL; mpt = mpt->m_next) {
9752
9753 mutex_enter(&mpt->m_mutex);
9754
9755 /* Skip device if not powered on */
9756 if (mpt->m_options & MPTSAS_OPT_PM) {
9757 if (mpt->m_power_level == PM_LEVEL_D0) {
9758 (void) pm_busy_component(mpt->m_dip, 0);
9759 mpt->m_busy = 1;
9760 } else {
9761 mutex_exit(&mpt->m_mutex);
9762 continue;
9763 }
9764 }
9765
9766 /*
9767 * Check if controller is in a FAULT state. If so, reset it.
9768 */
9769 doorbell = ddi_get32(mpt->m_datap, &mpt->m_reg->Doorbell);
9770 if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) {
9771 doorbell &= MPI2_DOORBELL_DATA_MASK;
9772 mptsas_log(mpt, CE_WARN, "MPT Firmware Fault, "
9773 "code: %04x", doorbell);
9774 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET;
9775 if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) {
9776 mptsas_log(mpt, CE_WARN, "Reset failed"
9777 "after fault was detected");
9778 }
9779 }
9780
9781 /*
9782 * For now, always call mptsas_watchsubr.
9783 */
9784 mptsas_watchsubr(mpt);
9785
9786 if (mpt->m_options & MPTSAS_OPT_PM) {
9787 mpt->m_busy = 0;
9788 (void) pm_idle_component(mpt->m_dip, 0);
9789 }
9790
9791 mutex_exit(&mpt->m_mutex);
9792 }
9793 rw_exit(&mptsas_global_rwlock);
9794
9795 mutex_enter(&mptsas_global_mutex);
9796 if (mptsas_timeouts_enabled)
9797 mptsas_timeout_id = timeout(mptsas_watch, NULL, mptsas_tick);
9798 mutex_exit(&mptsas_global_mutex);
9799 }
9800
9801 static void
9802 mptsas_watchsubr(mptsas_t *mpt)
9803 {
9804 int i;
9805 mptsas_cmd_t *cmd;
9806 mptsas_target_t *ptgt = NULL;
9807 hrtime_t timestamp = gethrtime();
9808
9809 ASSERT(MUTEX_HELD(&mpt->m_mutex));
9810
9811 NDBG30(("mptsas_watchsubr: mpt=0x%p", (void *)mpt));
9812
9813 #ifdef MPTSAS_TEST
9814 if (mptsas_enable_untagged) {
9815 mptsas_test_untagged++;
9816 }
9817 #endif
9818
9819 /*
9820 * Check for commands stuck in active slot
9821 * Account for TM requests, which use the last SMID.
9822 */
9823 for (i = 0; i <= mpt->m_active->m_n_normal; i++) {
9824 if ((cmd = mpt->m_active->m_slot[i]) != NULL) {
9825 if (cmd->cmd_active_expiration <= timestamp) {
9826 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) {
9827 /*
9828 * There seems to be a command stuck
9829 * in the active slot. Drain throttle.
9830 */
9831 mptsas_set_throttle(mpt,
9832 cmd->cmd_tgt_addr,
9833 DRAIN_THROTTLE);
9834 } else if (cmd->cmd_flags &
9835 (CFLAG_PASSTHRU | CFLAG_CONFIG |
9836 CFLAG_FW_DIAG)) {
9837 /*
9838 * passthrough command timeout
9839 */
9840 cmd->cmd_flags |= (CFLAG_FINISHED |
9841 CFLAG_TIMEOUT);
9842 cv_broadcast(&mpt->m_passthru_cv);
9843 cv_broadcast(&mpt->m_config_cv);
9844 cv_broadcast(&mpt->m_fw_diag_cv);
9845 }
9846 }
9847 }
9848 }
9849
9850 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
9851 ptgt = refhash_next(mpt->m_targets, ptgt)) {
9852 /*
9853 * If we were draining due to a qfull condition,
9854 * go back to full throttle.
9855 */
9856 if ((ptgt->m_t_throttle < MAX_THROTTLE) &&
9857 (ptgt->m_t_throttle > HOLD_THROTTLE) &&
9858 (ptgt->m_t_ncmds < ptgt->m_t_throttle)) {
9859 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
9860 mptsas_restart_hba(mpt);
9861 }
9862
9863 cmd = TAILQ_LAST(&ptgt->m_active_cmdq, mptsas_active_cmdq);
9864 if (cmd == NULL)
9865 continue;
9866
9867 if (cmd->cmd_active_expiration <= timestamp) {
9868 /*
9869 * Earliest command timeout expired. Drain throttle.
9870 */
9871 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
9872
9873 /*
9874 * Check for remaining commands.
9875 */
9876 cmd = TAILQ_FIRST(&ptgt->m_active_cmdq);
9877 if (cmd->cmd_active_expiration > timestamp) {
9878 /*
9879 * Wait for remaining commands to complete or
9880 * time out.
9881 */
9882 NDBG23(("command timed out, pending drain"));
9883 continue;
9884 }
9885
9886 /*
9887 * All command timeouts expired.
9888 */
9889 mptsas_log(mpt, CE_NOTE, "Timeout of %d seconds "
9890 "expired with %d commands on target %d lun %d.",
9891 cmd->cmd_pkt->pkt_time, ptgt->m_t_ncmds,
9892 ptgt->m_devhdl, Lun(cmd));
9893
9894 mptsas_cmd_timeout(mpt, ptgt);
9895 } else if (cmd->cmd_active_expiration <=
9896 timestamp + (hrtime_t)mptsas_scsi_watchdog_tick * NANOSEC) {
9897 NDBG23(("pending timeout"));
9898 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
9899 }
9900 }
9901 }
9902
9903 /*
9904 * timeout recovery
9905 */
9906 static void
9907 mptsas_cmd_timeout(mptsas_t *mpt, mptsas_target_t *ptgt)
9908 {
9909 uint16_t devhdl;
9910 uint64_t sas_wwn;
9911 uint8_t phy;
9912 char wwn_str[MPTSAS_WWN_STRLEN];
9913
9914 devhdl = ptgt->m_devhdl;
9915 sas_wwn = ptgt->m_addr.mta_wwn;
9916 phy = ptgt->m_phynum;
9917 if (sas_wwn == 0) {
9918 (void) sprintf(wwn_str, "p%x", phy);
9919 } else {
9920 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn);
9921 }
9922
9923 NDBG29(("mptsas_cmd_timeout: target=%d", devhdl));
9924 mptsas_log(mpt, CE_WARN, "Disconnected command timeout for "
9925 "target %d %s, enclosure %u", devhdl, wwn_str,
9926 ptgt->m_enclosure);
9927
9928 /*
9929 * Abort all outstanding commands on the device.
9930 */
9931 NDBG29(("mptsas_cmd_timeout: device reset"));
9932 if (mptsas_do_scsi_reset(mpt, devhdl) != TRUE) {
9933 mptsas_log(mpt, CE_WARN, "Target %d reset for command timeout "
9934 "recovery failed!", devhdl);
9935 }
9936 }
9937
9938 /*
9939 * Device / Hotplug control
9940 */
9941 static int
9942 mptsas_scsi_quiesce(dev_info_t *dip)
9943 {
9944 mptsas_t *mpt;
9945 scsi_hba_tran_t *tran;
9946
9947 tran = ddi_get_driver_private(dip);
9948 if (tran == NULL || (mpt = TRAN2MPT(tran)) == NULL)
9949 return (-1);
9950
9951 return (mptsas_quiesce_bus(mpt));
9952 }
9953
9954 static int
9955 mptsas_scsi_unquiesce(dev_info_t *dip)
9956 {
9957 mptsas_t *mpt;
9958 scsi_hba_tran_t *tran;
9959
9960 tran = ddi_get_driver_private(dip);
9961 if (tran == NULL || (mpt = TRAN2MPT(tran)) == NULL)
9962 return (-1);
9963
9964 return (mptsas_unquiesce_bus(mpt));
9965 }
9966
9967 static int
9968 mptsas_quiesce_bus(mptsas_t *mpt)
9969 {
9970 mptsas_target_t *ptgt = NULL;
9971
9972 NDBG28(("mptsas_quiesce_bus"));
9973 mutex_enter(&mpt->m_mutex);
9974
9975 /* Set all the throttles to zero */
9976 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
9977 ptgt = refhash_next(mpt->m_targets, ptgt)) {
9978 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
9979 }
9980
9981 /* If there are any outstanding commands in the queue */
9982 if (mpt->m_ncmds) {
9983 mpt->m_softstate |= MPTSAS_SS_DRAINING;
9984 mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain,
9985 mpt, (MPTSAS_QUIESCE_TIMEOUT * drv_usectohz(1000000)));
9986 if (cv_wait_sig(&mpt->m_cv, &mpt->m_mutex) == 0) {
9987 /*
9988 * Quiesce has been interrupted
9989 */
9990 mpt->m_softstate &= ~MPTSAS_SS_DRAINING;
9991 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
9992 ptgt = refhash_next(mpt->m_targets, ptgt)) {
9993 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
9994 }
9995 mptsas_restart_hba(mpt);
9996 if (mpt->m_quiesce_timeid != 0) {
9997 timeout_id_t tid = mpt->m_quiesce_timeid;
9998 mpt->m_quiesce_timeid = 0;
9999 mutex_exit(&mpt->m_mutex);
10000 (void) untimeout(tid);
10001 return (-1);
10002 }
10003 mutex_exit(&mpt->m_mutex);
10004 return (-1);
10005 } else {
10006 /* Bus has been quiesced */
10007 ASSERT(mpt->m_quiesce_timeid == 0);
10008 mpt->m_softstate &= ~MPTSAS_SS_DRAINING;
10009 mpt->m_softstate |= MPTSAS_SS_QUIESCED;
10010 mutex_exit(&mpt->m_mutex);
10011 return (0);
10012 }
10013 }
10014 /* Bus was not busy - QUIESCED */
10015 mutex_exit(&mpt->m_mutex);
10016
10017 return (0);
10018 }
10019
10020 static int
10021 mptsas_unquiesce_bus(mptsas_t *mpt)
10022 {
10023 mptsas_target_t *ptgt = NULL;
10024
10025 NDBG28(("mptsas_unquiesce_bus"));
10026 mutex_enter(&mpt->m_mutex);
10027 mpt->m_softstate &= ~MPTSAS_SS_QUIESCED;
10028 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
10029 ptgt = refhash_next(mpt->m_targets, ptgt)) {
10030 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
10031 }
10032 mptsas_restart_hba(mpt);
10033 mutex_exit(&mpt->m_mutex);
10034 return (0);
10035 }
10036
10037 static void
10038 mptsas_ncmds_checkdrain(void *arg)
10039 {
10040 mptsas_t *mpt = arg;
10041 mptsas_target_t *ptgt = NULL;
10042
10043 mutex_enter(&mpt->m_mutex);
10044 if (mpt->m_softstate & MPTSAS_SS_DRAINING) {
10045 mpt->m_quiesce_timeid = 0;
10046 if (mpt->m_ncmds == 0) {
10047 /* Command queue has been drained */
10048 cv_signal(&mpt->m_cv);
10049 } else {
10050 /*
10051 * The throttle may have been reset because
10052 * of a SCSI bus reset
10053 */
10054 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
10055 ptgt = refhash_next(mpt->m_targets, ptgt)) {
10056 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
10057 }
10058
10059 mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain,
10060 mpt, (MPTSAS_QUIESCE_TIMEOUT *
10061 drv_usectohz(1000000)));
10062 }
10063 }
10064 mutex_exit(&mpt->m_mutex);
10065 }
10066
10067 /*ARGSUSED*/
10068 static void
10069 mptsas_dump_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
10070 {
10071 int i;
10072 uint8_t *cp = (uchar_t *)cmd->cmd_pkt->pkt_cdbp;
10073 char buf[128];
10074
10075 buf[0] = '\0';
10076 NDBG25(("?Cmd (0x%p) dump for Target %d Lun %d:\n", (void *)cmd,
10077 Tgt(cmd), Lun(cmd)));
10078 (void) sprintf(&buf[0], "\tcdb=[");
10079 for (i = 0; i < (int)cmd->cmd_cdblen; i++) {
10080 (void) sprintf(&buf[strlen(buf)], " 0x%x", *cp++);
10081 }
10082 (void) sprintf(&buf[strlen(buf)], " ]");
10083 NDBG25(("?%s\n", buf));
10084 NDBG25(("?pkt_flags=0x%x pkt_statistics=0x%x pkt_state=0x%x\n",
10085 cmd->cmd_pkt->pkt_flags, cmd->cmd_pkt->pkt_statistics,
10086 cmd->cmd_pkt->pkt_state));
10087 NDBG25(("?pkt_scbp=0x%x cmd_flags=0x%x\n", cmd->cmd_pkt->pkt_scbp ?
10088 *(cmd->cmd_pkt->pkt_scbp) : 0, cmd->cmd_flags));
10089 }
10090
10091 static void
10092 mptsas_passthru_sge(ddi_acc_handle_t acc_hdl, mptsas_pt_request_t *pt,
10093 pMpi2SGESimple64_t sgep)
10094 {
10095 uint32_t sge_flags;
10096 uint32_t data_size, dataout_size;
10097 ddi_dma_cookie_t data_cookie;
10098 ddi_dma_cookie_t dataout_cookie;
10099
10100 data_size = pt->data_size;
10101 dataout_size = pt->dataout_size;
10102 data_cookie = pt->data_cookie;
10103 dataout_cookie = pt->dataout_cookie;
10104
10105 if (dataout_size) {
10106 sge_flags = dataout_size |
10107 ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
10108 MPI2_SGE_FLAGS_END_OF_BUFFER |
10109 MPI2_SGE_FLAGS_HOST_TO_IOC |
10110 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
10111 MPI2_SGE_FLAGS_SHIFT);
10112 ddi_put32(acc_hdl, &sgep->FlagsLength, sge_flags);
10113 ddi_put32(acc_hdl, &sgep->Address.Low,
10114 (uint32_t)(dataout_cookie.dmac_laddress &
10115 0xffffffffull));
10116 ddi_put32(acc_hdl, &sgep->Address.High,
10117 (uint32_t)(dataout_cookie.dmac_laddress
10118 >> 32));
10119 sgep++;
10120 }
10121 sge_flags = data_size;
10122 sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
10123 MPI2_SGE_FLAGS_LAST_ELEMENT |
10124 MPI2_SGE_FLAGS_END_OF_BUFFER |
10125 MPI2_SGE_FLAGS_END_OF_LIST |
10126 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
10127 MPI2_SGE_FLAGS_SHIFT);
10128 if (pt->direction == MPTSAS_PASS_THRU_DIRECTION_WRITE) {
10129 sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_HOST_TO_IOC) <<
10130 MPI2_SGE_FLAGS_SHIFT);
10131 } else {
10132 sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_IOC_TO_HOST) <<
10133 MPI2_SGE_FLAGS_SHIFT);
10134 }
10135 ddi_put32(acc_hdl, &sgep->FlagsLength,
10136 sge_flags);
10137 ddi_put32(acc_hdl, &sgep->Address.Low,
10138 (uint32_t)(data_cookie.dmac_laddress &
10139 0xffffffffull));
10140 ddi_put32(acc_hdl, &sgep->Address.High,
10141 (uint32_t)(data_cookie.dmac_laddress >> 32));
10142 }
10143
10144 static void
10145 mptsas_passthru_ieee_sge(ddi_acc_handle_t acc_hdl, mptsas_pt_request_t *pt,
10146 pMpi2IeeeSgeSimple64_t ieeesgep)
10147 {
10148 uint8_t sge_flags;
10149 uint32_t data_size, dataout_size;
10150 ddi_dma_cookie_t data_cookie;
10151 ddi_dma_cookie_t dataout_cookie;
10152
10153 data_size = pt->data_size;
10154 dataout_size = pt->dataout_size;
10155 data_cookie = pt->data_cookie;
10156 dataout_cookie = pt->dataout_cookie;
10157
10158 sge_flags = (MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT |
10159 MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR);
10160 if (dataout_size) {
10161 ddi_put32(acc_hdl, &ieeesgep->Length, dataout_size);
10162 ddi_put32(acc_hdl, &ieeesgep->Address.Low,
10163 (uint32_t)(dataout_cookie.dmac_laddress &
10164 0xffffffffull));
10165 ddi_put32(acc_hdl, &ieeesgep->Address.High,
10166 (uint32_t)(dataout_cookie.dmac_laddress >> 32));
10167 ddi_put8(acc_hdl, &ieeesgep->Flags, sge_flags);
10168 ieeesgep++;
10169 }
10170 sge_flags |= MPI25_IEEE_SGE_FLAGS_END_OF_LIST;
10171 ddi_put32(acc_hdl, &ieeesgep->Length, data_size);
10172 ddi_put32(acc_hdl, &ieeesgep->Address.Low,
10173 (uint32_t)(data_cookie.dmac_laddress & 0xffffffffull));
10174 ddi_put32(acc_hdl, &ieeesgep->Address.High,
10175 (uint32_t)(data_cookie.dmac_laddress >> 32));
10176 ddi_put8(acc_hdl, &ieeesgep->Flags, sge_flags);
10177 }
10178
10179 static void
10180 mptsas_start_passthru(mptsas_t *mpt, mptsas_cmd_t *cmd)
10181 {
10182 caddr_t memp;
10183 pMPI2RequestHeader_t request_hdrp;
10184 struct scsi_pkt *pkt = cmd->cmd_pkt;
10185 mptsas_pt_request_t *pt = pkt->pkt_ha_private;
10186 uint32_t request_size;
10187 uint32_t request_desc_low, request_desc_high = 0;
10188 uint32_t i, sense_bufp;
10189 uint8_t desc_type;
10190 uint8_t *request, function;
10191 ddi_dma_handle_t dma_hdl = mpt->m_dma_req_frame_hdl;
10192 ddi_acc_handle_t acc_hdl = mpt->m_acc_req_frame_hdl;
10193
10194 desc_type = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
10195
10196 request = pt->request;
10197 request_size = pt->request_size;
10198
10199 /*
10200 * Store the passthrough message in memory location
10201 * corresponding to our slot number
10202 */
10203 memp = mpt->m_req_frame + (mpt->m_req_frame_size * cmd->cmd_slot);
10204 request_hdrp = (pMPI2RequestHeader_t)memp;
10205 bzero(memp, mpt->m_req_frame_size);
10206
10207 for (i = 0; i < request_size; i++) {
10208 bcopy(request + i, memp + i, 1);
10209 }
10210
10211 NDBG15(("mptsas_start_passthru: Func 0x%x, MsgFlags 0x%x, "
10212 "size=%d, in %d, out %d", request_hdrp->Function,
10213 request_hdrp->MsgFlags, request_size,
10214 pt->data_size, pt->dataout_size));
10215
10216 /*
10217 * Add an SGE, even if the length is zero.
10218 */
10219 if (mpt->m_MPI25 && pt->simple == 0) {
10220 mptsas_passthru_ieee_sge(acc_hdl, pt,
10221 (pMpi2IeeeSgeSimple64_t)
10222 ((uint8_t *)request_hdrp + pt->sgl_offset));
10223 } else {
10224 mptsas_passthru_sge(acc_hdl, pt,
10225 (pMpi2SGESimple64_t)
10226 ((uint8_t *)request_hdrp + pt->sgl_offset));
10227 }
10228
10229 function = request_hdrp->Function;
10230 if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) ||
10231 (function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
10232 pMpi2SCSIIORequest_t scsi_io_req;
10233
10234 NDBG15(("mptsas_start_passthru: Is SCSI IO Req"));
10235 scsi_io_req = (pMpi2SCSIIORequest_t)request_hdrp;
10236 /*
10237 * Put SGE for data and data_out buffer at the end of
10238 * scsi_io_request message header.(64 bytes in total)
10239 * Following above SGEs, the residual space will be
10240 * used by sense data.
10241 */
10242 ddi_put8(acc_hdl,
10243 &scsi_io_req->SenseBufferLength,
10244 (uint8_t)(request_size - 64));
10245
10246 sense_bufp = mpt->m_req_frame_dma_addr +
10247 (mpt->m_req_frame_size * cmd->cmd_slot);
10248 sense_bufp += 64;
10249 ddi_put32(acc_hdl,
10250 &scsi_io_req->SenseBufferLowAddress, sense_bufp);
10251
10252 /*
10253 * Set SGLOffset0 value
10254 */
10255 ddi_put8(acc_hdl, &scsi_io_req->SGLOffset0,
10256 offsetof(MPI2_SCSI_IO_REQUEST, SGL) / 4);
10257
10258 /*
10259 * Setup descriptor info. RAID passthrough must use the
10260 * default request descriptor which is already set, so if this
10261 * is a SCSI IO request, change the descriptor to SCSI IO.
10262 */
10263 if (function == MPI2_FUNCTION_SCSI_IO_REQUEST) {
10264 desc_type = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO;
10265 request_desc_high = (ddi_get16(acc_hdl,
10266 &scsi_io_req->DevHandle) << 16);
10267 }
10268 }
10269
10270 /*
10271 * We must wait till the message has been completed before
10272 * beginning the next message so we wait for this one to
10273 * finish.
10274 */
10275 (void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
10276 request_desc_low = (cmd->cmd_slot << 16) + desc_type;
10277 cmd->cmd_rfm = NULL;
10278 MPTSAS_START_CMD(mpt, request_desc_low, request_desc_high);
10279 if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) ||
10280 (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) {
10281 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
10282 }
10283 }
10284
10285 typedef void (mptsas_pre_f)(mptsas_t *, mptsas_pt_request_t *);
10286 static mptsas_pre_f mpi_pre_ioc_facts;
10287 static mptsas_pre_f mpi_pre_port_facts;
10288 static mptsas_pre_f mpi_pre_fw_download;
10289 static mptsas_pre_f mpi_pre_fw_25_download;
10290 static mptsas_pre_f mpi_pre_fw_upload;
10291 static mptsas_pre_f mpi_pre_fw_25_upload;
10292 static mptsas_pre_f mpi_pre_sata_passthrough;
10293 static mptsas_pre_f mpi_pre_smp_passthrough;
10294 static mptsas_pre_f mpi_pre_config;
10295 static mptsas_pre_f mpi_pre_sas_io_unit_control;
10296 static mptsas_pre_f mpi_pre_scsi_io_req;
10297
10298 /*
10299 * Prepare the pt for a SAS2 FW_DOWNLOAD request.
10300 */
10301 static void
10302 mpi_pre_fw_download(mptsas_t *mpt, mptsas_pt_request_t *pt)
10303 {
10304 pMpi2FWDownloadTCSGE_t tcsge;
10305 pMpi2FWDownloadRequest req;
10306
10307 /*
10308 * If SAS3, call separate function.
10309 */
10310 if (mpt->m_MPI25) {
10311 mpi_pre_fw_25_download(mpt, pt);
10312 return;
10313 }
10314
10315 /*
10316 * User requests should come in with the Transaction
10317 * context element where the SGL will go. Putting the
10318 * SGL after that seems to work, but don't really know
10319 * why. Other drivers tend to create an extra SGL and
10320 * refer to the TCE through that.
10321 */
10322 req = (pMpi2FWDownloadRequest)pt->request;
10323 tcsge = (pMpi2FWDownloadTCSGE_t)&req->SGL;
10324 if (tcsge->ContextSize != 0 || tcsge->DetailsLength != 12 ||
10325 tcsge->Flags != MPI2_SGE_FLAGS_TRANSACTION_ELEMENT) {
10326 mptsas_log(mpt, CE_WARN, "FW Download tce invalid!");
10327 }
10328
10329 pt->sgl_offset = offsetof(MPI2_FW_DOWNLOAD_REQUEST, SGL) +
10330 sizeof (*tcsge);
10331 if (pt->request_size != pt->sgl_offset)
10332 NDBG15(("mpi_pre_fw_download(): Incorrect req size, "
10333 "0x%x, should be 0x%x, dataoutsz 0x%x",
10334 (int)pt->request_size, (int)pt->sgl_offset,
10335 (int)pt->dataout_size));
10336 if (pt->data_size < sizeof (MPI2_FW_DOWNLOAD_REPLY))
10337 NDBG15(("mpi_pre_fw_download(): Incorrect rep size, "
10338 "0x%x, should be 0x%x", pt->data_size,
10339 (int)sizeof (MPI2_FW_DOWNLOAD_REPLY)));
10340 }
10341
10342 /*
10343 * Prepare the pt for a SAS3 FW_DOWNLOAD request.
10344 */
10345 static void
10346 mpi_pre_fw_25_download(mptsas_t *mpt, mptsas_pt_request_t *pt)
10347 {
10348 pMpi2FWDownloadTCSGE_t tcsge;
10349 pMpi2FWDownloadRequest req2;
10350 pMpi25FWDownloadRequest req25;
10351
10352 /*
10353 * User requests should come in with the Transaction
10354 * context element where the SGL will go. The new firmware
10355 * Doesn't use TCE and has space in the main request for
10356 * this information. So move to the right place.
10357 */
10358 req2 = (pMpi2FWDownloadRequest)pt->request;
10359 req25 = (pMpi25FWDownloadRequest)pt->request;
10360 tcsge = (pMpi2FWDownloadTCSGE_t)&req2->SGL;
10361 if (tcsge->ContextSize != 0 || tcsge->DetailsLength != 12 ||
10362 tcsge->Flags != MPI2_SGE_FLAGS_TRANSACTION_ELEMENT) {
10363 mptsas_log(mpt, CE_WARN, "FW Download tce invalid!");
10364 }
10365 req25->ImageOffset = tcsge->ImageOffset;
10366 req25->ImageSize = tcsge->ImageSize;
10367
10368 pt->sgl_offset = offsetof(MPI25_FW_DOWNLOAD_REQUEST, SGL);
10369 if (pt->request_size != pt->sgl_offset)
10370 NDBG15(("mpi_pre_fw_25_download(): Incorrect req size, "
10371 "0x%x, should be 0x%x, dataoutsz 0x%x",
10372 pt->request_size, pt->sgl_offset,
10373 pt->dataout_size));
10374 if (pt->data_size < sizeof (MPI2_FW_DOWNLOAD_REPLY))
10375 NDBG15(("mpi_pre_fw_25_download(): Incorrect rep size, "
10376 "0x%x, should be 0x%x", pt->data_size,
10377 (int)sizeof (MPI2_FW_UPLOAD_REPLY)));
10378 }
10379
10380 /*
10381 * Prepare the pt for a SAS2 FW_UPLOAD request.
10382 */
10383 static void
10384 mpi_pre_fw_upload(mptsas_t *mpt, mptsas_pt_request_t *pt)
10385 {
10386 pMpi2FWUploadTCSGE_t tcsge;
10387 pMpi2FWUploadRequest_t req;
10388
10389 /*
10390 * If SAS3, call separate function.
10391 */
10392 if (mpt->m_MPI25) {
10393 mpi_pre_fw_25_upload(mpt, pt);
10394 return;
10395 }
10396
10397 /*
10398 * User requests should come in with the Transaction
10399 * context element where the SGL will go. Putting the
10400 * SGL after that seems to work, but don't really know
10401 * why. Other drivers tend to create an extra SGL and
10402 * refer to the TCE through that.
10403 */
10404 req = (pMpi2FWUploadRequest_t)pt->request;
10405 tcsge = (pMpi2FWUploadTCSGE_t)&req->SGL;
10406 if (tcsge->ContextSize != 0 || tcsge->DetailsLength != 12 ||
10407 tcsge->Flags != MPI2_SGE_FLAGS_TRANSACTION_ELEMENT) {
10408 mptsas_log(mpt, CE_WARN, "FW Upload tce invalid!");
10409 }
10410
10411 pt->sgl_offset = offsetof(MPI2_FW_UPLOAD_REQUEST, SGL) +
10412 sizeof (*tcsge);
10413 if (pt->request_size != pt->sgl_offset)
10414 NDBG15(("mpi_pre_fw_upload(): Incorrect req size, "
10415 "0x%x, should be 0x%x, dataoutsz 0x%x",
10416 pt->request_size, pt->sgl_offset,
10417 pt->dataout_size));
10418 if (pt->data_size < sizeof (MPI2_FW_UPLOAD_REPLY))
10419 NDBG15(("mpi_pre_fw_upload(): Incorrect rep size, "
10420 "0x%x, should be 0x%x", pt->data_size,
10421 (int)sizeof (MPI2_FW_UPLOAD_REPLY)));
10422 }
10423
10424 /*
10425 * Prepare the pt a SAS3 FW_UPLOAD request.
10426 */
10427 static void
10428 mpi_pre_fw_25_upload(mptsas_t *mpt, mptsas_pt_request_t *pt)
10429 {
10430 pMpi2FWUploadTCSGE_t tcsge;
10431 pMpi2FWUploadRequest_t req2;
10432 pMpi25FWUploadRequest_t req25;
10433
10434 /*
10435 * User requests should come in with the Transaction
10436 * context element where the SGL will go. The new firmware
10437 * Doesn't use TCE and has space in the main request for
10438 * this information. So move to the right place.
10439 */
10440 req2 = (pMpi2FWUploadRequest_t)pt->request;
10441 req25 = (pMpi25FWUploadRequest_t)pt->request;
10442 tcsge = (pMpi2FWUploadTCSGE_t)&req2->SGL;
10443 if (tcsge->ContextSize != 0 || tcsge->DetailsLength != 12 ||
10444 tcsge->Flags != MPI2_SGE_FLAGS_TRANSACTION_ELEMENT) {
10445 mptsas_log(mpt, CE_WARN, "FW Upload tce invalid!");
10446 }
10447 req25->ImageOffset = tcsge->ImageOffset;
10448 req25->ImageSize = tcsge->ImageSize;
10449
10450 pt->sgl_offset = offsetof(MPI25_FW_UPLOAD_REQUEST, SGL);
10451 if (pt->request_size != pt->sgl_offset)
10452 NDBG15(("mpi_pre_fw_25_upload(): Incorrect req size, "
10453 "0x%x, should be 0x%x, dataoutsz 0x%x",
10454 pt->request_size, pt->sgl_offset,
10455 pt->dataout_size));
10456 if (pt->data_size < sizeof (MPI2_FW_UPLOAD_REPLY))
10457 NDBG15(("mpi_pre_fw_25_upload(): Incorrect rep size, "
10458 "0x%x, should be 0x%x", pt->data_size,
10459 (int)sizeof (MPI2_FW_UPLOAD_REPLY)));
10460 }
10461
10462 /*
10463 * Prepare the pt for an IOC_FACTS request.
10464 */
10465 static void
10466 mpi_pre_ioc_facts(mptsas_t *mpt, mptsas_pt_request_t *pt)
10467 {
10468 #ifndef __lock_lint
10469 _NOTE(ARGUNUSED(mpt))
10470 #endif
10471 if (pt->request_size != sizeof (MPI2_IOC_FACTS_REQUEST))
10472 NDBG15(("mpi_pre_ioc_facts(): Incorrect req size, "
10473 "0x%x, should be 0x%x, dataoutsz 0x%x",
10474 pt->request_size,
10475 (int)sizeof (MPI2_IOC_FACTS_REQUEST),
10476 pt->dataout_size));
10477 if (pt->data_size != sizeof (MPI2_IOC_FACTS_REPLY))
10478 NDBG15(("mpi_pre_ioc_facts(): Incorrect rep size, "
10479 "0x%x, should be 0x%x", pt->data_size,
10480 (int)sizeof (MPI2_IOC_FACTS_REPLY)));
10481 pt->sgl_offset = (uint16_t)pt->request_size;
10482 }
10483
10484 /*
10485 * Prepare the pt for a PORT_FACTS request.
10486 */
10487 static void
10488 mpi_pre_port_facts(mptsas_t *mpt, mptsas_pt_request_t *pt)
10489 {
10490 #ifndef __lock_lint
10491 _NOTE(ARGUNUSED(mpt))
10492 #endif
10493 if (pt->request_size != sizeof (MPI2_PORT_FACTS_REQUEST))
10494 NDBG15(("mpi_pre_port_facts(): Incorrect req size, "
10495 "0x%x, should be 0x%x, dataoutsz 0x%x",
10496 pt->request_size,
10497 (int)sizeof (MPI2_PORT_FACTS_REQUEST),
10498 pt->dataout_size));
10499 if (pt->data_size != sizeof (MPI2_PORT_FACTS_REPLY))
10500 NDBG15(("mpi_pre_port_facts(): Incorrect rep size, "
10501 "0x%x, should be 0x%x", pt->data_size,
10502 (int)sizeof (MPI2_PORT_FACTS_REPLY)));
10503 pt->sgl_offset = (uint16_t)pt->request_size;
10504 }
10505
10506 /*
10507 * Prepare pt for a SATA_PASSTHROUGH request.
10508 */
10509 static void
10510 mpi_pre_sata_passthrough(mptsas_t *mpt, mptsas_pt_request_t *pt)
10511 {
10512 #ifndef __lock_lint
10513 _NOTE(ARGUNUSED(mpt))
10514 #endif
10515 pt->sgl_offset = offsetof(MPI2_SATA_PASSTHROUGH_REQUEST, SGL);
10516 if (pt->request_size != pt->sgl_offset)
10517 NDBG15(("mpi_pre_sata_passthrough(): Incorrect req size, "
10518 "0x%x, should be 0x%x, dataoutsz 0x%x",
10519 pt->request_size, pt->sgl_offset,
10520 pt->dataout_size));
10521 if (pt->data_size != sizeof (MPI2_SATA_PASSTHROUGH_REPLY))
10522 NDBG15(("mpi_pre_sata_passthrough(): Incorrect rep size, "
10523 "0x%x, should be 0x%x", pt->data_size,
10524 (int)sizeof (MPI2_SATA_PASSTHROUGH_REPLY)));
10525 }
10526
10527 static void
10528 mpi_pre_smp_passthrough(mptsas_t *mpt, mptsas_pt_request_t *pt)
10529 {
10530 #ifndef __lock_lint
10531 _NOTE(ARGUNUSED(mpt))
10532 #endif
10533 pt->sgl_offset = offsetof(MPI2_SMP_PASSTHROUGH_REQUEST, SGL);
10534 if (pt->request_size != pt->sgl_offset)
10535 NDBG15(("mpi_pre_smp_passthrough(): Incorrect req size, "
10536 "0x%x, should be 0x%x, dataoutsz 0x%x",
10537 pt->request_size, pt->sgl_offset,
10538 pt->dataout_size));
10539 if (pt->data_size != sizeof (MPI2_SMP_PASSTHROUGH_REPLY))
10540 NDBG15(("mpi_pre_smp_passthrough(): Incorrect rep size, "
10541 "0x%x, should be 0x%x", pt->data_size,
10542 (int)sizeof (MPI2_SMP_PASSTHROUGH_REPLY)));
10543 }
10544
10545 /*
10546 * Prepare pt for a CONFIG request.
10547 */
10548 static void
10549 mpi_pre_config(mptsas_t *mpt, mptsas_pt_request_t *pt)
10550 {
10551 #ifndef __lock_lint
10552 _NOTE(ARGUNUSED(mpt))
10553 #endif
10554 pt->sgl_offset = offsetof(MPI2_CONFIG_REQUEST, PageBufferSGE);
10555 if (pt->request_size != pt->sgl_offset)
10556 NDBG15(("mpi_pre_config(): Incorrect req size, 0x%x, "
10557 "should be 0x%x, dataoutsz 0x%x", pt->request_size,
10558 pt->sgl_offset, pt->dataout_size));
10559 if (pt->data_size != sizeof (MPI2_CONFIG_REPLY))
10560 NDBG15(("mpi_pre_config(): Incorrect rep size, 0x%x, "
10561 "should be 0x%x", pt->data_size,
10562 (int)sizeof (MPI2_CONFIG_REPLY)));
10563 pt->simple = 1;
10564 }
10565
10566 /*
10567 * Prepare pt for a SCSI_IO_REQ request.
10568 */
10569 static void
10570 mpi_pre_scsi_io_req(mptsas_t *mpt, mptsas_pt_request_t *pt)
10571 {
10572 #ifndef __lock_lint
10573 _NOTE(ARGUNUSED(mpt))
10574 #endif
10575 pt->sgl_offset = offsetof(MPI2_SCSI_IO_REQUEST, SGL);
10576 if (pt->request_size != pt->sgl_offset)
10577 NDBG15(("mpi_pre_config(): Incorrect req size, 0x%x, "
10578 "should be 0x%x, dataoutsz 0x%x", pt->request_size,
10579 pt->sgl_offset,
10580 pt->dataout_size));
10581 if (pt->data_size != sizeof (MPI2_SCSI_IO_REPLY))
10582 NDBG15(("mpi_pre_config(): Incorrect rep size, 0x%x, "
10583 "should be 0x%x", pt->data_size,
10584 (int)sizeof (MPI2_SCSI_IO_REPLY)));
10585 }
10586
10587 /*
10588 * Prepare the mptsas_cmd for a SAS_IO_UNIT_CONTROL request.
10589 */
10590 static void
10591 mpi_pre_sas_io_unit_control(mptsas_t *mpt, mptsas_pt_request_t *pt)
10592 {
10593 #ifndef __lock_lint
10594 _NOTE(ARGUNUSED(mpt))
10595 #endif
10596 pt->sgl_offset = (uint16_t)pt->request_size;
10597 }
10598
10599 /*
10600 * A set of functions to prepare an mptsas_cmd for the various
10601 * supported requests.
10602 */
10603 static struct mptsas_func {
10604 U8 Function;
10605 char *Name;
10606 mptsas_pre_f *f_pre;
10607 } mptsas_func_list[] = {
10608 { MPI2_FUNCTION_IOC_FACTS, "IOC_FACTS", mpi_pre_ioc_facts },
10609 { MPI2_FUNCTION_PORT_FACTS, "PORT_FACTS", mpi_pre_port_facts },
10610 { MPI2_FUNCTION_FW_DOWNLOAD, "FW_DOWNLOAD", mpi_pre_fw_download },
10611 { MPI2_FUNCTION_FW_UPLOAD, "FW_UPLOAD", mpi_pre_fw_upload },
10612 { MPI2_FUNCTION_SATA_PASSTHROUGH, "SATA_PASSTHROUGH",
10613 mpi_pre_sata_passthrough },
10614 { MPI2_FUNCTION_SMP_PASSTHROUGH, "SMP_PASSTHROUGH",
10615 mpi_pre_smp_passthrough},
10616 { MPI2_FUNCTION_SCSI_IO_REQUEST, "SCSI_IO_REQUEST",
10617 mpi_pre_scsi_io_req},
10618 { MPI2_FUNCTION_CONFIG, "CONFIG", mpi_pre_config},
10619 { MPI2_FUNCTION_SAS_IO_UNIT_CONTROL, "SAS_IO_UNIT_CONTROL",
10620 mpi_pre_sas_io_unit_control },
10621 { 0xFF, NULL, NULL } /* list end */
10622 };
10623
10624 static void
10625 mptsas_prep_sgl_offset(mptsas_t *mpt, mptsas_pt_request_t *pt)
10626 {
10627 pMPI2RequestHeader_t hdr;
10628 struct mptsas_func *f;
10629
10630 hdr = (pMPI2RequestHeader_t)pt->request;
10631
10632 for (f = mptsas_func_list; f->f_pre != NULL; f++) {
10633 if (hdr->Function == f->Function) {
10634 f->f_pre(mpt, pt);
10635 NDBG15(("mptsas_prep_sgl_offset: Function %s,"
10636 " sgl_offset 0x%x", f->Name,
10637 pt->sgl_offset));
10638 return;
10639 }
10640 }
10641 NDBG15(("mptsas_prep_sgl_offset: Unknown Function 0x%02x,"
10642 " returning req_size 0x%x for sgl_offset",
10643 hdr->Function, pt->request_size));
10644 pt->sgl_offset = (uint16_t)pt->request_size;
10645 }
10646
10647
10648 static int
10649 mptsas_do_passthru(mptsas_t *mpt, uint8_t *request, uint8_t *reply,
10650 uint8_t *data, uint32_t request_size, uint32_t reply_size,
10651 uint32_t data_size, uint32_t direction, uint8_t *dataout,
10652 uint32_t dataout_size, short timeout, int mode)
10653 {
10654 mptsas_pt_request_t pt;
10655 mptsas_dma_alloc_state_t data_dma_state;
10656 mptsas_dma_alloc_state_t dataout_dma_state;
10657 caddr_t memp;
10658 mptsas_cmd_t *cmd = NULL;
10659 struct scsi_pkt *pkt;
10660 uint32_t reply_len = 0, sense_len = 0;
10661 pMPI2RequestHeader_t request_hdrp;
10662 pMPI2RequestHeader_t request_msg;
10663 pMPI2DefaultReply_t reply_msg;
10664 Mpi2SCSIIOReply_t rep_msg;
10665 int i, status = 0, pt_flags = 0, rv = 0;
10666 int rvalue;
10667 uint8_t function;
10668
10669 ASSERT(mutex_owned(&mpt->m_mutex));
10670
10671 reply_msg = (pMPI2DefaultReply_t)(&rep_msg);
10672 bzero(reply_msg, sizeof (MPI2_DEFAULT_REPLY));
10673 request_msg = kmem_zalloc(request_size, KM_SLEEP);
10674
10675 mutex_exit(&mpt->m_mutex);
10676 /*
10677 * copy in the request buffer since it could be used by
10678 * another thread when the pt request into waitq
10679 */
10680 if (ddi_copyin(request, request_msg, request_size, mode)) {
10681 mutex_enter(&mpt->m_mutex);
10682 status = EFAULT;
10683 mptsas_log(mpt, CE_WARN, "failed to copy request data");
10684 goto out;
10685 }
10686 mutex_enter(&mpt->m_mutex);
10687
10688 function = request_msg->Function;
10689 if (function == MPI2_FUNCTION_SCSI_TASK_MGMT) {
10690 pMpi2SCSITaskManagementRequest_t task;
10691 task = (pMpi2SCSITaskManagementRequest_t)request_msg;
10692 mptsas_setup_bus_reset_delay(mpt);
10693 rv = mptsas_ioc_task_management(mpt, task->TaskType,
10694 task->DevHandle, (int)task->LUN[1], reply, reply_size,
10695 mode);
10696
10697 if (rv != TRUE) {
10698 status = EIO;
10699 mptsas_log(mpt, CE_WARN, "task management failed");
10700 }
10701 goto out;
10702 }
10703
10704 if (data_size != 0) {
10705 data_dma_state.size = data_size;
10706 if (mptsas_dma_alloc(mpt, &data_dma_state) != DDI_SUCCESS) {
10707 status = ENOMEM;
10708 mptsas_log(mpt, CE_WARN, "failed to alloc DMA "
10709 "resource");
10710 goto out;
10711 }
10712 pt_flags |= MPTSAS_DATA_ALLOCATED;
10713 if (direction == MPTSAS_PASS_THRU_DIRECTION_WRITE) {
10714 mutex_exit(&mpt->m_mutex);
10715 for (i = 0; i < data_size; i++) {
10716 if (ddi_copyin(data + i, (uint8_t *)
10717 data_dma_state.memp + i, 1, mode)) {
10718 mutex_enter(&mpt->m_mutex);
10719 status = EFAULT;
10720 mptsas_log(mpt, CE_WARN, "failed to "
10721 "copy read data");
10722 goto out;
10723 }
10724 }
10725 mutex_enter(&mpt->m_mutex);
10726 }
10727 } else {
10728 bzero(&data_dma_state, sizeof (data_dma_state));
10729 }
10730
10731 if (dataout_size != 0) {
10732 dataout_dma_state.size = dataout_size;
10733 if (mptsas_dma_alloc(mpt, &dataout_dma_state) != DDI_SUCCESS) {
10734 status = ENOMEM;
10735 mptsas_log(mpt, CE_WARN, "failed to alloc DMA "
10736 "resource");
10737 goto out;
10738 }
10739 pt_flags |= MPTSAS_DATAOUT_ALLOCATED;
10740 mutex_exit(&mpt->m_mutex);
10741 for (i = 0; i < dataout_size; i++) {
10742 if (ddi_copyin(dataout + i, (uint8_t *)
10743 dataout_dma_state.memp + i, 1, mode)) {
10744 mutex_enter(&mpt->m_mutex);
10745 mptsas_log(mpt, CE_WARN, "failed to copy out"
10746 " data");
10747 status = EFAULT;
10748 goto out;
10749 }
10750 }
10751 mutex_enter(&mpt->m_mutex);
10752 } else {
10753 bzero(&dataout_dma_state, sizeof (dataout_dma_state));
10754 }
10755
10756 if ((rvalue = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) {
10757 status = EAGAIN;
10758 mptsas_log(mpt, CE_NOTE, "event ack command pool is full");
10759 goto out;
10760 }
10761 pt_flags |= MPTSAS_REQUEST_POOL_CMD;
10762
10763 bzero((caddr_t)cmd, sizeof (*cmd));
10764 bzero((caddr_t)pkt, scsi_pkt_size());
10765 bzero((caddr_t)&pt, sizeof (pt));
10766
10767 cmd->ioc_cmd_slot = (uint32_t)(rvalue);
10768
10769 pt.request = (uint8_t *)request_msg;
10770 pt.direction = direction;
10771 pt.simple = 0;
10772 pt.request_size = request_size;
10773 pt.data_size = data_size;
10774 pt.dataout_size = dataout_size;
10775 pt.data_cookie = data_dma_state.cookie;
10776 pt.dataout_cookie = dataout_dma_state.cookie;
10777 mptsas_prep_sgl_offset(mpt, &pt);
10778
10779 /*
10780 * Form a blank cmd/pkt to store the acknowledgement message
10781 */
10782 pkt->pkt_cdbp = (opaque_t)&cmd->cmd_cdb[0];
10783 pkt->pkt_scbp = (opaque_t)&cmd->cmd_scb;
10784 pkt->pkt_ha_private = (opaque_t)&pt;
10785 pkt->pkt_flags = FLAG_HEAD;
10786 pkt->pkt_time = timeout;
10787 cmd->cmd_pkt = pkt;
10788 cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_PASSTHRU;
10789
10790 /*
10791 * Save the command in a slot
10792 */
10793 if (mptsas_save_cmd(mpt, cmd) == TRUE) {
10794 /*
10795 * Once passthru command get slot, set cmd_flags
10796 * CFLAG_PREPARED.
10797 */
10798 cmd->cmd_flags |= CFLAG_PREPARED;
10799 mptsas_start_passthru(mpt, cmd);
10800 } else {
10801 mptsas_waitq_add(mpt, cmd);
10802 }
10803
10804 while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) {
10805 cv_wait(&mpt->m_passthru_cv, &mpt->m_mutex);
10806 }
10807
10808 if (cmd->cmd_flags & CFLAG_PREPARED) {
10809 memp = mpt->m_req_frame + (mpt->m_req_frame_size *
10810 cmd->cmd_slot);
10811 request_hdrp = (pMPI2RequestHeader_t)memp;
10812 }
10813
10814 if (cmd->cmd_flags & CFLAG_TIMEOUT) {
10815 status = ETIMEDOUT;
10816 mptsas_log(mpt, CE_WARN, "passthrough command timeout");
10817 pt_flags |= MPTSAS_CMD_TIMEOUT;
10818 goto out;
10819 }
10820
10821 if (cmd->cmd_rfm) {
10822 /*
10823 * cmd_rfm is zero means the command reply is a CONTEXT
10824 * reply and no PCI Write to post the free reply SMFA
10825 * because no reply message frame is used.
10826 * cmd_rfm is non-zero means the reply is a ADDRESS
10827 * reply and reply message frame is used.
10828 */
10829 pt_flags |= MPTSAS_ADDRESS_REPLY;
10830 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
10831 DDI_DMA_SYNC_FORCPU);
10832 reply_msg = (pMPI2DefaultReply_t)
10833 (mpt->m_reply_frame + (cmd->cmd_rfm -
10834 mpt->m_reply_frame_dma_addr));
10835 }
10836
10837 mptsas_fma_check(mpt, cmd);
10838 if (pkt->pkt_reason == CMD_TRAN_ERR) {
10839 status = EAGAIN;
10840 mptsas_log(mpt, CE_WARN, "passthru fma error");
10841 goto out;
10842 }
10843 if (pkt->pkt_reason == CMD_RESET) {
10844 status = EAGAIN;
10845 mptsas_log(mpt, CE_WARN, "ioc reset abort passthru");
10846 goto out;
10847 }
10848
10849 if (pkt->pkt_reason == CMD_INCOMPLETE) {
10850 status = EIO;
10851 mptsas_log(mpt, CE_WARN, "passthrough command incomplete");
10852 goto out;
10853 }
10854
10855 mutex_exit(&mpt->m_mutex);
10856 if (cmd->cmd_flags & CFLAG_PREPARED) {
10857 function = request_hdrp->Function;
10858 if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) ||
10859 (function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
10860 reply_len = sizeof (MPI2_SCSI_IO_REPLY);
10861 sense_len = reply_size - reply_len;
10862 } else {
10863 reply_len = reply_size;
10864 sense_len = 0;
10865 }
10866
10867 for (i = 0; i < reply_len; i++) {
10868 if (ddi_copyout((uint8_t *)reply_msg + i, reply + i, 1,
10869 mode)) {
10870 mutex_enter(&mpt->m_mutex);
10871 status = EFAULT;
10872 mptsas_log(mpt, CE_WARN, "failed to copy out "
10873 "reply data");
10874 goto out;
10875 }
10876 }
10877 for (i = 0; i < sense_len; i++) {
10878 if (ddi_copyout((uint8_t *)request_hdrp + 64 + i,
10879 reply + reply_len + i, 1, mode)) {
10880 mutex_enter(&mpt->m_mutex);
10881 status = EFAULT;
10882 mptsas_log(mpt, CE_WARN, "failed to copy out "
10883 "sense data");
10884 goto out;
10885 }
10886 }
10887 }
10888
10889 if (data_size) {
10890 if (direction != MPTSAS_PASS_THRU_DIRECTION_WRITE) {
10891 (void) ddi_dma_sync(data_dma_state.handle, 0, 0,
10892 DDI_DMA_SYNC_FORCPU);
10893 for (i = 0; i < data_size; i++) {
10894 if (ddi_copyout((uint8_t *)(
10895 data_dma_state.memp + i), data + i, 1,
10896 mode)) {
10897 mutex_enter(&mpt->m_mutex);
10898 status = EFAULT;
10899 mptsas_log(mpt, CE_WARN, "failed to "
10900 "copy out the reply data");
10901 goto out;
10902 }
10903 }
10904 }
10905 }
10906 mutex_enter(&mpt->m_mutex);
10907 out:
10908 /*
10909 * Put the reply frame back on the free queue, increment the free
10910 * index, and write the new index to the free index register. But only
10911 * if this reply is an ADDRESS reply.
10912 */
10913 if (pt_flags & MPTSAS_ADDRESS_REPLY) {
10914 ddi_put32(mpt->m_acc_free_queue_hdl,
10915 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index],
10916 cmd->cmd_rfm);
10917 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
10918 DDI_DMA_SYNC_FORDEV);
10919 if (++mpt->m_free_index == mpt->m_free_queue_depth) {
10920 mpt->m_free_index = 0;
10921 }
10922 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
10923 mpt->m_free_index);
10924 }
10925 if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) {
10926 mptsas_remove_cmd(mpt, cmd);
10927 pt_flags &= (~MPTSAS_REQUEST_POOL_CMD);
10928 }
10929 if (pt_flags & MPTSAS_REQUEST_POOL_CMD)
10930 mptsas_return_to_pool(mpt, cmd);
10931 if (pt_flags & MPTSAS_DATA_ALLOCATED) {
10932 if (mptsas_check_dma_handle(data_dma_state.handle) !=
10933 DDI_SUCCESS) {
10934 ddi_fm_service_impact(mpt->m_dip,
10935 DDI_SERVICE_UNAFFECTED);
10936 status = EFAULT;
10937 }
10938 mptsas_dma_free(&data_dma_state);
10939 }
10940 if (pt_flags & MPTSAS_DATAOUT_ALLOCATED) {
10941 if (mptsas_check_dma_handle(dataout_dma_state.handle) !=
10942 DDI_SUCCESS) {
10943 ddi_fm_service_impact(mpt->m_dip,
10944 DDI_SERVICE_UNAFFECTED);
10945 status = EFAULT;
10946 }
10947 mptsas_dma_free(&dataout_dma_state);
10948 }
10949 if (pt_flags & MPTSAS_CMD_TIMEOUT) {
10950 if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) {
10951 mptsas_log(mpt, CE_WARN, "mptsas_restart_ioc failed");
10952 }
10953 }
10954 if (request_msg)
10955 kmem_free(request_msg, request_size);
10956
10957 return (status);
10958 }
10959
10960 static int
10961 mptsas_pass_thru(mptsas_t *mpt, mptsas_pass_thru_t *data, int mode)
10962 {
10963 /*
10964 * If timeout is 0, set timeout to default of 60 seconds.
10965 */
10966 if (data->Timeout == 0) {
10967 data->Timeout = MPTSAS_PASS_THRU_TIME_DEFAULT;
10968 }
10969
10970 if (((data->DataSize == 0) &&
10971 (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_NONE)) ||
10972 ((data->DataSize != 0) &&
10973 ((data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_READ) ||
10974 (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_WRITE) ||
10975 ((data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_BOTH) &&
10976 (data->DataOutSize != 0))))) {
10977 if (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_BOTH) {
10978 data->DataDirection = MPTSAS_PASS_THRU_DIRECTION_READ;
10979 } else {
10980 data->DataOutSize = 0;
10981 }
10982 /*
10983 * Send passthru request messages
10984 */
10985 return (mptsas_do_passthru(mpt,
10986 (uint8_t *)((uintptr_t)data->PtrRequest),
10987 (uint8_t *)((uintptr_t)data->PtrReply),
10988 (uint8_t *)((uintptr_t)data->PtrData),
10989 data->RequestSize, data->ReplySize,
10990 data->DataSize, data->DataDirection,
10991 (uint8_t *)((uintptr_t)data->PtrDataOut),
10992 data->DataOutSize, data->Timeout, mode));
10993 } else {
10994 return (EINVAL);
10995 }
10996 }
10997
10998 static uint8_t
10999 mptsas_get_fw_diag_buffer_number(mptsas_t *mpt, uint32_t unique_id)
11000 {
11001 uint8_t index;
11002
11003 for (index = 0; index < MPI2_DIAG_BUF_TYPE_COUNT; index++) {
11004 if (mpt->m_fw_diag_buffer_list[index].unique_id == unique_id) {
11005 return (index);
11006 }
11007 }
11008
11009 return (MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND);
11010 }
11011
11012 static void
11013 mptsas_start_diag(mptsas_t *mpt, mptsas_cmd_t *cmd)
11014 {
11015 pMpi2DiagBufferPostRequest_t pDiag_post_msg;
11016 pMpi2DiagReleaseRequest_t pDiag_release_msg;
11017 struct scsi_pkt *pkt = cmd->cmd_pkt;
11018 mptsas_diag_request_t *diag = pkt->pkt_ha_private;
11019 uint32_t request_desc_low, i;
11020
11021 ASSERT(mutex_owned(&mpt->m_mutex));
11022
11023 /*
11024 * Form the diag message depending on the post or release function.
11025 */
11026 if (diag->function == MPI2_FUNCTION_DIAG_BUFFER_POST) {
11027 pDiag_post_msg = (pMpi2DiagBufferPostRequest_t)
11028 (mpt->m_req_frame + (mpt->m_req_frame_size *
11029 cmd->cmd_slot));
11030 bzero(pDiag_post_msg, mpt->m_req_frame_size);
11031 ddi_put8(mpt->m_acc_req_frame_hdl, &pDiag_post_msg->Function,
11032 diag->function);
11033 ddi_put8(mpt->m_acc_req_frame_hdl, &pDiag_post_msg->BufferType,
11034 diag->pBuffer->buffer_type);
11035 ddi_put8(mpt->m_acc_req_frame_hdl,
11036 &pDiag_post_msg->ExtendedType,
11037 diag->pBuffer->extended_type);
11038 ddi_put32(mpt->m_acc_req_frame_hdl,
11039 &pDiag_post_msg->BufferLength,
11040 diag->pBuffer->buffer_data.size);
11041 for (i = 0; i < (sizeof (pDiag_post_msg->ProductSpecific) / 4);
11042 i++) {
11043 ddi_put32(mpt->m_acc_req_frame_hdl,
11044 &pDiag_post_msg->ProductSpecific[i],
11045 diag->pBuffer->product_specific[i]);
11046 }
11047 ddi_put32(mpt->m_acc_req_frame_hdl,
11048 &pDiag_post_msg->BufferAddress.Low,
11049 (uint32_t)(diag->pBuffer->buffer_data.cookie.dmac_laddress
11050 & 0xffffffffull));
11051 ddi_put32(mpt->m_acc_req_frame_hdl,
11052 &pDiag_post_msg->BufferAddress.High,
11053 (uint32_t)(diag->pBuffer->buffer_data.cookie.dmac_laddress
11054 >> 32));
11055 } else {
11056 pDiag_release_msg = (pMpi2DiagReleaseRequest_t)
11057 (mpt->m_req_frame + (mpt->m_req_frame_size *
11058 cmd->cmd_slot));
11059 bzero(pDiag_release_msg, mpt->m_req_frame_size);
11060 ddi_put8(mpt->m_acc_req_frame_hdl,
11061 &pDiag_release_msg->Function, diag->function);
11062 ddi_put8(mpt->m_acc_req_frame_hdl,
11063 &pDiag_release_msg->BufferType,
11064 diag->pBuffer->buffer_type);
11065 }
11066
11067 /*
11068 * Send the message
11069 */
11070 (void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0,
11071 DDI_DMA_SYNC_FORDEV);
11072 request_desc_low = (cmd->cmd_slot << 16) +
11073 MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
11074 cmd->cmd_rfm = NULL;
11075 MPTSAS_START_CMD(mpt, request_desc_low, 0);
11076 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) !=
11077 DDI_SUCCESS) ||
11078 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) !=
11079 DDI_SUCCESS)) {
11080 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
11081 }
11082 }
11083
11084 static int
11085 mptsas_post_fw_diag_buffer(mptsas_t *mpt,
11086 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code)
11087 {
11088 mptsas_diag_request_t diag;
11089 int status, slot_num, post_flags = 0;
11090 mptsas_cmd_t *cmd = NULL;
11091 struct scsi_pkt *pkt;
11092 pMpi2DiagBufferPostReply_t reply;
11093 uint16_t iocstatus;
11094 uint32_t iocloginfo, transfer_length;
11095
11096 /*
11097 * If buffer is not enabled, just leave.
11098 */
11099 *return_code = MPTSAS_FW_DIAG_ERROR_POST_FAILED;
11100 if (!pBuffer->enabled) {
11101 status = DDI_FAILURE;
11102 goto out;
11103 }
11104
11105 /*
11106 * Clear some flags initially.
11107 */
11108 pBuffer->force_release = FALSE;
11109 pBuffer->valid_data = FALSE;
11110 pBuffer->owned_by_firmware = FALSE;
11111
11112 /*
11113 * Get a cmd buffer from the cmd buffer pool
11114 */
11115 if ((slot_num = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) {
11116 status = DDI_FAILURE;
11117 mptsas_log(mpt, CE_NOTE, "command pool is full: Post FW Diag");
11118 goto out;
11119 }
11120 post_flags |= MPTSAS_REQUEST_POOL_CMD;
11121
11122 bzero((caddr_t)cmd, sizeof (*cmd));
11123 bzero((caddr_t)pkt, scsi_pkt_size());
11124
11125 cmd->ioc_cmd_slot = (uint32_t)(slot_num);
11126
11127 diag.pBuffer = pBuffer;
11128 diag.function = MPI2_FUNCTION_DIAG_BUFFER_POST;
11129
11130 /*
11131 * Form a blank cmd/pkt to store the acknowledgement message
11132 */
11133 pkt->pkt_ha_private = (opaque_t)&diag;
11134 pkt->pkt_flags = FLAG_HEAD;
11135 pkt->pkt_time = 60;
11136 cmd->cmd_pkt = pkt;
11137 cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_FW_DIAG;
11138
11139 /*
11140 * Save the command in a slot
11141 */
11142 if (mptsas_save_cmd(mpt, cmd) == TRUE) {
11143 /*
11144 * Once passthru command get slot, set cmd_flags
11145 * CFLAG_PREPARED.
11146 */
11147 cmd->cmd_flags |= CFLAG_PREPARED;
11148 mptsas_start_diag(mpt, cmd);
11149 } else {
11150 mptsas_waitq_add(mpt, cmd);
11151 }
11152
11153 while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) {
11154 cv_wait(&mpt->m_fw_diag_cv, &mpt->m_mutex);
11155 }
11156
11157 if (cmd->cmd_flags & CFLAG_TIMEOUT) {
11158 status = DDI_FAILURE;
11159 mptsas_log(mpt, CE_WARN, "Post FW Diag command timeout");
11160 goto out;
11161 }
11162
11163 /*
11164 * cmd_rfm points to the reply message if a reply was given. Check the
11165 * IOCStatus to make sure everything went OK with the FW diag request
11166 * and set buffer flags.
11167 */
11168 if (cmd->cmd_rfm) {
11169 post_flags |= MPTSAS_ADDRESS_REPLY;
11170 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
11171 DDI_DMA_SYNC_FORCPU);
11172 reply = (pMpi2DiagBufferPostReply_t)(mpt->m_reply_frame +
11173 (cmd->cmd_rfm - mpt->m_reply_frame_dma_addr));
11174
11175 /*
11176 * Get the reply message data
11177 */
11178 iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
11179 &reply->IOCStatus);
11180 iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl,
11181 &reply->IOCLogInfo);
11182 transfer_length = ddi_get32(mpt->m_acc_reply_frame_hdl,
11183 &reply->TransferLength);
11184
11185 /*
11186 * If post failed quit.
11187 */
11188 if (iocstatus != MPI2_IOCSTATUS_SUCCESS) {
11189 status = DDI_FAILURE;
11190 NDBG13(("post FW Diag Buffer failed: IOCStatus=0x%x, "
11191 "IOCLogInfo=0x%x, TransferLength=0x%x", iocstatus,
11192 iocloginfo, transfer_length));
11193 goto out;
11194 }
11195
11196 /*
11197 * Post was successful.
11198 */
11199 pBuffer->valid_data = TRUE;
11200 pBuffer->owned_by_firmware = TRUE;
11201 *return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS;
11202 status = DDI_SUCCESS;
11203 }
11204
11205 out:
11206 /*
11207 * Put the reply frame back on the free queue, increment the free
11208 * index, and write the new index to the free index register. But only
11209 * if this reply is an ADDRESS reply.
11210 */
11211 if (post_flags & MPTSAS_ADDRESS_REPLY) {
11212 ddi_put32(mpt->m_acc_free_queue_hdl,
11213 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index],
11214 cmd->cmd_rfm);
11215 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
11216 DDI_DMA_SYNC_FORDEV);
11217 if (++mpt->m_free_index == mpt->m_free_queue_depth) {
11218 mpt->m_free_index = 0;
11219 }
11220 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
11221 mpt->m_free_index);
11222 }
11223 if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) {
11224 mptsas_remove_cmd(mpt, cmd);
11225 post_flags &= (~MPTSAS_REQUEST_POOL_CMD);
11226 }
11227 if (post_flags & MPTSAS_REQUEST_POOL_CMD) {
11228 mptsas_return_to_pool(mpt, cmd);
11229 }
11230
11231 return (status);
11232 }
11233
11234 static int
11235 mptsas_release_fw_diag_buffer(mptsas_t *mpt,
11236 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code,
11237 uint32_t diag_type)
11238 {
11239 mptsas_diag_request_t diag;
11240 int status, slot_num, rel_flags = 0;
11241 mptsas_cmd_t *cmd = NULL;
11242 struct scsi_pkt *pkt;
11243 pMpi2DiagReleaseReply_t reply;
11244 uint16_t iocstatus;
11245 uint32_t iocloginfo;
11246
11247 /*
11248 * If buffer is not enabled, just leave.
11249 */
11250 *return_code = MPTSAS_FW_DIAG_ERROR_RELEASE_FAILED;
11251 if (!pBuffer->enabled) {
11252 mptsas_log(mpt, CE_NOTE, "This buffer type is not supported "
11253 "by the IOC");
11254 status = DDI_FAILURE;
11255 goto out;
11256 }
11257
11258 /*
11259 * Clear some flags initially.
11260 */
11261 pBuffer->force_release = FALSE;
11262 pBuffer->valid_data = FALSE;
11263 pBuffer->owned_by_firmware = FALSE;
11264
11265 /*
11266 * Get a cmd buffer from the cmd buffer pool
11267 */
11268 if ((slot_num = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) {
11269 status = DDI_FAILURE;
11270 mptsas_log(mpt, CE_NOTE, "command pool is full: Release FW "
11271 "Diag");
11272 goto out;
11273 }
11274 rel_flags |= MPTSAS_REQUEST_POOL_CMD;
11275
11276 bzero((caddr_t)cmd, sizeof (*cmd));
11277 bzero((caddr_t)pkt, scsi_pkt_size());
11278
11279 cmd->ioc_cmd_slot = (uint32_t)(slot_num);
11280
11281 diag.pBuffer = pBuffer;
11282 diag.function = MPI2_FUNCTION_DIAG_RELEASE;
11283
11284 /*
11285 * Form a blank cmd/pkt to store the acknowledgement message
11286 */
11287 pkt->pkt_ha_private = (opaque_t)&diag;
11288 pkt->pkt_flags = FLAG_HEAD;
11289 pkt->pkt_time = 60;
11290 cmd->cmd_pkt = pkt;
11291 cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_FW_DIAG;
11292
11293 /*
11294 * Save the command in a slot
11295 */
11296 if (mptsas_save_cmd(mpt, cmd) == TRUE) {
11297 /*
11298 * Once passthru command get slot, set cmd_flags
11299 * CFLAG_PREPARED.
11300 */
11301 cmd->cmd_flags |= CFLAG_PREPARED;
11302 mptsas_start_diag(mpt, cmd);
11303 } else {
11304 mptsas_waitq_add(mpt, cmd);
11305 }
11306
11307 while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) {
11308 cv_wait(&mpt->m_fw_diag_cv, &mpt->m_mutex);
11309 }
11310
11311 if (cmd->cmd_flags & CFLAG_TIMEOUT) {
11312 status = DDI_FAILURE;
11313 mptsas_log(mpt, CE_WARN, "Release FW Diag command timeout");
11314 goto out;
11315 }
11316
11317 /*
11318 * cmd_rfm points to the reply message if a reply was given. Check the
11319 * IOCStatus to make sure everything went OK with the FW diag request
11320 * and set buffer flags.
11321 */
11322 if (cmd->cmd_rfm) {
11323 rel_flags |= MPTSAS_ADDRESS_REPLY;
11324 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
11325 DDI_DMA_SYNC_FORCPU);
11326 reply = (pMpi2DiagReleaseReply_t)(mpt->m_reply_frame +
11327 (cmd->cmd_rfm - mpt->m_reply_frame_dma_addr));
11328
11329 /*
11330 * Get the reply message data
11331 */
11332 iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
11333 &reply->IOCStatus);
11334 iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl,
11335 &reply->IOCLogInfo);
11336
11337 /*
11338 * If release failed quit.
11339 */
11340 if ((iocstatus != MPI2_IOCSTATUS_SUCCESS) ||
11341 pBuffer->owned_by_firmware) {
11342 status = DDI_FAILURE;
11343 NDBG13(("release FW Diag Buffer failed: "
11344 "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus,
11345 iocloginfo));
11346 goto out;
11347 }
11348
11349 /*
11350 * Release was successful.
11351 */
11352 *return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS;
11353 status = DDI_SUCCESS;
11354
11355 /*
11356 * If this was for an UNREGISTER diag type command, clear the
11357 * unique ID.
11358 */
11359 if (diag_type == MPTSAS_FW_DIAG_TYPE_UNREGISTER) {
11360 pBuffer->unique_id = MPTSAS_FW_DIAG_INVALID_UID;
11361 }
11362 }
11363
11364 out:
11365 /*
11366 * Put the reply frame back on the free queue, increment the free
11367 * index, and write the new index to the free index register. But only
11368 * if this reply is an ADDRESS reply.
11369 */
11370 if (rel_flags & MPTSAS_ADDRESS_REPLY) {
11371 ddi_put32(mpt->m_acc_free_queue_hdl,
11372 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index],
11373 cmd->cmd_rfm);
11374 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
11375 DDI_DMA_SYNC_FORDEV);
11376 if (++mpt->m_free_index == mpt->m_free_queue_depth) {
11377 mpt->m_free_index = 0;
11378 }
11379 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
11380 mpt->m_free_index);
11381 }
11382 if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) {
11383 mptsas_remove_cmd(mpt, cmd);
11384 rel_flags &= (~MPTSAS_REQUEST_POOL_CMD);
11385 }
11386 if (rel_flags & MPTSAS_REQUEST_POOL_CMD) {
11387 mptsas_return_to_pool(mpt, cmd);
11388 }
11389
11390 return (status);
11391 }
11392
11393 static int
11394 mptsas_diag_register(mptsas_t *mpt, mptsas_fw_diag_register_t *diag_register,
11395 uint32_t *return_code)
11396 {
11397 mptsas_fw_diagnostic_buffer_t *pBuffer;
11398 uint8_t extended_type, buffer_type, i;
11399 uint32_t buffer_size;
11400 uint32_t unique_id;
11401 int status;
11402
11403 ASSERT(mutex_owned(&mpt->m_mutex));
11404
11405 extended_type = diag_register->ExtendedType;
11406 buffer_type = diag_register->BufferType;
11407 buffer_size = diag_register->RequestedBufferSize;
11408 unique_id = diag_register->UniqueId;
11409
11410 /*
11411 * Check for valid buffer type
11412 */
11413 if (buffer_type >= MPI2_DIAG_BUF_TYPE_COUNT) {
11414 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
11415 return (DDI_FAILURE);
11416 }
11417
11418 /*
11419 * Get the current buffer and look up the unique ID. The unique ID
11420 * should not be found. If it is, the ID is already in use.
11421 */
11422 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id);
11423 pBuffer = &mpt->m_fw_diag_buffer_list[buffer_type];
11424 if (i != MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) {
11425 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
11426 return (DDI_FAILURE);
11427 }
11428
11429 /*
11430 * The buffer's unique ID should not be registered yet, and the given
11431 * unique ID cannot be 0.
11432 */
11433 if ((pBuffer->unique_id != MPTSAS_FW_DIAG_INVALID_UID) ||
11434 (unique_id == MPTSAS_FW_DIAG_INVALID_UID)) {
11435 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
11436 return (DDI_FAILURE);
11437 }
11438
11439 /*
11440 * If this buffer is already posted as immediate, just change owner.
11441 */
11442 if (pBuffer->immediate && pBuffer->owned_by_firmware &&
11443 (pBuffer->unique_id == MPTSAS_FW_DIAG_INVALID_UID)) {
11444 pBuffer->immediate = FALSE;
11445 pBuffer->unique_id = unique_id;
11446 return (DDI_SUCCESS);
11447 }
11448
11449 /*
11450 * Post a new buffer after checking if it's enabled. The DMA buffer
11451 * that is allocated will be contiguous (sgl_len = 1).
11452 */
11453 if (!pBuffer->enabled) {
11454 *return_code = MPTSAS_FW_DIAG_ERROR_NO_BUFFER;
11455 return (DDI_FAILURE);
11456 }
11457 bzero(&pBuffer->buffer_data, sizeof (mptsas_dma_alloc_state_t));
11458 pBuffer->buffer_data.size = buffer_size;
11459 if (mptsas_dma_alloc(mpt, &pBuffer->buffer_data) != DDI_SUCCESS) {
11460 mptsas_log(mpt, CE_WARN, "failed to alloc DMA resource for "
11461 "diag buffer: size = %d bytes", buffer_size);
11462 *return_code = MPTSAS_FW_DIAG_ERROR_NO_BUFFER;
11463 return (DDI_FAILURE);
11464 }
11465
11466 /*
11467 * Copy the given info to the diag buffer and post the buffer.
11468 */
11469 pBuffer->buffer_type = buffer_type;
11470 pBuffer->immediate = FALSE;
11471 if (buffer_type == MPI2_DIAG_BUF_TYPE_TRACE) {
11472 for (i = 0; i < (sizeof (pBuffer->product_specific) / 4);
11473 i++) {
11474 pBuffer->product_specific[i] =
11475 diag_register->ProductSpecific[i];
11476 }
11477 }
11478 pBuffer->extended_type = extended_type;
11479 pBuffer->unique_id = unique_id;
11480 status = mptsas_post_fw_diag_buffer(mpt, pBuffer, return_code);
11481
11482 if (mptsas_check_dma_handle(pBuffer->buffer_data.handle) !=
11483 DDI_SUCCESS) {
11484 mptsas_log(mpt, CE_WARN, "Check of DMA handle failed in "
11485 "mptsas_diag_register.");
11486 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
11487 status = DDI_FAILURE;
11488 }
11489
11490 /*
11491 * In case there was a failure, free the DMA buffer.
11492 */
11493 if (status == DDI_FAILURE) {
11494 mptsas_dma_free(&pBuffer->buffer_data);
11495 }
11496
11497 return (status);
11498 }
11499
11500 static int
11501 mptsas_diag_unregister(mptsas_t *mpt,
11502 mptsas_fw_diag_unregister_t *diag_unregister, uint32_t *return_code)
11503 {
11504 mptsas_fw_diagnostic_buffer_t *pBuffer;
11505 uint8_t i;
11506 uint32_t unique_id;
11507 int status;
11508
11509 ASSERT(mutex_owned(&mpt->m_mutex));
11510
11511 unique_id = diag_unregister->UniqueId;
11512
11513 /*
11514 * Get the current buffer and look up the unique ID. The unique ID
11515 * should be there.
11516 */
11517 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id);
11518 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) {
11519 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
11520 return (DDI_FAILURE);
11521 }
11522
11523 pBuffer = &mpt->m_fw_diag_buffer_list[i];
11524
11525 /*
11526 * Try to release the buffer from FW before freeing it. If release
11527 * fails, don't free the DMA buffer in case FW tries to access it
11528 * later. If buffer is not owned by firmware, can't release it.
11529 */
11530 if (!pBuffer->owned_by_firmware) {
11531 status = DDI_SUCCESS;
11532 } else {
11533 status = mptsas_release_fw_diag_buffer(mpt, pBuffer,
11534 return_code, MPTSAS_FW_DIAG_TYPE_UNREGISTER);
11535 }
11536
11537 /*
11538 * At this point, return the current status no matter what happens with
11539 * the DMA buffer.
11540 */
11541 pBuffer->unique_id = MPTSAS_FW_DIAG_INVALID_UID;
11542 if (status == DDI_SUCCESS) {
11543 if (mptsas_check_dma_handle(pBuffer->buffer_data.handle) !=
11544 DDI_SUCCESS) {
11545 mptsas_log(mpt, CE_WARN, "Check of DMA handle failed "
11546 "in mptsas_diag_unregister.");
11547 ddi_fm_service_impact(mpt->m_dip,
11548 DDI_SERVICE_UNAFFECTED);
11549 }
11550 mptsas_dma_free(&pBuffer->buffer_data);
11551 }
11552
11553 return (status);
11554 }
11555
11556 static int
11557 mptsas_diag_query(mptsas_t *mpt, mptsas_fw_diag_query_t *diag_query,
11558 uint32_t *return_code)
11559 {
11560 mptsas_fw_diagnostic_buffer_t *pBuffer;
11561 uint8_t i;
11562 uint32_t unique_id;
11563
11564 ASSERT(mutex_owned(&mpt->m_mutex));
11565
11566 unique_id = diag_query->UniqueId;
11567
11568 /*
11569 * If ID is valid, query on ID.
11570 * If ID is invalid, query on buffer type.
11571 */
11572 if (unique_id == MPTSAS_FW_DIAG_INVALID_UID) {
11573 i = diag_query->BufferType;
11574 if (i >= MPI2_DIAG_BUF_TYPE_COUNT) {
11575 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
11576 return (DDI_FAILURE);
11577 }
11578 } else {
11579 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id);
11580 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) {
11581 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
11582 return (DDI_FAILURE);
11583 }
11584 }
11585
11586 /*
11587 * Fill query structure with the diag buffer info.
11588 */
11589 pBuffer = &mpt->m_fw_diag_buffer_list[i];
11590 diag_query->BufferType = pBuffer->buffer_type;
11591 diag_query->ExtendedType = pBuffer->extended_type;
11592 if (diag_query->BufferType == MPI2_DIAG_BUF_TYPE_TRACE) {
11593 for (i = 0; i < (sizeof (diag_query->ProductSpecific) / 4);
11594 i++) {
11595 diag_query->ProductSpecific[i] =
11596 pBuffer->product_specific[i];
11597 }
11598 }
11599 diag_query->TotalBufferSize = pBuffer->buffer_data.size;
11600 diag_query->DriverAddedBufferSize = 0;
11601 diag_query->UniqueId = pBuffer->unique_id;
11602 diag_query->ApplicationFlags = 0;
11603 diag_query->DiagnosticFlags = 0;
11604
11605 /*
11606 * Set/Clear application flags
11607 */
11608 if (pBuffer->immediate) {
11609 diag_query->ApplicationFlags &= ~MPTSAS_FW_DIAG_FLAG_APP_OWNED;
11610 } else {
11611 diag_query->ApplicationFlags |= MPTSAS_FW_DIAG_FLAG_APP_OWNED;
11612 }
11613 if (pBuffer->valid_data || pBuffer->owned_by_firmware) {
11614 diag_query->ApplicationFlags |=
11615 MPTSAS_FW_DIAG_FLAG_BUFFER_VALID;
11616 } else {
11617 diag_query->ApplicationFlags &=
11618 ~MPTSAS_FW_DIAG_FLAG_BUFFER_VALID;
11619 }
11620 if (pBuffer->owned_by_firmware) {
11621 diag_query->ApplicationFlags |=
11622 MPTSAS_FW_DIAG_FLAG_FW_BUFFER_ACCESS;
11623 } else {
11624 diag_query->ApplicationFlags &=
11625 ~MPTSAS_FW_DIAG_FLAG_FW_BUFFER_ACCESS;
11626 }
11627
11628 return (DDI_SUCCESS);
11629 }
11630
11631 static int
11632 mptsas_diag_read_buffer(mptsas_t *mpt,
11633 mptsas_diag_read_buffer_t *diag_read_buffer, uint8_t *ioctl_buf,
11634 uint32_t *return_code, int ioctl_mode)
11635 {
11636 mptsas_fw_diagnostic_buffer_t *pBuffer;
11637 uint8_t i, *pData;
11638 uint32_t unique_id, byte;
11639 int status;
11640
11641 ASSERT(mutex_owned(&mpt->m_mutex));
11642
11643 unique_id = diag_read_buffer->UniqueId;
11644
11645 /*
11646 * Get the current buffer and look up the unique ID. The unique ID
11647 * should be there.
11648 */
11649 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id);
11650 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) {
11651 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
11652 return (DDI_FAILURE);
11653 }
11654
11655 pBuffer = &mpt->m_fw_diag_buffer_list[i];
11656
11657 /*
11658 * Make sure requested read is within limits
11659 */
11660 if (diag_read_buffer->StartingOffset + diag_read_buffer->BytesToRead >
11661 pBuffer->buffer_data.size) {
11662 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
11663 return (DDI_FAILURE);
11664 }
11665
11666 /*
11667 * Copy the requested data from DMA to the diag_read_buffer. The DMA
11668 * buffer that was allocated is one contiguous buffer.
11669 */
11670 pData = (uint8_t *)(pBuffer->buffer_data.memp +
11671 diag_read_buffer->StartingOffset);
11672 (void) ddi_dma_sync(pBuffer->buffer_data.handle, 0, 0,
11673 DDI_DMA_SYNC_FORCPU);
11674 for (byte = 0; byte < diag_read_buffer->BytesToRead; byte++) {
11675 if (ddi_copyout(pData + byte, ioctl_buf + byte, 1, ioctl_mode)
11676 != 0) {
11677 return (DDI_FAILURE);
11678 }
11679 }
11680 diag_read_buffer->Status = 0;
11681
11682 /*
11683 * Set or clear the Force Release flag.
11684 */
11685 if (pBuffer->force_release) {
11686 diag_read_buffer->Flags |= MPTSAS_FW_DIAG_FLAG_FORCE_RELEASE;
11687 } else {
11688 diag_read_buffer->Flags &= ~MPTSAS_FW_DIAG_FLAG_FORCE_RELEASE;
11689 }
11690
11691 /*
11692 * If buffer is to be reregistered, make sure it's not already owned by
11693 * firmware first.
11694 */
11695 status = DDI_SUCCESS;
11696 if (!pBuffer->owned_by_firmware) {
11697 if (diag_read_buffer->Flags & MPTSAS_FW_DIAG_FLAG_REREGISTER) {
11698 status = mptsas_post_fw_diag_buffer(mpt, pBuffer,
11699 return_code);
11700 }
11701 }
11702
11703 return (status);
11704 }
11705
11706 static int
11707 mptsas_diag_release(mptsas_t *mpt, mptsas_fw_diag_release_t *diag_release,
11708 uint32_t *return_code)
11709 {
11710 mptsas_fw_diagnostic_buffer_t *pBuffer;
11711 uint8_t i;
11712 uint32_t unique_id;
11713 int status;
11714
11715 ASSERT(mutex_owned(&mpt->m_mutex));
11716
11717 unique_id = diag_release->UniqueId;
11718
11719 /*
11720 * Get the current buffer and look up the unique ID. The unique ID
11721 * should be there.
11722 */
11723 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id);
11724 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) {
11725 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
11726 return (DDI_FAILURE);
11727 }
11728
11729 pBuffer = &mpt->m_fw_diag_buffer_list[i];
11730
11731 /*
11732 * If buffer is not owned by firmware, it's already been released.
11733 */
11734 if (!pBuffer->owned_by_firmware) {
11735 *return_code = MPTSAS_FW_DIAG_ERROR_ALREADY_RELEASED;
11736 return (DDI_FAILURE);
11737 }
11738
11739 /*
11740 * Release the buffer.
11741 */
11742 status = mptsas_release_fw_diag_buffer(mpt, pBuffer, return_code,
11743 MPTSAS_FW_DIAG_TYPE_RELEASE);
11744 return (status);
11745 }
11746
11747 static int
11748 mptsas_do_diag_action(mptsas_t *mpt, uint32_t action, uint8_t *diag_action,
11749 uint32_t length, uint32_t *return_code, int ioctl_mode)
11750 {
11751 mptsas_fw_diag_register_t diag_register;
11752 mptsas_fw_diag_unregister_t diag_unregister;
11753 mptsas_fw_diag_query_t diag_query;
11754 mptsas_diag_read_buffer_t diag_read_buffer;
11755 mptsas_fw_diag_release_t diag_release;
11756 int status = DDI_SUCCESS;
11757 uint32_t original_return_code, read_buf_len;
11758
11759 ASSERT(mutex_owned(&mpt->m_mutex));
11760
11761 original_return_code = *return_code;
11762 *return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS;
11763
11764 switch (action) {
11765 case MPTSAS_FW_DIAG_TYPE_REGISTER:
11766 if (!length) {
11767 *return_code =
11768 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
11769 status = DDI_FAILURE;
11770 break;
11771 }
11772 if (ddi_copyin(diag_action, &diag_register,
11773 sizeof (diag_register), ioctl_mode) != 0) {
11774 return (DDI_FAILURE);
11775 }
11776 status = mptsas_diag_register(mpt, &diag_register,
11777 return_code);
11778 break;
11779
11780 case MPTSAS_FW_DIAG_TYPE_UNREGISTER:
11781 if (length < sizeof (diag_unregister)) {
11782 *return_code =
11783 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
11784 status = DDI_FAILURE;
11785 break;
11786 }
11787 if (ddi_copyin(diag_action, &diag_unregister,
11788 sizeof (diag_unregister), ioctl_mode) != 0) {
11789 return (DDI_FAILURE);
11790 }
11791 status = mptsas_diag_unregister(mpt, &diag_unregister,
11792 return_code);
11793 break;
11794
11795 case MPTSAS_FW_DIAG_TYPE_QUERY:
11796 if (length < sizeof (diag_query)) {
11797 *return_code =
11798 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
11799 status = DDI_FAILURE;
11800 break;
11801 }
11802 if (ddi_copyin(diag_action, &diag_query,
11803 sizeof (diag_query), ioctl_mode) != 0) {
11804 return (DDI_FAILURE);
11805 }
11806 status = mptsas_diag_query(mpt, &diag_query,
11807 return_code);
11808 if (status == DDI_SUCCESS) {
11809 if (ddi_copyout(&diag_query, diag_action,
11810 sizeof (diag_query), ioctl_mode) != 0) {
11811 return (DDI_FAILURE);
11812 }
11813 }
11814 break;
11815
11816 case MPTSAS_FW_DIAG_TYPE_READ_BUFFER:
11817 if (ddi_copyin(diag_action, &diag_read_buffer,
11818 sizeof (diag_read_buffer) - 4, ioctl_mode) != 0) {
11819 return (DDI_FAILURE);
11820 }
11821 read_buf_len = sizeof (diag_read_buffer) -
11822 sizeof (diag_read_buffer.DataBuffer) +
11823 diag_read_buffer.BytesToRead;
11824 if (length < read_buf_len) {
11825 *return_code =
11826 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
11827 status = DDI_FAILURE;
11828 break;
11829 }
11830 status = mptsas_diag_read_buffer(mpt,
11831 &diag_read_buffer, diag_action +
11832 sizeof (diag_read_buffer) - 4, return_code,
11833 ioctl_mode);
11834 if (status == DDI_SUCCESS) {
11835 if (ddi_copyout(&diag_read_buffer, diag_action,
11836 sizeof (diag_read_buffer) - 4, ioctl_mode)
11837 != 0) {
11838 return (DDI_FAILURE);
11839 }
11840 }
11841 break;
11842
11843 case MPTSAS_FW_DIAG_TYPE_RELEASE:
11844 if (length < sizeof (diag_release)) {
11845 *return_code =
11846 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
11847 status = DDI_FAILURE;
11848 break;
11849 }
11850 if (ddi_copyin(diag_action, &diag_release,
11851 sizeof (diag_release), ioctl_mode) != 0) {
11852 return (DDI_FAILURE);
11853 }
11854 status = mptsas_diag_release(mpt, &diag_release,
11855 return_code);
11856 break;
11857
11858 default:
11859 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
11860 status = DDI_FAILURE;
11861 break;
11862 }
11863
11864 if ((status == DDI_FAILURE) &&
11865 (original_return_code == MPTSAS_FW_DIAG_NEW) &&
11866 (*return_code != MPTSAS_FW_DIAG_ERROR_SUCCESS)) {
11867 status = DDI_SUCCESS;
11868 }
11869
11870 return (status);
11871 }
11872
11873 static int
11874 mptsas_diag_action(mptsas_t *mpt, mptsas_diag_action_t *user_data, int mode)
11875 {
11876 int status;
11877 mptsas_diag_action_t driver_data;
11878
11879 ASSERT(mutex_owned(&mpt->m_mutex));
11880
11881 /*
11882 * Copy the user data to a driver data buffer.
11883 */
11884 if (ddi_copyin(user_data, &driver_data, sizeof (mptsas_diag_action_t),
11885 mode) == 0) {
11886 /*
11887 * Send diag action request if Action is valid
11888 */
11889 if (driver_data.Action == MPTSAS_FW_DIAG_TYPE_REGISTER ||
11890 driver_data.Action == MPTSAS_FW_DIAG_TYPE_UNREGISTER ||
11891 driver_data.Action == MPTSAS_FW_DIAG_TYPE_QUERY ||
11892 driver_data.Action == MPTSAS_FW_DIAG_TYPE_READ_BUFFER ||
11893 driver_data.Action == MPTSAS_FW_DIAG_TYPE_RELEASE) {
11894 status = mptsas_do_diag_action(mpt, driver_data.Action,
11895 (void *)(uintptr_t)driver_data.PtrDiagAction,
11896 driver_data.Length, &driver_data.ReturnCode,
11897 mode);
11898 if (status == DDI_SUCCESS) {
11899 if (ddi_copyout(&driver_data.ReturnCode,
11900 &user_data->ReturnCode,
11901 sizeof (user_data->ReturnCode), mode)
11902 != 0) {
11903 status = EFAULT;
11904 } else {
11905 status = 0;
11906 }
11907 } else {
11908 status = EIO;
11909 }
11910 } else {
11911 status = EINVAL;
11912 }
11913 } else {
11914 status = EFAULT;
11915 }
11916
11917 return (status);
11918 }
11919
11920 /*
11921 * This routine handles the "event query" ioctl.
11922 */
11923 static int
11924 mptsas_event_query(mptsas_t *mpt, mptsas_event_query_t *data, int mode,
11925 int *rval)
11926 {
11927 int status;
11928 mptsas_event_query_t driverdata;
11929 uint8_t i;
11930
11931 driverdata.Entries = MPTSAS_EVENT_QUEUE_SIZE;
11932
11933 mutex_enter(&mpt->m_mutex);
11934 for (i = 0; i < 4; i++) {
11935 driverdata.Types[i] = mpt->m_event_mask[i];
11936 }
11937 mutex_exit(&mpt->m_mutex);
11938
11939 if (ddi_copyout(&driverdata, data, sizeof (driverdata), mode) != 0) {
11940 status = EFAULT;
11941 } else {
11942 *rval = MPTIOCTL_STATUS_GOOD;
11943 status = 0;
11944 }
11945
11946 return (status);
11947 }
11948
11949 /*
11950 * This routine handles the "event enable" ioctl.
11951 */
11952 static int
11953 mptsas_event_enable(mptsas_t *mpt, mptsas_event_enable_t *data, int mode,
11954 int *rval)
11955 {
11956 int status;
11957 mptsas_event_enable_t driverdata;
11958 uint8_t i;
11959
11960 if (ddi_copyin(data, &driverdata, sizeof (driverdata), mode) == 0) {
11961 mutex_enter(&mpt->m_mutex);
11962 for (i = 0; i < 4; i++) {
11963 mpt->m_event_mask[i] = driverdata.Types[i];
11964 }
11965 mutex_exit(&mpt->m_mutex);
11966
11967 *rval = MPTIOCTL_STATUS_GOOD;
11968 status = 0;
11969 } else {
11970 status = EFAULT;
11971 }
11972 return (status);
11973 }
11974
11975 /*
11976 * This routine handles the "event report" ioctl.
11977 */
11978 static int
11979 mptsas_event_report(mptsas_t *mpt, mptsas_event_report_t *data, int mode,
11980 int *rval)
11981 {
11982 int status;
11983 mptsas_event_report_t driverdata;
11984
11985 mutex_enter(&mpt->m_mutex);
11986
11987 if (ddi_copyin(&data->Size, &driverdata.Size, sizeof (driverdata.Size),
11988 mode) == 0) {
11989 if (driverdata.Size >= sizeof (mpt->m_events)) {
11990 if (ddi_copyout(mpt->m_events, data->Events,
11991 sizeof (mpt->m_events), mode) != 0) {
11992 status = EFAULT;
11993 } else {
11994 if (driverdata.Size > sizeof (mpt->m_events)) {
11995 driverdata.Size =
11996 sizeof (mpt->m_events);
11997 if (ddi_copyout(&driverdata.Size,
11998 &data->Size,
11999 sizeof (driverdata.Size),
12000 mode) != 0) {
12001 status = EFAULT;
12002 } else {
12003 *rval = MPTIOCTL_STATUS_GOOD;
12004 status = 0;
12005 }
12006 } else {
12007 *rval = MPTIOCTL_STATUS_GOOD;
12008 status = 0;
12009 }
12010 }
12011 } else {
12012 *rval = MPTIOCTL_STATUS_LEN_TOO_SHORT;
12013 status = 0;
12014 }
12015 } else {
12016 status = EFAULT;
12017 }
12018
12019 mutex_exit(&mpt->m_mutex);
12020 return (status);
12021 }
12022
12023 static void
12024 mptsas_lookup_pci_data(mptsas_t *mpt, mptsas_adapter_data_t *adapter_data)
12025 {
12026 int *reg_data;
12027 uint_t reglen;
12028
12029 /*
12030 * Lookup the 'reg' property and extract the other data
12031 */
12032 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, mpt->m_dip,
12033 DDI_PROP_DONTPASS, "reg", ®_data, ®len) ==
12034 DDI_PROP_SUCCESS) {
12035 /*
12036 * Extract the PCI data from the 'reg' property first DWORD.
12037 * The entry looks like the following:
12038 * First DWORD:
12039 * Bits 0 - 7 8-bit Register number
12040 * Bits 8 - 10 3-bit Function number
12041 * Bits 11 - 15 5-bit Device number
12042 * Bits 16 - 23 8-bit Bus number
12043 * Bits 24 - 25 2-bit Address Space type identifier
12044 *
12045 */
12046 adapter_data->PciInformation.u.bits.BusNumber =
12047 (reg_data[0] & 0x00FF0000) >> 16;
12048 adapter_data->PciInformation.u.bits.DeviceNumber =
12049 (reg_data[0] & 0x0000F800) >> 11;
12050 adapter_data->PciInformation.u.bits.FunctionNumber =
12051 (reg_data[0] & 0x00000700) >> 8;
12052 ddi_prop_free((void *)reg_data);
12053 } else {
12054 /*
12055 * If we can't determine the PCI data then we fill in FF's for
12056 * the data to indicate this.
12057 */
12058 adapter_data->PCIDeviceHwId = 0xFFFFFFFF;
12059 adapter_data->MpiPortNumber = 0xFFFFFFFF;
12060 adapter_data->PciInformation.u.AsDWORD = 0xFFFFFFFF;
12061 }
12062
12063 /*
12064 * Saved in the mpt->m_fwversion
12065 */
12066 adapter_data->MpiFirmwareVersion = mpt->m_fwversion;
12067 }
12068
12069 static void
12070 mptsas_read_adapter_data(mptsas_t *mpt, mptsas_adapter_data_t *adapter_data)
12071 {
12072 char *driver_verstr = MPTSAS_MOD_STRING;
12073
12074 mptsas_lookup_pci_data(mpt, adapter_data);
12075 adapter_data->AdapterType = mpt->m_MPI25 ?
12076 MPTIOCTL_ADAPTER_TYPE_SAS3 :
12077 MPTIOCTL_ADAPTER_TYPE_SAS2;
12078 adapter_data->PCIDeviceHwId = (uint32_t)mpt->m_devid;
12079 adapter_data->PCIDeviceHwRev = (uint32_t)mpt->m_revid;
12080 adapter_data->SubSystemId = (uint32_t)mpt->m_ssid;
12081 adapter_data->SubsystemVendorId = (uint32_t)mpt->m_svid;
12082 (void) strcpy((char *)&adapter_data->DriverVersion[0], driver_verstr);
12083 adapter_data->BiosVersion = 0;
12084 (void) mptsas_get_bios_page3(mpt, &adapter_data->BiosVersion);
12085 }
12086
12087 static void
12088 mptsas_read_pci_info(mptsas_t *mpt, mptsas_pci_info_t *pci_info)
12089 {
12090 int *reg_data, i;
12091 uint_t reglen;
12092
12093 /*
12094 * Lookup the 'reg' property and extract the other data
12095 */
12096 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, mpt->m_dip,
12097 DDI_PROP_DONTPASS, "reg", ®_data, ®len) ==
12098 DDI_PROP_SUCCESS) {
12099 /*
12100 * Extract the PCI data from the 'reg' property first DWORD.
12101 * The entry looks like the following:
12102 * First DWORD:
12103 * Bits 8 - 10 3-bit Function number
12104 * Bits 11 - 15 5-bit Device number
12105 * Bits 16 - 23 8-bit Bus number
12106 */
12107 pci_info->BusNumber = (reg_data[0] & 0x00FF0000) >> 16;
12108 pci_info->DeviceNumber = (reg_data[0] & 0x0000F800) >> 11;
12109 pci_info->FunctionNumber = (reg_data[0] & 0x00000700) >> 8;
12110 ddi_prop_free((void *)reg_data);
12111 } else {
12112 /*
12113 * If we can't determine the PCI info then we fill in FF's for
12114 * the data to indicate this.
12115 */
12116 pci_info->BusNumber = 0xFFFFFFFF;
12117 pci_info->DeviceNumber = 0xFF;
12118 pci_info->FunctionNumber = 0xFF;
12119 }
12120
12121 /*
12122 * Now get the interrupt vector and the pci header. The vector can
12123 * only be 0 right now. The header is the first 256 bytes of config
12124 * space.
12125 */
12126 pci_info->InterruptVector = 0;
12127 for (i = 0; i < sizeof (pci_info->PciHeader); i++) {
12128 pci_info->PciHeader[i] = pci_config_get8(mpt->m_config_handle,
12129 i);
12130 }
12131 }
12132
12133 static int
12134 mptsas_reg_access(mptsas_t *mpt, mptsas_reg_access_t *data, int mode)
12135 {
12136 int status = 0;
12137 mptsas_reg_access_t driverdata;
12138
12139 mutex_enter(&mpt->m_mutex);
12140 if (ddi_copyin(data, &driverdata, sizeof (driverdata), mode) == 0) {
12141 switch (driverdata.Command) {
12142 /*
12143 * IO access is not supported.
12144 */
12145 case REG_IO_READ:
12146 case REG_IO_WRITE:
12147 mptsas_log(mpt, CE_WARN, "IO access is not "
12148 "supported. Use memory access.");
12149 status = EINVAL;
12150 break;
12151
12152 case REG_MEM_READ:
12153 driverdata.RegData = ddi_get32(mpt->m_datap,
12154 (uint32_t *)(void *)mpt->m_reg +
12155 driverdata.RegOffset);
12156 if (ddi_copyout(&driverdata.RegData,
12157 &data->RegData,
12158 sizeof (driverdata.RegData), mode) != 0) {
12159 mptsas_log(mpt, CE_WARN, "Register "
12160 "Read Failed");
12161 status = EFAULT;
12162 }
12163 break;
12164
12165 case REG_MEM_WRITE:
12166 ddi_put32(mpt->m_datap,
12167 (uint32_t *)(void *)mpt->m_reg +
12168 driverdata.RegOffset,
12169 driverdata.RegData);
12170 break;
12171
12172 default:
12173 status = EINVAL;
12174 break;
12175 }
12176 } else {
12177 status = EFAULT;
12178 }
12179
12180 mutex_exit(&mpt->m_mutex);
12181 return (status);
12182 }
12183
12184 static int
12185 led_control(mptsas_t *mpt, intptr_t data, int mode)
12186 {
12187 int ret = 0;
12188 mptsas_led_control_t lc;
12189 mptsas_target_t *ptgt;
12190
12191 if (ddi_copyin((void *)data, &lc, sizeof (lc), mode) != 0) {
12192 return (EFAULT);
12193 }
12194
12195 if ((lc.Command != MPTSAS_LEDCTL_FLAG_SET &&
12196 lc.Command != MPTSAS_LEDCTL_FLAG_GET) ||
12197 lc.Led < MPTSAS_LEDCTL_LED_MIN ||
12198 lc.Led > MPTSAS_LEDCTL_LED_MAX ||
12199 (lc.Command == MPTSAS_LEDCTL_FLAG_SET && lc.LedStatus != 0 &&
12200 lc.LedStatus != 1)) {
12201 return (EINVAL);
12202 }
12203
12204 if ((lc.Command == MPTSAS_LEDCTL_FLAG_SET && (mode & FWRITE) == 0) ||
12205 (lc.Command == MPTSAS_LEDCTL_FLAG_GET && (mode & FREAD) == 0))
12206 return (EACCES);
12207
12208 /* Locate the target we're interrogating... */
12209 mutex_enter(&mpt->m_mutex);
12210 ptgt = refhash_linear_search(mpt->m_targets,
12211 mptsas_target_eval_slot, &lc);
12212 if (ptgt == NULL) {
12213 /* We could not find a target for that enclosure/slot. */
12214 mutex_exit(&mpt->m_mutex);
12215 return (ENOENT);
12216 }
12217
12218 if (lc.Command == MPTSAS_LEDCTL_FLAG_SET) {
12219 /* Update our internal LED state. */
12220 ptgt->m_led_status &= ~(1 << (lc.Led - 1));
12221 ptgt->m_led_status |= lc.LedStatus << (lc.Led - 1);
12222
12223 /* Flush it to the controller. */
12224 ret = mptsas_flush_led_status(mpt, ptgt);
12225 mutex_exit(&mpt->m_mutex);
12226 return (ret);
12227 }
12228
12229 /* Return our internal LED state. */
12230 lc.LedStatus = (ptgt->m_led_status >> (lc.Led - 1)) & 1;
12231 mutex_exit(&mpt->m_mutex);
12232
12233 if (ddi_copyout(&lc, (void *)data, sizeof (lc), mode) != 0) {
12234 return (EFAULT);
12235 }
12236
12237 return (0);
12238 }
12239
12240 static int
12241 get_disk_info(mptsas_t *mpt, intptr_t data, int mode)
12242 {
12243 uint16_t i = 0;
12244 uint16_t count = 0;
12245 int ret = 0;
12246 mptsas_target_t *ptgt;
12247 mptsas_disk_info_t *di;
12248 STRUCT_DECL(mptsas_get_disk_info, gdi);
12249
12250 if ((mode & FREAD) == 0)
12251 return (EACCES);
12252
12253 STRUCT_INIT(gdi, get_udatamodel());
12254
12255 if (ddi_copyin((void *)data, STRUCT_BUF(gdi), STRUCT_SIZE(gdi),
12256 mode) != 0) {
12257 return (EFAULT);
12258 }
12259
12260 /* Find out how many targets there are. */
12261 mutex_enter(&mpt->m_mutex);
12262 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
12263 ptgt = refhash_next(mpt->m_targets, ptgt)) {
12264 count++;
12265 }
12266 mutex_exit(&mpt->m_mutex);
12267
12268 /*
12269 * If we haven't been asked to copy out information on each target,
12270 * then just return the count.
12271 */
12272 STRUCT_FSET(gdi, DiskCount, count);
12273 if (STRUCT_FGETP(gdi, PtrDiskInfoArray) == NULL)
12274 goto copy_out;
12275
12276 /*
12277 * If we haven't been given a large enough buffer to copy out into,
12278 * let the caller know.
12279 */
12280 if (STRUCT_FGET(gdi, DiskInfoArraySize) <
12281 count * sizeof (mptsas_disk_info_t)) {
12282 ret = ENOSPC;
12283 goto copy_out;
12284 }
12285
12286 di = kmem_zalloc(count * sizeof (mptsas_disk_info_t), KM_SLEEP);
12287
12288 mutex_enter(&mpt->m_mutex);
12289 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
12290 ptgt = refhash_next(mpt->m_targets, ptgt)) {
12291 if (i >= count) {
12292 /*
12293 * The number of targets changed while we weren't
12294 * looking, so give up.
12295 */
12296 refhash_rele(mpt->m_targets, ptgt);
12297 mutex_exit(&mpt->m_mutex);
12298 kmem_free(di, count * sizeof (mptsas_disk_info_t));
12299 return (EAGAIN);
12300 }
12301 di[i].Instance = mpt->m_instance;
12302 di[i].Enclosure = ptgt->m_enclosure;
12303 di[i].Slot = ptgt->m_slot_num;
12304 di[i].SasAddress = ptgt->m_addr.mta_wwn;
12305 i++;
12306 }
12307 mutex_exit(&mpt->m_mutex);
12308 STRUCT_FSET(gdi, DiskCount, i);
12309
12310 /* Copy out the disk information to the caller. */
12311 if (ddi_copyout((void *)di, STRUCT_FGETP(gdi, PtrDiskInfoArray),
12312 i * sizeof (mptsas_disk_info_t), mode) != 0) {
12313 ret = EFAULT;
12314 }
12315
12316 kmem_free(di, count * sizeof (mptsas_disk_info_t));
12317
12318 copy_out:
12319 if (ddi_copyout(STRUCT_BUF(gdi), (void *)data, STRUCT_SIZE(gdi),
12320 mode) != 0) {
12321 ret = EFAULT;
12322 }
12323
12324 return (ret);
12325 }
12326
12327 static int
12328 mptsas_ioctl(dev_t dev, int cmd, intptr_t data, int mode, cred_t *credp,
12329 int *rval)
12330 {
12331 int status = 0;
12332 mptsas_t *mpt;
12333 mptsas_update_flash_t flashdata;
12334 mptsas_pass_thru_t passthru_data;
12335 mptsas_adapter_data_t adapter_data;
12336 mptsas_pci_info_t pci_info;
12337 int copylen;
12338
12339 int iport_flag = 0;
12340 dev_info_t *dip = NULL;
12341 mptsas_phymask_t phymask = 0;
12342 struct devctl_iocdata *dcp = NULL;
12343 char *addr = NULL;
12344 mptsas_target_t *ptgt = NULL;
12345
12346 *rval = MPTIOCTL_STATUS_GOOD;
12347 if (secpolicy_sys_config(credp, B_FALSE) != 0) {
12348 return (EPERM);
12349 }
12350
12351 mpt = ddi_get_soft_state(mptsas_state, MINOR2INST(getminor(dev)));
12352 if (mpt == NULL) {
12353 /*
12354 * Called from iport node, get the states
12355 */
12356 iport_flag = 1;
12357 dip = mptsas_get_dip_from_dev(dev, &phymask);
12358 if (dip == NULL) {
12359 return (ENXIO);
12360 }
12361 mpt = DIP2MPT(dip);
12362 }
12363 /* Make sure power level is D0 before accessing registers */
12364 mutex_enter(&mpt->m_mutex);
12365 if (mpt->m_options & MPTSAS_OPT_PM) {
12366 (void) pm_busy_component(mpt->m_dip, 0);
12367 if (mpt->m_power_level != PM_LEVEL_D0) {
12368 mutex_exit(&mpt->m_mutex);
12369 if (pm_raise_power(mpt->m_dip, 0, PM_LEVEL_D0) !=
12370 DDI_SUCCESS) {
12371 mptsas_log(mpt, CE_WARN,
12372 "mptsas%d: mptsas_ioctl: Raise power "
12373 "request failed.", mpt->m_instance);
12374 (void) pm_idle_component(mpt->m_dip, 0);
12375 return (ENXIO);
12376 }
12377 } else {
12378 mutex_exit(&mpt->m_mutex);
12379 }
12380 } else {
12381 mutex_exit(&mpt->m_mutex);
12382 }
12383
12384 if (iport_flag) {
12385 status = scsi_hba_ioctl(dev, cmd, data, mode, credp, rval);
12386 if (status != 0) {
12387 goto out;
12388 }
12389 /*
12390 * The following code control the OK2RM LED, it doesn't affect
12391 * the ioctl return status.
12392 */
12393 if ((cmd == DEVCTL_DEVICE_ONLINE) ||
12394 (cmd == DEVCTL_DEVICE_OFFLINE)) {
12395 if (ndi_dc_allochdl((void *)data, &dcp) !=
12396 NDI_SUCCESS) {
12397 goto out;
12398 }
12399 addr = ndi_dc_getaddr(dcp);
12400 ptgt = mptsas_addr_to_ptgt(mpt, addr, phymask);
12401 if (ptgt == NULL) {
12402 NDBG14(("mptsas_ioctl led control: tgt %s not "
12403 "found", addr));
12404 ndi_dc_freehdl(dcp);
12405 goto out;
12406 }
12407 mutex_enter(&mpt->m_mutex);
12408 if (cmd == DEVCTL_DEVICE_ONLINE) {
12409 ptgt->m_tgt_unconfigured = 0;
12410 } else if (cmd == DEVCTL_DEVICE_OFFLINE) {
12411 ptgt->m_tgt_unconfigured = 1;
12412 }
12413 if (cmd == DEVCTL_DEVICE_OFFLINE) {
12414 ptgt->m_led_status |=
12415 (1 << (MPTSAS_LEDCTL_LED_OK2RM - 1));
12416 } else {
12417 ptgt->m_led_status &=
12418 ~(1 << (MPTSAS_LEDCTL_LED_OK2RM - 1));
12419 }
12420 (void) mptsas_flush_led_status(mpt, ptgt);
12421 mutex_exit(&mpt->m_mutex);
12422 ndi_dc_freehdl(dcp);
12423 }
12424 goto out;
12425 }
12426 switch (cmd) {
12427 case MPTIOCTL_GET_DISK_INFO:
12428 status = get_disk_info(mpt, data, mode);
12429 break;
12430 case MPTIOCTL_LED_CONTROL:
12431 status = led_control(mpt, data, mode);
12432 break;
12433 case MPTIOCTL_UPDATE_FLASH:
12434 if (ddi_copyin((void *)data, &flashdata,
12435 sizeof (struct mptsas_update_flash), mode)) {
12436 status = EFAULT;
12437 break;
12438 }
12439
12440 mutex_enter(&mpt->m_mutex);
12441 if (mptsas_update_flash(mpt,
12442 (caddr_t)(long)flashdata.PtrBuffer,
12443 flashdata.ImageSize, flashdata.ImageType, mode)) {
12444 status = EFAULT;
12445 }
12446
12447 /*
12448 * Reset the chip to start using the new
12449 * firmware. Reset if failed also.
12450 */
12451 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET;
12452 if (mptsas_restart_ioc(mpt) == DDI_FAILURE) {
12453 status = EFAULT;
12454 }
12455 mutex_exit(&mpt->m_mutex);
12456 break;
12457 case MPTIOCTL_PASS_THRU:
12458 /*
12459 * The user has requested to pass through a command to
12460 * be executed by the MPT firmware. Call our routine
12461 * which does this. Only allow one passthru IOCTL at
12462 * one time. Other threads will block on
12463 * m_passthru_mutex, which is of adaptive variant.
12464 */
12465 if (ddi_copyin((void *)data, &passthru_data,
12466 sizeof (mptsas_pass_thru_t), mode)) {
12467 status = EFAULT;
12468 break;
12469 }
12470 mutex_enter(&mpt->m_passthru_mutex);
12471 mutex_enter(&mpt->m_mutex);
12472 status = mptsas_pass_thru(mpt, &passthru_data, mode);
12473 mutex_exit(&mpt->m_mutex);
12474 mutex_exit(&mpt->m_passthru_mutex);
12475
12476 break;
12477 case MPTIOCTL_GET_ADAPTER_DATA:
12478 /*
12479 * The user has requested to read adapter data. Call
12480 * our routine which does this.
12481 */
12482 bzero(&adapter_data, sizeof (mptsas_adapter_data_t));
12483 if (ddi_copyin((void *)data, (void *)&adapter_data,
12484 sizeof (mptsas_adapter_data_t), mode)) {
12485 status = EFAULT;
12486 break;
12487 }
12488 if (adapter_data.StructureLength >=
12489 sizeof (mptsas_adapter_data_t)) {
12490 adapter_data.StructureLength = (uint32_t)
12491 sizeof (mptsas_adapter_data_t);
12492 copylen = sizeof (mptsas_adapter_data_t);
12493 mutex_enter(&mpt->m_mutex);
12494 mptsas_read_adapter_data(mpt, &adapter_data);
12495 mutex_exit(&mpt->m_mutex);
12496 } else {
12497 adapter_data.StructureLength = (uint32_t)
12498 sizeof (mptsas_adapter_data_t);
12499 copylen = sizeof (adapter_data.StructureLength);
12500 *rval = MPTIOCTL_STATUS_LEN_TOO_SHORT;
12501 }
12502 if (ddi_copyout((void *)(&adapter_data), (void *)data,
12503 copylen, mode) != 0) {
12504 status = EFAULT;
12505 }
12506 break;
12507 case MPTIOCTL_GET_PCI_INFO:
12508 /*
12509 * The user has requested to read pci info. Call
12510 * our routine which does this.
12511 */
12512 bzero(&pci_info, sizeof (mptsas_pci_info_t));
12513 mutex_enter(&mpt->m_mutex);
12514 mptsas_read_pci_info(mpt, &pci_info);
12515 mutex_exit(&mpt->m_mutex);
12516 if (ddi_copyout((void *)(&pci_info), (void *)data,
12517 sizeof (mptsas_pci_info_t), mode) != 0) {
12518 status = EFAULT;
12519 }
12520 break;
12521 case MPTIOCTL_RESET_ADAPTER:
12522 mutex_enter(&mpt->m_mutex);
12523 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET;
12524 if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) {
12525 mptsas_log(mpt, CE_WARN, "reset adapter IOCTL "
12526 "failed");
12527 status = EFAULT;
12528 }
12529 mutex_exit(&mpt->m_mutex);
12530 break;
12531 case MPTIOCTL_DIAG_ACTION:
12532 /*
12533 * The user has done a diag buffer action. Call our
12534 * routine which does this. Only allow one diag action
12535 * at one time.
12536 */
12537 mutex_enter(&mpt->m_mutex);
12538 if (mpt->m_diag_action_in_progress) {
12539 mutex_exit(&mpt->m_mutex);
12540 return (EBUSY);
12541 }
12542 mpt->m_diag_action_in_progress = 1;
12543 status = mptsas_diag_action(mpt,
12544 (mptsas_diag_action_t *)data, mode);
12545 mpt->m_diag_action_in_progress = 0;
12546 mutex_exit(&mpt->m_mutex);
12547 break;
12548 case MPTIOCTL_EVENT_QUERY:
12549 /*
12550 * The user has done an event query. Call our routine
12551 * which does this.
12552 */
12553 status = mptsas_event_query(mpt,
12554 (mptsas_event_query_t *)data, mode, rval);
12555 break;
12556 case MPTIOCTL_EVENT_ENABLE:
12557 /*
12558 * The user has done an event enable. Call our routine
12559 * which does this.
12560 */
12561 status = mptsas_event_enable(mpt,
12562 (mptsas_event_enable_t *)data, mode, rval);
12563 break;
12564 case MPTIOCTL_EVENT_REPORT:
12565 /*
12566 * The user has done an event report. Call our routine
12567 * which does this.
12568 */
12569 status = mptsas_event_report(mpt,
12570 (mptsas_event_report_t *)data, mode, rval);
12571 break;
12572 case MPTIOCTL_REG_ACCESS:
12573 /*
12574 * The user has requested register access. Call our
12575 * routine which does this.
12576 */
12577 status = mptsas_reg_access(mpt,
12578 (mptsas_reg_access_t *)data, mode);
12579 break;
12580 default:
12581 status = scsi_hba_ioctl(dev, cmd, data, mode, credp,
12582 rval);
12583 break;
12584 }
12585
12586 out:
12587 return (status);
12588 }
12589
12590 int
12591 mptsas_restart_ioc(mptsas_t *mpt)
12592 {
12593 int rval = DDI_SUCCESS;
12594 mptsas_target_t *ptgt = NULL;
12595
12596 ASSERT(mutex_owned(&mpt->m_mutex));
12597
12598 /*
12599 * Set a flag telling I/O path that we're processing a reset. This is
12600 * needed because after the reset is complete, the hash table still
12601 * needs to be rebuilt. If I/Os are started before the hash table is
12602 * rebuilt, I/O errors will occur. This flag allows I/Os to be marked
12603 * so that they can be retried.
12604 */
12605 mpt->m_in_reset = TRUE;
12606
12607 /*
12608 * Set all throttles to HOLD
12609 */
12610 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
12611 ptgt = refhash_next(mpt->m_targets, ptgt)) {
12612 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
12613 }
12614
12615 /*
12616 * Disable interrupts
12617 */
12618 MPTSAS_DISABLE_INTR(mpt);
12619
12620 /*
12621 * Abort all commands: outstanding commands, commands in waitq and
12622 * tx_waitq.
12623 */
12624 mptsas_flush_hba(mpt);
12625
12626 /*
12627 * Reinitialize the chip.
12628 */
12629 if (mptsas_init_chip(mpt, FALSE) == DDI_FAILURE) {
12630 rval = DDI_FAILURE;
12631 }
12632
12633 /*
12634 * Enable interrupts again
12635 */
12636 MPTSAS_ENABLE_INTR(mpt);
12637
12638 /*
12639 * If mptsas_init_chip was successful, update the driver data.
12640 */
12641 if (rval == DDI_SUCCESS) {
12642 mptsas_update_driver_data(mpt);
12643 }
12644
12645 /*
12646 * Reset the throttles
12647 */
12648 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
12649 ptgt = refhash_next(mpt->m_targets, ptgt)) {
12650 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
12651 }
12652
12653 mptsas_doneq_empty(mpt);
12654 mptsas_restart_hba(mpt);
12655
12656 if (rval != DDI_SUCCESS) {
12657 mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE);
12658 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST);
12659 }
12660
12661 /*
12662 * Clear the reset flag so that I/Os can continue.
12663 */
12664 mpt->m_in_reset = FALSE;
12665
12666 return (rval);
12667 }
12668
12669 static int
12670 mptsas_init_chip(mptsas_t *mpt, int first_time)
12671 {
12672 ddi_dma_cookie_t cookie;
12673 uint32_t i;
12674 int rval;
12675
12676 /*
12677 * Check to see if the firmware image is valid
12678 */
12679 if (ddi_get32(mpt->m_datap, &mpt->m_reg->HostDiagnostic) &
12680 MPI2_DIAG_FLASH_BAD_SIG) {
12681 mptsas_log(mpt, CE_WARN, "mptsas bad flash signature!");
12682 goto fail;
12683 }
12684
12685 /*
12686 * Reset the chip
12687 */
12688 rval = mptsas_ioc_reset(mpt, first_time);
12689 if (rval == MPTSAS_RESET_FAIL) {
12690 mptsas_log(mpt, CE_WARN, "hard reset failed!");
12691 goto fail;
12692 }
12693
12694 if ((rval == MPTSAS_SUCCESS_MUR) && (!first_time)) {
12695 goto mur;
12696 }
12697 /*
12698 * Setup configuration space
12699 */
12700 if (mptsas_config_space_init(mpt) == FALSE) {
12701 mptsas_log(mpt, CE_WARN, "mptsas_config_space_init "
12702 "failed!");
12703 goto fail;
12704 }
12705
12706 /*
12707 * IOC facts can change after a diag reset so all buffers that are
12708 * based on these numbers must be de-allocated and re-allocated. Get
12709 * new IOC facts each time chip is initialized.
12710 */
12711 if (mptsas_ioc_get_facts(mpt) == DDI_FAILURE) {
12712 mptsas_log(mpt, CE_WARN, "mptsas_ioc_get_facts failed");
12713 goto fail;
12714 }
12715
12716 mpt->m_targets = refhash_create(MPTSAS_TARGET_BUCKET_COUNT,
12717 mptsas_target_addr_hash, mptsas_target_addr_cmp,
12718 mptsas_target_free, sizeof (mptsas_target_t),
12719 offsetof(mptsas_target_t, m_link),
12720 offsetof(mptsas_target_t, m_addr), KM_SLEEP);
12721
12722 if (mptsas_alloc_active_slots(mpt, KM_SLEEP)) {
12723 goto fail;
12724 }
12725 /*
12726 * Allocate request message frames, reply free queue, reply descriptor
12727 * post queue, and reply message frames using latest IOC facts.
12728 */
12729 if (mptsas_alloc_request_frames(mpt) == DDI_FAILURE) {
12730 mptsas_log(mpt, CE_WARN, "mptsas_alloc_request_frames failed");
12731 goto fail;
12732 }
12733 if (mptsas_alloc_free_queue(mpt) == DDI_FAILURE) {
12734 mptsas_log(mpt, CE_WARN, "mptsas_alloc_free_queue failed!");
12735 goto fail;
12736 }
12737 if (mptsas_alloc_post_queue(mpt) == DDI_FAILURE) {
12738 mptsas_log(mpt, CE_WARN, "mptsas_alloc_post_queue failed!");
12739 goto fail;
12740 }
12741 if (mptsas_alloc_reply_frames(mpt) == DDI_FAILURE) {
12742 mptsas_log(mpt, CE_WARN, "mptsas_alloc_reply_frames failed!");
12743 goto fail;
12744 }
12745
12746 mur:
12747 /*
12748 * Re-Initialize ioc to operational state
12749 */
12750 if (mptsas_ioc_init(mpt) == DDI_FAILURE) {
12751 mptsas_log(mpt, CE_WARN, "mptsas_ioc_init failed");
12752 goto fail;
12753 }
12754
12755 mptsas_alloc_reply_args(mpt);
12756
12757 /*
12758 * Initialize reply post index. Reply free index is initialized after
12759 * the next loop.
12760 */
12761 mpt->m_post_index = 0;
12762
12763 /*
12764 * Initialize the Reply Free Queue with the physical addresses of our
12765 * reply frames.
12766 */
12767 cookie.dmac_address = mpt->m_reply_frame_dma_addr;
12768 for (i = 0; i < mpt->m_max_replies; i++) {
12769 ddi_put32(mpt->m_acc_free_queue_hdl,
12770 &((uint32_t *)(void *)mpt->m_free_queue)[i],
12771 cookie.dmac_address);
12772 cookie.dmac_address += mpt->m_reply_frame_size;
12773 }
12774 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
12775 DDI_DMA_SYNC_FORDEV);
12776
12777 /*
12778 * Initialize the reply free index to one past the last frame on the
12779 * queue. This will signify that the queue is empty to start with.
12780 */
12781 mpt->m_free_index = i;
12782 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, i);
12783
12784 /*
12785 * Initialize the reply post queue to 0xFFFFFFFF,0xFFFFFFFF's.
12786 */
12787 for (i = 0; i < mpt->m_post_queue_depth; i++) {
12788 ddi_put64(mpt->m_acc_post_queue_hdl,
12789 &((uint64_t *)(void *)mpt->m_post_queue)[i],
12790 0xFFFFFFFFFFFFFFFF);
12791 }
12792 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0,
12793 DDI_DMA_SYNC_FORDEV);
12794
12795 /*
12796 * Enable ports
12797 */
12798 if (mptsas_ioc_enable_port(mpt) == DDI_FAILURE) {
12799 mptsas_log(mpt, CE_WARN, "mptsas_ioc_enable_port failed");
12800 goto fail;
12801 }
12802
12803 /*
12804 * enable events
12805 */
12806 if (mptsas_ioc_enable_event_notification(mpt)) {
12807 goto fail;
12808 }
12809
12810 /*
12811 * We need checks in attach and these.
12812 * chip_init is called in mult. places
12813 */
12814
12815 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) !=
12816 DDI_SUCCESS) ||
12817 (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl) !=
12818 DDI_SUCCESS) ||
12819 (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl) !=
12820 DDI_SUCCESS) ||
12821 (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) !=
12822 DDI_SUCCESS) ||
12823 (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl) !=
12824 DDI_SUCCESS)) {
12825 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
12826 goto fail;
12827 }
12828
12829 /* Check all acc handles */
12830 if ((mptsas_check_acc_handle(mpt->m_datap) != DDI_SUCCESS) ||
12831 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) !=
12832 DDI_SUCCESS) ||
12833 (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl) !=
12834 DDI_SUCCESS) ||
12835 (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl) !=
12836 DDI_SUCCESS) ||
12837 (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl) !=
12838 DDI_SUCCESS) ||
12839 (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl) !=
12840 DDI_SUCCESS) ||
12841 (mptsas_check_acc_handle(mpt->m_config_handle) !=
12842 DDI_SUCCESS)) {
12843 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
12844 goto fail;
12845 }
12846
12847 return (DDI_SUCCESS);
12848
12849 fail:
12850 return (DDI_FAILURE);
12851 }
12852
12853 static int
12854 mptsas_get_pci_cap(mptsas_t *mpt)
12855 {
12856 ushort_t caps_ptr, cap, cap_count;
12857
12858 if (mpt->m_config_handle == NULL)
12859 return (FALSE);
12860 /*
12861 * Check if capabilities list is supported and if so,
12862 * get initial capabilities pointer and clear bits 0,1.
12863 */
12864 if (pci_config_get16(mpt->m_config_handle, PCI_CONF_STAT)
12865 & PCI_STAT_CAP) {
12866 caps_ptr = P2ALIGN(pci_config_get8(mpt->m_config_handle,
12867 PCI_CONF_CAP_PTR), 4);
12868 } else {
12869 caps_ptr = PCI_CAP_NEXT_PTR_NULL;
12870 }
12871
12872 /*
12873 * Walk capabilities if supported.
12874 */
12875 for (cap_count = 0; caps_ptr != PCI_CAP_NEXT_PTR_NULL; ) {
12876
12877 /*
12878 * Check that we haven't exceeded the maximum number of
12879 * capabilities and that the pointer is in a valid range.
12880 */
12881 if (++cap_count > 48) {
12882 mptsas_log(mpt, CE_WARN,
12883 "too many device capabilities.\n");
12884 break;
12885 }
12886 if (caps_ptr < 64) {
12887 mptsas_log(mpt, CE_WARN,
12888 "capabilities pointer 0x%x out of range.\n",
12889 caps_ptr);
12890 break;
12891 }
12892
12893 /*
12894 * Get next capability and check that it is valid.
12895 * For now, we only support power management.
12896 */
12897 cap = pci_config_get8(mpt->m_config_handle, caps_ptr);
12898 switch (cap) {
12899 case PCI_CAP_ID_PM:
12900 mptsas_log(mpt, CE_NOTE,
12901 "?mptsas%d supports power management.\n",
12902 mpt->m_instance);
12903 mpt->m_options |= MPTSAS_OPT_PM;
12904
12905 /* Save PMCSR offset */
12906 mpt->m_pmcsr_offset = caps_ptr + PCI_PMCSR;
12907 break;
12908 /*
12909 * The following capabilities are valid. Any others
12910 * will cause a message to be logged.
12911 */
12912 case PCI_CAP_ID_VPD:
12913 case PCI_CAP_ID_MSI:
12914 case PCI_CAP_ID_PCIX:
12915 case PCI_CAP_ID_PCI_E:
12916 case PCI_CAP_ID_MSI_X:
12917 break;
12918 default:
12919 mptsas_log(mpt, CE_NOTE,
12920 "?mptsas%d unrecognized capability "
12921 "0x%x.\n", mpt->m_instance, cap);
12922 break;
12923 }
12924
12925 /*
12926 * Get next capabilities pointer and clear bits 0,1.
12927 */
12928 caps_ptr = P2ALIGN(pci_config_get8(mpt->m_config_handle,
12929 (caps_ptr + PCI_CAP_NEXT_PTR)), 4);
12930 }
12931 return (TRUE);
12932 }
12933
12934 static int
12935 mptsas_init_pm(mptsas_t *mpt)
12936 {
12937 char pmc_name[16];
12938 char *pmc[] = {
12939 NULL,
12940 "0=Off (PCI D3 State)",
12941 "3=On (PCI D0 State)",
12942 NULL
12943 };
12944 uint16_t pmcsr_stat;
12945
12946 if (mptsas_get_pci_cap(mpt) == FALSE) {
12947 return (DDI_FAILURE);
12948 }
12949 /*
12950 * If PCI's capability does not support PM, then don't need
12951 * to registe the pm-components
12952 */
12953 if (!(mpt->m_options & MPTSAS_OPT_PM))
12954 return (DDI_SUCCESS);
12955 /*
12956 * If power management is supported by this chip, create
12957 * pm-components property for the power management framework
12958 */
12959 (void) sprintf(pmc_name, "NAME=mptsas%d", mpt->m_instance);
12960 pmc[0] = pmc_name;
12961 if (ddi_prop_update_string_array(DDI_DEV_T_NONE, mpt->m_dip,
12962 "pm-components", pmc, 3) != DDI_PROP_SUCCESS) {
12963 mpt->m_options &= ~MPTSAS_OPT_PM;
12964 mptsas_log(mpt, CE_WARN,
12965 "mptsas%d: pm-component property creation failed.",
12966 mpt->m_instance);
12967 return (DDI_FAILURE);
12968 }
12969
12970 /*
12971 * Power on device.
12972 */
12973 (void) pm_busy_component(mpt->m_dip, 0);
12974 pmcsr_stat = pci_config_get16(mpt->m_config_handle,
12975 mpt->m_pmcsr_offset);
12976 if ((pmcsr_stat & PCI_PMCSR_STATE_MASK) != PCI_PMCSR_D0) {
12977 mptsas_log(mpt, CE_WARN, "mptsas%d: Power up the device",
12978 mpt->m_instance);
12979 pci_config_put16(mpt->m_config_handle, mpt->m_pmcsr_offset,
12980 PCI_PMCSR_D0);
12981 }
12982 if (pm_power_has_changed(mpt->m_dip, 0, PM_LEVEL_D0) != DDI_SUCCESS) {
12983 mptsas_log(mpt, CE_WARN, "pm_power_has_changed failed");
12984 return (DDI_FAILURE);
12985 }
12986 mpt->m_power_level = PM_LEVEL_D0;
12987 /*
12988 * Set pm idle delay.
12989 */
12990 mpt->m_pm_idle_delay = ddi_prop_get_int(DDI_DEV_T_ANY,
12991 mpt->m_dip, 0, "mptsas-pm-idle-delay", MPTSAS_PM_IDLE_TIMEOUT);
12992
12993 return (DDI_SUCCESS);
12994 }
12995
12996 static int
12997 mptsas_register_intrs(mptsas_t *mpt)
12998 {
12999 dev_info_t *dip;
13000 int intr_types;
13001
13002 dip = mpt->m_dip;
13003
13004 /* Get supported interrupt types */
13005 if (ddi_intr_get_supported_types(dip, &intr_types) != DDI_SUCCESS) {
13006 mptsas_log(mpt, CE_WARN, "ddi_intr_get_supported_types "
13007 "failed\n");
13008 return (FALSE);
13009 }
13010
13011 NDBG6(("ddi_intr_get_supported_types() returned: 0x%x", intr_types));
13012
13013 /*
13014 * Try MSI, but fall back to FIXED
13015 */
13016 if (mptsas_enable_msi && (intr_types & DDI_INTR_TYPE_MSI)) {
13017 if (mptsas_add_intrs(mpt, DDI_INTR_TYPE_MSI) == DDI_SUCCESS) {
13018 NDBG0(("Using MSI interrupt type"));
13019 mpt->m_intr_type = DDI_INTR_TYPE_MSI;
13020 return (TRUE);
13021 }
13022 }
13023 if (intr_types & DDI_INTR_TYPE_FIXED) {
13024 if (mptsas_add_intrs(mpt, DDI_INTR_TYPE_FIXED) == DDI_SUCCESS) {
13025 NDBG0(("Using FIXED interrupt type"));
13026 mpt->m_intr_type = DDI_INTR_TYPE_FIXED;
13027 return (TRUE);
13028 } else {
13029 NDBG0(("FIXED interrupt registration failed"));
13030 return (FALSE);
13031 }
13032 }
13033
13034 return (FALSE);
13035 }
13036
13037 static void
13038 mptsas_unregister_intrs(mptsas_t *mpt)
13039 {
13040 mptsas_rem_intrs(mpt);
13041 }
13042
13043 /*
13044 * mptsas_add_intrs:
13045 *
13046 * Register FIXED or MSI interrupts.
13047 */
13048 static int
13049 mptsas_add_intrs(mptsas_t *mpt, int intr_type)
13050 {
13051 dev_info_t *dip = mpt->m_dip;
13052 int avail, actual, count = 0;
13053 int i, flag, ret;
13054
13055 NDBG6(("mptsas_add_intrs:interrupt type 0x%x", intr_type));
13056
13057 /* Get number of interrupts */
13058 ret = ddi_intr_get_nintrs(dip, intr_type, &count);
13059 if ((ret != DDI_SUCCESS) || (count <= 0)) {
13060 mptsas_log(mpt, CE_WARN, "ddi_intr_get_nintrs() failed, "
13061 "ret %d count %d\n", ret, count);
13062
13063 return (DDI_FAILURE);
13064 }
13065
13066 /* Get number of available interrupts */
13067 ret = ddi_intr_get_navail(dip, intr_type, &avail);
13068 if ((ret != DDI_SUCCESS) || (avail == 0)) {
13069 mptsas_log(mpt, CE_WARN, "ddi_intr_get_navail() failed, "
13070 "ret %d avail %d\n", ret, avail);
13071
13072 return (DDI_FAILURE);
13073 }
13074
13075 if (avail < count) {
13076 mptsas_log(mpt, CE_NOTE, "ddi_intr_get_nvail returned %d, "
13077 "navail() returned %d", count, avail);
13078 }
13079
13080 /* Mpt only have one interrupt routine */
13081 if ((intr_type == DDI_INTR_TYPE_MSI) && (count > 1)) {
13082 count = 1;
13083 }
13084
13085 /* Allocate an array of interrupt handles */
13086 mpt->m_intr_size = count * sizeof (ddi_intr_handle_t);
13087 mpt->m_htable = kmem_alloc(mpt->m_intr_size, KM_SLEEP);
13088
13089 flag = DDI_INTR_ALLOC_NORMAL;
13090
13091 /* call ddi_intr_alloc() */
13092 ret = ddi_intr_alloc(dip, mpt->m_htable, intr_type, 0,
13093 count, &actual, flag);
13094
13095 if ((ret != DDI_SUCCESS) || (actual == 0)) {
13096 mptsas_log(mpt, CE_WARN, "ddi_intr_alloc() failed, ret %d\n",
13097 ret);
13098 kmem_free(mpt->m_htable, mpt->m_intr_size);
13099 return (DDI_FAILURE);
13100 }
13101
13102 /* use interrupt count returned or abort? */
13103 if (actual < count) {
13104 mptsas_log(mpt, CE_NOTE, "Requested: %d, Received: %d\n",
13105 count, actual);
13106 }
13107
13108 mpt->m_intr_cnt = actual;
13109
13110 /*
13111 * Get priority for first msi, assume remaining are all the same
13112 */
13113 if ((ret = ddi_intr_get_pri(mpt->m_htable[0],
13114 &mpt->m_intr_pri)) != DDI_SUCCESS) {
13115 mptsas_log(mpt, CE_WARN, "ddi_intr_get_pri() failed %d\n", ret);
13116
13117 /* Free already allocated intr */
13118 for (i = 0; i < actual; i++) {
13119 (void) ddi_intr_free(mpt->m_htable[i]);
13120 }
13121
13122 kmem_free(mpt->m_htable, mpt->m_intr_size);
13123 return (DDI_FAILURE);
13124 }
13125
13126 /* Test for high level mutex */
13127 if (mpt->m_intr_pri >= ddi_intr_get_hilevel_pri()) {
13128 mptsas_log(mpt, CE_WARN, "mptsas_add_intrs: "
13129 "Hi level interrupt not supported\n");
13130
13131 /* Free already allocated intr */
13132 for (i = 0; i < actual; i++) {
13133 (void) ddi_intr_free(mpt->m_htable[i]);
13134 }
13135
13136 kmem_free(mpt->m_htable, mpt->m_intr_size);
13137 return (DDI_FAILURE);
13138 }
13139
13140 /* Call ddi_intr_add_handler() */
13141 for (i = 0; i < actual; i++) {
13142 if ((ret = ddi_intr_add_handler(mpt->m_htable[i], mptsas_intr,
13143 (caddr_t)mpt, (caddr_t)(uintptr_t)i)) != DDI_SUCCESS) {
13144 mptsas_log(mpt, CE_WARN, "ddi_intr_add_handler() "
13145 "failed %d\n", ret);
13146
13147 /* Free already allocated intr */
13148 for (i = 0; i < actual; i++) {
13149 (void) ddi_intr_free(mpt->m_htable[i]);
13150 }
13151
13152 kmem_free(mpt->m_htable, mpt->m_intr_size);
13153 return (DDI_FAILURE);
13154 }
13155 }
13156
13157 if ((ret = ddi_intr_get_cap(mpt->m_htable[0], &mpt->m_intr_cap))
13158 != DDI_SUCCESS) {
13159 mptsas_log(mpt, CE_WARN, "ddi_intr_get_cap() failed %d\n", ret);
13160
13161 /* Free already allocated intr */
13162 for (i = 0; i < actual; i++) {
13163 (void) ddi_intr_free(mpt->m_htable[i]);
13164 }
13165
13166 kmem_free(mpt->m_htable, mpt->m_intr_size);
13167 return (DDI_FAILURE);
13168 }
13169
13170 /*
13171 * Enable interrupts
13172 */
13173 if (mpt->m_intr_cap & DDI_INTR_FLAG_BLOCK) {
13174 /* Call ddi_intr_block_enable() for MSI interrupts */
13175 (void) ddi_intr_block_enable(mpt->m_htable, mpt->m_intr_cnt);
13176 } else {
13177 /* Call ddi_intr_enable for MSI or FIXED interrupts */
13178 for (i = 0; i < mpt->m_intr_cnt; i++) {
13179 (void) ddi_intr_enable(mpt->m_htable[i]);
13180 }
13181 }
13182 return (DDI_SUCCESS);
13183 }
13184
13185 /*
13186 * mptsas_rem_intrs:
13187 *
13188 * Unregister FIXED or MSI interrupts
13189 */
13190 static void
13191 mptsas_rem_intrs(mptsas_t *mpt)
13192 {
13193 int i;
13194
13195 NDBG6(("mptsas_rem_intrs"));
13196
13197 /* Disable all interrupts */
13198 if (mpt->m_intr_cap & DDI_INTR_FLAG_BLOCK) {
13199 /* Call ddi_intr_block_disable() */
13200 (void) ddi_intr_block_disable(mpt->m_htable, mpt->m_intr_cnt);
13201 } else {
13202 for (i = 0; i < mpt->m_intr_cnt; i++) {
13203 (void) ddi_intr_disable(mpt->m_htable[i]);
13204 }
13205 }
13206
13207 /* Call ddi_intr_remove_handler() */
13208 for (i = 0; i < mpt->m_intr_cnt; i++) {
13209 (void) ddi_intr_remove_handler(mpt->m_htable[i]);
13210 (void) ddi_intr_free(mpt->m_htable[i]);
13211 }
13212
13213 kmem_free(mpt->m_htable, mpt->m_intr_size);
13214 }
13215
13216 /*
13217 * The IO fault service error handling callback function
13218 */
13219 /*ARGSUSED*/
13220 static int
13221 mptsas_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data)
13222 {
13223 /*
13224 * as the driver can always deal with an error in any dma or
13225 * access handle, we can just return the fme_status value.
13226 */
13227 pci_ereport_post(dip, err, NULL);
13228 return (err->fme_status);
13229 }
13230
13231 /*
13232 * mptsas_fm_init - initialize fma capabilities and register with IO
13233 * fault services.
13234 */
13235 static void
13236 mptsas_fm_init(mptsas_t *mpt)
13237 {
13238 /*
13239 * Need to change iblock to priority for new MSI intr
13240 */
13241 ddi_iblock_cookie_t fm_ibc;
13242
13243 /* Only register with IO Fault Services if we have some capability */
13244 if (mpt->m_fm_capabilities) {
13245 /* Adjust access and dma attributes for FMA */
13246 mpt->m_reg_acc_attr.devacc_attr_access = DDI_FLAGERR_ACC;
13247 mpt->m_msg_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
13248 mpt->m_io_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
13249
13250 /*
13251 * Register capabilities with IO Fault Services.
13252 * mpt->m_fm_capabilities will be updated to indicate
13253 * capabilities actually supported (not requested.)
13254 */
13255 ddi_fm_init(mpt->m_dip, &mpt->m_fm_capabilities, &fm_ibc);
13256
13257 /*
13258 * Initialize pci ereport capabilities if ereport
13259 * capable (should always be.)
13260 */
13261 if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities) ||
13262 DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) {
13263 pci_ereport_setup(mpt->m_dip);
13264 }
13265
13266 /*
13267 * Register error callback if error callback capable.
13268 */
13269 if (DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) {
13270 ddi_fm_handler_register(mpt->m_dip,
13271 mptsas_fm_error_cb, (void *) mpt);
13272 }
13273 }
13274 }
13275
13276 /*
13277 * mptsas_fm_fini - Releases fma capabilities and un-registers with IO
13278 * fault services.
13279 *
13280 */
13281 static void
13282 mptsas_fm_fini(mptsas_t *mpt)
13283 {
13284 /* Only unregister FMA capabilities if registered */
13285 if (mpt->m_fm_capabilities) {
13286
13287 /*
13288 * Un-register error callback if error callback capable.
13289 */
13290
13291 if (DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) {
13292 ddi_fm_handler_unregister(mpt->m_dip);
13293 }
13294
13295 /*
13296 * Release any resources allocated by pci_ereport_setup()
13297 */
13298
13299 if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities) ||
13300 DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) {
13301 pci_ereport_teardown(mpt->m_dip);
13302 }
13303
13304 /* Unregister from IO Fault Services */
13305 ddi_fm_fini(mpt->m_dip);
13306
13307 /* Adjust access and dma attributes for FMA */
13308 mpt->m_reg_acc_attr.devacc_attr_access = DDI_DEFAULT_ACC;
13309 mpt->m_msg_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
13310 mpt->m_io_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
13311
13312 }
13313 }
13314
13315 int
13316 mptsas_check_acc_handle(ddi_acc_handle_t handle)
13317 {
13318 ddi_fm_error_t de;
13319
13320 if (handle == NULL)
13321 return (DDI_FAILURE);
13322 ddi_fm_acc_err_get(handle, &de, DDI_FME_VER0);
13323 return (de.fme_status);
13324 }
13325
13326 int
13327 mptsas_check_dma_handle(ddi_dma_handle_t handle)
13328 {
13329 ddi_fm_error_t de;
13330
13331 if (handle == NULL)
13332 return (DDI_FAILURE);
13333 ddi_fm_dma_err_get(handle, &de, DDI_FME_VER0);
13334 return (de.fme_status);
13335 }
13336
13337 void
13338 mptsas_fm_ereport(mptsas_t *mpt, char *detail)
13339 {
13340 uint64_t ena;
13341 char buf[FM_MAX_CLASS];
13342
13343 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail);
13344 ena = fm_ena_generate(0, FM_ENA_FMT1);
13345 if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities)) {
13346 ddi_fm_ereport_post(mpt->m_dip, buf, ena, DDI_NOSLEEP,
13347 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, NULL);
13348 }
13349 }
13350
13351 static int
13352 mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address,
13353 uint16_t *dev_handle, mptsas_target_t **pptgt)
13354 {
13355 int rval;
13356 uint32_t dev_info;
13357 uint64_t sas_wwn;
13358 mptsas_phymask_t phymask;
13359 uint8_t physport, phynum, config, disk;
13360 uint64_t devicename;
13361 uint16_t pdev_hdl;
13362 mptsas_target_t *tmp_tgt = NULL;
13363 uint16_t bay_num, enclosure, io_flags;
13364
13365 ASSERT(*pptgt == NULL);
13366
13367 rval = mptsas_get_sas_device_page0(mpt, page_address, dev_handle,
13368 &sas_wwn, &dev_info, &physport, &phynum, &pdev_hdl,
13369 &bay_num, &enclosure, &io_flags);
13370 if (rval != DDI_SUCCESS) {
13371 rval = DEV_INFO_FAIL_PAGE0;
13372 return (rval);
13373 }
13374
13375 if ((dev_info & (MPI2_SAS_DEVICE_INFO_SSP_TARGET |
13376 MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
13377 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) == NULL) {
13378 rval = DEV_INFO_WRONG_DEVICE_TYPE;
13379 return (rval);
13380 }
13381
13382 /*
13383 * Check if the dev handle is for a Phys Disk. If so, set return value
13384 * and exit. Don't add Phys Disks to hash.
13385 */
13386 for (config = 0; config < mpt->m_num_raid_configs; config++) {
13387 for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) {
13388 if (*dev_handle == mpt->m_raidconfig[config].
13389 m_physdisk_devhdl[disk]) {
13390 rval = DEV_INFO_PHYS_DISK;
13391 return (rval);
13392 }
13393 }
13394 }
13395
13396 /*
13397 * Get SATA Device Name from SAS device page0 for
13398 * sata device, if device name doesn't exist, set mta_wwn to
13399 * 0 for direct attached SATA. For the device behind the expander
13400 * we still can use STP address assigned by expander.
13401 */
13402 if (dev_info & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
13403 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
13404 mutex_exit(&mpt->m_mutex);
13405 /* alloc a tmp_tgt to send the cmd */
13406 tmp_tgt = kmem_zalloc(sizeof (struct mptsas_target),
13407 KM_SLEEP);
13408 tmp_tgt->m_devhdl = *dev_handle;
13409 tmp_tgt->m_deviceinfo = dev_info;
13410 tmp_tgt->m_qfull_retries = QFULL_RETRIES;
13411 tmp_tgt->m_qfull_retry_interval =
13412 drv_usectohz(QFULL_RETRY_INTERVAL * 1000);
13413 tmp_tgt->m_t_throttle = MAX_THROTTLE;
13414 devicename = mptsas_get_sata_guid(mpt, tmp_tgt, 0);
13415 kmem_free(tmp_tgt, sizeof (struct mptsas_target));
13416 mutex_enter(&mpt->m_mutex);
13417 if (devicename != 0 && (((devicename >> 56) & 0xf0) == 0x50)) {
13418 sas_wwn = devicename;
13419 } else if (dev_info & MPI2_SAS_DEVICE_INFO_DIRECT_ATTACH) {
13420 sas_wwn = 0;
13421 }
13422 }
13423
13424 phymask = mptsas_physport_to_phymask(mpt, physport);
13425 *pptgt = mptsas_tgt_alloc(mpt, *dev_handle, sas_wwn,
13426 dev_info, phymask, phynum);
13427 if (*pptgt == NULL) {
13428 mptsas_log(mpt, CE_WARN, "Failed to allocated target"
13429 "structure!");
13430 rval = DEV_INFO_FAIL_ALLOC;
13431 return (rval);
13432 }
13433 (*pptgt)->m_io_flags = io_flags;
13434 (*pptgt)->m_enclosure = enclosure;
13435 (*pptgt)->m_slot_num = bay_num;
13436 return (DEV_INFO_SUCCESS);
13437 }
13438
13439 uint64_t
13440 mptsas_get_sata_guid(mptsas_t *mpt, mptsas_target_t *ptgt, int lun)
13441 {
13442 uint64_t sata_guid = 0, *pwwn = NULL;
13443 int target = ptgt->m_devhdl;
13444 uchar_t *inq83 = NULL;
13445 int inq83_len = 0xFF;
13446 uchar_t *dblk = NULL;
13447 int inq83_retry = 3;
13448 int rval = DDI_FAILURE;
13449
13450 inq83 = kmem_zalloc(inq83_len, KM_SLEEP);
13451
13452 inq83_retry:
13453 rval = mptsas_inquiry(mpt, ptgt, lun, 0x83, inq83,
13454 inq83_len, NULL, 1);
13455 if (rval != DDI_SUCCESS) {
13456 mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page "
13457 "0x83 for target:%x, lun:%x failed!", target, lun);
13458 goto out;
13459 }
13460 /* According to SAT2, the first descriptor is logic unit name */
13461 dblk = &inq83[4];
13462 if ((dblk[1] & 0x30) != 0) {
13463 mptsas_log(mpt, CE_WARN, "!Descriptor is not lun associated.");
13464 goto out;
13465 }
13466 pwwn = (uint64_t *)(void *)(&dblk[4]);
13467 if ((dblk[4] & 0xf0) == 0x50) {
13468 sata_guid = BE_64(*pwwn);
13469 goto out;
13470 } else if (dblk[4] == 'A') {
13471 NDBG20(("SATA drive has no NAA format GUID."));
13472 goto out;
13473 } else {
13474 /* The data is not ready, wait and retry */
13475 inq83_retry--;
13476 if (inq83_retry <= 0) {
13477 goto out;
13478 }
13479 NDBG20(("The GUID is not ready, retry..."));
13480 delay(1 * drv_usectohz(1000000));
13481 goto inq83_retry;
13482 }
13483 out:
13484 kmem_free(inq83, inq83_len);
13485 return (sata_guid);
13486 }
13487
13488 static int
13489 mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun, uchar_t page,
13490 unsigned char *buf, int len, int *reallen, uchar_t evpd)
13491 {
13492 uchar_t cdb[CDB_GROUP0];
13493 struct scsi_address ap;
13494 struct buf *data_bp = NULL;
13495 int resid = 0;
13496 int ret = DDI_FAILURE;
13497
13498 ASSERT(len <= 0xffff);
13499
13500 ap.a_target = MPTSAS_INVALID_DEVHDL;
13501 ap.a_lun = (uchar_t)(lun);
13502 ap.a_hba_tran = mpt->m_tran;
13503
13504 data_bp = scsi_alloc_consistent_buf(&ap,
13505 (struct buf *)NULL, len, B_READ, NULL_FUNC, NULL);
13506 if (data_bp == NULL) {
13507 return (ret);
13508 }
13509 bzero(cdb, CDB_GROUP0);
13510 cdb[0] = SCMD_INQUIRY;
13511 cdb[1] = evpd;
13512 cdb[2] = page;
13513 cdb[3] = (len & 0xff00) >> 8;
13514 cdb[4] = (len & 0x00ff);
13515 cdb[5] = 0;
13516
13517 ret = mptsas_send_scsi_cmd(mpt, &ap, ptgt, &cdb[0], CDB_GROUP0, data_bp,
13518 &resid);
13519 if (ret == DDI_SUCCESS) {
13520 if (reallen) {
13521 *reallen = len - resid;
13522 }
13523 bcopy((caddr_t)data_bp->b_un.b_addr, buf, len);
13524 }
13525 if (data_bp) {
13526 scsi_free_consistent_buf(data_bp);
13527 }
13528 return (ret);
13529 }
13530
13531 static int
13532 mptsas_send_scsi_cmd(mptsas_t *mpt, struct scsi_address *ap,
13533 mptsas_target_t *ptgt, uchar_t *cdb, int cdblen, struct buf *data_bp,
13534 int *resid)
13535 {
13536 struct scsi_pkt *pktp = NULL;
13537 scsi_hba_tran_t *tran_clone = NULL;
13538 mptsas_tgt_private_t *tgt_private = NULL;
13539 int ret = DDI_FAILURE;
13540
13541 /*
13542 * scsi_hba_tran_t->tran_tgt_private is used to pass the address
13543 * information to scsi_init_pkt, allocate a scsi_hba_tran structure
13544 * to simulate the cmds from sd
13545 */
13546 tran_clone = kmem_alloc(
13547 sizeof (scsi_hba_tran_t), KM_SLEEP);
13548 if (tran_clone == NULL) {
13549 goto out;
13550 }
13551 bcopy((caddr_t)mpt->m_tran,
13552 (caddr_t)tran_clone, sizeof (scsi_hba_tran_t));
13553 tgt_private = kmem_alloc(
13554 sizeof (mptsas_tgt_private_t), KM_SLEEP);
13555 if (tgt_private == NULL) {
13556 goto out;
13557 }
13558 tgt_private->t_lun = ap->a_lun;
13559 tgt_private->t_private = ptgt;
13560 tran_clone->tran_tgt_private = tgt_private;
13561 ap->a_hba_tran = tran_clone;
13562
13563 pktp = scsi_init_pkt(ap, (struct scsi_pkt *)NULL,
13564 data_bp, cdblen, sizeof (struct scsi_arq_status),
13565 0, PKT_CONSISTENT, NULL, NULL);
13566 if (pktp == NULL) {
13567 goto out;
13568 }
13569 bcopy(cdb, pktp->pkt_cdbp, cdblen);
13570 pktp->pkt_flags = FLAG_NOPARITY;
13571 if (scsi_poll(pktp) < 0) {
13572 goto out;
13573 }
13574 if (((struct scsi_status *)pktp->pkt_scbp)->sts_chk) {
13575 goto out;
13576 }
13577 if (resid != NULL) {
13578 *resid = pktp->pkt_resid;
13579 }
13580
13581 ret = DDI_SUCCESS;
13582 out:
13583 if (pktp) {
13584 scsi_destroy_pkt(pktp);
13585 }
13586 if (tran_clone) {
13587 kmem_free(tran_clone, sizeof (scsi_hba_tran_t));
13588 }
13589 if (tgt_private) {
13590 kmem_free(tgt_private, sizeof (mptsas_tgt_private_t));
13591 }
13592 return (ret);
13593 }
13594 static int
13595 mptsas_parse_address(char *name, uint64_t *wwid, uint8_t *phy, int *lun)
13596 {
13597 char *cp = NULL;
13598 char *ptr = NULL;
13599 size_t s = 0;
13600 char *wwid_str = NULL;
13601 char *lun_str = NULL;
13602 long lunnum;
13603 long phyid = -1;
13604 int rc = DDI_FAILURE;
13605
13606 ptr = name;
13607 ASSERT(ptr[0] == 'w' || ptr[0] == 'p');
13608 ptr++;
13609 if ((cp = strchr(ptr, ',')) == NULL) {
13610 return (DDI_FAILURE);
13611 }
13612
13613 wwid_str = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
13614 s = (uintptr_t)cp - (uintptr_t)ptr;
13615
13616 bcopy(ptr, wwid_str, s);
13617 wwid_str[s] = '\0';
13618
13619 ptr = ++cp;
13620
13621 if ((cp = strchr(ptr, '\0')) == NULL) {
13622 goto out;
13623 }
13624 lun_str = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
13625 s = (uintptr_t)cp - (uintptr_t)ptr;
13626
13627 bcopy(ptr, lun_str, s);
13628 lun_str[s] = '\0';
13629
13630 if (name[0] == 'p') {
13631 rc = ddi_strtol(wwid_str, NULL, 0x10, &phyid);
13632 } else {
13633 rc = scsi_wwnstr_to_wwn(wwid_str, wwid);
13634 }
13635 if (rc != DDI_SUCCESS)
13636 goto out;
13637
13638 if (phyid != -1) {
13639 ASSERT(phyid < MPTSAS_MAX_PHYS);
13640 *phy = (uint8_t)phyid;
13641 }
13642 rc = ddi_strtol(lun_str, NULL, 0x10, &lunnum);
13643 if (rc != 0)
13644 goto out;
13645
13646 *lun = (int)lunnum;
13647 rc = DDI_SUCCESS;
13648 out:
13649 if (wwid_str)
13650 kmem_free(wwid_str, SCSI_MAXNAMELEN);
13651 if (lun_str)
13652 kmem_free(lun_str, SCSI_MAXNAMELEN);
13653
13654 return (rc);
13655 }
13656
13657 /*
13658 * mptsas_parse_smp_name() is to parse sas wwn string
13659 * which format is "wWWN"
13660 */
13661 static int
13662 mptsas_parse_smp_name(char *name, uint64_t *wwn)
13663 {
13664 char *ptr = name;
13665
13666 if (*ptr != 'w') {
13667 return (DDI_FAILURE);
13668 }
13669
13670 ptr++;
13671 if (scsi_wwnstr_to_wwn(ptr, wwn)) {
13672 return (DDI_FAILURE);
13673 }
13674 return (DDI_SUCCESS);
13675 }
13676
13677 static int
13678 mptsas_bus_config(dev_info_t *pdip, uint_t flag,
13679 ddi_bus_config_op_t op, void *arg, dev_info_t **childp)
13680 {
13681 int ret = NDI_FAILURE;
13682 int circ = 0;
13683 int circ1 = 0;
13684 mptsas_t *mpt;
13685 char *ptr = NULL;
13686 char *devnm = NULL;
13687 uint64_t wwid = 0;
13688 uint8_t phy = 0xFF;
13689 int lun = 0;
13690 uint_t mflags = flag;
13691 int bconfig = TRUE;
13692
13693 if (scsi_hba_iport_unit_address(pdip) == 0) {
13694 return (DDI_FAILURE);
13695 }
13696
13697 mpt = DIP2MPT(pdip);
13698 if (!mpt) {
13699 return (DDI_FAILURE);
13700 }
13701 /*
13702 * Hold the nexus across the bus_config
13703 */
13704 ndi_devi_enter(scsi_vhci_dip, &circ);
13705 ndi_devi_enter(pdip, &circ1);
13706 switch (op) {
13707 case BUS_CONFIG_ONE:
13708 /* parse wwid/target name out of name given */
13709 if ((ptr = strchr((char *)arg, '@')) == NULL) {
13710 ret = NDI_FAILURE;
13711 break;
13712 }
13713 ptr++;
13714 if (strncmp((char *)arg, "smp", 3) == 0) {
13715 /*
13716 * This is a SMP target device
13717 */
13718 ret = mptsas_parse_smp_name(ptr, &wwid);
13719 if (ret != DDI_SUCCESS) {
13720 ret = NDI_FAILURE;
13721 break;
13722 }
13723 ret = mptsas_config_smp(pdip, wwid, childp);
13724 } else if ((ptr[0] == 'w') || (ptr[0] == 'p')) {
13725 /*
13726 * OBP could pass down a non-canonical form
13727 * bootpath without LUN part when LUN is 0.
13728 * So driver need adjust the string.
13729 */
13730 if (strchr(ptr, ',') == NULL) {
13731 devnm = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
13732 (void) sprintf(devnm, "%s,0", (char *)arg);
13733 ptr = strchr(devnm, '@');
13734 ptr++;
13735 }
13736
13737 /*
13738 * The device path is wWWID format and the device
13739 * is not SMP target device.
13740 */
13741 ret = mptsas_parse_address(ptr, &wwid, &phy, &lun);
13742 if (ret != DDI_SUCCESS) {
13743 ret = NDI_FAILURE;
13744 break;
13745 }
13746 *childp = NULL;
13747 if (ptr[0] == 'w') {
13748 ret = mptsas_config_one_addr(pdip, wwid,
13749 lun, childp);
13750 } else if (ptr[0] == 'p') {
13751 ret = mptsas_config_one_phy(pdip, phy, lun,
13752 childp);
13753 }
13754
13755 /*
13756 * If this is CD/DVD device in OBP path, the
13757 * ndi_busop_bus_config can be skipped as config one
13758 * operation is done above.
13759 */
13760 if ((ret == NDI_SUCCESS) && (*childp != NULL) &&
13761 (strcmp(ddi_node_name(*childp), "cdrom") == 0) &&
13762 (strncmp((char *)arg, "disk", 4) == 0)) {
13763 bconfig = FALSE;
13764 ndi_hold_devi(*childp);
13765 }
13766 } else {
13767 ret = NDI_FAILURE;
13768 break;
13769 }
13770
13771 /*
13772 * DDI group instructed us to use this flag.
13773 */
13774 mflags |= NDI_MDI_FALLBACK;
13775 break;
13776 case BUS_CONFIG_DRIVER:
13777 case BUS_CONFIG_ALL:
13778 mptsas_config_all(pdip);
13779 ret = NDI_SUCCESS;
13780 break;
13781 }
13782
13783 if ((ret == NDI_SUCCESS) && bconfig) {
13784 ret = ndi_busop_bus_config(pdip, mflags, op,
13785 (devnm == NULL) ? arg : devnm, childp, 0);
13786 }
13787
13788 ndi_devi_exit(pdip, circ1);
13789 ndi_devi_exit(scsi_vhci_dip, circ);
13790 if (devnm != NULL)
13791 kmem_free(devnm, SCSI_MAXNAMELEN);
13792 return (ret);
13793 }
13794
13795 static int
13796 mptsas_probe_lun(dev_info_t *pdip, int lun, dev_info_t **dip,
13797 mptsas_target_t *ptgt)
13798 {
13799 int rval = DDI_FAILURE;
13800 struct scsi_inquiry *sd_inq = NULL;
13801 mptsas_t *mpt = DIP2MPT(pdip);
13802
13803 sd_inq = (struct scsi_inquiry *)kmem_alloc(SUN_INQSIZE, KM_SLEEP);
13804
13805 rval = mptsas_inquiry(mpt, ptgt, lun, 0, (uchar_t *)sd_inq,
13806 SUN_INQSIZE, 0, (uchar_t)0);
13807
13808 if ((rval == DDI_SUCCESS) && MPTSAS_VALID_LUN(sd_inq)) {
13809 rval = mptsas_create_lun(pdip, sd_inq, dip, ptgt, lun);
13810 } else {
13811 rval = DDI_FAILURE;
13812 }
13813
13814 kmem_free(sd_inq, SUN_INQSIZE);
13815 return (rval);
13816 }
13817
13818 static int
13819 mptsas_config_one_addr(dev_info_t *pdip, uint64_t sasaddr, int lun,
13820 dev_info_t **lundip)
13821 {
13822 int rval;
13823 mptsas_t *mpt = DIP2MPT(pdip);
13824 int phymask;
13825 mptsas_target_t *ptgt = NULL;
13826
13827 /*
13828 * Get the physical port associated to the iport
13829 */
13830 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
13831 "phymask", 0);
13832
13833 ptgt = mptsas_wwid_to_ptgt(mpt, phymask, sasaddr);
13834 if (ptgt == NULL) {
13835 /*
13836 * didn't match any device by searching
13837 */
13838 return (DDI_FAILURE);
13839 }
13840 /*
13841 * If the LUN already exists and the status is online,
13842 * we just return the pointer to dev_info_t directly.
13843 * For the mdi_pathinfo node, we'll handle it in
13844 * mptsas_create_virt_lun()
13845 * TODO should be also in mptsas_handle_dr
13846 */
13847
13848 *lundip = mptsas_find_child_addr(pdip, sasaddr, lun);
13849 if (*lundip != NULL) {
13850 /*
13851 * TODO Another senario is, we hotplug the same disk
13852 * on the same slot, the devhdl changed, is this
13853 * possible?
13854 * tgt_private->t_private != ptgt
13855 */
13856 if (sasaddr != ptgt->m_addr.mta_wwn) {
13857 /*
13858 * The device has changed although the devhdl is the
13859 * same (Enclosure mapping mode, change drive on the
13860 * same slot)
13861 */
13862 return (DDI_FAILURE);
13863 }
13864 return (DDI_SUCCESS);
13865 }
13866
13867 if (phymask == 0) {
13868 /*
13869 * Configure IR volume
13870 */
13871 rval = mptsas_config_raid(pdip, ptgt->m_devhdl, lundip);
13872 return (rval);
13873 }
13874 rval = mptsas_probe_lun(pdip, lun, lundip, ptgt);
13875
13876 return (rval);
13877 }
13878
13879 static int
13880 mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun,
13881 dev_info_t **lundip)
13882 {
13883 int rval;
13884 mptsas_t *mpt = DIP2MPT(pdip);
13885 mptsas_phymask_t phymask;
13886 mptsas_target_t *ptgt = NULL;
13887
13888 /*
13889 * Get the physical port associated to the iport
13890 */
13891 phymask = (mptsas_phymask_t)ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
13892 "phymask", 0);
13893
13894 ptgt = mptsas_phy_to_tgt(mpt, phymask, phy);
13895 if (ptgt == NULL) {
13896 /*
13897 * didn't match any device by searching
13898 */
13899 return (DDI_FAILURE);
13900 }
13901
13902 /*
13903 * If the LUN already exists and the status is online,
13904 * we just return the pointer to dev_info_t directly.
13905 * For the mdi_pathinfo node, we'll handle it in
13906 * mptsas_create_virt_lun().
13907 */
13908
13909 *lundip = mptsas_find_child_phy(pdip, phy);
13910 if (*lundip != NULL) {
13911 return (DDI_SUCCESS);
13912 }
13913
13914 rval = mptsas_probe_lun(pdip, lun, lundip, ptgt);
13915
13916 return (rval);
13917 }
13918
13919 static int
13920 mptsas_retrieve_lundata(int lun_cnt, uint8_t *buf, uint16_t *lun_num,
13921 uint8_t *lun_addr_type)
13922 {
13923 uint32_t lun_idx = 0;
13924
13925 ASSERT(lun_num != NULL);
13926 ASSERT(lun_addr_type != NULL);
13927
13928 lun_idx = (lun_cnt + 1) * MPTSAS_SCSI_REPORTLUNS_ADDRESS_SIZE;
13929 /* determine report luns addressing type */
13930 switch (buf[lun_idx] & MPTSAS_SCSI_REPORTLUNS_ADDRESS_MASK) {
13931 /*
13932 * Vendors in the field have been found to be concatenating
13933 * bus/target/lun to equal the complete lun value instead
13934 * of switching to flat space addressing
13935 */
13936 /* 00b - peripheral device addressing method */
13937 case MPTSAS_SCSI_REPORTLUNS_ADDRESS_PERIPHERAL:
13938 /* FALLTHRU */
13939 /* 10b - logical unit addressing method */
13940 case MPTSAS_SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT:
13941 /* FALLTHRU */
13942 /* 01b - flat space addressing method */
13943 case MPTSAS_SCSI_REPORTLUNS_ADDRESS_FLAT_SPACE:
13944 /* byte0 bit0-5=msb lun byte1 bit0-7=lsb lun */
13945 *lun_addr_type = (buf[lun_idx] &
13946 MPTSAS_SCSI_REPORTLUNS_ADDRESS_MASK) >> 6;
13947 *lun_num = (buf[lun_idx] & 0x3F) << 8;
13948 *lun_num |= buf[lun_idx + 1];
13949 return (DDI_SUCCESS);
13950 default:
13951 return (DDI_FAILURE);
13952 }
13953 }
13954
13955 static int
13956 mptsas_config_luns(dev_info_t *pdip, mptsas_target_t *ptgt)
13957 {
13958 struct buf *repluns_bp = NULL;
13959 struct scsi_address ap;
13960 uchar_t cdb[CDB_GROUP5];
13961 int ret = DDI_FAILURE;
13962 int retry = 0;
13963 int lun_list_len = 0;
13964 uint16_t lun_num = 0;
13965 uint8_t lun_addr_type = 0;
13966 uint32_t lun_cnt = 0;
13967 uint32_t lun_total = 0;
13968 dev_info_t *cdip = NULL;
13969 uint16_t *saved_repluns = NULL;
13970 char *buffer = NULL;
13971 int buf_len = 128;
13972 mptsas_t *mpt = DIP2MPT(pdip);
13973 uint64_t sas_wwn = 0;
13974 uint8_t phy = 0xFF;
13975 uint32_t dev_info = 0;
13976
13977 mutex_enter(&mpt->m_mutex);
13978 sas_wwn = ptgt->m_addr.mta_wwn;
13979 phy = ptgt->m_phynum;
13980 dev_info = ptgt->m_deviceinfo;
13981 mutex_exit(&mpt->m_mutex);
13982
13983 if (sas_wwn == 0) {
13984 /*
13985 * It's a SATA without Device Name
13986 * So don't try multi-LUNs
13987 */
13988 if (mptsas_find_child_phy(pdip, phy)) {
13989 return (DDI_SUCCESS);
13990 } else {
13991 /*
13992 * need configure and create node
13993 */
13994 return (DDI_FAILURE);
13995 }
13996 }
13997
13998 /*
13999 * WWN (SAS address or Device Name exist)
14000 */
14001 if (dev_info & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
14002 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
14003 /*
14004 * SATA device with Device Name
14005 * So don't try multi-LUNs
14006 */
14007 if (mptsas_find_child_addr(pdip, sas_wwn, 0)) {
14008 return (DDI_SUCCESS);
14009 } else {
14010 return (DDI_FAILURE);
14011 }
14012 }
14013
14014 do {
14015 ap.a_target = MPTSAS_INVALID_DEVHDL;
14016 ap.a_lun = 0;
14017 ap.a_hba_tran = mpt->m_tran;
14018 repluns_bp = scsi_alloc_consistent_buf(&ap,
14019 (struct buf *)NULL, buf_len, B_READ, NULL_FUNC, NULL);
14020 if (repluns_bp == NULL) {
14021 retry++;
14022 continue;
14023 }
14024 bzero(cdb, CDB_GROUP5);
14025 cdb[0] = SCMD_REPORT_LUNS;
14026 cdb[6] = (buf_len & 0xff000000) >> 24;
14027 cdb[7] = (buf_len & 0x00ff0000) >> 16;
14028 cdb[8] = (buf_len & 0x0000ff00) >> 8;
14029 cdb[9] = (buf_len & 0x000000ff);
14030
14031 ret = mptsas_send_scsi_cmd(mpt, &ap, ptgt, &cdb[0], CDB_GROUP5,
14032 repluns_bp, NULL);
14033 if (ret != DDI_SUCCESS) {
14034 scsi_free_consistent_buf(repluns_bp);
14035 retry++;
14036 continue;
14037 }
14038 lun_list_len = BE_32(*(int *)((void *)(
14039 repluns_bp->b_un.b_addr)));
14040 if (buf_len >= lun_list_len + 8) {
14041 ret = DDI_SUCCESS;
14042 break;
14043 }
14044 scsi_free_consistent_buf(repluns_bp);
14045 buf_len = lun_list_len + 8;
14046
14047 } while (retry < 3);
14048
14049 if (ret != DDI_SUCCESS)
14050 return (ret);
14051 buffer = (char *)repluns_bp->b_un.b_addr;
14052 /*
14053 * find out the number of luns returned by the SCSI ReportLun call
14054 * and allocate buffer space
14055 */
14056 lun_total = lun_list_len / MPTSAS_SCSI_REPORTLUNS_ADDRESS_SIZE;
14057 saved_repluns = kmem_zalloc(sizeof (uint16_t) * lun_total, KM_SLEEP);
14058 if (saved_repluns == NULL) {
14059 scsi_free_consistent_buf(repluns_bp);
14060 return (DDI_FAILURE);
14061 }
14062 for (lun_cnt = 0; lun_cnt < lun_total; lun_cnt++) {
14063 if (mptsas_retrieve_lundata(lun_cnt, (uint8_t *)(buffer),
14064 &lun_num, &lun_addr_type) != DDI_SUCCESS) {
14065 continue;
14066 }
14067 saved_repluns[lun_cnt] = lun_num;
14068 if (cdip = mptsas_find_child_addr(pdip, sas_wwn, lun_num))
14069 ret = DDI_SUCCESS;
14070 else
14071 ret = mptsas_probe_lun(pdip, lun_num, &cdip,
14072 ptgt);
14073 if ((ret == DDI_SUCCESS) && (cdip != NULL)) {
14074 (void) ndi_prop_remove(DDI_DEV_T_NONE, cdip,
14075 MPTSAS_DEV_GONE);
14076 }
14077 }
14078 mptsas_offline_missed_luns(pdip, saved_repluns, lun_total, ptgt);
14079 kmem_free(saved_repluns, sizeof (uint16_t) * lun_total);
14080 scsi_free_consistent_buf(repluns_bp);
14081 return (DDI_SUCCESS);
14082 }
14083
14084 static int
14085 mptsas_config_raid(dev_info_t *pdip, uint16_t target, dev_info_t **dip)
14086 {
14087 int rval = DDI_FAILURE;
14088 struct scsi_inquiry *sd_inq = NULL;
14089 mptsas_t *mpt = DIP2MPT(pdip);
14090 mptsas_target_t *ptgt = NULL;
14091
14092 mutex_enter(&mpt->m_mutex);
14093 ptgt = refhash_linear_search(mpt->m_targets,
14094 mptsas_target_eval_devhdl, &target);
14095 mutex_exit(&mpt->m_mutex);
14096 if (ptgt == NULL) {
14097 mptsas_log(mpt, CE_WARN, "Volume with VolDevHandle of 0x%x "
14098 "not found.", target);
14099 return (rval);
14100 }
14101
14102 sd_inq = (struct scsi_inquiry *)kmem_alloc(SUN_INQSIZE, KM_SLEEP);
14103 rval = mptsas_inquiry(mpt, ptgt, 0, 0, (uchar_t *)sd_inq,
14104 SUN_INQSIZE, 0, (uchar_t)0);
14105
14106 if ((rval == DDI_SUCCESS) && MPTSAS_VALID_LUN(sd_inq)) {
14107 rval = mptsas_create_phys_lun(pdip, sd_inq, NULL, dip, ptgt,
14108 0);
14109 } else {
14110 rval = DDI_FAILURE;
14111 }
14112
14113 kmem_free(sd_inq, SUN_INQSIZE);
14114 return (rval);
14115 }
14116
14117 /*
14118 * configure all RAID volumes for virtual iport
14119 */
14120 static void
14121 mptsas_config_all_viport(dev_info_t *pdip)
14122 {
14123 mptsas_t *mpt = DIP2MPT(pdip);
14124 int config, vol;
14125 int target;
14126 dev_info_t *lundip = NULL;
14127
14128 /*
14129 * Get latest RAID info and search for any Volume DevHandles. If any
14130 * are found, configure the volume.
14131 */
14132 mutex_enter(&mpt->m_mutex);
14133 for (config = 0; config < mpt->m_num_raid_configs; config++) {
14134 for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) {
14135 if (mpt->m_raidconfig[config].m_raidvol[vol].m_israid
14136 == 1) {
14137 target = mpt->m_raidconfig[config].
14138 m_raidvol[vol].m_raidhandle;
14139 mutex_exit(&mpt->m_mutex);
14140 (void) mptsas_config_raid(pdip, target,
14141 &lundip);
14142 mutex_enter(&mpt->m_mutex);
14143 }
14144 }
14145 }
14146 mutex_exit(&mpt->m_mutex);
14147 }
14148
14149 static void
14150 mptsas_offline_missed_luns(dev_info_t *pdip, uint16_t *repluns,
14151 int lun_cnt, mptsas_target_t *ptgt)
14152 {
14153 dev_info_t *child = NULL, *savechild = NULL;
14154 mdi_pathinfo_t *pip = NULL, *savepip = NULL;
14155 uint64_t sas_wwn, wwid;
14156 uint8_t phy;
14157 int lun;
14158 int i;
14159 int find;
14160 char *addr;
14161 char *nodename;
14162 mptsas_t *mpt = DIP2MPT(pdip);
14163
14164 mutex_enter(&mpt->m_mutex);
14165 wwid = ptgt->m_addr.mta_wwn;
14166 mutex_exit(&mpt->m_mutex);
14167
14168 child = ddi_get_child(pdip);
14169 while (child) {
14170 find = 0;
14171 savechild = child;
14172 child = ddi_get_next_sibling(child);
14173
14174 nodename = ddi_node_name(savechild);
14175 if (strcmp(nodename, "smp") == 0) {
14176 continue;
14177 }
14178
14179 addr = ddi_get_name_addr(savechild);
14180 if (addr == NULL) {
14181 continue;
14182 }
14183
14184 if (mptsas_parse_address(addr, &sas_wwn, &phy, &lun) !=
14185 DDI_SUCCESS) {
14186 continue;
14187 }
14188
14189 if (wwid == sas_wwn) {
14190 for (i = 0; i < lun_cnt; i++) {
14191 if (repluns[i] == lun) {
14192 find = 1;
14193 break;
14194 }
14195 }
14196 } else {
14197 continue;
14198 }
14199 if (find == 0) {
14200 /*
14201 * The lun has not been there already
14202 */
14203 (void) mptsas_offline_lun(pdip, savechild, NULL,
14204 NDI_DEVI_REMOVE);
14205 }
14206 }
14207
14208 pip = mdi_get_next_client_path(pdip, NULL);
14209 while (pip) {
14210 find = 0;
14211 savepip = pip;
14212 addr = MDI_PI(pip)->pi_addr;
14213
14214 pip = mdi_get_next_client_path(pdip, pip);
14215
14216 if (addr == NULL) {
14217 continue;
14218 }
14219
14220 if (mptsas_parse_address(addr, &sas_wwn, &phy,
14221 &lun) != DDI_SUCCESS) {
14222 continue;
14223 }
14224
14225 if (sas_wwn == wwid) {
14226 for (i = 0; i < lun_cnt; i++) {
14227 if (repluns[i] == lun) {
14228 find = 1;
14229 break;
14230 }
14231 }
14232 } else {
14233 continue;
14234 }
14235
14236 if (find == 0) {
14237 /*
14238 * The lun has not been there already
14239 */
14240 (void) mptsas_offline_lun(pdip, NULL, savepip,
14241 NDI_DEVI_REMOVE);
14242 }
14243 }
14244 }
14245
14246 void
14247 mptsas_update_hashtab(struct mptsas *mpt)
14248 {
14249 uint32_t page_address;
14250 int rval = 0;
14251 uint16_t dev_handle;
14252 mptsas_target_t *ptgt = NULL;
14253 mptsas_smp_t smp_node;
14254
14255 /*
14256 * Get latest RAID info.
14257 */
14258 (void) mptsas_get_raid_info(mpt);
14259
14260 dev_handle = mpt->m_smp_devhdl;
14261 for (; mpt->m_done_traverse_smp == 0; ) {
14262 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL &
14263 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)dev_handle;
14264 if (mptsas_get_sas_expander_page0(mpt, page_address, &smp_node)
14265 != DDI_SUCCESS) {
14266 break;
14267 }
14268 mpt->m_smp_devhdl = dev_handle = smp_node.m_devhdl;
14269 (void) mptsas_smp_alloc(mpt, &smp_node);
14270 }
14271
14272 /*
14273 * Config target devices
14274 */
14275 dev_handle = mpt->m_dev_handle;
14276
14277 /*
14278 * Do loop to get sas device page 0 by GetNextHandle till the
14279 * the last handle. If the sas device is a SATA/SSP target,
14280 * we try to config it.
14281 */
14282 for (; mpt->m_done_traverse_dev == 0; ) {
14283 ptgt = NULL;
14284 page_address =
14285 (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE &
14286 MPI2_SAS_DEVICE_PGAD_FORM_MASK) |
14287 (uint32_t)dev_handle;
14288 rval = mptsas_get_target_device_info(mpt, page_address,
14289 &dev_handle, &ptgt);
14290 if ((rval == DEV_INFO_FAIL_PAGE0) ||
14291 (rval == DEV_INFO_FAIL_ALLOC)) {
14292 break;
14293 }
14294
14295 mpt->m_dev_handle = dev_handle;
14296 }
14297
14298 }
14299
14300 void
14301 mptsas_update_driver_data(struct mptsas *mpt)
14302 {
14303 mptsas_target_t *tp;
14304 mptsas_smp_t *sp;
14305
14306 ASSERT(MUTEX_HELD(&mpt->m_mutex));
14307
14308 /*
14309 * TODO after hard reset, update the driver data structures
14310 * 1. update port/phymask mapping table mpt->m_phy_info
14311 * 2. invalid all the entries in hash table
14312 * m_devhdl = 0xffff and m_deviceinfo = 0
14313 * 3. call sas_device_page/expander_page to update hash table
14314 */
14315 mptsas_update_phymask(mpt);
14316 /*
14317 * Invalid the existing entries
14318 *
14319 * XXX - It seems like we should just delete everything here. We are
14320 * holding the lock and are about to refresh all the targets in both
14321 * hashes anyway. Given the path we're in, what outstanding async
14322 * event could possibly be trying to reference one of these things
14323 * without taking the lock, and how would that be useful anyway?
14324 */
14325 for (tp = refhash_first(mpt->m_targets); tp != NULL;
14326 tp = refhash_next(mpt->m_targets, tp)) {
14327 tp->m_devhdl = MPTSAS_INVALID_DEVHDL;
14328 tp->m_deviceinfo = 0;
14329 tp->m_dr_flag = MPTSAS_DR_INACTIVE;
14330 }
14331 for (sp = refhash_first(mpt->m_smp_targets); sp != NULL;
14332 sp = refhash_next(mpt->m_smp_targets, sp)) {
14333 sp->m_devhdl = MPTSAS_INVALID_DEVHDL;
14334 sp->m_deviceinfo = 0;
14335 }
14336 mpt->m_done_traverse_dev = 0;
14337 mpt->m_done_traverse_smp = 0;
14338 mpt->m_dev_handle = mpt->m_smp_devhdl = MPTSAS_INVALID_DEVHDL;
14339 mptsas_update_hashtab(mpt);
14340 }
14341
14342 static void
14343 mptsas_config_all(dev_info_t *pdip)
14344 {
14345 dev_info_t *smpdip = NULL;
14346 mptsas_t *mpt = DIP2MPT(pdip);
14347 int phymask = 0;
14348 mptsas_phymask_t phy_mask;
14349 mptsas_target_t *ptgt = NULL;
14350 mptsas_smp_t *psmp;
14351
14352 /*
14353 * Get the phymask associated to the iport
14354 */
14355 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
14356 "phymask", 0);
14357
14358 /*
14359 * Enumerate RAID volumes here (phymask == 0).
14360 */
14361 if (phymask == 0) {
14362 mptsas_config_all_viport(pdip);
14363 return;
14364 }
14365
14366 mutex_enter(&mpt->m_mutex);
14367
14368 if (!mpt->m_done_traverse_dev || !mpt->m_done_traverse_smp) {
14369 mptsas_update_hashtab(mpt);
14370 }
14371
14372 for (psmp = refhash_first(mpt->m_smp_targets); psmp != NULL;
14373 psmp = refhash_next(mpt->m_smp_targets, psmp)) {
14374 phy_mask = psmp->m_addr.mta_phymask;
14375 if (phy_mask == phymask) {
14376 smpdip = NULL;
14377 mutex_exit(&mpt->m_mutex);
14378 (void) mptsas_online_smp(pdip, psmp, &smpdip);
14379 mutex_enter(&mpt->m_mutex);
14380 }
14381 }
14382
14383 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
14384 ptgt = refhash_next(mpt->m_targets, ptgt)) {
14385 phy_mask = ptgt->m_addr.mta_phymask;
14386 if (phy_mask == phymask) {
14387 mutex_exit(&mpt->m_mutex);
14388 (void) mptsas_config_target(pdip, ptgt);
14389 mutex_enter(&mpt->m_mutex);
14390 }
14391 }
14392 mutex_exit(&mpt->m_mutex);
14393 }
14394
14395 static int
14396 mptsas_config_target(dev_info_t *pdip, mptsas_target_t *ptgt)
14397 {
14398 int rval = DDI_FAILURE;
14399 dev_info_t *tdip;
14400
14401 rval = mptsas_config_luns(pdip, ptgt);
14402 if (rval != DDI_SUCCESS) {
14403 /*
14404 * The return value means the SCMD_REPORT_LUNS
14405 * did not execute successfully. The target maybe
14406 * doesn't support such command.
14407 */
14408 rval = mptsas_probe_lun(pdip, 0, &tdip, ptgt);
14409 }
14410 return (rval);
14411 }
14412
14413 /*
14414 * Return fail if not all the childs/paths are freed.
14415 * if there is any path under the HBA, the return value will be always fail
14416 * because we didn't call mdi_pi_free for path
14417 */
14418 static int
14419 mptsas_offline_target(dev_info_t *pdip, char *name)
14420 {
14421 dev_info_t *child = NULL, *prechild = NULL;
14422 mdi_pathinfo_t *pip = NULL, *savepip = NULL;
14423 int tmp_rval, rval = DDI_SUCCESS;
14424 char *addr, *cp;
14425 size_t s;
14426 mptsas_t *mpt = DIP2MPT(pdip);
14427
14428 child = ddi_get_child(pdip);
14429 while (child) {
14430 addr = ddi_get_name_addr(child);
14431 prechild = child;
14432 child = ddi_get_next_sibling(child);
14433
14434 if (addr == NULL) {
14435 continue;
14436 }
14437 if ((cp = strchr(addr, ',')) == NULL) {
14438 continue;
14439 }
14440
14441 s = (uintptr_t)cp - (uintptr_t)addr;
14442
14443 if (strncmp(addr, name, s) != 0) {
14444 continue;
14445 }
14446
14447 tmp_rval = mptsas_offline_lun(pdip, prechild, NULL,
14448 NDI_DEVI_REMOVE);
14449 if (tmp_rval != DDI_SUCCESS) {
14450 rval = DDI_FAILURE;
14451 if (ndi_prop_create_boolean(DDI_DEV_T_NONE,
14452 prechild, MPTSAS_DEV_GONE) !=
14453 DDI_PROP_SUCCESS) {
14454 mptsas_log(mpt, CE_WARN, "mptsas driver "
14455 "unable to create property for "
14456 "SAS %s (MPTSAS_DEV_GONE)", addr);
14457 }
14458 }
14459 }
14460
14461 pip = mdi_get_next_client_path(pdip, NULL);
14462 while (pip) {
14463 addr = MDI_PI(pip)->pi_addr;
14464 savepip = pip;
14465 pip = mdi_get_next_client_path(pdip, pip);
14466 if (addr == NULL) {
14467 continue;
14468 }
14469
14470 if ((cp = strchr(addr, ',')) == NULL) {
14471 continue;
14472 }
14473
14474 s = (uintptr_t)cp - (uintptr_t)addr;
14475
14476 if (strncmp(addr, name, s) != 0) {
14477 continue;
14478 }
14479
14480 (void) mptsas_offline_lun(pdip, NULL, savepip,
14481 NDI_DEVI_REMOVE);
14482 /*
14483 * driver will not invoke mdi_pi_free, so path will not
14484 * be freed forever, return DDI_FAILURE.
14485 */
14486 rval = DDI_FAILURE;
14487 }
14488 return (rval);
14489 }
14490
14491 static int
14492 mptsas_offline_lun(dev_info_t *pdip, dev_info_t *rdip,
14493 mdi_pathinfo_t *rpip, uint_t flags)
14494 {
14495 int rval = DDI_FAILURE;
14496 char *devname;
14497 dev_info_t *cdip, *parent;
14498
14499 if (rpip != NULL) {
14500 parent = scsi_vhci_dip;
14501 cdip = mdi_pi_get_client(rpip);
14502 } else if (rdip != NULL) {
14503 parent = pdip;
14504 cdip = rdip;
14505 } else {
14506 return (DDI_FAILURE);
14507 }
14508
14509 /*
14510 * Make sure node is attached otherwise
14511 * it won't have related cache nodes to
14512 * clean up. i_ddi_devi_attached is
14513 * similiar to i_ddi_node_state(cdip) >=
14514 * DS_ATTACHED.
14515 */
14516 if (i_ddi_devi_attached(cdip)) {
14517
14518 /* Get full devname */
14519 devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP);
14520 (void) ddi_deviname(cdip, devname);
14521 /* Clean cache */
14522 (void) devfs_clean(parent, devname + 1,
14523 DV_CLEAN_FORCE);
14524 kmem_free(devname, MAXNAMELEN + 1);
14525 }
14526 if (rpip != NULL) {
14527 if (MDI_PI_IS_OFFLINE(rpip)) {
14528 rval = DDI_SUCCESS;
14529 } else {
14530 rval = mdi_pi_offline(rpip, 0);
14531 }
14532 } else {
14533 rval = ndi_devi_offline(cdip, flags);
14534 }
14535
14536 return (rval);
14537 }
14538
14539 static dev_info_t *
14540 mptsas_find_smp_child(dev_info_t *parent, char *str_wwn)
14541 {
14542 dev_info_t *child = NULL;
14543 char *smp_wwn = NULL;
14544
14545 child = ddi_get_child(parent);
14546 while (child) {
14547 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child,
14548 DDI_PROP_DONTPASS, SMP_WWN, &smp_wwn)
14549 != DDI_SUCCESS) {
14550 child = ddi_get_next_sibling(child);
14551 continue;
14552 }
14553
14554 if (strcmp(smp_wwn, str_wwn) == 0) {
14555 ddi_prop_free(smp_wwn);
14556 break;
14557 }
14558 child = ddi_get_next_sibling(child);
14559 ddi_prop_free(smp_wwn);
14560 }
14561 return (child);
14562 }
14563
14564 static int
14565 mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, uint_t flags)
14566 {
14567 int rval = DDI_FAILURE;
14568 char *devname;
14569 char wwn_str[MPTSAS_WWN_STRLEN];
14570 dev_info_t *cdip;
14571
14572 (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_addr.mta_wwn);
14573
14574 cdip = mptsas_find_smp_child(pdip, wwn_str);
14575
14576 if (cdip == NULL)
14577 return (DDI_SUCCESS);
14578
14579 /*
14580 * Make sure node is attached otherwise
14581 * it won't have related cache nodes to
14582 * clean up. i_ddi_devi_attached is
14583 * similiar to i_ddi_node_state(cdip) >=
14584 * DS_ATTACHED.
14585 */
14586 if (i_ddi_devi_attached(cdip)) {
14587
14588 /* Get full devname */
14589 devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP);
14590 (void) ddi_deviname(cdip, devname);
14591 /* Clean cache */
14592 (void) devfs_clean(pdip, devname + 1,
14593 DV_CLEAN_FORCE);
14594 kmem_free(devname, MAXNAMELEN + 1);
14595 }
14596
14597 rval = ndi_devi_offline(cdip, flags);
14598
14599 return (rval);
14600 }
14601
14602 static dev_info_t *
14603 mptsas_find_child(dev_info_t *pdip, char *name)
14604 {
14605 dev_info_t *child = NULL;
14606 char *rname = NULL;
14607 int rval = DDI_FAILURE;
14608
14609 rname = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
14610
14611 child = ddi_get_child(pdip);
14612 while (child) {
14613 rval = mptsas_name_child(child, rname, SCSI_MAXNAMELEN);
14614 if (rval != DDI_SUCCESS) {
14615 child = ddi_get_next_sibling(child);
14616 bzero(rname, SCSI_MAXNAMELEN);
14617 continue;
14618 }
14619
14620 if (strcmp(rname, name) == 0) {
14621 break;
14622 }
14623 child = ddi_get_next_sibling(child);
14624 bzero(rname, SCSI_MAXNAMELEN);
14625 }
14626
14627 kmem_free(rname, SCSI_MAXNAMELEN);
14628
14629 return (child);
14630 }
14631
14632
14633 static dev_info_t *
14634 mptsas_find_child_addr(dev_info_t *pdip, uint64_t sasaddr, int lun)
14635 {
14636 dev_info_t *child = NULL;
14637 char *name = NULL;
14638 char *addr = NULL;
14639
14640 name = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
14641 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
14642 (void) sprintf(name, "%016"PRIx64, sasaddr);
14643 (void) sprintf(addr, "w%s,%x", name, lun);
14644 child = mptsas_find_child(pdip, addr);
14645 kmem_free(name, SCSI_MAXNAMELEN);
14646 kmem_free(addr, SCSI_MAXNAMELEN);
14647 return (child);
14648 }
14649
14650 static dev_info_t *
14651 mptsas_find_child_phy(dev_info_t *pdip, uint8_t phy)
14652 {
14653 dev_info_t *child;
14654 char *addr;
14655
14656 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
14657 (void) sprintf(addr, "p%x,0", phy);
14658 child = mptsas_find_child(pdip, addr);
14659 kmem_free(addr, SCSI_MAXNAMELEN);
14660 return (child);
14661 }
14662
14663 static mdi_pathinfo_t *
14664 mptsas_find_path_phy(dev_info_t *pdip, uint8_t phy)
14665 {
14666 mdi_pathinfo_t *path;
14667 char *addr = NULL;
14668
14669 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
14670 (void) sprintf(addr, "p%x,0", phy);
14671 path = mdi_pi_find(pdip, NULL, addr);
14672 kmem_free(addr, SCSI_MAXNAMELEN);
14673 return (path);
14674 }
14675
14676 static mdi_pathinfo_t *
14677 mptsas_find_path_addr(dev_info_t *parent, uint64_t sasaddr, int lun)
14678 {
14679 mdi_pathinfo_t *path;
14680 char *name = NULL;
14681 char *addr = NULL;
14682
14683 name = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
14684 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
14685 (void) sprintf(name, "%016"PRIx64, sasaddr);
14686 (void) sprintf(addr, "w%s,%x", name, lun);
14687 path = mdi_pi_find(parent, NULL, addr);
14688 kmem_free(name, SCSI_MAXNAMELEN);
14689 kmem_free(addr, SCSI_MAXNAMELEN);
14690
14691 return (path);
14692 }
14693
14694 static int
14695 mptsas_create_lun(dev_info_t *pdip, struct scsi_inquiry *sd_inq,
14696 dev_info_t **lun_dip, mptsas_target_t *ptgt, int lun)
14697 {
14698 int i = 0;
14699 uchar_t *inq83 = NULL;
14700 int inq83_len1 = 0xFF;
14701 int inq83_len = 0;
14702 int rval = DDI_FAILURE;
14703 ddi_devid_t devid;
14704 char *guid = NULL;
14705 int target = ptgt->m_devhdl;
14706 mdi_pathinfo_t *pip = NULL;
14707 mptsas_t *mpt = DIP2MPT(pdip);
14708
14709 /*
14710 * For DVD/CD ROM and tape devices and optical
14711 * devices, we won't try to enumerate them under
14712 * scsi_vhci, so no need to try page83
14713 */
14714 if (sd_inq && (sd_inq->inq_dtype == DTYPE_RODIRECT ||
14715 sd_inq->inq_dtype == DTYPE_OPTICAL ||
14716 sd_inq->inq_dtype == DTYPE_ESI))
14717 goto create_lun;
14718
14719 /*
14720 * The LCA returns good SCSI status, but corrupt page 83 data the first
14721 * time it is queried. The solution is to keep trying to request page83
14722 * and verify the GUID is not (DDI_NOT_WELL_FORMED) in
14723 * mptsas_inq83_retry_timeout seconds. If the timeout expires, driver
14724 * give up to get VPD page at this stage and fail the enumeration.
14725 */
14726
14727 inq83 = kmem_zalloc(inq83_len1, KM_SLEEP);
14728
14729 for (i = 0; i < mptsas_inq83_retry_timeout; i++) {
14730 rval = mptsas_inquiry(mpt, ptgt, lun, 0x83, inq83,
14731 inq83_len1, &inq83_len, 1);
14732 if (rval != 0) {
14733 mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page "
14734 "0x83 for target:%x, lun:%x failed!", target, lun);
14735 if (mptsas_physical_bind_failed_page_83 != B_FALSE)
14736 goto create_lun;
14737 goto out;
14738 }
14739 /*
14740 * create DEVID from inquiry data
14741 */
14742 if ((rval = ddi_devid_scsi_encode(
14743 DEVID_SCSI_ENCODE_VERSION_LATEST, NULL, (uchar_t *)sd_inq,
14744 sizeof (struct scsi_inquiry), NULL, 0, inq83,
14745 (size_t)inq83_len, &devid)) == DDI_SUCCESS) {
14746 /*
14747 * extract GUID from DEVID
14748 */
14749 guid = ddi_devid_to_guid(devid);
14750
14751 /*
14752 * Do not enable MPXIO if the strlen(guid) is greater
14753 * than MPTSAS_MAX_GUID_LEN, this constrain would be
14754 * handled by framework later.
14755 */
14756 if (guid && (strlen(guid) > MPTSAS_MAX_GUID_LEN)) {
14757 ddi_devid_free_guid(guid);
14758 guid = NULL;
14759 if (mpt->m_mpxio_enable == TRUE) {
14760 mptsas_log(mpt, CE_NOTE, "!Target:%x, "
14761 "lun:%x doesn't have a valid GUID, "
14762 "multipathing for this drive is "
14763 "not enabled", target, lun);
14764 }
14765 }
14766
14767 /*
14768 * devid no longer needed
14769 */
14770 ddi_devid_free(devid);
14771 break;
14772 } else if (rval == DDI_NOT_WELL_FORMED) {
14773 /*
14774 * return value of ddi_devid_scsi_encode equal to
14775 * DDI_NOT_WELL_FORMED means DEVID_RETRY, it worth
14776 * to retry inquiry page 0x83 and get GUID.
14777 */
14778 NDBG20(("Not well formed devid, retry..."));
14779 delay(1 * drv_usectohz(1000000));
14780 continue;
14781 } else {
14782 mptsas_log(mpt, CE_WARN, "!Encode devid failed for "
14783 "path target:%x, lun:%x", target, lun);
14784 rval = DDI_FAILURE;
14785 goto create_lun;
14786 }
14787 }
14788
14789 if (i == mptsas_inq83_retry_timeout) {
14790 mptsas_log(mpt, CE_WARN, "!Repeated page83 requests timeout "
14791 "for path target:%x, lun:%x", target, lun);
14792 }
14793
14794 rval = DDI_FAILURE;
14795
14796 create_lun:
14797 if ((guid != NULL) && (mpt->m_mpxio_enable == TRUE)) {
14798 rval = mptsas_create_virt_lun(pdip, sd_inq, guid, lun_dip, &pip,
14799 ptgt, lun);
14800 }
14801 if (rval != DDI_SUCCESS) {
14802 rval = mptsas_create_phys_lun(pdip, sd_inq, guid, lun_dip,
14803 ptgt, lun);
14804
14805 }
14806 out:
14807 if (guid != NULL) {
14808 /*
14809 * guid no longer needed
14810 */
14811 ddi_devid_free_guid(guid);
14812 }
14813 if (inq83 != NULL)
14814 kmem_free(inq83, inq83_len1);
14815 return (rval);
14816 }
14817
14818 static int
14819 mptsas_create_virt_lun(dev_info_t *pdip, struct scsi_inquiry *inq, char *guid,
14820 dev_info_t **lun_dip, mdi_pathinfo_t **pip, mptsas_target_t *ptgt, int lun)
14821 {
14822 int target;
14823 char *nodename = NULL;
14824 char **compatible = NULL;
14825 int ncompatible = 0;
14826 int mdi_rtn = MDI_FAILURE;
14827 int rval = DDI_FAILURE;
14828 char *old_guid = NULL;
14829 mptsas_t *mpt = DIP2MPT(pdip);
14830 char *lun_addr = NULL;
14831 char *wwn_str = NULL;
14832 char *attached_wwn_str = NULL;
14833 char *component = NULL;
14834 uint8_t phy = 0xFF;
14835 uint64_t sas_wwn;
14836 int64_t lun64 = 0;
14837 uint32_t devinfo;
14838 uint16_t dev_hdl;
14839 uint16_t pdev_hdl;
14840 uint64_t dev_sas_wwn;
14841 uint64_t pdev_sas_wwn;
14842 uint32_t pdev_info;
14843 uint8_t physport;
14844 uint8_t phy_id;
14845 uint32_t page_address;
14846 uint16_t bay_num, enclosure, io_flags;
14847 char pdev_wwn_str[MPTSAS_WWN_STRLEN];
14848 uint32_t dev_info;
14849
14850 mutex_enter(&mpt->m_mutex);
14851 target = ptgt->m_devhdl;
14852 sas_wwn = ptgt->m_addr.mta_wwn;
14853 devinfo = ptgt->m_deviceinfo;
14854 phy = ptgt->m_phynum;
14855 mutex_exit(&mpt->m_mutex);
14856
14857 if (sas_wwn) {
14858 *pip = mptsas_find_path_addr(pdip, sas_wwn, lun);
14859 } else {
14860 *pip = mptsas_find_path_phy(pdip, phy);
14861 }
14862
14863 if (*pip != NULL) {
14864 *lun_dip = MDI_PI(*pip)->pi_client->ct_dip;
14865 ASSERT(*lun_dip != NULL);
14866 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, *lun_dip,
14867 (DDI_PROP_DONTPASS | DDI_PROP_NOTPROM),
14868 MDI_CLIENT_GUID_PROP, &old_guid) == DDI_SUCCESS) {
14869 if (strncmp(guid, old_guid, strlen(guid)) == 0) {
14870 /*
14871 * Same path back online again.
14872 */
14873 (void) ddi_prop_free(old_guid);
14874 if ((!MDI_PI_IS_ONLINE(*pip)) &&
14875 (!MDI_PI_IS_STANDBY(*pip)) &&
14876 (ptgt->m_tgt_unconfigured == 0)) {
14877 rval = mdi_pi_online(*pip, 0);
14878 mutex_enter(&mpt->m_mutex);
14879 ptgt->m_led_status = 0;
14880 (void) mptsas_flush_led_status(mpt,
14881 ptgt);
14882 mutex_exit(&mpt->m_mutex);
14883 } else {
14884 rval = DDI_SUCCESS;
14885 }
14886 if (rval != DDI_SUCCESS) {
14887 mptsas_log(mpt, CE_WARN, "path:target: "
14888 "%x, lun:%x online failed!", target,
14889 lun);
14890 *pip = NULL;
14891 *lun_dip = NULL;
14892 }
14893 return (rval);
14894 } else {
14895 /*
14896 * The GUID of the LUN has changed which maybe
14897 * because customer mapped another volume to the
14898 * same LUN.
14899 */
14900 mptsas_log(mpt, CE_WARN, "The GUID of the "
14901 "target:%x, lun:%x was changed, maybe "
14902 "because someone mapped another volume "
14903 "to the same LUN", target, lun);
14904 (void) ddi_prop_free(old_guid);
14905 if (!MDI_PI_IS_OFFLINE(*pip)) {
14906 rval = mdi_pi_offline(*pip, 0);
14907 if (rval != MDI_SUCCESS) {
14908 mptsas_log(mpt, CE_WARN, "path:"
14909 "target:%x, lun:%x offline "
14910 "failed!", target, lun);
14911 *pip = NULL;
14912 *lun_dip = NULL;
14913 return (DDI_FAILURE);
14914 }
14915 }
14916 if (mdi_pi_free(*pip, 0) != MDI_SUCCESS) {
14917 mptsas_log(mpt, CE_WARN, "path:target:"
14918 "%x, lun:%x free failed!", target,
14919 lun);
14920 *pip = NULL;
14921 *lun_dip = NULL;
14922 return (DDI_FAILURE);
14923 }
14924 }
14925 } else {
14926 mptsas_log(mpt, CE_WARN, "Can't get client-guid "
14927 "property for path:target:%x, lun:%x", target, lun);
14928 *pip = NULL;
14929 *lun_dip = NULL;
14930 return (DDI_FAILURE);
14931 }
14932 }
14933 scsi_hba_nodename_compatible_get(inq, NULL,
14934 inq->inq_dtype, NULL, &nodename, &compatible, &ncompatible);
14935
14936 /*
14937 * if nodename can't be determined then print a message and skip it
14938 */
14939 if (nodename == NULL) {
14940 mptsas_log(mpt, CE_WARN, "mptsas driver found no compatible "
14941 "driver for target%d lun %d dtype:0x%02x", target, lun,
14942 inq->inq_dtype);
14943 return (DDI_FAILURE);
14944 }
14945
14946 wwn_str = kmem_zalloc(MPTSAS_WWN_STRLEN, KM_SLEEP);
14947 /* The property is needed by MPAPI */
14948 (void) sprintf(wwn_str, "%016"PRIx64, sas_wwn);
14949
14950 lun_addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
14951 if (guid) {
14952 (void) sprintf(lun_addr, "w%s,%x", wwn_str, lun);
14953 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn);
14954 } else {
14955 (void) sprintf(lun_addr, "p%x,%x", phy, lun);
14956 (void) sprintf(wwn_str, "p%x", phy);
14957 }
14958
14959 mdi_rtn = mdi_pi_alloc_compatible(pdip, nodename,
14960 guid, lun_addr, compatible, ncompatible,
14961 0, pip);
14962 if (mdi_rtn == MDI_SUCCESS) {
14963
14964 if (mdi_prop_update_string(*pip, MDI_GUID,
14965 guid) != DDI_SUCCESS) {
14966 mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
14967 "create prop for target %d lun %d (MDI_GUID)",
14968 target, lun);
14969 mdi_rtn = MDI_FAILURE;
14970 goto virt_create_done;
14971 }
14972
14973 if (mdi_prop_update_int(*pip, LUN_PROP,
14974 lun) != DDI_SUCCESS) {
14975 mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
14976 "create prop for target %d lun %d (LUN_PROP)",
14977 target, lun);
14978 mdi_rtn = MDI_FAILURE;
14979 goto virt_create_done;
14980 }
14981 lun64 = (int64_t)lun;
14982 if (mdi_prop_update_int64(*pip, LUN64_PROP,
14983 lun64) != DDI_SUCCESS) {
14984 mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
14985 "create prop for target %d (LUN64_PROP)",
14986 target);
14987 mdi_rtn = MDI_FAILURE;
14988 goto virt_create_done;
14989 }
14990 if (mdi_prop_update_string_array(*pip, "compatible",
14991 compatible, ncompatible) !=
14992 DDI_PROP_SUCCESS) {
14993 mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
14994 "create prop for target %d lun %d (COMPATIBLE)",
14995 target, lun);
14996 mdi_rtn = MDI_FAILURE;
14997 goto virt_create_done;
14998 }
14999 if (sas_wwn && (mdi_prop_update_string(*pip,
15000 SCSI_ADDR_PROP_TARGET_PORT, wwn_str) != DDI_PROP_SUCCESS)) {
15001 mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
15002 "create prop for target %d lun %d "
15003 "(target-port)", target, lun);
15004 mdi_rtn = MDI_FAILURE;
15005 goto virt_create_done;
15006 } else if ((sas_wwn == 0) && (mdi_prop_update_int(*pip,
15007 "sata-phy", phy) != DDI_PROP_SUCCESS)) {
15008 /*
15009 * Direct attached SATA device without DeviceName
15010 */
15011 mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
15012 "create prop for SAS target %d lun %d "
15013 "(sata-phy)", target, lun);
15014 mdi_rtn = MDI_FAILURE;
15015 goto virt_create_done;
15016 }
15017 mutex_enter(&mpt->m_mutex);
15018
15019 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
15020 MPI2_SAS_DEVICE_PGAD_FORM_MASK) |
15021 (uint32_t)ptgt->m_devhdl;
15022 rval = mptsas_get_sas_device_page0(mpt, page_address,
15023 &dev_hdl, &dev_sas_wwn, &dev_info, &physport,
15024 &phy_id, &pdev_hdl, &bay_num, &enclosure, &io_flags);
15025 if (rval != DDI_SUCCESS) {
15026 mutex_exit(&mpt->m_mutex);
15027 mptsas_log(mpt, CE_WARN, "mptsas unable to get "
15028 "parent device for handle %d", page_address);
15029 mdi_rtn = MDI_FAILURE;
15030 goto virt_create_done;
15031 }
15032
15033 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
15034 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)pdev_hdl;
15035 rval = mptsas_get_sas_device_page0(mpt, page_address,
15036 &dev_hdl, &pdev_sas_wwn, &pdev_info, &physport,
15037 &phy_id, &pdev_hdl, &bay_num, &enclosure, &io_flags);
15038 if (rval != DDI_SUCCESS) {
15039 mutex_exit(&mpt->m_mutex);
15040 mptsas_log(mpt, CE_WARN, "mptsas unable to get"
15041 "device info for handle %d", page_address);
15042 mdi_rtn = MDI_FAILURE;
15043 goto virt_create_done;
15044 }
15045
15046 mutex_exit(&mpt->m_mutex);
15047
15048 /*
15049 * If this device direct attached to the controller
15050 * set the attached-port to the base wwid
15051 */
15052 if ((ptgt->m_deviceinfo & DEVINFO_DIRECT_ATTACHED)
15053 != DEVINFO_DIRECT_ATTACHED) {
15054 (void) sprintf(pdev_wwn_str, "w%016"PRIx64,
15055 pdev_sas_wwn);
15056 } else {
15057 /*
15058 * Update the iport's attached-port to guid
15059 */
15060 if (sas_wwn == 0) {
15061 (void) sprintf(wwn_str, "p%x", phy);
15062 } else {
15063 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn);
15064 }
15065 if (ddi_prop_update_string(DDI_DEV_T_NONE,
15066 pdip, SCSI_ADDR_PROP_ATTACHED_PORT, wwn_str) !=
15067 DDI_PROP_SUCCESS) {
15068 mptsas_log(mpt, CE_WARN,
15069 "mptsas unable to create "
15070 "property for iport target-port"
15071 " %s (sas_wwn)",
15072 wwn_str);
15073 mdi_rtn = MDI_FAILURE;
15074 goto virt_create_done;
15075 }
15076
15077 (void) sprintf(pdev_wwn_str, "w%016"PRIx64,
15078 mpt->un.m_base_wwid);
15079 }
15080
15081 if (mdi_prop_update_string(*pip,
15082 SCSI_ADDR_PROP_ATTACHED_PORT, pdev_wwn_str) !=
15083 DDI_PROP_SUCCESS) {
15084 mptsas_log(mpt, CE_WARN, "mptsas unable to create "
15085 "property for iport attached-port %s (sas_wwn)",
15086 attached_wwn_str);
15087 mdi_rtn = MDI_FAILURE;
15088 goto virt_create_done;
15089 }
15090
15091
15092 if (inq->inq_dtype == 0) {
15093 component = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
15094 /*
15095 * set obp path for pathinfo
15096 */
15097 (void) snprintf(component, MAXPATHLEN,
15098 "disk@%s", lun_addr);
15099
15100 if (mdi_pi_pathname_obp_set(*pip, component) !=
15101 DDI_SUCCESS) {
15102 mptsas_log(mpt, CE_WARN, "mpt_sas driver "
15103 "unable to set obp-path for object %s",
15104 component);
15105 mdi_rtn = MDI_FAILURE;
15106 goto virt_create_done;
15107 }
15108 }
15109
15110 *lun_dip = MDI_PI(*pip)->pi_client->ct_dip;
15111 if (devinfo & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
15112 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
15113 if ((ndi_prop_update_int(DDI_DEV_T_NONE, *lun_dip,
15114 "pm-capable", 1)) !=
15115 DDI_PROP_SUCCESS) {
15116 mptsas_log(mpt, CE_WARN, "mptsas driver"
15117 "failed to create pm-capable "
15118 "property, target %d", target);
15119 mdi_rtn = MDI_FAILURE;
15120 goto virt_create_done;
15121 }
15122 }
15123 /*
15124 * Create the phy-num property
15125 */
15126 if (mdi_prop_update_int(*pip, "phy-num",
15127 ptgt->m_phynum) != DDI_SUCCESS) {
15128 mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
15129 "create phy-num property for target %d lun %d",
15130 target, lun);
15131 mdi_rtn = MDI_FAILURE;
15132 goto virt_create_done;
15133 }
15134 NDBG20(("new path:%s onlining,", MDI_PI(*pip)->pi_addr));
15135 mdi_rtn = mdi_pi_online(*pip, 0);
15136 if (mdi_rtn == MDI_SUCCESS) {
15137 mutex_enter(&mpt->m_mutex);
15138 ptgt->m_led_status = 0;
15139 (void) mptsas_flush_led_status(mpt, ptgt);
15140 mutex_exit(&mpt->m_mutex);
15141 }
15142 if (mdi_rtn == MDI_NOT_SUPPORTED) {
15143 mdi_rtn = MDI_FAILURE;
15144 }
15145 virt_create_done:
15146 if (*pip && mdi_rtn != MDI_SUCCESS) {
15147 (void) mdi_pi_free(*pip, 0);
15148 *pip = NULL;
15149 *lun_dip = NULL;
15150 }
15151 }
15152
15153 scsi_hba_nodename_compatible_free(nodename, compatible);
15154 if (lun_addr != NULL) {
15155 kmem_free(lun_addr, SCSI_MAXNAMELEN);
15156 }
15157 if (wwn_str != NULL) {
15158 kmem_free(wwn_str, MPTSAS_WWN_STRLEN);
15159 }
15160 if (component != NULL) {
15161 kmem_free(component, MAXPATHLEN);
15162 }
15163
15164 return ((mdi_rtn == MDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
15165 }
15166
15167 static int
15168 mptsas_create_phys_lun(dev_info_t *pdip, struct scsi_inquiry *inq,
15169 char *guid, dev_info_t **lun_dip, mptsas_target_t *ptgt, int lun)
15170 {
15171 int target;
15172 int rval;
15173 int ndi_rtn = NDI_FAILURE;
15174 uint64_t be_sas_wwn;
15175 char *nodename = NULL;
15176 char **compatible = NULL;
15177 int ncompatible = 0;
15178 int instance = 0;
15179 mptsas_t *mpt = DIP2MPT(pdip);
15180 char *wwn_str = NULL;
15181 char *component = NULL;
15182 char *attached_wwn_str = NULL;
15183 uint8_t phy = 0xFF;
15184 uint64_t sas_wwn;
15185 uint32_t devinfo;
15186 uint16_t dev_hdl;
15187 uint16_t pdev_hdl;
15188 uint64_t pdev_sas_wwn;
15189 uint64_t dev_sas_wwn;
15190 uint32_t pdev_info;
15191 uint8_t physport;
15192 uint8_t phy_id;
15193 uint32_t page_address;
15194 uint16_t bay_num, enclosure, io_flags;
15195 char pdev_wwn_str[MPTSAS_WWN_STRLEN];
15196 uint32_t dev_info;
15197 int64_t lun64 = 0;
15198
15199 mutex_enter(&mpt->m_mutex);
15200 target = ptgt->m_devhdl;
15201 sas_wwn = ptgt->m_addr.mta_wwn;
15202 devinfo = ptgt->m_deviceinfo;
15203 phy = ptgt->m_phynum;
15204 mutex_exit(&mpt->m_mutex);
15205
15206 /*
15207 * generate compatible property with binding-set "mpt"
15208 */
15209 scsi_hba_nodename_compatible_get(inq, NULL, inq->inq_dtype, NULL,
15210 &nodename, &compatible, &ncompatible);
15211
15212 /*
15213 * if nodename can't be determined then print a message and skip it
15214 */
15215 if (nodename == NULL) {
15216 mptsas_log(mpt, CE_WARN, "mptsas found no compatible driver "
15217 "for target %d lun %d", target, lun);
15218 return (DDI_FAILURE);
15219 }
15220
15221 ndi_rtn = ndi_devi_alloc(pdip, nodename,
15222 DEVI_SID_NODEID, lun_dip);
15223
15224 /*
15225 * if lun alloc success, set props
15226 */
15227 if (ndi_rtn == NDI_SUCCESS) {
15228
15229 if (ndi_prop_update_int(DDI_DEV_T_NONE,
15230 *lun_dip, LUN_PROP, lun) !=
15231 DDI_PROP_SUCCESS) {
15232 mptsas_log(mpt, CE_WARN, "mptsas unable to create "
15233 "property for target %d lun %d (LUN_PROP)",
15234 target, lun);
15235 ndi_rtn = NDI_FAILURE;
15236 goto phys_create_done;
15237 }
15238
15239 lun64 = (int64_t)lun;
15240 if (ndi_prop_update_int64(DDI_DEV_T_NONE,
15241 *lun_dip, LUN64_PROP, lun64) !=
15242 DDI_PROP_SUCCESS) {
15243 mptsas_log(mpt, CE_WARN, "mptsas unable to create "
15244 "property for target %d lun64 %d (LUN64_PROP)",
15245 target, lun);
15246 ndi_rtn = NDI_FAILURE;
15247 goto phys_create_done;
15248 }
15249 if (ndi_prop_update_string_array(DDI_DEV_T_NONE,
15250 *lun_dip, "compatible", compatible, ncompatible)
15251 != DDI_PROP_SUCCESS) {
15252 mptsas_log(mpt, CE_WARN, "mptsas unable to create "
15253 "property for target %d lun %d (COMPATIBLE)",
15254 target, lun);
15255 ndi_rtn = NDI_FAILURE;
15256 goto phys_create_done;
15257 }
15258
15259 /*
15260 * We need the SAS WWN for non-multipath devices, so
15261 * we'll use the same property as that multipathing
15262 * devices need to present for MPAPI. If we don't have
15263 * a WWN (e.g. parallel SCSI), don't create the prop.
15264 */
15265 wwn_str = kmem_zalloc(MPTSAS_WWN_STRLEN, KM_SLEEP);
15266 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn);
15267 if (sas_wwn && ndi_prop_update_string(DDI_DEV_T_NONE,
15268 *lun_dip, SCSI_ADDR_PROP_TARGET_PORT, wwn_str)
15269 != DDI_PROP_SUCCESS) {
15270 mptsas_log(mpt, CE_WARN, "mptsas unable to "
15271 "create property for SAS target %d lun %d "
15272 "(target-port)", target, lun);
15273 ndi_rtn = NDI_FAILURE;
15274 goto phys_create_done;
15275 }
15276
15277 be_sas_wwn = BE_64(sas_wwn);
15278 if (sas_wwn && ndi_prop_update_byte_array(
15279 DDI_DEV_T_NONE, *lun_dip, "port-wwn",
15280 (uchar_t *)&be_sas_wwn, 8) != DDI_PROP_SUCCESS) {
15281 mptsas_log(mpt, CE_WARN, "mptsas unable to "
15282 "create property for SAS target %d lun %d "
15283 "(port-wwn)", target, lun);
15284 ndi_rtn = NDI_FAILURE;
15285 goto phys_create_done;
15286 } else if ((sas_wwn == 0) && (ndi_prop_update_int(
15287 DDI_DEV_T_NONE, *lun_dip, "sata-phy", phy) !=
15288 DDI_PROP_SUCCESS)) {
15289 /*
15290 * Direct attached SATA device without DeviceName
15291 */
15292 mptsas_log(mpt, CE_WARN, "mptsas unable to "
15293 "create property for SAS target %d lun %d "
15294 "(sata-phy)", target, lun);
15295 ndi_rtn = NDI_FAILURE;
15296 goto phys_create_done;
15297 }
15298
15299 if (ndi_prop_create_boolean(DDI_DEV_T_NONE,
15300 *lun_dip, SAS_PROP) != DDI_PROP_SUCCESS) {
15301 mptsas_log(mpt, CE_WARN, "mptsas unable to"
15302 "create property for SAS target %d lun %d"
15303 " (SAS_PROP)", target, lun);
15304 ndi_rtn = NDI_FAILURE;
15305 goto phys_create_done;
15306 }
15307 if (guid && (ndi_prop_update_string(DDI_DEV_T_NONE,
15308 *lun_dip, NDI_GUID, guid) != DDI_SUCCESS)) {
15309 mptsas_log(mpt, CE_WARN, "mptsas unable "
15310 "to create guid property for target %d "
15311 "lun %d", target, lun);
15312 ndi_rtn = NDI_FAILURE;
15313 goto phys_create_done;
15314 }
15315
15316 /*
15317 * The following code is to set properties for SM-HBA support,
15318 * it doesn't apply to RAID volumes
15319 */
15320 if (ptgt->m_addr.mta_phymask == 0)
15321 goto phys_raid_lun;
15322
15323 mutex_enter(&mpt->m_mutex);
15324
15325 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
15326 MPI2_SAS_DEVICE_PGAD_FORM_MASK) |
15327 (uint32_t)ptgt->m_devhdl;
15328 rval = mptsas_get_sas_device_page0(mpt, page_address,
15329 &dev_hdl, &dev_sas_wwn, &dev_info,
15330 &physport, &phy_id, &pdev_hdl,
15331 &bay_num, &enclosure, &io_flags);
15332 if (rval != DDI_SUCCESS) {
15333 mutex_exit(&mpt->m_mutex);
15334 mptsas_log(mpt, CE_WARN, "mptsas unable to get"
15335 "parent device for handle %d.", page_address);
15336 ndi_rtn = NDI_FAILURE;
15337 goto phys_create_done;
15338 }
15339
15340 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
15341 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)pdev_hdl;
15342 rval = mptsas_get_sas_device_page0(mpt, page_address,
15343 &dev_hdl, &pdev_sas_wwn, &pdev_info, &physport,
15344 &phy_id, &pdev_hdl, &bay_num, &enclosure, &io_flags);
15345 if (rval != DDI_SUCCESS) {
15346 mutex_exit(&mpt->m_mutex);
15347 mptsas_log(mpt, CE_WARN, "mptsas unable to create "
15348 "device for handle %d.", page_address);
15349 ndi_rtn = NDI_FAILURE;
15350 goto phys_create_done;
15351 }
15352
15353 mutex_exit(&mpt->m_mutex);
15354
15355 /*
15356 * If this device direct attached to the controller
15357 * set the attached-port to the base wwid
15358 */
15359 if ((ptgt->m_deviceinfo & DEVINFO_DIRECT_ATTACHED)
15360 != DEVINFO_DIRECT_ATTACHED) {
15361 (void) sprintf(pdev_wwn_str, "w%016"PRIx64,
15362 pdev_sas_wwn);
15363 } else {
15364 /*
15365 * Update the iport's attached-port to guid
15366 */
15367 if (sas_wwn == 0) {
15368 (void) sprintf(wwn_str, "p%x", phy);
15369 } else {
15370 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn);
15371 }
15372 if (ddi_prop_update_string(DDI_DEV_T_NONE,
15373 pdip, SCSI_ADDR_PROP_ATTACHED_PORT, wwn_str) !=
15374 DDI_PROP_SUCCESS) {
15375 mptsas_log(mpt, CE_WARN,
15376 "mptsas unable to create "
15377 "property for iport target-port"
15378 " %s (sas_wwn)",
15379 wwn_str);
15380 ndi_rtn = NDI_FAILURE;
15381 goto phys_create_done;
15382 }
15383
15384 (void) sprintf(pdev_wwn_str, "w%016"PRIx64,
15385 mpt->un.m_base_wwid);
15386 }
15387
15388 if (ndi_prop_update_string(DDI_DEV_T_NONE,
15389 *lun_dip, SCSI_ADDR_PROP_ATTACHED_PORT, pdev_wwn_str) !=
15390 DDI_PROP_SUCCESS) {
15391 mptsas_log(mpt, CE_WARN,
15392 "mptsas unable to create "
15393 "property for iport attached-port %s (sas_wwn)",
15394 attached_wwn_str);
15395 ndi_rtn = NDI_FAILURE;
15396 goto phys_create_done;
15397 }
15398
15399 if (IS_SATA_DEVICE(dev_info)) {
15400 if (ndi_prop_update_string(DDI_DEV_T_NONE,
15401 *lun_dip, MPTSAS_VARIANT, "sata") !=
15402 DDI_PROP_SUCCESS) {
15403 mptsas_log(mpt, CE_WARN,
15404 "mptsas unable to create "
15405 "property for device variant ");
15406 ndi_rtn = NDI_FAILURE;
15407 goto phys_create_done;
15408 }
15409 }
15410
15411 if (IS_ATAPI_DEVICE(dev_info)) {
15412 if (ndi_prop_update_string(DDI_DEV_T_NONE,
15413 *lun_dip, MPTSAS_VARIANT, "atapi") !=
15414 DDI_PROP_SUCCESS) {
15415 mptsas_log(mpt, CE_WARN,
15416 "mptsas unable to create "
15417 "property for device variant ");
15418 ndi_rtn = NDI_FAILURE;
15419 goto phys_create_done;
15420 }
15421 }
15422
15423 phys_raid_lun:
15424 /*
15425 * if this is a SAS controller, and the target is a SATA
15426 * drive, set the 'pm-capable' property for sd and if on
15427 * an OPL platform, also check if this is an ATAPI
15428 * device.
15429 */
15430 instance = ddi_get_instance(mpt->m_dip);
15431 if (devinfo & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
15432 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
15433 NDBG2(("mptsas%d: creating pm-capable property, "
15434 "target %d", instance, target));
15435
15436 if ((ndi_prop_update_int(DDI_DEV_T_NONE,
15437 *lun_dip, "pm-capable", 1)) !=
15438 DDI_PROP_SUCCESS) {
15439 mptsas_log(mpt, CE_WARN, "mptsas "
15440 "failed to create pm-capable "
15441 "property, target %d", target);
15442 ndi_rtn = NDI_FAILURE;
15443 goto phys_create_done;
15444 }
15445
15446 }
15447
15448 if ((inq->inq_dtype == 0) || (inq->inq_dtype == 5)) {
15449 /*
15450 * add 'obp-path' properties for devinfo
15451 */
15452 bzero(wwn_str, sizeof (wwn_str));
15453 (void) sprintf(wwn_str, "%016"PRIx64, sas_wwn);
15454 component = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
15455 if (guid) {
15456 (void) snprintf(component, MAXPATHLEN,
15457 "disk@w%s,%x", wwn_str, lun);
15458 } else {
15459 (void) snprintf(component, MAXPATHLEN,
15460 "disk@p%x,%x", phy, lun);
15461 }
15462 if (ddi_pathname_obp_set(*lun_dip, component)
15463 != DDI_SUCCESS) {
15464 mptsas_log(mpt, CE_WARN, "mpt_sas driver "
15465 "unable to set obp-path for SAS "
15466 "object %s", component);
15467 ndi_rtn = NDI_FAILURE;
15468 goto phys_create_done;
15469 }
15470 }
15471 /*
15472 * Create the phy-num property for non-raid disk
15473 */
15474 if (ptgt->m_addr.mta_phymask != 0) {
15475 if (ndi_prop_update_int(DDI_DEV_T_NONE,
15476 *lun_dip, "phy-num", ptgt->m_phynum) !=
15477 DDI_PROP_SUCCESS) {
15478 mptsas_log(mpt, CE_WARN, "mptsas driver "
15479 "failed to create phy-num property for "
15480 "target %d", target);
15481 ndi_rtn = NDI_FAILURE;
15482 goto phys_create_done;
15483 }
15484 }
15485 phys_create_done:
15486 /*
15487 * If props were setup ok, online the lun
15488 */
15489 if (ndi_rtn == NDI_SUCCESS) {
15490 /*
15491 * Try to online the new node
15492 */
15493 ndi_rtn = ndi_devi_online(*lun_dip, NDI_ONLINE_ATTACH);
15494 }
15495 if (ndi_rtn == NDI_SUCCESS) {
15496 mutex_enter(&mpt->m_mutex);
15497 ptgt->m_led_status = 0;
15498 (void) mptsas_flush_led_status(mpt, ptgt);
15499 mutex_exit(&mpt->m_mutex);
15500 }
15501
15502 /*
15503 * If success set rtn flag, else unwire alloc'd lun
15504 */
15505 if (ndi_rtn != NDI_SUCCESS) {
15506 NDBG12(("mptsas driver unable to online "
15507 "target %d lun %d", target, lun));
15508 ndi_prop_remove_all(*lun_dip);
15509 (void) ndi_devi_free(*lun_dip);
15510 *lun_dip = NULL;
15511 }
15512 }
15513
15514 scsi_hba_nodename_compatible_free(nodename, compatible);
15515
15516 if (wwn_str != NULL) {
15517 kmem_free(wwn_str, MPTSAS_WWN_STRLEN);
15518 }
15519 if (component != NULL) {
15520 kmem_free(component, MAXPATHLEN);
15521 }
15522
15523
15524 return ((ndi_rtn == NDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
15525 }
15526
15527 static int
15528 mptsas_probe_smp(dev_info_t *pdip, uint64_t wwn)
15529 {
15530 mptsas_t *mpt = DIP2MPT(pdip);
15531 struct smp_device smp_sd;
15532
15533 /* XXX An HBA driver should not be allocating an smp_device. */
15534 bzero(&smp_sd, sizeof (struct smp_device));
15535 smp_sd.smp_sd_address.smp_a_hba_tran = mpt->m_smptran;
15536 bcopy(&wwn, smp_sd.smp_sd_address.smp_a_wwn, SAS_WWN_BYTE_SIZE);
15537
15538 if (smp_probe(&smp_sd) != DDI_PROBE_SUCCESS)
15539 return (NDI_FAILURE);
15540 return (NDI_SUCCESS);
15541 }
15542
15543 static int
15544 mptsas_config_smp(dev_info_t *pdip, uint64_t sas_wwn, dev_info_t **smp_dip)
15545 {
15546 mptsas_t *mpt = DIP2MPT(pdip);
15547 mptsas_smp_t *psmp = NULL;
15548 int rval;
15549 int phymask;
15550
15551 /*
15552 * Get the physical port associated to the iport
15553 * PHYMASK TODO
15554 */
15555 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
15556 "phymask", 0);
15557 /*
15558 * Find the smp node in hash table with specified sas address and
15559 * physical port
15560 */
15561 psmp = mptsas_wwid_to_psmp(mpt, phymask, sas_wwn);
15562 if (psmp == NULL) {
15563 return (DDI_FAILURE);
15564 }
15565
15566 rval = mptsas_online_smp(pdip, psmp, smp_dip);
15567
15568 return (rval);
15569 }
15570
15571 static int
15572 mptsas_online_smp(dev_info_t *pdip, mptsas_smp_t *smp_node,
15573 dev_info_t **smp_dip)
15574 {
15575 char wwn_str[MPTSAS_WWN_STRLEN];
15576 char attached_wwn_str[MPTSAS_WWN_STRLEN];
15577 int ndi_rtn = NDI_FAILURE;
15578 int rval = 0;
15579 mptsas_smp_t dev_info;
15580 uint32_t page_address;
15581 mptsas_t *mpt = DIP2MPT(pdip);
15582 uint16_t dev_hdl;
15583 uint64_t sas_wwn;
15584 uint64_t smp_sas_wwn;
15585 uint8_t physport;
15586 uint8_t phy_id;
15587 uint16_t pdev_hdl;
15588 uint8_t numphys = 0;
15589 uint16_t i = 0;
15590 char phymask[MPTSAS_MAX_PHYS];
15591 char *iport = NULL;
15592 mptsas_phymask_t phy_mask = 0;
15593 uint16_t attached_devhdl;
15594 uint16_t bay_num, enclosure, io_flags;
15595
15596 (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_addr.mta_wwn);
15597
15598 /*
15599 * Probe smp device, prevent the node of removed device from being
15600 * configured succesfully
15601 */
15602 if (mptsas_probe_smp(pdip, smp_node->m_addr.mta_wwn) != NDI_SUCCESS) {
15603 return (DDI_FAILURE);
15604 }
15605
15606 if ((*smp_dip = mptsas_find_smp_child(pdip, wwn_str)) != NULL) {
15607 return (DDI_SUCCESS);
15608 }
15609
15610 ndi_rtn = ndi_devi_alloc(pdip, "smp", DEVI_SID_NODEID, smp_dip);
15611
15612 /*
15613 * if lun alloc success, set props
15614 */
15615 if (ndi_rtn == NDI_SUCCESS) {
15616 /*
15617 * Set the flavor of the child to be SMP flavored
15618 */
15619 ndi_flavor_set(*smp_dip, SCSA_FLAVOR_SMP);
15620
15621 if (ndi_prop_update_string(DDI_DEV_T_NONE,
15622 *smp_dip, SMP_WWN, wwn_str) !=
15623 DDI_PROP_SUCCESS) {
15624 mptsas_log(mpt, CE_WARN, "mptsas unable to create "
15625 "property for smp device %s (sas_wwn)",
15626 wwn_str);
15627 ndi_rtn = NDI_FAILURE;
15628 goto smp_create_done;
15629 }
15630 (void) sprintf(wwn_str, "w%"PRIx64, smp_node->m_addr.mta_wwn);
15631 if (ndi_prop_update_string(DDI_DEV_T_NONE,
15632 *smp_dip, SCSI_ADDR_PROP_TARGET_PORT, wwn_str) !=
15633 DDI_PROP_SUCCESS) {
15634 mptsas_log(mpt, CE_WARN, "mptsas unable to create "
15635 "property for iport target-port %s (sas_wwn)",
15636 wwn_str);
15637 ndi_rtn = NDI_FAILURE;
15638 goto smp_create_done;
15639 }
15640
15641 mutex_enter(&mpt->m_mutex);
15642
15643 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_HNDL &
15644 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | smp_node->m_devhdl;
15645 rval = mptsas_get_sas_expander_page0(mpt, page_address,
15646 &dev_info);
15647 if (rval != DDI_SUCCESS) {
15648 mutex_exit(&mpt->m_mutex);
15649 mptsas_log(mpt, CE_WARN,
15650 "mptsas unable to get expander "
15651 "parent device info for %x", page_address);
15652 ndi_rtn = NDI_FAILURE;
15653 goto smp_create_done;
15654 }
15655
15656 smp_node->m_pdevhdl = dev_info.m_pdevhdl;
15657 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
15658 MPI2_SAS_DEVICE_PGAD_FORM_MASK) |
15659 (uint32_t)dev_info.m_pdevhdl;
15660 rval = mptsas_get_sas_device_page0(mpt, page_address,
15661 &dev_hdl, &sas_wwn, &smp_node->m_pdevinfo, &physport,
15662 &phy_id, &pdev_hdl, &bay_num, &enclosure, &io_flags);
15663 if (rval != DDI_SUCCESS) {
15664 mutex_exit(&mpt->m_mutex);
15665 mptsas_log(mpt, CE_WARN, "mptsas unable to get "
15666 "device info for %x", page_address);
15667 ndi_rtn = NDI_FAILURE;
15668 goto smp_create_done;
15669 }
15670
15671 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
15672 MPI2_SAS_DEVICE_PGAD_FORM_MASK) |
15673 (uint32_t)dev_info.m_devhdl;
15674 rval = mptsas_get_sas_device_page0(mpt, page_address,
15675 &dev_hdl, &smp_sas_wwn, &smp_node->m_deviceinfo,
15676 &physport, &phy_id, &pdev_hdl, &bay_num, &enclosure,
15677 &io_flags);
15678 if (rval != DDI_SUCCESS) {
15679 mutex_exit(&mpt->m_mutex);
15680 mptsas_log(mpt, CE_WARN, "mptsas unable to get "
15681 "device info for %x", page_address);
15682 ndi_rtn = NDI_FAILURE;
15683 goto smp_create_done;
15684 }
15685 mutex_exit(&mpt->m_mutex);
15686
15687 /*
15688 * If this smp direct attached to the controller
15689 * set the attached-port to the base wwid
15690 */
15691 if ((smp_node->m_deviceinfo & DEVINFO_DIRECT_ATTACHED)
15692 != DEVINFO_DIRECT_ATTACHED) {
15693 (void) sprintf(attached_wwn_str, "w%016"PRIx64,
15694 sas_wwn);
15695 } else {
15696 (void) sprintf(attached_wwn_str, "w%016"PRIx64,
15697 mpt->un.m_base_wwid);
15698 }
15699
15700 if (ndi_prop_update_string(DDI_DEV_T_NONE,
15701 *smp_dip, SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwn_str) !=
15702 DDI_PROP_SUCCESS) {
15703 mptsas_log(mpt, CE_WARN, "mptsas unable to create "
15704 "property for smp attached-port %s (sas_wwn)",
15705 attached_wwn_str);
15706 ndi_rtn = NDI_FAILURE;
15707 goto smp_create_done;
15708 }
15709
15710 if (ndi_prop_create_boolean(DDI_DEV_T_NONE,
15711 *smp_dip, SMP_PROP) != DDI_PROP_SUCCESS) {
15712 mptsas_log(mpt, CE_WARN, "mptsas unable to "
15713 "create property for SMP %s (SMP_PROP) ",
15714 wwn_str);
15715 ndi_rtn = NDI_FAILURE;
15716 goto smp_create_done;
15717 }
15718
15719 /*
15720 * check the smp to see whether it direct
15721 * attached to the controller
15722 */
15723 if ((smp_node->m_deviceinfo & DEVINFO_DIRECT_ATTACHED)
15724 != DEVINFO_DIRECT_ATTACHED) {
15725 goto smp_create_done;
15726 }
15727 numphys = ddi_prop_get_int(DDI_DEV_T_ANY, pdip,
15728 DDI_PROP_DONTPASS, MPTSAS_NUM_PHYS, -1);
15729 if (numphys > 0) {
15730 goto smp_create_done;
15731 }
15732 /*
15733 * this iport is an old iport, we need to
15734 * reconfig the props for it.
15735 */
15736 if (ddi_prop_update_int(DDI_DEV_T_NONE, pdip,
15737 MPTSAS_VIRTUAL_PORT, 0) !=
15738 DDI_PROP_SUCCESS) {
15739 (void) ddi_prop_remove(DDI_DEV_T_NONE, pdip,
15740 MPTSAS_VIRTUAL_PORT);
15741 mptsas_log(mpt, CE_WARN, "mptsas virtual port "
15742 "prop update failed");
15743 goto smp_create_done;
15744 }
15745
15746 mutex_enter(&mpt->m_mutex);
15747 numphys = 0;
15748 iport = ddi_get_name_addr(pdip);
15749 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
15750 bzero(phymask, sizeof (phymask));
15751 (void) sprintf(phymask,
15752 "%x", mpt->m_phy_info[i].phy_mask);
15753 if (strcmp(phymask, iport) == 0) {
15754 phy_mask = mpt->m_phy_info[i].phy_mask;
15755 break;
15756 }
15757 }
15758
15759 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
15760 if ((phy_mask >> i) & 0x01) {
15761 numphys++;
15762 }
15763 }
15764 /*
15765 * Update PHY info for smhba
15766 */
15767 if (mptsas_smhba_phy_init(mpt)) {
15768 mutex_exit(&mpt->m_mutex);
15769 mptsas_log(mpt, CE_WARN, "mptsas phy update "
15770 "failed");
15771 goto smp_create_done;
15772 }
15773 mutex_exit(&mpt->m_mutex);
15774
15775 mptsas_smhba_set_all_phy_props(mpt, pdip, numphys, phy_mask,
15776 &attached_devhdl);
15777
15778 if (ddi_prop_update_int(DDI_DEV_T_NONE, pdip,
15779 MPTSAS_NUM_PHYS, numphys) !=
15780 DDI_PROP_SUCCESS) {
15781 (void) ddi_prop_remove(DDI_DEV_T_NONE, pdip,
15782 MPTSAS_NUM_PHYS);
15783 mptsas_log(mpt, CE_WARN, "mptsas update "
15784 "num phys props failed");
15785 goto smp_create_done;
15786 }
15787 /*
15788 * Add parent's props for SMHBA support
15789 */
15790 if (ddi_prop_update_string(DDI_DEV_T_NONE, pdip,
15791 SCSI_ADDR_PROP_ATTACHED_PORT, wwn_str) !=
15792 DDI_PROP_SUCCESS) {
15793 (void) ddi_prop_remove(DDI_DEV_T_NONE, pdip,
15794 SCSI_ADDR_PROP_ATTACHED_PORT);
15795 mptsas_log(mpt, CE_WARN, "mptsas update iport"
15796 "attached-port failed");
15797 goto smp_create_done;
15798 }
15799
15800 smp_create_done:
15801 /*
15802 * If props were setup ok, online the lun
15803 */
15804 if (ndi_rtn == NDI_SUCCESS) {
15805 /*
15806 * Try to online the new node
15807 */
15808 ndi_rtn = ndi_devi_online(*smp_dip, NDI_ONLINE_ATTACH);
15809 }
15810
15811 /*
15812 * If success set rtn flag, else unwire alloc'd lun
15813 */
15814 if (ndi_rtn != NDI_SUCCESS) {
15815 NDBG12(("mptsas unable to online "
15816 "SMP target %s", wwn_str));
15817 ndi_prop_remove_all(*smp_dip);
15818 (void) ndi_devi_free(*smp_dip);
15819 }
15820 }
15821
15822 return ((ndi_rtn == NDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
15823 }
15824
15825 /* smp transport routine */
15826 static int mptsas_smp_start(struct smp_pkt *smp_pkt)
15827 {
15828 uint64_t wwn;
15829 Mpi2SmpPassthroughRequest_t req;
15830 Mpi2SmpPassthroughReply_t rep;
15831 uint32_t direction = 0;
15832 mptsas_t *mpt;
15833 int ret;
15834 uint64_t tmp64;
15835
15836 mpt = (mptsas_t *)smp_pkt->smp_pkt_address->
15837 smp_a_hba_tran->smp_tran_hba_private;
15838
15839 bcopy(smp_pkt->smp_pkt_address->smp_a_wwn, &wwn, SAS_WWN_BYTE_SIZE);
15840 /*
15841 * Need to compose a SMP request message
15842 * and call mptsas_do_passthru() function
15843 */
15844 bzero(&req, sizeof (req));
15845 bzero(&rep, sizeof (rep));
15846 req.PassthroughFlags = 0;
15847 req.PhysicalPort = 0xff;
15848 req.ChainOffset = 0;
15849 req.Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
15850
15851 if ((smp_pkt->smp_pkt_reqsize & 0xffff0000ul) != 0) {
15852 smp_pkt->smp_pkt_reason = ERANGE;
15853 return (DDI_FAILURE);
15854 }
15855 req.RequestDataLength = LE_16((uint16_t)(smp_pkt->smp_pkt_reqsize - 4));
15856
15857 req.MsgFlags = 0;
15858 tmp64 = LE_64(wwn);
15859 bcopy(&tmp64, &req.SASAddress, SAS_WWN_BYTE_SIZE);
15860 if (smp_pkt->smp_pkt_rspsize > 0) {
15861 direction |= MPTSAS_PASS_THRU_DIRECTION_READ;
15862 }
15863 if (smp_pkt->smp_pkt_reqsize > 0) {
15864 direction |= MPTSAS_PASS_THRU_DIRECTION_WRITE;
15865 }
15866
15867 mutex_enter(&mpt->m_mutex);
15868 ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep,
15869 (uint8_t *)smp_pkt->smp_pkt_rsp,
15870 offsetof(Mpi2SmpPassthroughRequest_t, SGL), sizeof (rep),
15871 smp_pkt->smp_pkt_rspsize - 4, direction,
15872 (uint8_t *)smp_pkt->smp_pkt_req, smp_pkt->smp_pkt_reqsize - 4,
15873 smp_pkt->smp_pkt_timeout, FKIOCTL);
15874 mutex_exit(&mpt->m_mutex);
15875 if (ret != 0) {
15876 cmn_err(CE_WARN, "smp_start do passthru error %d", ret);
15877 smp_pkt->smp_pkt_reason = (uchar_t)(ret);
15878 return (DDI_FAILURE);
15879 }
15880 /* do passthrough success, check the smp status */
15881 if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) {
15882 switch (LE_16(rep.IOCStatus)) {
15883 case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
15884 smp_pkt->smp_pkt_reason = ENODEV;
15885 break;
15886 case MPI2_IOCSTATUS_SAS_SMP_DATA_OVERRUN:
15887 smp_pkt->smp_pkt_reason = EOVERFLOW;
15888 break;
15889 case MPI2_IOCSTATUS_SAS_SMP_REQUEST_FAILED:
15890 smp_pkt->smp_pkt_reason = EIO;
15891 break;
15892 default:
15893 mptsas_log(mpt, CE_NOTE, "smp_start: get unknown ioc"
15894 "status:%x", LE_16(rep.IOCStatus));
15895 smp_pkt->smp_pkt_reason = EIO;
15896 break;
15897 }
15898 return (DDI_FAILURE);
15899 }
15900 if (rep.SASStatus != MPI2_SASSTATUS_SUCCESS) {
15901 mptsas_log(mpt, CE_NOTE, "smp_start: get error SAS status:%x",
15902 rep.SASStatus);
15903 smp_pkt->smp_pkt_reason = EIO;
15904 return (DDI_FAILURE);
15905 }
15906
15907 return (DDI_SUCCESS);
15908 }
15909
15910 /*
15911 * If we didn't get a match, we need to get sas page0 for each device, and
15912 * untill we get a match. If failed, return NULL
15913 */
15914 static mptsas_target_t *
15915 mptsas_phy_to_tgt(mptsas_t *mpt, mptsas_phymask_t phymask, uint8_t phy)
15916 {
15917 int i, j = 0;
15918 int rval = 0;
15919 uint16_t cur_handle;
15920 uint32_t page_address;
15921 mptsas_target_t *ptgt = NULL;
15922
15923 /*
15924 * PHY named device must be direct attached and attaches to
15925 * narrow port, if the iport is not parent of the device which
15926 * we are looking for.
15927 */
15928 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
15929 if ((1 << i) & phymask)
15930 j++;
15931 }
15932
15933 if (j > 1)
15934 return (NULL);
15935
15936 /*
15937 * Must be a narrow port and single device attached to the narrow port
15938 * So the physical port num of device which is equal to the iport's
15939 * port num is the device what we are looking for.
15940 */
15941
15942 if (mpt->m_phy_info[phy].phy_mask != phymask)
15943 return (NULL);
15944
15945 mutex_enter(&mpt->m_mutex);
15946
15947 ptgt = refhash_linear_search(mpt->m_targets, mptsas_target_eval_nowwn,
15948 &phy);
15949 if (ptgt != NULL) {
15950 mutex_exit(&mpt->m_mutex);
15951 return (ptgt);
15952 }
15953
15954 if (mpt->m_done_traverse_dev) {
15955 mutex_exit(&mpt->m_mutex);
15956 return (NULL);
15957 }
15958
15959 /* If didn't get a match, come here */
15960 cur_handle = mpt->m_dev_handle;
15961 for (; ; ) {
15962 ptgt = NULL;
15963 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE &
15964 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)cur_handle;
15965 rval = mptsas_get_target_device_info(mpt, page_address,
15966 &cur_handle, &ptgt);
15967 if ((rval == DEV_INFO_FAIL_PAGE0) ||
15968 (rval == DEV_INFO_FAIL_ALLOC)) {
15969 break;
15970 }
15971 if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) ||
15972 (rval == DEV_INFO_PHYS_DISK)) {
15973 continue;
15974 }
15975 mpt->m_dev_handle = cur_handle;
15976
15977 if ((ptgt->m_addr.mta_wwn == 0) && (ptgt->m_phynum == phy)) {
15978 break;
15979 }
15980 }
15981
15982 mutex_exit(&mpt->m_mutex);
15983 return (ptgt);
15984 }
15985
15986 /*
15987 * The ptgt->m_addr.mta_wwn contains the wwid for each disk.
15988 * For Raid volumes, we need to check m_raidvol[x].m_raidwwid
15989 * If we didn't get a match, we need to get sas page0 for each device, and
15990 * untill we get a match
15991 * If failed, return NULL
15992 */
15993 static mptsas_target_t *
15994 mptsas_wwid_to_ptgt(mptsas_t *mpt, mptsas_phymask_t phymask, uint64_t wwid)
15995 {
15996 int rval = 0;
15997 uint16_t cur_handle;
15998 uint32_t page_address;
15999 mptsas_target_t *tmp_tgt = NULL;
16000 mptsas_target_addr_t addr;
16001
16002 addr.mta_wwn = wwid;
16003 addr.mta_phymask = phymask;
16004 mutex_enter(&mpt->m_mutex);
16005 tmp_tgt = refhash_lookup(mpt->m_targets, &addr);
16006 if (tmp_tgt != NULL) {
16007 mutex_exit(&mpt->m_mutex);
16008 return (tmp_tgt);
16009 }
16010
16011 if (phymask == 0) {
16012 /*
16013 * It's IR volume
16014 */
16015 rval = mptsas_get_raid_info(mpt);
16016 if (rval) {
16017 tmp_tgt = refhash_lookup(mpt->m_targets, &addr);
16018 }
16019 mutex_exit(&mpt->m_mutex);
16020 return (tmp_tgt);
16021 }
16022
16023 if (mpt->m_done_traverse_dev) {
16024 mutex_exit(&mpt->m_mutex);
16025 return (NULL);
16026 }
16027
16028 /* If didn't get a match, come here */
16029 cur_handle = mpt->m_dev_handle;
16030 for (;;) {
16031 tmp_tgt = NULL;
16032 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE &
16033 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | cur_handle;
16034 rval = mptsas_get_target_device_info(mpt, page_address,
16035 &cur_handle, &tmp_tgt);
16036 if ((rval == DEV_INFO_FAIL_PAGE0) ||
16037 (rval == DEV_INFO_FAIL_ALLOC)) {
16038 tmp_tgt = NULL;
16039 break;
16040 }
16041 if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) ||
16042 (rval == DEV_INFO_PHYS_DISK)) {
16043 continue;
16044 }
16045 mpt->m_dev_handle = cur_handle;
16046 if ((tmp_tgt->m_addr.mta_wwn) &&
16047 (tmp_tgt->m_addr.mta_wwn == wwid) &&
16048 (tmp_tgt->m_addr.mta_phymask == phymask)) {
16049 break;
16050 }
16051 }
16052
16053 mutex_exit(&mpt->m_mutex);
16054 return (tmp_tgt);
16055 }
16056
16057 static mptsas_smp_t *
16058 mptsas_wwid_to_psmp(mptsas_t *mpt, mptsas_phymask_t phymask, uint64_t wwid)
16059 {
16060 int rval = 0;
16061 uint16_t cur_handle;
16062 uint32_t page_address;
16063 mptsas_smp_t smp_node, *psmp = NULL;
16064 mptsas_target_addr_t addr;
16065
16066 addr.mta_wwn = wwid;
16067 addr.mta_phymask = phymask;
16068 mutex_enter(&mpt->m_mutex);
16069 psmp = refhash_lookup(mpt->m_smp_targets, &addr);
16070 if (psmp != NULL) {
16071 mutex_exit(&mpt->m_mutex);
16072 return (psmp);
16073 }
16074
16075 if (mpt->m_done_traverse_smp) {
16076 mutex_exit(&mpt->m_mutex);
16077 return (NULL);
16078 }
16079
16080 /* If didn't get a match, come here */
16081 cur_handle = mpt->m_smp_devhdl;
16082 for (;;) {
16083 psmp = NULL;
16084 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL &
16085 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)cur_handle;
16086 rval = mptsas_get_sas_expander_page0(mpt, page_address,
16087 &smp_node);
16088 if (rval != DDI_SUCCESS) {
16089 break;
16090 }
16091 mpt->m_smp_devhdl = cur_handle = smp_node.m_devhdl;
16092 psmp = mptsas_smp_alloc(mpt, &smp_node);
16093 ASSERT(psmp);
16094 if ((psmp->m_addr.mta_wwn) && (psmp->m_addr.mta_wwn == wwid) &&
16095 (psmp->m_addr.mta_phymask == phymask)) {
16096 break;
16097 }
16098 }
16099
16100 mutex_exit(&mpt->m_mutex);
16101 return (psmp);
16102 }
16103
16104 mptsas_target_t *
16105 mptsas_tgt_alloc(mptsas_t *mpt, uint16_t devhdl, uint64_t wwid,
16106 uint32_t devinfo, mptsas_phymask_t phymask, uint8_t phynum)
16107 {
16108 mptsas_target_t *tmp_tgt = NULL;
16109 mptsas_target_addr_t addr;
16110
16111 addr.mta_wwn = wwid;
16112 addr.mta_phymask = phymask;
16113 tmp_tgt = refhash_lookup(mpt->m_targets, &addr);
16114 if (tmp_tgt != NULL) {
16115 NDBG20(("Hash item already exist"));
16116 tmp_tgt->m_deviceinfo = devinfo;
16117 tmp_tgt->m_devhdl = devhdl; /* XXX - duplicate? */
16118 return (tmp_tgt);
16119 }
16120 tmp_tgt = kmem_zalloc(sizeof (struct mptsas_target), KM_SLEEP);
16121 if (tmp_tgt == NULL) {
16122 cmn_err(CE_WARN, "Fatal, allocated tgt failed");
16123 return (NULL);
16124 }
16125 tmp_tgt->m_devhdl = devhdl;
16126 tmp_tgt->m_addr.mta_wwn = wwid;
16127 tmp_tgt->m_deviceinfo = devinfo;
16128 tmp_tgt->m_addr.mta_phymask = phymask;
16129 tmp_tgt->m_phynum = phynum;
16130 /* Initialized the tgt structure */
16131 tmp_tgt->m_qfull_retries = QFULL_RETRIES;
16132 tmp_tgt->m_qfull_retry_interval =
16133 drv_usectohz(QFULL_RETRY_INTERVAL * 1000);
16134 tmp_tgt->m_t_throttle = MAX_THROTTLE;
16135 TAILQ_INIT(&tmp_tgt->m_active_cmdq);
16136
16137 refhash_insert(mpt->m_targets, tmp_tgt);
16138
16139 return (tmp_tgt);
16140 }
16141
16142 static void
16143 mptsas_smp_target_copy(mptsas_smp_t *src, mptsas_smp_t *dst)
16144 {
16145 dst->m_devhdl = src->m_devhdl;
16146 dst->m_deviceinfo = src->m_deviceinfo;
16147 dst->m_pdevhdl = src->m_pdevhdl;
16148 dst->m_pdevinfo = src->m_pdevinfo;
16149 }
16150
16151 static mptsas_smp_t *
16152 mptsas_smp_alloc(mptsas_t *mpt, mptsas_smp_t *data)
16153 {
16154 mptsas_target_addr_t addr;
16155 mptsas_smp_t *ret_data;
16156
16157 addr.mta_wwn = data->m_addr.mta_wwn;
16158 addr.mta_phymask = data->m_addr.mta_phymask;
16159 ret_data = refhash_lookup(mpt->m_smp_targets, &addr);
16160 /*
16161 * If there's already a matching SMP target, update its fields
16162 * in place. Since the address is not changing, it's safe to do
16163 * this. We cannot just bcopy() here because the structure we've
16164 * been given has invalid hash links.
16165 */
16166 if (ret_data != NULL) {
16167 mptsas_smp_target_copy(data, ret_data);
16168 return (ret_data);
16169 }
16170
16171 ret_data = kmem_alloc(sizeof (mptsas_smp_t), KM_SLEEP);
16172 bcopy(data, ret_data, sizeof (mptsas_smp_t));
16173 refhash_insert(mpt->m_smp_targets, ret_data);
16174 return (ret_data);
16175 }
16176
16177 /*
16178 * Functions for SGPIO LED support
16179 */
16180 static dev_info_t *
16181 mptsas_get_dip_from_dev(dev_t dev, mptsas_phymask_t *phymask)
16182 {
16183 dev_info_t *dip;
16184 int prop;
16185 dip = e_ddi_hold_devi_by_dev(dev, 0);
16186 if (dip == NULL)
16187 return (dip);
16188 prop = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0,
16189 "phymask", 0);
16190 *phymask = (mptsas_phymask_t)prop;
16191 ddi_release_devi(dip);
16192 return (dip);
16193 }
16194 static mptsas_target_t *
16195 mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr, mptsas_phymask_t phymask)
16196 {
16197 uint8_t phynum;
16198 uint64_t wwn;
16199 int lun;
16200 mptsas_target_t *ptgt = NULL;
16201
16202 if (mptsas_parse_address(addr, &wwn, &phynum, &lun) != DDI_SUCCESS) {
16203 return (NULL);
16204 }
16205 if (addr[0] == 'w') {
16206 ptgt = mptsas_wwid_to_ptgt(mpt, (int)phymask, wwn);
16207 } else {
16208 ptgt = mptsas_phy_to_tgt(mpt, (int)phymask, phynum);
16209 }
16210 return (ptgt);
16211 }
16212
16213 static int
16214 mptsas_flush_led_status(mptsas_t *mpt, mptsas_target_t *ptgt)
16215 {
16216 uint32_t slotstatus = 0;
16217
16218 /* Build an MPI2 Slot Status based on our view of the world */
16219 if (ptgt->m_led_status & (1 << (MPTSAS_LEDCTL_LED_IDENT - 1)))
16220 slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_IDENTIFY_REQUEST;
16221 if (ptgt->m_led_status & (1 << (MPTSAS_LEDCTL_LED_FAIL - 1)))
16222 slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT;
16223 if (ptgt->m_led_status & (1 << (MPTSAS_LEDCTL_LED_OK2RM - 1)))
16224 slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE;
16225
16226 /* Write it to the controller */
16227 NDBG14(("mptsas_ioctl: set LED status %x for slot %x",
16228 slotstatus, ptgt->m_slot_num));
16229 return (mptsas_send_sep(mpt, ptgt, &slotstatus,
16230 MPI2_SEP_REQ_ACTION_WRITE_STATUS));
16231 }
16232
16233 /*
16234 * send sep request, use enclosure/slot addressing
16235 */
16236 static int
16237 mptsas_send_sep(mptsas_t *mpt, mptsas_target_t *ptgt,
16238 uint32_t *status, uint8_t act)
16239 {
16240 Mpi2SepRequest_t req;
16241 Mpi2SepReply_t rep;
16242 int ret;
16243
16244 ASSERT(mutex_owned(&mpt->m_mutex));
16245
16246 /*
16247 * We only support SEP control of directly-attached targets, in which
16248 * case the "SEP" we're talking to is a virtual one contained within
16249 * the HBA itself. This is necessary because DA targets typically have
16250 * no other mechanism for LED control. Targets for which a separate
16251 * enclosure service processor exists should be controlled via ses(7d)
16252 * or sgen(7d). Furthermore, since such requests can time out, they
16253 * should be made in user context rather than in response to
16254 * asynchronous fabric changes.
16255 *
16256 * In addition, we do not support this operation for RAID volumes,
16257 * since there is no slot associated with them.
16258 */
16259 if (!(ptgt->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) ||
16260 ptgt->m_addr.mta_phymask == 0) {
16261 return (ENOTTY);
16262 }
16263
16264 bzero(&req, sizeof (req));
16265 bzero(&rep, sizeof (rep));
16266
16267 req.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
16268 req.Action = act;
16269 req.Flags = MPI2_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS;
16270 req.EnclosureHandle = LE_16(ptgt->m_enclosure);
16271 req.Slot = LE_16(ptgt->m_slot_num);
16272 if (act == MPI2_SEP_REQ_ACTION_WRITE_STATUS) {
16273 req.SlotStatus = LE_32(*status);
16274 }
16275 ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, NULL,
16276 sizeof (req), sizeof (rep), NULL, 0, NULL, 0, 60, FKIOCTL);
16277 if (ret != 0) {
16278 mptsas_log(mpt, CE_NOTE, "mptsas_send_sep: passthru SEP "
16279 "Processor Request message error %d", ret);
16280 return (ret);
16281 }
16282 /* do passthrough success, check the ioc status */
16283 if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) {
16284 mptsas_log(mpt, CE_NOTE, "send_sep act %x: ioc "
16285 "status:%x loginfo %x", act, LE_16(rep.IOCStatus),
16286 LE_32(rep.IOCLogInfo));
16287 switch (LE_16(rep.IOCStatus) & MPI2_IOCSTATUS_MASK) {
16288 case MPI2_IOCSTATUS_INVALID_FUNCTION:
16289 case MPI2_IOCSTATUS_INVALID_VPID:
16290 case MPI2_IOCSTATUS_INVALID_FIELD:
16291 case MPI2_IOCSTATUS_INVALID_STATE:
16292 case MPI2_IOCSTATUS_OP_STATE_NOT_SUPPORTED:
16293 case MPI2_IOCSTATUS_CONFIG_INVALID_ACTION:
16294 case MPI2_IOCSTATUS_CONFIG_INVALID_TYPE:
16295 case MPI2_IOCSTATUS_CONFIG_INVALID_PAGE:
16296 case MPI2_IOCSTATUS_CONFIG_INVALID_DATA:
16297 case MPI2_IOCSTATUS_CONFIG_NO_DEFAULTS:
16298 return (EINVAL);
16299 case MPI2_IOCSTATUS_BUSY:
16300 return (EBUSY);
16301 case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES:
16302 return (EAGAIN);
16303 case MPI2_IOCSTATUS_INVALID_SGL:
16304 case MPI2_IOCSTATUS_INTERNAL_ERROR:
16305 case MPI2_IOCSTATUS_CONFIG_CANT_COMMIT:
16306 default:
16307 return (EIO);
16308 }
16309 }
16310 if (act != MPI2_SEP_REQ_ACTION_WRITE_STATUS) {
16311 *status = LE_32(rep.SlotStatus);
16312 }
16313
16314 return (0);
16315 }
16316
16317 int
16318 mptsas_dma_addr_create(mptsas_t *mpt, ddi_dma_attr_t dma_attr,
16319 ddi_dma_handle_t *dma_hdp, ddi_acc_handle_t *acc_hdp, caddr_t *dma_memp,
16320 uint32_t alloc_size, ddi_dma_cookie_t *cookiep)
16321 {
16322 ddi_dma_cookie_t new_cookie;
16323 size_t alloc_len;
16324 uint_t ncookie;
16325
16326 if (cookiep == NULL)
16327 cookiep = &new_cookie;
16328
16329 if (ddi_dma_alloc_handle(mpt->m_dip, &dma_attr, DDI_DMA_SLEEP,
16330 NULL, dma_hdp) != DDI_SUCCESS) {
16331 return (FALSE);
16332 }
16333
16334 if (ddi_dma_mem_alloc(*dma_hdp, alloc_size, &mpt->m_dev_acc_attr,
16335 DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, dma_memp, &alloc_len,
16336 acc_hdp) != DDI_SUCCESS) {
16337 ddi_dma_free_handle(dma_hdp);
16338 return (FALSE);
16339 }
16340
16341 if (ddi_dma_addr_bind_handle(*dma_hdp, NULL, *dma_memp, alloc_len,
16342 (DDI_DMA_RDWR | DDI_DMA_CONSISTENT), DDI_DMA_SLEEP, NULL,
16343 cookiep, &ncookie) != DDI_DMA_MAPPED) {
16344 (void) ddi_dma_mem_free(acc_hdp);
16345 ddi_dma_free_handle(dma_hdp);
16346 return (FALSE);
16347 }
16348
16349 return (TRUE);
16350 }
16351
16352 void
16353 mptsas_dma_addr_destroy(ddi_dma_handle_t *dma_hdp, ddi_acc_handle_t *acc_hdp)
16354 {
16355 if (*dma_hdp == NULL)
16356 return;
16357
16358 (void) ddi_dma_unbind_handle(*dma_hdp);
16359 (void) ddi_dma_mem_free(acc_hdp);
16360 ddi_dma_free_handle(dma_hdp);
16361 }