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 2016 Nexenta Systems, Inc. All rights reserved.
25 * Copyright (c) 2017, Joyent, Inc.
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/sata/sata_hba.h>
80 #include <sys/scsi/generic/sas.h>
81 #include <sys/scsi/impl/scsi_sas.h>
82
83 #pragma pack(1)
84 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h>
85 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h>
86 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h>
87 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h>
88 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h>
89 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_sas.h>
90 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h>
91 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_raid.h>
92 #pragma pack()
93
94 /*
95 * private header files.
96 *
97 */
98 #include <sys/scsi/impl/scsi_reset_notify.h>
99 #include <sys/scsi/adapters/mpt_sas/mptsas_var.h>
100 #include <sys/scsi/adapters/mpt_sas/mptsas_ioctl.h>
101 #include <sys/scsi/adapters/mpt_sas/mptsas_smhba.h>
102 #include <sys/scsi/adapters/mpt_sas/mptsas_hash.h>
103 #include <sys/raidioctl.h>
104
105 #include <sys/fs/dv_node.h> /* devfs_clean */
106
107 /*
108 * FMA header files
109 */
110 #include <sys/ddifm.h>
111 #include <sys/fm/protocol.h>
112 #include <sys/fm/util.h>
113 #include <sys/fm/io/ddi.h>
114
115 /*
116 * autoconfiguration data and routines.
117 */
118 static int mptsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
119 static int mptsas_detach(dev_info_t *devi, ddi_detach_cmd_t cmd);
120 static int mptsas_power(dev_info_t *dip, int component, int level);
121
122 /*
123 * cb_ops function
124 */
125 static int mptsas_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
126 cred_t *credp, int *rval);
127 #ifdef __sparc
128 static int mptsas_reset(dev_info_t *devi, ddi_reset_cmd_t cmd);
129 #else /* __sparc */
130 static int mptsas_quiesce(dev_info_t *devi);
131 #endif /* __sparc */
132
133 /*
134 * Resource initilaization for hardware
135 */
136 static void mptsas_setup_cmd_reg(mptsas_t *mpt);
137 static void mptsas_disable_bus_master(mptsas_t *mpt);
138 static void mptsas_hba_fini(mptsas_t *mpt);
139 static void mptsas_cfg_fini(mptsas_t *mptsas_blkp);
140 static int mptsas_hba_setup(mptsas_t *mpt);
141 static void mptsas_hba_teardown(mptsas_t *mpt);
142 static int mptsas_config_space_init(mptsas_t *mpt);
143 static void mptsas_config_space_fini(mptsas_t *mpt);
144 static void mptsas_iport_register(mptsas_t *mpt);
145 static int mptsas_smp_setup(mptsas_t *mpt);
146 static void mptsas_smp_teardown(mptsas_t *mpt);
147 static int mptsas_enc_setup(mptsas_t *mpt);
148 static void mptsas_enc_teardown(mptsas_t *mpt);
149 static int mptsas_cache_create(mptsas_t *mpt);
150 static void mptsas_cache_destroy(mptsas_t *mpt);
151 static int mptsas_alloc_request_frames(mptsas_t *mpt);
152 static int mptsas_alloc_sense_bufs(mptsas_t *mpt);
153 static int mptsas_alloc_reply_frames(mptsas_t *mpt);
154 static int mptsas_alloc_free_queue(mptsas_t *mpt);
155 static int mptsas_alloc_post_queue(mptsas_t *mpt);
156 static void mptsas_alloc_reply_args(mptsas_t *mpt);
157 static int mptsas_alloc_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd);
158 static void mptsas_free_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd);
159 static int mptsas_init_chip(mptsas_t *mpt, int first_time);
160 static void mptsas_update_hashtab(mptsas_t *mpt);
161
162 /*
163 * SCSA function prototypes
164 */
165 static int mptsas_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt);
166 static int mptsas_scsi_reset(struct scsi_address *ap, int level);
167 static int mptsas_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt);
168 static int mptsas_scsi_getcap(struct scsi_address *ap, char *cap, int tgtonly);
169 static int mptsas_scsi_setcap(struct scsi_address *ap, char *cap, int value,
170 int tgtonly);
171 static void mptsas_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt);
172 static struct scsi_pkt *mptsas_scsi_init_pkt(struct scsi_address *ap,
173 struct scsi_pkt *pkt, struct buf *bp, int cmdlen, int statuslen,
174 int tgtlen, int flags, int (*callback)(), caddr_t arg);
175 static void mptsas_scsi_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt);
176 static void mptsas_scsi_destroy_pkt(struct scsi_address *ap,
177 struct scsi_pkt *pkt);
178 static int mptsas_scsi_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
179 scsi_hba_tran_t *hba_tran, struct scsi_device *sd);
180 static void mptsas_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip,
181 scsi_hba_tran_t *hba_tran, struct scsi_device *sd);
182 static int mptsas_scsi_reset_notify(struct scsi_address *ap, int flag,
183 void (*callback)(caddr_t), caddr_t arg);
184 static int mptsas_get_name(struct scsi_device *sd, char *name, int len);
185 static int mptsas_get_bus_addr(struct scsi_device *sd, char *name, int len);
186 static int mptsas_scsi_quiesce(dev_info_t *dip);
187 static int mptsas_scsi_unquiesce(dev_info_t *dip);
188 static int mptsas_bus_config(dev_info_t *pdip, uint_t flags,
189 ddi_bus_config_op_t op, void *arg, dev_info_t **childp);
190
191 /*
192 * SMP functions
193 */
194 static int mptsas_smp_start(struct smp_pkt *smp_pkt);
195
196 /*
197 * internal function prototypes.
198 */
199 static void mptsas_list_add(mptsas_t *mpt);
200 static void mptsas_list_del(mptsas_t *mpt);
201
202 static int mptsas_quiesce_bus(mptsas_t *mpt);
203 static int mptsas_unquiesce_bus(mptsas_t *mpt);
204
205 static int mptsas_alloc_handshake_msg(mptsas_t *mpt, size_t alloc_size);
206 static void mptsas_free_handshake_msg(mptsas_t *mpt);
207
208 static void mptsas_ncmds_checkdrain(void *arg);
209
210 static int mptsas_prepare_pkt(mptsas_cmd_t *cmd);
211 static int mptsas_accept_pkt(mptsas_t *mpt, mptsas_cmd_t *sp);
212 static int mptsas_accept_txwq_and_pkt(mptsas_t *mpt, mptsas_cmd_t *sp);
213 static void mptsas_accept_tx_waitq(mptsas_t *mpt);
214
215 static int mptsas_do_detach(dev_info_t *dev);
216 static int mptsas_do_scsi_reset(mptsas_t *mpt, uint16_t devhdl);
217 static int mptsas_do_scsi_abort(mptsas_t *mpt, int target, int lun,
218 struct scsi_pkt *pkt);
219 static int mptsas_scsi_capchk(char *cap, int tgtonly, int *cidxp);
220
221 static void mptsas_handle_qfull(mptsas_t *mpt, mptsas_cmd_t *cmd);
222 static void mptsas_handle_event(void *args);
223 static int mptsas_handle_event_sync(void *args);
224 static void mptsas_handle_dr(void *args);
225 static void mptsas_handle_topo_change(mptsas_topo_change_list_t *topo_node,
226 dev_info_t *pdip);
227
228 static void mptsas_restart_cmd(void *);
229
230 static void mptsas_flush_hba(mptsas_t *mpt);
231 static void mptsas_flush_target(mptsas_t *mpt, ushort_t target, int lun,
232 uint8_t tasktype);
233 static void mptsas_set_pkt_reason(mptsas_t *mpt, mptsas_cmd_t *cmd,
234 uchar_t reason, uint_t stat);
235
236 static uint_t mptsas_intr(caddr_t arg1, caddr_t arg2);
237 static void mptsas_process_intr(mptsas_t *mpt,
238 pMpi2ReplyDescriptorsUnion_t reply_desc_union);
239 static void mptsas_handle_scsi_io_success(mptsas_t *mpt,
240 pMpi2ReplyDescriptorsUnion_t reply_desc);
241 static void mptsas_handle_address_reply(mptsas_t *mpt,
242 pMpi2ReplyDescriptorsUnion_t reply_desc);
243 static int mptsas_wait_intr(mptsas_t *mpt, int polltime);
244 static void mptsas_sge_setup(mptsas_t *mpt, mptsas_cmd_t *cmd,
245 uint32_t *control, pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl);
246
247 static void mptsas_watch(void *arg);
248 static void mptsas_watchsubr(mptsas_t *mpt);
249 static void mptsas_cmd_timeout(mptsas_t *mpt, mptsas_target_t *ptgt);
250
251 static void mptsas_start_passthru(mptsas_t *mpt, mptsas_cmd_t *cmd);
252 static int mptsas_do_passthru(mptsas_t *mpt, uint8_t *request, uint8_t *reply,
253 uint8_t *data, uint32_t request_size, uint32_t reply_size,
254 uint32_t data_size, uint32_t direction, uint8_t *dataout,
255 uint32_t dataout_size, short timeout, int mode);
256 static int mptsas_free_devhdl(mptsas_t *mpt, uint16_t devhdl);
257
258 static uint8_t mptsas_get_fw_diag_buffer_number(mptsas_t *mpt,
259 uint32_t unique_id);
260 static void mptsas_start_diag(mptsas_t *mpt, mptsas_cmd_t *cmd);
261 static int mptsas_post_fw_diag_buffer(mptsas_t *mpt,
262 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code);
263 static int mptsas_release_fw_diag_buffer(mptsas_t *mpt,
264 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code,
265 uint32_t diag_type);
266 static int mptsas_diag_register(mptsas_t *mpt,
267 mptsas_fw_diag_register_t *diag_register, uint32_t *return_code);
268 static int mptsas_diag_unregister(mptsas_t *mpt,
269 mptsas_fw_diag_unregister_t *diag_unregister, uint32_t *return_code);
270 static int mptsas_diag_query(mptsas_t *mpt, mptsas_fw_diag_query_t *diag_query,
271 uint32_t *return_code);
272 static int mptsas_diag_read_buffer(mptsas_t *mpt,
273 mptsas_diag_read_buffer_t *diag_read_buffer, uint8_t *ioctl_buf,
274 uint32_t *return_code, int ioctl_mode);
275 static int mptsas_diag_release(mptsas_t *mpt,
276 mptsas_fw_diag_release_t *diag_release, uint32_t *return_code);
277 static int mptsas_do_diag_action(mptsas_t *mpt, uint32_t action,
278 uint8_t *diag_action, uint32_t length, uint32_t *return_code,
279 int ioctl_mode);
280 static int mptsas_diag_action(mptsas_t *mpt, mptsas_diag_action_t *data,
281 int mode);
282
283 static int mptsas_pkt_alloc_extern(mptsas_t *mpt, mptsas_cmd_t *cmd,
284 int cmdlen, int tgtlen, int statuslen, int kf);
285 static void mptsas_pkt_destroy_extern(mptsas_t *mpt, mptsas_cmd_t *cmd);
286
287 static int mptsas_kmem_cache_constructor(void *buf, void *cdrarg, int kmflags);
288 static void mptsas_kmem_cache_destructor(void *buf, void *cdrarg);
289
290 static int mptsas_cache_frames_constructor(void *buf, void *cdrarg,
291 int kmflags);
292 static void mptsas_cache_frames_destructor(void *buf, void *cdrarg);
293
294 static void mptsas_check_scsi_io_error(mptsas_t *mpt, pMpi2SCSIIOReply_t reply,
295 mptsas_cmd_t *cmd);
296 static void mptsas_check_task_mgt(mptsas_t *mpt,
297 pMpi2SCSIManagementReply_t reply, mptsas_cmd_t *cmd);
298 static int mptsas_send_scsi_cmd(mptsas_t *mpt, struct scsi_address *ap,
299 mptsas_target_t *ptgt, uchar_t *cdb, int cdblen, struct buf *data_bp,
300 int *resid);
301
302 static int mptsas_alloc_active_slots(mptsas_t *mpt, int flag);
303 static void mptsas_free_active_slots(mptsas_t *mpt);
304 static int mptsas_start_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd);
305
306 static void mptsas_restart_hba(mptsas_t *mpt);
307 static void mptsas_restart_waitq(mptsas_t *mpt);
308
309 static void mptsas_deliver_doneq_thread(mptsas_t *mpt);
310 static void mptsas_doneq_add(mptsas_t *mpt, mptsas_cmd_t *cmd);
311 static void mptsas_doneq_mv(mptsas_t *mpt, uint64_t t);
312
313 static mptsas_cmd_t *mptsas_doneq_thread_rm(mptsas_t *mpt, uint64_t t);
314 static void mptsas_doneq_empty(mptsas_t *mpt);
315 static void mptsas_doneq_thread(mptsas_doneq_thread_arg_t *arg);
316
317 static mptsas_cmd_t *mptsas_waitq_rm(mptsas_t *mpt);
318 static void mptsas_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd);
319 static mptsas_cmd_t *mptsas_tx_waitq_rm(mptsas_t *mpt);
320 static void mptsas_tx_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd);
321
322
323 static void mptsas_start_watch_reset_delay();
324 static void mptsas_setup_bus_reset_delay(mptsas_t *mpt);
325 static void mptsas_watch_reset_delay(void *arg);
326 static int mptsas_watch_reset_delay_subr(mptsas_t *mpt);
327
328 /*
329 * helper functions
330 */
331 static void mptsas_dump_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd);
332
333 static dev_info_t *mptsas_find_child(dev_info_t *pdip, char *name);
334 static dev_info_t *mptsas_find_child_phy(dev_info_t *pdip, uint8_t phy);
335 static dev_info_t *mptsas_find_child_addr(dev_info_t *pdip, uint64_t sasaddr,
336 int lun);
337 static mdi_pathinfo_t *mptsas_find_path_addr(dev_info_t *pdip, uint64_t sasaddr,
338 int lun);
339 static mdi_pathinfo_t *mptsas_find_path_phy(dev_info_t *pdip, uint8_t phy);
340 static dev_info_t *mptsas_find_smp_child(dev_info_t *pdip, char *str_wwn);
341
342 static int mptsas_parse_address(char *name, uint64_t *wwid, uint8_t *phy,
343 int *lun);
344 static int mptsas_parse_smp_name(char *name, uint64_t *wwn);
345
346 static mptsas_target_t *mptsas_phy_to_tgt(mptsas_t *mpt,
347 mptsas_phymask_t phymask, uint8_t phy);
348 static mptsas_target_t *mptsas_wwid_to_ptgt(mptsas_t *mpt,
349 mptsas_phymask_t phymask, uint64_t wwid);
350 static mptsas_smp_t *mptsas_wwid_to_psmp(mptsas_t *mpt,
351 mptsas_phymask_t phymask, uint64_t wwid);
352
353 static int mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun,
354 uchar_t page, unsigned char *buf, int len, int *rlen, uchar_t evpd);
355
356 static int mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address,
357 uint16_t *handle, mptsas_target_t **pptgt);
358 static void mptsas_update_phymask(mptsas_t *mpt);
359
360 static int mptsas_send_sep(mptsas_t *mpt, mptsas_target_t *ptgt,
361 uint32_t *status, uint8_t cmd);
362 static dev_info_t *mptsas_get_dip_from_dev(dev_t dev,
363 mptsas_phymask_t *phymask);
364 static mptsas_target_t *mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr,
365 mptsas_phymask_t phymask);
366 static int mptsas_flush_led_status(mptsas_t *mpt, mptsas_target_t *ptgt);
367
368
369 /*
370 * Enumeration / DR functions
371 */
372 static void mptsas_config_all(dev_info_t *pdip);
373 static int mptsas_config_one_addr(dev_info_t *pdip, uint64_t sasaddr, int lun,
374 dev_info_t **lundip);
375 static int mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun,
376 dev_info_t **lundip);
377
378 static int mptsas_config_target(dev_info_t *pdip, mptsas_target_t *ptgt);
379 static int mptsas_offline_target(dev_info_t *pdip, char *name);
380
381 static int mptsas_config_raid(dev_info_t *pdip, uint16_t target,
382 dev_info_t **dip);
383
384 static int mptsas_config_luns(dev_info_t *pdip, mptsas_target_t *ptgt);
385 static int mptsas_probe_lun(dev_info_t *pdip, int lun,
386 dev_info_t **dip, mptsas_target_t *ptgt);
387
388 static int mptsas_create_lun(dev_info_t *pdip, struct scsi_inquiry *sd_inq,
389 dev_info_t **dip, mptsas_target_t *ptgt, int lun);
390
391 static int mptsas_create_phys_lun(dev_info_t *pdip, struct scsi_inquiry *sd,
392 char *guid, dev_info_t **dip, mptsas_target_t *ptgt, int lun);
393 static int mptsas_create_virt_lun(dev_info_t *pdip, struct scsi_inquiry *sd,
394 char *guid, dev_info_t **dip, mdi_pathinfo_t **pip, mptsas_target_t *ptgt,
395 int lun);
396
397 static void mptsas_offline_missed_luns(dev_info_t *pdip,
398 uint16_t *repluns, int lun_cnt, mptsas_target_t *ptgt);
399 static int mptsas_offline_lun(dev_info_t *pdip, dev_info_t *rdip,
400 mdi_pathinfo_t *rpip, uint_t flags);
401
402 static int mptsas_config_smp(dev_info_t *pdip, uint64_t sas_wwn,
403 dev_info_t **smp_dip);
404 static int mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node,
405 uint_t flags);
406
407 static int mptsas_event_query(mptsas_t *mpt, mptsas_event_query_t *data,
408 int mode, int *rval);
409 static int mptsas_event_enable(mptsas_t *mpt, mptsas_event_enable_t *data,
410 int mode, int *rval);
411 static int mptsas_event_report(mptsas_t *mpt, mptsas_event_report_t *data,
412 int mode, int *rval);
413 static void mptsas_record_event(void *args);
414 static int mptsas_reg_access(mptsas_t *mpt, mptsas_reg_access_t *data,
415 int mode);
416
417 mptsas_target_t *mptsas_tgt_alloc(refhash_t *, uint16_t, uint64_t,
418 uint32_t, mptsas_phymask_t, uint8_t);
419 static mptsas_smp_t *mptsas_smp_alloc(mptsas_t *, mptsas_smp_t *);
420 static int mptsas_online_smp(dev_info_t *pdip, mptsas_smp_t *smp_node,
421 dev_info_t **smp_dip);
422
423 /*
424 * Power management functions
425 */
426 static int mptsas_get_pci_cap(mptsas_t *mpt);
427 static int mptsas_init_pm(mptsas_t *mpt);
428
429 /*
430 * MPT MSI tunable:
431 *
432 * By default MSI is enabled on all supported platforms.
433 */
434 boolean_t mptsas_enable_msi = B_TRUE;
435 boolean_t mptsas_physical_bind_failed_page_83 = B_FALSE;
436
437 /*
438 * Global switch for use of MPI2.5 FAST PATH.
439 * We don't really know what FAST PATH actually does, so if it is suspected
440 * to cause problems it can be turned off by setting this variable to B_FALSE.
441 */
442 boolean_t mptsas_use_fastpath = B_TRUE;
443
444 static int mptsas_register_intrs(mptsas_t *);
445 static void mptsas_unregister_intrs(mptsas_t *);
446 static int mptsas_add_intrs(mptsas_t *, int);
447 static void mptsas_rem_intrs(mptsas_t *);
448
449 /*
450 * FMA Prototypes
451 */
452 static void mptsas_fm_init(mptsas_t *mpt);
453 static void mptsas_fm_fini(mptsas_t *mpt);
454 static int mptsas_fm_error_cb(dev_info_t *, ddi_fm_error_t *, const void *);
455
456 extern pri_t minclsyspri, maxclsyspri;
457
458 /*
459 * This device is created by the SCSI pseudo nexus driver (SCSI vHCI). It is
460 * under this device that the paths to a physical device are created when
461 * MPxIO is used.
462 */
463 extern dev_info_t *scsi_vhci_dip;
464
465 /*
466 * Tunable timeout value for Inquiry VPD page 0x83
467 * By default the value is 30 seconds.
468 */
469 int mptsas_inq83_retry_timeout = 30;
470
471 /*
472 * This is used to allocate memory for message frame storage, not for
473 * data I/O DMA. All message frames must be stored in the first 4G of
474 * physical memory.
475 */
476 ddi_dma_attr_t mptsas_dma_attrs = {
477 DMA_ATTR_V0, /* attribute layout version */
478 0x0ull, /* address low - should be 0 (longlong) */
479 0xffffffffull, /* address high - 32-bit max range */
480 0x00ffffffull, /* count max - max DMA object size */
481 4, /* allocation alignment requirements */
482 0x78, /* burstsizes - binary encoded values */
483 1, /* minxfer - gran. of DMA engine */
484 0x00ffffffull, /* maxxfer - gran. of DMA engine */
485 0xffffffffull, /* max segment size (DMA boundary) */
486 MPTSAS_MAX_DMA_SEGS, /* scatter/gather list length */
487 512, /* granularity - device transfer size */
488 0 /* flags, set to 0 */
489 };
490
491 /*
492 * This is used for data I/O DMA memory allocation. (full 64-bit DMA
493 * physical addresses are supported.)
494 */
495 ddi_dma_attr_t mptsas_dma_attrs64 = {
496 DMA_ATTR_V0, /* attribute layout version */
497 0x0ull, /* address low - should be 0 (longlong) */
498 0xffffffffffffffffull, /* address high - 64-bit max */
499 0x00ffffffull, /* count max - max DMA object size */
500 4, /* allocation alignment requirements */
501 0x78, /* burstsizes - binary encoded values */
502 1, /* minxfer - gran. of DMA engine */
503 0x00ffffffull, /* maxxfer - gran. of DMA engine */
504 0xffffffffull, /* max segment size (DMA boundary) */
505 MPTSAS_MAX_DMA_SEGS, /* scatter/gather list length */
506 512, /* granularity - device transfer size */
507 0 /* flags, set to 0 */
508 };
509
510 ddi_device_acc_attr_t mptsas_dev_attr = {
511 DDI_DEVICE_ATTR_V1,
512 DDI_STRUCTURE_LE_ACC,
513 DDI_STRICTORDER_ACC,
514 DDI_DEFAULT_ACC
515 };
516
517 static struct cb_ops mptsas_cb_ops = {
518 scsi_hba_open, /* open */
519 scsi_hba_close, /* close */
520 nodev, /* strategy */
521 nodev, /* print */
522 nodev, /* dump */
523 nodev, /* read */
524 nodev, /* write */
525 mptsas_ioctl, /* ioctl */
526 nodev, /* devmap */
527 nodev, /* mmap */
528 nodev, /* segmap */
529 nochpoll, /* chpoll */
530 ddi_prop_op, /* cb_prop_op */
531 NULL, /* streamtab */
532 D_MP, /* cb_flag */
533 CB_REV, /* rev */
534 nodev, /* aread */
535 nodev /* awrite */
536 };
537
538 static struct dev_ops mptsas_ops = {
539 DEVO_REV, /* devo_rev, */
540 0, /* refcnt */
541 ddi_no_info, /* info */
542 nulldev, /* identify */
543 nulldev, /* probe */
544 mptsas_attach, /* attach */
545 mptsas_detach, /* detach */
546 #ifdef __sparc
547 mptsas_reset,
548 #else
549 nodev, /* reset */
550 #endif /* __sparc */
551 &mptsas_cb_ops, /* driver operations */
552 NULL, /* bus operations */
553 mptsas_power, /* power management */
554 #ifdef __sparc
555 ddi_quiesce_not_needed
556 #else
557 mptsas_quiesce /* quiesce */
558 #endif /* __sparc */
559 };
560
561
562 #define MPTSAS_MOD_STRING "MPTSAS HBA Driver 00.00.00.24"
563
564 static struct modldrv modldrv = {
565 &mod_driverops, /* Type of module. This one is a driver */
566 MPTSAS_MOD_STRING, /* Name of the module. */
567 &mptsas_ops, /* driver ops */
568 };
569
570 static struct modlinkage modlinkage = {
571 MODREV_1, &modldrv, NULL
572 };
573 #define TARGET_PROP "target"
574 #define LUN_PROP "lun"
575 #define LUN64_PROP "lun64"
576 #define SAS_PROP "sas-mpt"
577 #define MDI_GUID "wwn"
578 #define NDI_GUID "guid"
579 #define MPTSAS_DEV_GONE "mptsas_dev_gone"
580
581 /*
582 * Local static data
583 */
584 #if defined(MPTSAS_DEBUG)
585 /*
586 * Flags to indicate which debug messages are to be printed and which go to the
587 * debug log ring buffer. Default is to not print anything, and to log
588 * everything except the watchsubr() output which normally happens every second.
589 */
590 uint32_t mptsas_debugprt_flags = 0x0;
591 uint32_t mptsas_debuglog_flags = ~(1U << 30);
592 #endif /* defined(MPTSAS_DEBUG) */
593 uint32_t mptsas_debug_resets = 0;
594
595 static kmutex_t mptsas_global_mutex;
596 static void *mptsas_state; /* soft state ptr */
597 static krwlock_t mptsas_global_rwlock;
598
599 static kmutex_t mptsas_log_mutex;
600 static char mptsas_log_buf[256];
601 _NOTE(MUTEX_PROTECTS_DATA(mptsas_log_mutex, mptsas_log_buf))
602
603 static mptsas_t *mptsas_head, *mptsas_tail;
604 static clock_t mptsas_scsi_watchdog_tick;
605 static clock_t mptsas_tick;
606 static timeout_id_t mptsas_reset_watch;
607 static timeout_id_t mptsas_timeout_id;
608 static int mptsas_timeouts_enabled = 0;
609
610 /*
611 * Default length for extended auto request sense buffers.
612 * All sense buffers need to be under the same alloc because there
613 * is only one common top 32bits (of 64bits) address register.
614 * Most requests only require 32 bytes, but some request >256.
615 * We use rmalloc()/rmfree() on this additional memory to manage the
616 * "extended" requests.
617 */
618 int mptsas_extreq_sense_bufsize = 256*64;
619
620 /*
621 * We believe that all software resrictions of having to run with DMA
622 * attributes to limit allocation to the first 4G are removed.
623 * However, this flag remains to enable quick switchback should suspicious
624 * problems emerge.
625 * Note that scsi_alloc_consistent_buf() does still adhere to allocating
626 * 32 bit addressable memory, but we can cope if that is changed now.
627 */
628 int mptsas_use_64bit_msgaddr = 1;
629
630 /*
631 * warlock directives
632 */
633 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", scsi_pkt \
634 mptsas_cmd NcrTableIndirect buf scsi_cdb scsi_status))
635 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", smp_pkt))
636 _NOTE(SCHEME_PROTECTS_DATA("stable data", scsi_device scsi_address))
637 _NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", mptsas_tgt_private))
638 _NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", scsi_hba_tran::tran_tgt_private))
639
640 /*
641 * SM - HBA statics
642 */
643 char *mptsas_driver_rev = MPTSAS_MOD_STRING;
644
645 #ifdef MPTSAS_DEBUG
646 void debug_enter(char *);
647 #endif
648
649 /*
650 * Notes:
651 * - scsi_hba_init(9F) initializes SCSI HBA modules
652 * - must call scsi_hba_fini(9F) if modload() fails
653 */
654 int
655 _init(void)
656 {
657 int status;
658 /* CONSTCOND */
659 ASSERT(NO_COMPETING_THREADS);
660
661 NDBG0(("_init"));
662
663 status = ddi_soft_state_init(&mptsas_state, MPTSAS_SIZE,
664 MPTSAS_INITIAL_SOFT_SPACE);
665 if (status != 0) {
666 return (status);
667 }
668
669 if ((status = scsi_hba_init(&modlinkage)) != 0) {
670 ddi_soft_state_fini(&mptsas_state);
671 return (status);
672 }
673
674 mutex_init(&mptsas_global_mutex, NULL, MUTEX_DRIVER, NULL);
675 rw_init(&mptsas_global_rwlock, NULL, RW_DRIVER, NULL);
676 mutex_init(&mptsas_log_mutex, NULL, MUTEX_DRIVER, NULL);
677
678 if ((status = mod_install(&modlinkage)) != 0) {
679 mutex_destroy(&mptsas_log_mutex);
680 rw_destroy(&mptsas_global_rwlock);
681 mutex_destroy(&mptsas_global_mutex);
682 ddi_soft_state_fini(&mptsas_state);
683 scsi_hba_fini(&modlinkage);
684 }
685
686 return (status);
687 }
688
689 /*
690 * Notes:
691 * - scsi_hba_fini(9F) uninitializes SCSI HBA modules
692 */
693 int
694 _fini(void)
695 {
696 int status;
697 /* CONSTCOND */
698 ASSERT(NO_COMPETING_THREADS);
699
700 NDBG0(("_fini"));
701
702 if ((status = mod_remove(&modlinkage)) == 0) {
703 ddi_soft_state_fini(&mptsas_state);
704 scsi_hba_fini(&modlinkage);
705 mutex_destroy(&mptsas_global_mutex);
706 rw_destroy(&mptsas_global_rwlock);
707 mutex_destroy(&mptsas_log_mutex);
708 }
709 return (status);
710 }
711
712 /*
713 * The loadable-module _info(9E) entry point
714 */
715 int
716 _info(struct modinfo *modinfop)
717 {
718 /* CONSTCOND */
719 ASSERT(NO_COMPETING_THREADS);
720 NDBG0(("mptsas _info"));
721
722 return (mod_info(&modlinkage, modinfop));
723 }
724
725 static int
726 mptsas_target_eval_devhdl(const void *op, void *arg)
727 {
728 uint16_t dh = *(uint16_t *)arg;
729 const mptsas_target_t *tp = op;
730
731 return ((int)tp->m_devhdl - (int)dh);
732 }
733
734 static int
735 mptsas_target_eval_slot(const void *op, void *arg)
736 {
737 mptsas_led_control_t *lcp = arg;
738 const mptsas_target_t *tp = op;
739
740 if (tp->m_enclosure != lcp->Enclosure)
741 return ((int)tp->m_enclosure - (int)lcp->Enclosure);
742
743 return ((int)tp->m_slot_num - (int)lcp->Slot);
744 }
745
746 static int
747 mptsas_target_eval_nowwn(const void *op, void *arg)
748 {
749 uint8_t phy = *(uint8_t *)arg;
750 const mptsas_target_t *tp = op;
751
752 if (tp->m_addr.mta_wwn != 0)
753 return (-1);
754
755 return ((int)tp->m_phynum - (int)phy);
756 }
757
758 static int
759 mptsas_smp_eval_devhdl(const void *op, void *arg)
760 {
761 uint16_t dh = *(uint16_t *)arg;
762 const mptsas_smp_t *sp = op;
763
764 return ((int)sp->m_devhdl - (int)dh);
765 }
766
767 static uint64_t
768 mptsas_target_addr_hash(const void *tp)
769 {
770 const mptsas_target_addr_t *tap = tp;
771
772 return ((tap->mta_wwn & 0xffffffffffffULL) |
773 ((uint64_t)tap->mta_phymask << 48));
774 }
775
776 static int
777 mptsas_target_addr_cmp(const void *a, const void *b)
778 {
779 const mptsas_target_addr_t *aap = a;
780 const mptsas_target_addr_t *bap = b;
781
782 if (aap->mta_wwn < bap->mta_wwn)
783 return (-1);
784 if (aap->mta_wwn > bap->mta_wwn)
785 return (1);
786 return ((int)bap->mta_phymask - (int)aap->mta_phymask);
787 }
788
789 static uint64_t
790 mptsas_tmp_target_hash(const void *tp)
791 {
792 return ((uint64_t)(uintptr_t)tp);
793 }
794
795 static int
796 mptsas_tmp_target_cmp(const void *a, const void *b)
797 {
798 if (a > b)
799 return (1);
800 if (b < a)
801 return (-1);
802
803 return (0);
804 }
805
806 static void
807 mptsas_target_free(void *op)
808 {
809 kmem_free(op, sizeof (mptsas_target_t));
810 }
811
812 static void
813 mptsas_smp_free(void *op)
814 {
815 kmem_free(op, sizeof (mptsas_smp_t));
816 }
817
818 static void
819 mptsas_destroy_hashes(mptsas_t *mpt)
820 {
821 mptsas_target_t *tp;
822 mptsas_smp_t *sp;
823
824 for (tp = refhash_first(mpt->m_targets); tp != NULL;
825 tp = refhash_next(mpt->m_targets, tp)) {
826 refhash_remove(mpt->m_targets, tp);
827 }
828 for (sp = refhash_first(mpt->m_smp_targets); sp != NULL;
829 sp = refhash_next(mpt->m_smp_targets, sp)) {
830 refhash_remove(mpt->m_smp_targets, sp);
831 }
832 refhash_destroy(mpt->m_tmp_targets);
833 refhash_destroy(mpt->m_targets);
834 refhash_destroy(mpt->m_smp_targets);
835 mpt->m_targets = NULL;
836 mpt->m_smp_targets = NULL;
837 }
838
839 static int
840 mptsas_iport_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
841 {
842 dev_info_t *pdip;
843 mptsas_t *mpt;
844 scsi_hba_tran_t *hba_tran;
845 char *iport = NULL;
846 char phymask[MPTSAS_MAX_PHYS];
847 mptsas_phymask_t phy_mask = 0;
848 int dynamic_port = 0;
849 uint32_t page_address;
850 char initiator_wwnstr[MPTSAS_WWN_STRLEN];
851 int rval = DDI_FAILURE;
852 int i = 0;
853 uint8_t numphys = 0;
854 uint8_t phy_id;
855 uint8_t phy_port = 0;
856 uint16_t attached_devhdl = 0;
857 uint32_t dev_info;
858 uint64_t attached_sas_wwn;
859 uint16_t dev_hdl;
860 uint16_t pdev_hdl;
861 uint16_t bay_num, enclosure, io_flags;
862 char attached_wwnstr[MPTSAS_WWN_STRLEN];
863
864 /* CONSTCOND */
865 ASSERT(NO_COMPETING_THREADS);
866
867 switch (cmd) {
868 case DDI_ATTACH:
869 break;
870
871 case DDI_RESUME:
872 /*
873 * If this a scsi-iport node, nothing to do here.
874 */
875 return (DDI_SUCCESS);
876
877 default:
878 return (DDI_FAILURE);
879 }
880
881 pdip = ddi_get_parent(dip);
882
883 if ((hba_tran = ndi_flavorv_get(pdip, SCSA_FLAVOR_SCSI_DEVICE)) ==
884 NULL) {
885 cmn_err(CE_WARN, "Failed attach iport because fail to "
886 "get tran vector for the HBA node");
887 return (DDI_FAILURE);
888 }
889
890 mpt = TRAN2MPT(hba_tran);
891 ASSERT(mpt != NULL);
892 if (mpt == NULL)
893 return (DDI_FAILURE);
894
895 if ((hba_tran = ndi_flavorv_get(dip, SCSA_FLAVOR_SCSI_DEVICE)) ==
896 NULL) {
897 mptsas_log(mpt, CE_WARN, "Failed attach iport because fail to "
898 "get tran vector for the iport node");
899 return (DDI_FAILURE);
900 }
901
902 /*
903 * Overwrite parent's tran_hba_private to iport's tran vector
904 */
905 hba_tran->tran_hba_private = mpt;
906
907 ddi_report_dev(dip);
908
909 /*
910 * Get SAS address for initiator port according dev_handle
911 */
912 iport = ddi_get_name_addr(dip);
913 if (iport && strncmp(iport, "v0", 2) == 0) {
914 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip,
915 MPTSAS_VIRTUAL_PORT, 1) !=
916 DDI_PROP_SUCCESS) {
917 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip,
918 MPTSAS_VIRTUAL_PORT);
919 mptsas_log(mpt, CE_WARN, "mptsas virtual port "
920 "prop update failed");
921 return (DDI_FAILURE);
922 }
923 return (DDI_SUCCESS);
924 }
925
926 mutex_enter(&mpt->m_mutex);
927 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
928 bzero(phymask, sizeof (phymask));
929 (void) sprintf(phymask,
930 "%x", mpt->m_phy_info[i].phy_mask);
931 if (strcmp(phymask, iport) == 0) {
932 break;
933 }
934 }
935
936 if (i == MPTSAS_MAX_PHYS) {
937 mptsas_log(mpt, CE_WARN, "Failed attach port %s because port"
938 "seems not exist", iport);
939 mutex_exit(&mpt->m_mutex);
940 return (DDI_FAILURE);
941 }
942
943 phy_mask = mpt->m_phy_info[i].phy_mask;
944
945 if (mpt->m_phy_info[i].port_flags & AUTO_PORT_CONFIGURATION)
946 dynamic_port = 1;
947 else
948 dynamic_port = 0;
949
950 /*
951 * Update PHY info for smhba
952 */
953 if (mptsas_smhba_phy_init(mpt)) {
954 mutex_exit(&mpt->m_mutex);
955 mptsas_log(mpt, CE_WARN, "mptsas phy update "
956 "failed");
957 return (DDI_FAILURE);
958 }
959
960 mutex_exit(&mpt->m_mutex);
961
962 numphys = 0;
963 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
964 if ((phy_mask >> i) & 0x01) {
965 numphys++;
966 }
967 }
968
969 bzero(initiator_wwnstr, sizeof (initiator_wwnstr));
970 (void) sprintf(initiator_wwnstr, "w%016"PRIx64,
971 mpt->un.m_base_wwid);
972
973 if (ddi_prop_update_string(DDI_DEV_T_NONE, dip,
974 SCSI_ADDR_PROP_INITIATOR_PORT, initiator_wwnstr) !=
975 DDI_PROP_SUCCESS) {
976 (void) ddi_prop_remove(DDI_DEV_T_NONE,
977 dip, SCSI_ADDR_PROP_INITIATOR_PORT);
978 mptsas_log(mpt, CE_WARN, "mptsas Initiator port "
979 "prop update failed");
980 return (DDI_FAILURE);
981 }
982 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip,
983 MPTSAS_NUM_PHYS, numphys) !=
984 DDI_PROP_SUCCESS) {
985 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, MPTSAS_NUM_PHYS);
986 return (DDI_FAILURE);
987 }
988
989 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip,
990 "phymask", phy_mask) !=
991 DDI_PROP_SUCCESS) {
992 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "phymask");
993 mptsas_log(mpt, CE_WARN, "mptsas phy mask "
994 "prop update failed");
995 return (DDI_FAILURE);
996 }
997
998 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip,
999 "dynamic-port", dynamic_port) !=
1000 DDI_PROP_SUCCESS) {
1001 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "dynamic-port");
1002 mptsas_log(mpt, CE_WARN, "mptsas dynamic port "
1003 "prop update failed");
1004 return (DDI_FAILURE);
1005 }
1006 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip,
1007 MPTSAS_VIRTUAL_PORT, 0) !=
1008 DDI_PROP_SUCCESS) {
1009 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip,
1010 MPTSAS_VIRTUAL_PORT);
1011 mptsas_log(mpt, CE_WARN, "mptsas virtual port "
1012 "prop update failed");
1013 return (DDI_FAILURE);
1014 }
1015 mptsas_smhba_set_all_phy_props(mpt, dip, numphys, phy_mask,
1016 &attached_devhdl);
1017
1018 mutex_enter(&mpt->m_mutex);
1019 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
1020 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)attached_devhdl;
1021 rval = mptsas_get_sas_device_page0(mpt, page_address, &dev_hdl,
1022 &attached_sas_wwn, &dev_info, &phy_port, &phy_id,
1023 &pdev_hdl, &bay_num, &enclosure, &io_flags);
1024 if (rval != DDI_SUCCESS) {
1025 mptsas_log(mpt, CE_WARN,
1026 "Failed to get device page0 for handle:%d",
1027 attached_devhdl);
1028 mutex_exit(&mpt->m_mutex);
1029 return (DDI_FAILURE);
1030 }
1031
1032 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
1033 bzero(phymask, sizeof (phymask));
1034 (void) sprintf(phymask, "%x", mpt->m_phy_info[i].phy_mask);
1035 if (strcmp(phymask, iport) == 0) {
1036 (void) sprintf(&mpt->m_phy_info[i].smhba_info.path[0],
1037 "%x",
1038 mpt->m_phy_info[i].phy_mask);
1039 }
1040 }
1041 mutex_exit(&mpt->m_mutex);
1042
1043 bzero(attached_wwnstr, sizeof (attached_wwnstr));
1044 (void) sprintf(attached_wwnstr, "w%016"PRIx64,
1045 attached_sas_wwn);
1046 if (ddi_prop_update_string(DDI_DEV_T_NONE, dip,
1047 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) !=
1048 DDI_PROP_SUCCESS) {
1049 (void) ddi_prop_remove(DDI_DEV_T_NONE,
1050 dip, SCSI_ADDR_PROP_ATTACHED_PORT);
1051 return (DDI_FAILURE);
1052 }
1053
1054 /* Create kstats for each phy on this iport */
1055
1056 mptsas_create_phy_stats(mpt, iport, dip);
1057
1058 /*
1059 * register sas hba iport with mdi (MPxIO/vhci)
1060 */
1061 if (mdi_phci_register(MDI_HCI_CLASS_SCSI,
1062 dip, 0) == MDI_SUCCESS) {
1063 mpt->m_mpxio_enable = TRUE;
1064 }
1065 return (DDI_SUCCESS);
1066 }
1067
1068 /*
1069 * Notes:
1070 * Set up all device state and allocate data structures,
1071 * mutexes, condition variables, etc. for device operation.
1072 * Add interrupts needed.
1073 * Return DDI_SUCCESS if device is ready, else return DDI_FAILURE.
1074 */
1075 static int
1076 mptsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
1077 {
1078 mptsas_t *mpt = NULL;
1079 int instance, i, j;
1080 int doneq_thread_num;
1081 char intr_added = 0;
1082 char map_setup = 0;
1083 char config_setup = 0;
1084 char hba_attach_setup = 0;
1085 char smp_attach_setup = 0;
1086 char enc_attach_setup = 0;
1087 char mutex_init_done = 0;
1088 char event_taskq_create = 0;
1089 char dr_taskq_create = 0;
1090 char doneq_thread_create = 0;
1091 char added_watchdog = 0;
1092 scsi_hba_tran_t *hba_tran;
1093 uint_t mem_bar = MEM_SPACE;
1094 int rval = DDI_FAILURE;
1095
1096 /* CONSTCOND */
1097 ASSERT(NO_COMPETING_THREADS);
1098
1099 if (scsi_hba_iport_unit_address(dip)) {
1100 return (mptsas_iport_attach(dip, cmd));
1101 }
1102
1103 switch (cmd) {
1104 case DDI_ATTACH:
1105 break;
1106
1107 case DDI_RESUME:
1108 if ((hba_tran = ddi_get_driver_private(dip)) == NULL)
1109 return (DDI_FAILURE);
1110
1111 mpt = TRAN2MPT(hba_tran);
1112
1113 if (!mpt) {
1114 return (DDI_FAILURE);
1115 }
1116
1117 /*
1118 * Reset hardware and softc to "no outstanding commands"
1119 * Note that a check condition can result on first command
1120 * to a target.
1121 */
1122 mutex_enter(&mpt->m_mutex);
1123
1124 /*
1125 * raise power.
1126 */
1127 if (mpt->m_options & MPTSAS_OPT_PM) {
1128 mutex_exit(&mpt->m_mutex);
1129 (void) pm_busy_component(dip, 0);
1130 rval = pm_power_has_changed(dip, 0, PM_LEVEL_D0);
1131 if (rval == DDI_SUCCESS) {
1132 mutex_enter(&mpt->m_mutex);
1133 } else {
1134 /*
1135 * The pm_raise_power() call above failed,
1136 * and that can only occur if we were unable
1137 * to reset the hardware. This is probably
1138 * due to unhealty hardware, and because
1139 * important filesystems(such as the root
1140 * filesystem) could be on the attached disks,
1141 * it would not be a good idea to continue,
1142 * as we won't be entirely certain we are
1143 * writing correct data. So we panic() here
1144 * to not only prevent possible data corruption,
1145 * but to give developers or end users a hope
1146 * of identifying and correcting any problems.
1147 */
1148 fm_panic("mptsas could not reset hardware "
1149 "during resume");
1150 }
1151 }
1152
1153 mpt->m_suspended = 0;
1154
1155 /*
1156 * Reinitialize ioc
1157 */
1158 mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET;
1159 if (mptsas_init_chip(mpt, FALSE) == DDI_FAILURE) {
1160 mutex_exit(&mpt->m_mutex);
1161 if (mpt->m_options & MPTSAS_OPT_PM) {
1162 (void) pm_idle_component(dip, 0);
1163 }
1164 fm_panic("mptsas init chip fail during resume");
1165 }
1166 /*
1167 * mptsas_update_driver_data needs interrupts so enable them
1168 * first.
1169 */
1170 MPTSAS_ENABLE_INTR(mpt);
1171 mptsas_update_driver_data(mpt);
1172
1173 /* start requests, if possible */
1174 mptsas_restart_hba(mpt);
1175
1176 mutex_exit(&mpt->m_mutex);
1177
1178 /*
1179 * Restart watch thread
1180 */
1181 mutex_enter(&mptsas_global_mutex);
1182 if (mptsas_timeout_id == 0) {
1183 mptsas_timeout_id = timeout(mptsas_watch, NULL,
1184 mptsas_tick);
1185 mptsas_timeouts_enabled = 1;
1186 }
1187 mutex_exit(&mptsas_global_mutex);
1188
1189 /* report idle status to pm framework */
1190 if (mpt->m_options & MPTSAS_OPT_PM) {
1191 (void) pm_idle_component(dip, 0);
1192 }
1193
1194 return (DDI_SUCCESS);
1195
1196 default:
1197 return (DDI_FAILURE);
1198
1199 }
1200
1201 instance = ddi_get_instance(dip);
1202
1203 /*
1204 * Allocate softc information.
1205 */
1206 if (ddi_soft_state_zalloc(mptsas_state, instance) != DDI_SUCCESS) {
1207 mptsas_log(NULL, CE_WARN,
1208 "mptsas%d: cannot allocate soft state", instance);
1209 goto fail;
1210 }
1211
1212 mpt = ddi_get_soft_state(mptsas_state, instance);
1213
1214 if (mpt == NULL) {
1215 mptsas_log(NULL, CE_WARN,
1216 "mptsas%d: cannot get soft state", instance);
1217 goto fail;
1218 }
1219
1220 /* Indicate that we are 'sizeof (scsi_*(9S))' clean. */
1221 scsi_size_clean(dip);
1222
1223 mpt->m_dip = dip;
1224 mpt->m_instance = instance;
1225
1226 /* Make a per-instance copy of the structures */
1227 mpt->m_io_dma_attr = mptsas_dma_attrs64;
1228 if (mptsas_use_64bit_msgaddr) {
1229 mpt->m_msg_dma_attr = mptsas_dma_attrs64;
1230 } else {
1231 mpt->m_msg_dma_attr = mptsas_dma_attrs;
1232 }
1233 mpt->m_reg_acc_attr = mptsas_dev_attr;
1234 mpt->m_dev_acc_attr = mptsas_dev_attr;
1235
1236 /*
1237 * Size of individual request sense buffer
1238 */
1239 mpt->m_req_sense_size = EXTCMDS_STATUS_SIZE;
1240
1241 /*
1242 * Initialize FMA
1243 */
1244 mpt->m_fm_capabilities = ddi_getprop(DDI_DEV_T_ANY, mpt->m_dip,
1245 DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "fm-capable",
1246 DDI_FM_EREPORT_CAPABLE | DDI_FM_ACCCHK_CAPABLE |
1247 DDI_FM_DMACHK_CAPABLE | DDI_FM_ERRCB_CAPABLE);
1248
1249 mptsas_fm_init(mpt);
1250
1251 if (mptsas_alloc_handshake_msg(mpt,
1252 sizeof (Mpi2SCSITaskManagementRequest_t)) == DDI_FAILURE) {
1253 mptsas_log(mpt, CE_WARN, "cannot initialize handshake msg.");
1254 goto fail;
1255 }
1256
1257 /*
1258 * Setup configuration space
1259 */
1260 if (mptsas_config_space_init(mpt) == FALSE) {
1261 mptsas_log(mpt, CE_WARN, "mptsas_config_space_init failed");
1262 goto fail;
1263 }
1264 config_setup++;
1265
1266 if (ddi_regs_map_setup(dip, mem_bar, (caddr_t *)&mpt->m_reg,
1267 0, 0, &mpt->m_reg_acc_attr, &mpt->m_datap) != DDI_SUCCESS) {
1268 mptsas_log(mpt, CE_WARN, "map setup failed");
1269 goto fail;
1270 }
1271 map_setup++;
1272
1273 /*
1274 * A taskq is created for dealing with the event handler
1275 */
1276 if ((mpt->m_event_taskq = ddi_taskq_create(dip, "mptsas_event_taskq",
1277 1, TASKQ_DEFAULTPRI, 0)) == NULL) {
1278 mptsas_log(mpt, CE_NOTE, "ddi_taskq_create failed");
1279 goto fail;
1280 }
1281 event_taskq_create++;
1282
1283 /*
1284 * A taskq is created for dealing with dr events
1285 */
1286 if ((mpt->m_dr_taskq = ddi_taskq_create(dip,
1287 "mptsas_dr_taskq",
1288 1, TASKQ_DEFAULTPRI, 0)) == NULL) {
1289 mptsas_log(mpt, CE_NOTE, "ddi_taskq_create for discovery "
1290 "failed");
1291 goto fail;
1292 }
1293 dr_taskq_create++;
1294
1295 mpt->m_doneq_thread_threshold = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
1296 0, "mptsas_doneq_thread_threshold_prop", 10);
1297 mpt->m_doneq_length_threshold = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
1298 0, "mptsas_doneq_length_threshold_prop", 8);
1299 mpt->m_doneq_thread_n = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
1300 0, "mptsas_doneq_thread_n_prop", 8);
1301
1302 if (mpt->m_doneq_thread_n) {
1303 cv_init(&mpt->m_doneq_thread_cv, NULL, CV_DRIVER, NULL);
1304 mutex_init(&mpt->m_doneq_mutex, NULL, MUTEX_DRIVER, NULL);
1305
1306 mutex_enter(&mpt->m_doneq_mutex);
1307 mpt->m_doneq_thread_id =
1308 kmem_zalloc(sizeof (mptsas_doneq_thread_list_t)
1309 * mpt->m_doneq_thread_n, KM_SLEEP);
1310
1311 for (j = 0; j < mpt->m_doneq_thread_n; j++) {
1312 cv_init(&mpt->m_doneq_thread_id[j].cv, NULL,
1313 CV_DRIVER, NULL);
1314 mutex_init(&mpt->m_doneq_thread_id[j].mutex, NULL,
1315 MUTEX_DRIVER, NULL);
1316 mutex_enter(&mpt->m_doneq_thread_id[j].mutex);
1317 mpt->m_doneq_thread_id[j].flag |=
1318 MPTSAS_DONEQ_THREAD_ACTIVE;
1319 mpt->m_doneq_thread_id[j].arg.mpt = mpt;
1320 mpt->m_doneq_thread_id[j].arg.t = j;
1321 mpt->m_doneq_thread_id[j].threadp =
1322 thread_create(NULL, 0, mptsas_doneq_thread,
1323 &mpt->m_doneq_thread_id[j].arg,
1324 0, &p0, TS_RUN, minclsyspri);
1325 mpt->m_doneq_thread_id[j].donetail =
1326 &mpt->m_doneq_thread_id[j].doneq;
1327 mutex_exit(&mpt->m_doneq_thread_id[j].mutex);
1328 }
1329 mutex_exit(&mpt->m_doneq_mutex);
1330 doneq_thread_create++;
1331 }
1332
1333 /*
1334 * Disable hardware interrupt since we're not ready to
1335 * handle it yet.
1336 */
1337 MPTSAS_DISABLE_INTR(mpt);
1338 if (mptsas_register_intrs(mpt) == FALSE)
1339 goto fail;
1340 intr_added++;
1341
1342 /* Initialize mutex used in interrupt handler */
1343 mutex_init(&mpt->m_mutex, NULL, MUTEX_DRIVER,
1344 DDI_INTR_PRI(mpt->m_intr_pri));
1345 mutex_init(&mpt->m_passthru_mutex, NULL, MUTEX_DRIVER, NULL);
1346 mutex_init(&mpt->m_tx_waitq_mutex, NULL, MUTEX_DRIVER,
1347 DDI_INTR_PRI(mpt->m_intr_pri));
1348 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
1349 mutex_init(&mpt->m_phy_info[i].smhba_info.phy_mutex,
1350 NULL, MUTEX_DRIVER,
1351 DDI_INTR_PRI(mpt->m_intr_pri));
1352 }
1353
1354 cv_init(&mpt->m_cv, NULL, CV_DRIVER, NULL);
1355 cv_init(&mpt->m_passthru_cv, NULL, CV_DRIVER, NULL);
1356 cv_init(&mpt->m_fw_cv, NULL, CV_DRIVER, NULL);
1357 cv_init(&mpt->m_config_cv, NULL, CV_DRIVER, NULL);
1358 cv_init(&mpt->m_fw_diag_cv, NULL, CV_DRIVER, NULL);
1359 cv_init(&mpt->m_extreq_sense_refcount_cv, NULL, CV_DRIVER, NULL);
1360 mutex_init_done++;
1361
1362 mutex_enter(&mpt->m_mutex);
1363 /*
1364 * Initialize power management component
1365 */
1366 if (mpt->m_options & MPTSAS_OPT_PM) {
1367 if (mptsas_init_pm(mpt)) {
1368 mutex_exit(&mpt->m_mutex);
1369 mptsas_log(mpt, CE_WARN, "mptsas pm initialization "
1370 "failed");
1371 goto fail;
1372 }
1373 }
1374
1375 /*
1376 * Initialize chip using Message Unit Reset, if allowed
1377 */
1378 mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET;
1379 if (mptsas_init_chip(mpt, TRUE) == DDI_FAILURE) {
1380 mutex_exit(&mpt->m_mutex);
1381 mptsas_log(mpt, CE_WARN, "mptsas chip initialization failed");
1382 goto fail;
1383 }
1384
1385 mpt->m_targets = refhash_create(MPTSAS_TARGET_BUCKET_COUNT,
1386 mptsas_target_addr_hash, mptsas_target_addr_cmp,
1387 mptsas_target_free, sizeof (mptsas_target_t),
1388 offsetof(mptsas_target_t, m_link),
1389 offsetof(mptsas_target_t, m_addr), KM_SLEEP);
1390
1391 /*
1392 * The refhash for temporary targets uses the address of the target
1393 * struct itself as tag, so the tag offset is 0. See the implementation
1394 * of mptsas_tmp_target_hash() and mptsas_tmp_target_cmp().
1395 */
1396 mpt->m_tmp_targets = refhash_create(MPTSAS_TMP_TARGET_BUCKET_COUNT,
1397 mptsas_tmp_target_hash, mptsas_tmp_target_cmp,
1398 mptsas_target_free, sizeof (mptsas_target_t),
1399 offsetof(mptsas_target_t, m_link), 0, KM_SLEEP);
1400
1401 /*
1402 * Fill in the phy_info structure and get the base WWID
1403 */
1404 if (mptsas_get_manufacture_page5(mpt) == DDI_FAILURE) {
1405 mptsas_log(mpt, CE_WARN,
1406 "mptsas_get_manufacture_page5 failed!");
1407 goto fail;
1408 }
1409
1410 if (mptsas_get_sas_io_unit_page_hndshk(mpt)) {
1411 mptsas_log(mpt, CE_WARN,
1412 "mptsas_get_sas_io_unit_page_hndshk failed!");
1413 goto fail;
1414 }
1415
1416 if (mptsas_get_manufacture_page0(mpt) == DDI_FAILURE) {
1417 mptsas_log(mpt, CE_WARN,
1418 "mptsas_get_manufacture_page0 failed!");
1419 goto fail;
1420 }
1421
1422 mutex_exit(&mpt->m_mutex);
1423
1424 /*
1425 * Register the iport for multiple port HBA
1426 */
1427 mptsas_iport_register(mpt);
1428
1429 /*
1430 * initialize SCSI HBA transport structure
1431 */
1432 if (mptsas_hba_setup(mpt) == FALSE)
1433 goto fail;
1434 hba_attach_setup++;
1435
1436 if (mptsas_smp_setup(mpt) == FALSE)
1437 goto fail;
1438 smp_attach_setup++;
1439
1440 if (mptsas_enc_setup(mpt) == FALSE)
1441 goto fail;
1442 enc_attach_setup++;
1443
1444 if (mptsas_cache_create(mpt) == FALSE)
1445 goto fail;
1446
1447 mpt->m_scsi_reset_delay = ddi_prop_get_int(DDI_DEV_T_ANY,
1448 dip, 0, "scsi-reset-delay", SCSI_DEFAULT_RESET_DELAY);
1449 if (mpt->m_scsi_reset_delay == 0) {
1450 mptsas_log(mpt, CE_NOTE,
1451 "scsi_reset_delay of 0 is not recommended,"
1452 " resetting to SCSI_DEFAULT_RESET_DELAY\n");
1453 mpt->m_scsi_reset_delay = SCSI_DEFAULT_RESET_DELAY;
1454 }
1455
1456 /*
1457 * Initialize the wait and done FIFO queue
1458 */
1459 mpt->m_donetail = &mpt->m_doneq;
1460 mpt->m_waitqtail = &mpt->m_waitq;
1461 mpt->m_tx_waitqtail = &mpt->m_tx_waitq;
1462 mpt->m_tx_draining = 0;
1463
1464 /*
1465 * ioc cmd queue initialize
1466 */
1467 mpt->m_ioc_event_cmdtail = &mpt->m_ioc_event_cmdq;
1468 mpt->m_dev_handle = 0xFFFF;
1469
1470 MPTSAS_ENABLE_INTR(mpt);
1471
1472 /*
1473 * enable event notification
1474 */
1475 mutex_enter(&mpt->m_mutex);
1476 if (mptsas_ioc_enable_event_notification(mpt)) {
1477 mutex_exit(&mpt->m_mutex);
1478 goto fail;
1479 }
1480 mutex_exit(&mpt->m_mutex);
1481
1482 /*
1483 * used for mptsas_watch
1484 */
1485 mptsas_list_add(mpt);
1486
1487 mutex_enter(&mptsas_global_mutex);
1488 if (mptsas_timeouts_enabled == 0) {
1489 mptsas_scsi_watchdog_tick = ddi_prop_get_int(DDI_DEV_T_ANY,
1490 dip, 0, "scsi-watchdog-tick", DEFAULT_WD_TICK);
1491
1492 mptsas_tick = mptsas_scsi_watchdog_tick *
1493 drv_usectohz((clock_t)1000000);
1494
1495 mptsas_timeout_id = timeout(mptsas_watch, NULL, mptsas_tick);
1496 mptsas_timeouts_enabled = 1;
1497 }
1498 mutex_exit(&mptsas_global_mutex);
1499 added_watchdog++;
1500
1501 /*
1502 * Initialize PHY info for smhba.
1503 * This requires watchdog to be enabled otherwise if interrupts
1504 * don't work the system will hang.
1505 */
1506 if (mptsas_smhba_setup(mpt)) {
1507 mptsas_log(mpt, CE_WARN, "mptsas phy initialization "
1508 "failed");
1509 goto fail;
1510 }
1511
1512 /* Check all dma handles allocated in attach */
1513 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl)
1514 != DDI_SUCCESS) ||
1515 (mptsas_check_dma_handle(mpt->m_dma_req_sense_hdl)
1516 != DDI_SUCCESS) ||
1517 (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl)
1518 != DDI_SUCCESS) ||
1519 (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl)
1520 != DDI_SUCCESS) ||
1521 (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl)
1522 != DDI_SUCCESS) ||
1523 (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl)
1524 != DDI_SUCCESS)) {
1525 goto fail;
1526 }
1527
1528 /* Check all acc handles allocated in attach */
1529 if ((mptsas_check_acc_handle(mpt->m_datap) != DDI_SUCCESS) ||
1530 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl)
1531 != DDI_SUCCESS) ||
1532 (mptsas_check_acc_handle(mpt->m_acc_req_sense_hdl)
1533 != DDI_SUCCESS) ||
1534 (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl)
1535 != DDI_SUCCESS) ||
1536 (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl)
1537 != DDI_SUCCESS) ||
1538 (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl)
1539 != DDI_SUCCESS) ||
1540 (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl)
1541 != DDI_SUCCESS) ||
1542 (mptsas_check_acc_handle(mpt->m_config_handle)
1543 != DDI_SUCCESS)) {
1544 goto fail;
1545 }
1546
1547 /*
1548 * After this point, we are not going to fail the attach.
1549 */
1550
1551 /* Print message of HBA present */
1552 ddi_report_dev(dip);
1553
1554 /* report idle status to pm framework */
1555 if (mpt->m_options & MPTSAS_OPT_PM) {
1556 (void) pm_idle_component(dip, 0);
1557 }
1558
1559 return (DDI_SUCCESS);
1560
1561 fail:
1562 mptsas_log(mpt, CE_WARN, "attach failed");
1563 mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE);
1564 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST);
1565 if (mpt) {
1566 /* deallocate in reverse order */
1567 if (added_watchdog) {
1568 mptsas_list_del(mpt);
1569 mutex_enter(&mptsas_global_mutex);
1570
1571 if (mptsas_timeout_id && (mptsas_head == NULL)) {
1572 timeout_id_t tid = mptsas_timeout_id;
1573 mptsas_timeouts_enabled = 0;
1574 mptsas_timeout_id = 0;
1575 mutex_exit(&mptsas_global_mutex);
1576 (void) untimeout(tid);
1577 mutex_enter(&mptsas_global_mutex);
1578 }
1579 mutex_exit(&mptsas_global_mutex);
1580 }
1581
1582 mptsas_cache_destroy(mpt);
1583
1584 if (smp_attach_setup) {
1585 mptsas_smp_teardown(mpt);
1586 }
1587 if (enc_attach_setup) {
1588 mptsas_enc_teardown(mpt);
1589 }
1590 if (hba_attach_setup) {
1591 mptsas_hba_teardown(mpt);
1592 }
1593
1594 if (mpt->m_tmp_targets)
1595 refhash_destroy(mpt->m_tmp_targets);
1596 if (mpt->m_targets)
1597 refhash_destroy(mpt->m_targets);
1598 if (mpt->m_smp_targets)
1599 refhash_destroy(mpt->m_smp_targets);
1600
1601 if (mpt->m_active) {
1602 mptsas_free_active_slots(mpt);
1603 }
1604 if (intr_added) {
1605 mptsas_unregister_intrs(mpt);
1606 }
1607
1608 if (doneq_thread_create) {
1609 mutex_enter(&mpt->m_doneq_mutex);
1610 doneq_thread_num = mpt->m_doneq_thread_n;
1611 for (j = 0; j < mpt->m_doneq_thread_n; j++) {
1612 mutex_enter(&mpt->m_doneq_thread_id[j].mutex);
1613 mpt->m_doneq_thread_id[j].flag &=
1614 (~MPTSAS_DONEQ_THREAD_ACTIVE);
1615 cv_signal(&mpt->m_doneq_thread_id[j].cv);
1616 mutex_exit(&mpt->m_doneq_thread_id[j].mutex);
1617 }
1618 while (mpt->m_doneq_thread_n) {
1619 cv_wait(&mpt->m_doneq_thread_cv,
1620 &mpt->m_doneq_mutex);
1621 }
1622 for (j = 0; j < doneq_thread_num; j++) {
1623 cv_destroy(&mpt->m_doneq_thread_id[j].cv);
1624 mutex_destroy(&mpt->m_doneq_thread_id[j].mutex);
1625 }
1626 kmem_free(mpt->m_doneq_thread_id,
1627 sizeof (mptsas_doneq_thread_list_t)
1628 * doneq_thread_num);
1629 mutex_exit(&mpt->m_doneq_mutex);
1630 cv_destroy(&mpt->m_doneq_thread_cv);
1631 mutex_destroy(&mpt->m_doneq_mutex);
1632 }
1633 if (event_taskq_create) {
1634 ddi_taskq_destroy(mpt->m_event_taskq);
1635 }
1636 if (dr_taskq_create) {
1637 ddi_taskq_destroy(mpt->m_dr_taskq);
1638 }
1639 if (mutex_init_done) {
1640 mutex_destroy(&mpt->m_tx_waitq_mutex);
1641 mutex_destroy(&mpt->m_passthru_mutex);
1642 mutex_destroy(&mpt->m_mutex);
1643 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
1644 mutex_destroy(
1645 &mpt->m_phy_info[i].smhba_info.phy_mutex);
1646 }
1647 cv_destroy(&mpt->m_cv);
1648 cv_destroy(&mpt->m_passthru_cv);
1649 cv_destroy(&mpt->m_fw_cv);
1650 cv_destroy(&mpt->m_config_cv);
1651 cv_destroy(&mpt->m_fw_diag_cv);
1652 cv_destroy(&mpt->m_extreq_sense_refcount_cv);
1653 }
1654
1655 if (map_setup) {
1656 mptsas_cfg_fini(mpt);
1657 }
1658 if (config_setup) {
1659 mptsas_config_space_fini(mpt);
1660 }
1661 mptsas_free_handshake_msg(mpt);
1662 mptsas_hba_fini(mpt);
1663
1664 mptsas_fm_fini(mpt);
1665 ddi_soft_state_free(mptsas_state, instance);
1666 ddi_prop_remove_all(dip);
1667 }
1668 return (DDI_FAILURE);
1669 }
1670
1671 static int
1672 mptsas_suspend(dev_info_t *devi)
1673 {
1674 mptsas_t *mpt, *g;
1675 scsi_hba_tran_t *tran;
1676
1677 if (scsi_hba_iport_unit_address(devi)) {
1678 return (DDI_SUCCESS);
1679 }
1680
1681 if ((tran = ddi_get_driver_private(devi)) == NULL)
1682 return (DDI_SUCCESS);
1683
1684 mpt = TRAN2MPT(tran);
1685 if (!mpt) {
1686 return (DDI_SUCCESS);
1687 }
1688
1689 mutex_enter(&mpt->m_mutex);
1690
1691 if (mpt->m_suspended++) {
1692 mutex_exit(&mpt->m_mutex);
1693 return (DDI_SUCCESS);
1694 }
1695
1696 /*
1697 * Cancel timeout threads for this mpt
1698 */
1699 if (mpt->m_quiesce_timeid) {
1700 timeout_id_t tid = mpt->m_quiesce_timeid;
1701 mpt->m_quiesce_timeid = 0;
1702 mutex_exit(&mpt->m_mutex);
1703 (void) untimeout(tid);
1704 mutex_enter(&mpt->m_mutex);
1705 }
1706
1707 if (mpt->m_restart_cmd_timeid) {
1708 timeout_id_t tid = mpt->m_restart_cmd_timeid;
1709 mpt->m_restart_cmd_timeid = 0;
1710 mutex_exit(&mpt->m_mutex);
1711 (void) untimeout(tid);
1712 mutex_enter(&mpt->m_mutex);
1713 }
1714
1715 mutex_exit(&mpt->m_mutex);
1716
1717 (void) pm_idle_component(mpt->m_dip, 0);
1718
1719 /*
1720 * Cancel watch threads if all mpts suspended
1721 */
1722 rw_enter(&mptsas_global_rwlock, RW_WRITER);
1723 for (g = mptsas_head; g != NULL; g = g->m_next) {
1724 if (!g->m_suspended)
1725 break;
1726 }
1727 rw_exit(&mptsas_global_rwlock);
1728
1729 mutex_enter(&mptsas_global_mutex);
1730 if (g == NULL) {
1731 timeout_id_t tid;
1732
1733 mptsas_timeouts_enabled = 0;
1734 if (mptsas_timeout_id) {
1735 tid = mptsas_timeout_id;
1736 mptsas_timeout_id = 0;
1737 mutex_exit(&mptsas_global_mutex);
1738 (void) untimeout(tid);
1739 mutex_enter(&mptsas_global_mutex);
1740 }
1741 if (mptsas_reset_watch) {
1742 tid = mptsas_reset_watch;
1743 mptsas_reset_watch = 0;
1744 mutex_exit(&mptsas_global_mutex);
1745 (void) untimeout(tid);
1746 mutex_enter(&mptsas_global_mutex);
1747 }
1748 }
1749 mutex_exit(&mptsas_global_mutex);
1750
1751 mutex_enter(&mpt->m_mutex);
1752
1753 /*
1754 * If this mpt is not in full power(PM_LEVEL_D0), just return.
1755 */
1756 if ((mpt->m_options & MPTSAS_OPT_PM) &&
1757 (mpt->m_power_level != PM_LEVEL_D0)) {
1758 mutex_exit(&mpt->m_mutex);
1759 return (DDI_SUCCESS);
1760 }
1761
1762 /* Disable HBA interrupts in hardware */
1763 MPTSAS_DISABLE_INTR(mpt);
1764 /*
1765 * Send RAID action system shutdown to sync IR
1766 */
1767 mptsas_raid_action_system_shutdown(mpt);
1768
1769 mutex_exit(&mpt->m_mutex);
1770
1771 /* drain the taskq */
1772 ddi_taskq_wait(mpt->m_event_taskq);
1773 ddi_taskq_wait(mpt->m_dr_taskq);
1774
1775 return (DDI_SUCCESS);
1776 }
1777
1778 #ifdef __sparc
1779 /*ARGSUSED*/
1780 static int
1781 mptsas_reset(dev_info_t *devi, ddi_reset_cmd_t cmd)
1782 {
1783 mptsas_t *mpt;
1784 scsi_hba_tran_t *tran;
1785
1786 /*
1787 * If this call is for iport, just return.
1788 */
1789 if (scsi_hba_iport_unit_address(devi))
1790 return (DDI_SUCCESS);
1791
1792 if ((tran = ddi_get_driver_private(devi)) == NULL)
1793 return (DDI_SUCCESS);
1794
1795 if ((mpt = TRAN2MPT(tran)) == NULL)
1796 return (DDI_SUCCESS);
1797
1798 /*
1799 * Send RAID action system shutdown to sync IR. Disable HBA
1800 * interrupts in hardware first.
1801 */
1802 MPTSAS_DISABLE_INTR(mpt);
1803 mptsas_raid_action_system_shutdown(mpt);
1804
1805 return (DDI_SUCCESS);
1806 }
1807 #else /* __sparc */
1808 /*
1809 * quiesce(9E) entry point.
1810 *
1811 * This function is called when the system is single-threaded at high
1812 * PIL with preemption disabled. Therefore, this function must not be
1813 * blocked.
1814 *
1815 * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
1816 * DDI_FAILURE indicates an error condition and should almost never happen.
1817 */
1818 static int
1819 mptsas_quiesce(dev_info_t *devi)
1820 {
1821 mptsas_t *mpt;
1822 scsi_hba_tran_t *tran;
1823
1824 /*
1825 * If this call is for iport, just return.
1826 */
1827 if (scsi_hba_iport_unit_address(devi))
1828 return (DDI_SUCCESS);
1829
1830 if ((tran = ddi_get_driver_private(devi)) == NULL)
1831 return (DDI_SUCCESS);
1832
1833 if ((mpt = TRAN2MPT(tran)) == NULL)
1834 return (DDI_SUCCESS);
1835
1836 /* Disable HBA interrupts in hardware */
1837 MPTSAS_DISABLE_INTR(mpt);
1838 /* Send RAID action system shutdonw to sync IR */
1839 mptsas_raid_action_system_shutdown(mpt);
1840
1841 return (DDI_SUCCESS);
1842 }
1843 #endif /* __sparc */
1844
1845 /*
1846 * detach(9E). Remove all device allocations and system resources;
1847 * disable device interrupts.
1848 * Return DDI_SUCCESS if done; DDI_FAILURE if there's a problem.
1849 */
1850 static int
1851 mptsas_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
1852 {
1853 /* CONSTCOND */
1854 ASSERT(NO_COMPETING_THREADS);
1855 NDBG0(("mptsas_detach: dip=0x%p cmd=0x%p", (void *)devi, (void *)cmd));
1856
1857 switch (cmd) {
1858 case DDI_DETACH:
1859 return (mptsas_do_detach(devi));
1860
1861 case DDI_SUSPEND:
1862 return (mptsas_suspend(devi));
1863
1864 default:
1865 return (DDI_FAILURE);
1866 }
1867 /* NOTREACHED */
1868 }
1869
1870 static int
1871 mptsas_do_detach(dev_info_t *dip)
1872 {
1873 mptsas_t *mpt;
1874 scsi_hba_tran_t *tran;
1875 int circ = 0;
1876 int circ1 = 0;
1877 mdi_pathinfo_t *pip = NULL;
1878 int i;
1879 int doneq_thread_num = 0;
1880
1881 NDBG0(("mptsas_do_detach: dip=0x%p", (void *)dip));
1882
1883 if ((tran = ndi_flavorv_get(dip, SCSA_FLAVOR_SCSI_DEVICE)) == NULL)
1884 return (DDI_FAILURE);
1885
1886 mpt = TRAN2MPT(tran);
1887 if (!mpt) {
1888 return (DDI_FAILURE);
1889 }
1890 /*
1891 * Still have pathinfo child, should not detach mpt driver
1892 */
1893 if (scsi_hba_iport_unit_address(dip)) {
1894 if (mpt->m_mpxio_enable) {
1895 /*
1896 * MPxIO enabled for the iport
1897 */
1898 ndi_devi_enter(scsi_vhci_dip, &circ1);
1899 ndi_devi_enter(dip, &circ);
1900 while (pip = mdi_get_next_client_path(dip, NULL)) {
1901 if (mdi_pi_free(pip, 0) == MDI_SUCCESS) {
1902 continue;
1903 }
1904 ndi_devi_exit(dip, circ);
1905 ndi_devi_exit(scsi_vhci_dip, circ1);
1906 NDBG12(("detach failed because of "
1907 "outstanding path info"));
1908 return (DDI_FAILURE);
1909 }
1910 ndi_devi_exit(dip, circ);
1911 ndi_devi_exit(scsi_vhci_dip, circ1);
1912 (void) mdi_phci_unregister(dip, 0);
1913 }
1914
1915 ddi_prop_remove_all(dip);
1916
1917 return (DDI_SUCCESS);
1918 }
1919
1920 /* Make sure power level is D0 before accessing registers */
1921 if (mpt->m_options & MPTSAS_OPT_PM) {
1922 (void) pm_busy_component(dip, 0);
1923 if (mpt->m_power_level != PM_LEVEL_D0) {
1924 if (pm_raise_power(dip, 0, PM_LEVEL_D0) !=
1925 DDI_SUCCESS) {
1926 mptsas_log(mpt, CE_WARN,
1927 "mptsas%d: Raise power request failed.",
1928 mpt->m_instance);
1929 (void) pm_idle_component(dip, 0);
1930 return (DDI_FAILURE);
1931 }
1932 }
1933 }
1934
1935 /*
1936 * Send RAID action system shutdown to sync IR. After action, send a
1937 * Message Unit Reset. Since after that DMA resource will be freed,
1938 * set ioc to READY state will avoid HBA initiated DMA operation.
1939 */
1940 mutex_enter(&mpt->m_mutex);
1941 MPTSAS_DISABLE_INTR(mpt);
1942 mptsas_raid_action_system_shutdown(mpt);
1943 mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET;
1944 (void) mptsas_ioc_reset(mpt, FALSE);
1945 mutex_exit(&mpt->m_mutex);
1946 mptsas_rem_intrs(mpt);
1947 ddi_taskq_destroy(mpt->m_event_taskq);
1948 ddi_taskq_destroy(mpt->m_dr_taskq);
1949
1950 if (mpt->m_doneq_thread_n) {
1951 mutex_enter(&mpt->m_doneq_mutex);
1952 doneq_thread_num = mpt->m_doneq_thread_n;
1953 for (i = 0; i < mpt->m_doneq_thread_n; i++) {
1954 mutex_enter(&mpt->m_doneq_thread_id[i].mutex);
1955 mpt->m_doneq_thread_id[i].flag &=
1956 (~MPTSAS_DONEQ_THREAD_ACTIVE);
1957 cv_signal(&mpt->m_doneq_thread_id[i].cv);
1958 mutex_exit(&mpt->m_doneq_thread_id[i].mutex);
1959 }
1960 while (mpt->m_doneq_thread_n) {
1961 cv_wait(&mpt->m_doneq_thread_cv,
1962 &mpt->m_doneq_mutex);
1963 }
1964 for (i = 0; i < doneq_thread_num; i++) {
1965 cv_destroy(&mpt->m_doneq_thread_id[i].cv);
1966 mutex_destroy(&mpt->m_doneq_thread_id[i].mutex);
1967 }
1968 kmem_free(mpt->m_doneq_thread_id,
1969 sizeof (mptsas_doneq_thread_list_t)
1970 * doneq_thread_num);
1971 mutex_exit(&mpt->m_doneq_mutex);
1972 cv_destroy(&mpt->m_doneq_thread_cv);
1973 mutex_destroy(&mpt->m_doneq_mutex);
1974 }
1975
1976 scsi_hba_reset_notify_tear_down(mpt->m_reset_notify_listf);
1977
1978 mptsas_list_del(mpt);
1979
1980 /*
1981 * Cancel timeout threads for this mpt
1982 */
1983 mutex_enter(&mpt->m_mutex);
1984 if (mpt->m_quiesce_timeid) {
1985 timeout_id_t tid = mpt->m_quiesce_timeid;
1986 mpt->m_quiesce_timeid = 0;
1987 mutex_exit(&mpt->m_mutex);
1988 (void) untimeout(tid);
1989 mutex_enter(&mpt->m_mutex);
1990 }
1991
1992 if (mpt->m_restart_cmd_timeid) {
1993 timeout_id_t tid = mpt->m_restart_cmd_timeid;
1994 mpt->m_restart_cmd_timeid = 0;
1995 mutex_exit(&mpt->m_mutex);
1996 (void) untimeout(tid);
1997 mutex_enter(&mpt->m_mutex);
1998 }
1999
2000 mutex_exit(&mpt->m_mutex);
2001
2002 /*
2003 * last mpt? ... if active, CANCEL watch threads.
2004 */
2005 mutex_enter(&mptsas_global_mutex);
2006 if (mptsas_head == NULL) {
2007 timeout_id_t tid;
2008 /*
2009 * Clear mptsas_timeouts_enable so that the watch thread
2010 * gets restarted on DDI_ATTACH
2011 */
2012 mptsas_timeouts_enabled = 0;
2013 if (mptsas_timeout_id) {
2014 tid = mptsas_timeout_id;
2015 mptsas_timeout_id = 0;
2016 mutex_exit(&mptsas_global_mutex);
2017 (void) untimeout(tid);
2018 mutex_enter(&mptsas_global_mutex);
2019 }
2020 if (mptsas_reset_watch) {
2021 tid = mptsas_reset_watch;
2022 mptsas_reset_watch = 0;
2023 mutex_exit(&mptsas_global_mutex);
2024 (void) untimeout(tid);
2025 mutex_enter(&mptsas_global_mutex);
2026 }
2027 }
2028 mutex_exit(&mptsas_global_mutex);
2029
2030 /*
2031 * Delete Phy stats
2032 */
2033 mptsas_destroy_phy_stats(mpt);
2034
2035 mptsas_destroy_hashes(mpt);
2036
2037 /*
2038 * Delete nt_active.
2039 */
2040 mutex_enter(&mpt->m_mutex);
2041 mptsas_free_active_slots(mpt);
2042 mutex_exit(&mpt->m_mutex);
2043
2044 /* deallocate everything that was allocated in mptsas_attach */
2045 mptsas_cache_destroy(mpt);
2046
2047 mptsas_hba_fini(mpt);
2048 mptsas_cfg_fini(mpt);
2049
2050 /* Lower the power informing PM Framework */
2051 if (mpt->m_options & MPTSAS_OPT_PM) {
2052 if (pm_lower_power(dip, 0, PM_LEVEL_D3) != DDI_SUCCESS)
2053 mptsas_log(mpt, CE_WARN,
2054 "!mptsas%d: Lower power request failed "
2055 "during detach, ignoring.",
2056 mpt->m_instance);
2057 }
2058
2059 mutex_destroy(&mpt->m_tx_waitq_mutex);
2060 mutex_destroy(&mpt->m_passthru_mutex);
2061 mutex_destroy(&mpt->m_mutex);
2062 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
2063 mutex_destroy(&mpt->m_phy_info[i].smhba_info.phy_mutex);
2064 }
2065 cv_destroy(&mpt->m_cv);
2066 cv_destroy(&mpt->m_passthru_cv);
2067 cv_destroy(&mpt->m_fw_cv);
2068 cv_destroy(&mpt->m_config_cv);
2069 cv_destroy(&mpt->m_fw_diag_cv);
2070 cv_destroy(&mpt->m_extreq_sense_refcount_cv);
2071
2072 mptsas_smp_teardown(mpt);
2073 mptsas_enc_teardown(mpt);
2074 mptsas_hba_teardown(mpt);
2075
2076 mptsas_config_space_fini(mpt);
2077
2078 mptsas_free_handshake_msg(mpt);
2079
2080 mptsas_fm_fini(mpt);
2081 ddi_soft_state_free(mptsas_state, ddi_get_instance(dip));
2082 ddi_prop_remove_all(dip);
2083
2084 return (DDI_SUCCESS);
2085 }
2086
2087 static void
2088 mptsas_list_add(mptsas_t *mpt)
2089 {
2090 rw_enter(&mptsas_global_rwlock, RW_WRITER);
2091
2092 if (mptsas_head == NULL) {
2093 mptsas_head = mpt;
2094 } else {
2095 mptsas_tail->m_next = mpt;
2096 }
2097 mptsas_tail = mpt;
2098 rw_exit(&mptsas_global_rwlock);
2099 }
2100
2101 static void
2102 mptsas_list_del(mptsas_t *mpt)
2103 {
2104 mptsas_t *m;
2105 /*
2106 * Remove device instance from the global linked list
2107 */
2108 rw_enter(&mptsas_global_rwlock, RW_WRITER);
2109 if (mptsas_head == mpt) {
2110 m = mptsas_head = mpt->m_next;
2111 } else {
2112 for (m = mptsas_head; m != NULL; m = m->m_next) {
2113 if (m->m_next == mpt) {
2114 m->m_next = mpt->m_next;
2115 break;
2116 }
2117 }
2118 if (m == NULL) {
2119 mptsas_log(mpt, CE_PANIC, "Not in softc list!");
2120 }
2121 }
2122
2123 if (mptsas_tail == mpt) {
2124 mptsas_tail = m;
2125 }
2126 rw_exit(&mptsas_global_rwlock);
2127 }
2128
2129 static int
2130 mptsas_alloc_handshake_msg(mptsas_t *mpt, size_t alloc_size)
2131 {
2132 ddi_dma_attr_t task_dma_attrs;
2133
2134 mpt->m_hshk_dma_size = 0;
2135 task_dma_attrs = mpt->m_msg_dma_attr;
2136 task_dma_attrs.dma_attr_sgllen = 1;
2137 task_dma_attrs.dma_attr_granular = (uint32_t)(alloc_size);
2138
2139 /* allocate Task Management ddi_dma resources */
2140 if (mptsas_dma_addr_create(mpt, task_dma_attrs,
2141 &mpt->m_hshk_dma_hdl, &mpt->m_hshk_acc_hdl, &mpt->m_hshk_memp,
2142 alloc_size, NULL) == FALSE) {
2143 return (DDI_FAILURE);
2144 }
2145 mpt->m_hshk_dma_size = alloc_size;
2146
2147 return (DDI_SUCCESS);
2148 }
2149
2150 static void
2151 mptsas_free_handshake_msg(mptsas_t *mpt)
2152 {
2153 if (mpt->m_hshk_dma_size == 0)
2154 return;
2155 mptsas_dma_addr_destroy(&mpt->m_hshk_dma_hdl, &mpt->m_hshk_acc_hdl);
2156 mpt->m_hshk_dma_size = 0;
2157 }
2158
2159 static int
2160 mptsas_hba_setup(mptsas_t *mpt)
2161 {
2162 scsi_hba_tran_t *hba_tran;
2163 int tran_flags;
2164
2165 /* Allocate a transport structure */
2166 hba_tran = mpt->m_tran = scsi_hba_tran_alloc(mpt->m_dip,
2167 SCSI_HBA_CANSLEEP);
2168 ASSERT(mpt->m_tran != NULL);
2169
2170 hba_tran->tran_hba_private = mpt;
2171 hba_tran->tran_tgt_private = NULL;
2172
2173 hba_tran->tran_tgt_init = mptsas_scsi_tgt_init;
2174 hba_tran->tran_tgt_free = mptsas_scsi_tgt_free;
2175
2176 hba_tran->tran_start = mptsas_scsi_start;
2177 hba_tran->tran_reset = mptsas_scsi_reset;
2178 hba_tran->tran_abort = mptsas_scsi_abort;
2179 hba_tran->tran_getcap = mptsas_scsi_getcap;
2180 hba_tran->tran_setcap = mptsas_scsi_setcap;
2181 hba_tran->tran_init_pkt = mptsas_scsi_init_pkt;
2182 hba_tran->tran_destroy_pkt = mptsas_scsi_destroy_pkt;
2183
2184 hba_tran->tran_dmafree = mptsas_scsi_dmafree;
2185 hba_tran->tran_sync_pkt = mptsas_scsi_sync_pkt;
2186 hba_tran->tran_reset_notify = mptsas_scsi_reset_notify;
2187
2188 hba_tran->tran_get_bus_addr = mptsas_get_bus_addr;
2189 hba_tran->tran_get_name = mptsas_get_name;
2190
2191 hba_tran->tran_quiesce = mptsas_scsi_quiesce;
2192 hba_tran->tran_unquiesce = mptsas_scsi_unquiesce;
2193 hba_tran->tran_bus_reset = NULL;
2194
2195 hba_tran->tran_add_eventcall = NULL;
2196 hba_tran->tran_get_eventcookie = NULL;
2197 hba_tran->tran_post_event = NULL;
2198 hba_tran->tran_remove_eventcall = NULL;
2199
2200 hba_tran->tran_bus_config = mptsas_bus_config;
2201
2202 hba_tran->tran_interconnect_type = INTERCONNECT_SAS;
2203
2204 /*
2205 * All children of the HBA are iports. We need tran was cloned.
2206 * So we pass the flags to SCSA. SCSI_HBA_TRAN_CLONE will be
2207 * inherited to iport's tran vector.
2208 */
2209 tran_flags = (SCSI_HBA_HBA | SCSI_HBA_TRAN_CLONE);
2210
2211 if (scsi_hba_attach_setup(mpt->m_dip, &mpt->m_msg_dma_attr,
2212 hba_tran, tran_flags) != DDI_SUCCESS) {
2213 mptsas_log(mpt, CE_WARN, "hba attach setup failed");
2214 scsi_hba_tran_free(hba_tran);
2215 mpt->m_tran = NULL;
2216 return (FALSE);
2217 }
2218 return (TRUE);
2219 }
2220
2221 static void
2222 mptsas_hba_teardown(mptsas_t *mpt)
2223 {
2224 (void) scsi_hba_detach(mpt->m_dip);
2225 if (mpt->m_tran != NULL) {
2226 scsi_hba_tran_free(mpt->m_tran);
2227 mpt->m_tran = NULL;
2228 }
2229 }
2230
2231 static void
2232 mptsas_iport_register(mptsas_t *mpt)
2233 {
2234 int i, j;
2235 mptsas_phymask_t mask = 0x0;
2236 /*
2237 * initial value of mask is 0
2238 */
2239 mutex_enter(&mpt->m_mutex);
2240 for (i = 0; i < mpt->m_num_phys; i++) {
2241 mptsas_phymask_t phy_mask = 0x0;
2242 char phy_mask_name[MPTSAS_MAX_PHYS];
2243 uint8_t current_port;
2244
2245 if (mpt->m_phy_info[i].attached_devhdl == 0)
2246 continue;
2247
2248 bzero(phy_mask_name, sizeof (phy_mask_name));
2249
2250 current_port = mpt->m_phy_info[i].port_num;
2251
2252 if ((mask & (1 << i)) != 0)
2253 continue;
2254
2255 for (j = 0; j < mpt->m_num_phys; j++) {
2256 if (mpt->m_phy_info[j].attached_devhdl &&
2257 (mpt->m_phy_info[j].port_num == current_port)) {
2258 phy_mask |= (1 << j);
2259 }
2260 }
2261 mask = mask | phy_mask;
2262
2263 for (j = 0; j < mpt->m_num_phys; j++) {
2264 if ((phy_mask >> j) & 0x01) {
2265 mpt->m_phy_info[j].phy_mask = phy_mask;
2266 }
2267 }
2268
2269 (void) sprintf(phy_mask_name, "%x", phy_mask);
2270
2271 mutex_exit(&mpt->m_mutex);
2272 /*
2273 * register a iport
2274 */
2275 (void) scsi_hba_iport_register(mpt->m_dip, phy_mask_name);
2276 mutex_enter(&mpt->m_mutex);
2277 }
2278 mutex_exit(&mpt->m_mutex);
2279 /*
2280 * register a virtual port for RAID volume always
2281 */
2282 (void) scsi_hba_iport_register(mpt->m_dip, "v0");
2283
2284 }
2285
2286 static int
2287 mptsas_smp_setup(mptsas_t *mpt)
2288 {
2289 mpt->m_smptran = smp_hba_tran_alloc(mpt->m_dip);
2290 ASSERT(mpt->m_smptran != NULL);
2291 mpt->m_smptran->smp_tran_hba_private = mpt;
2292 mpt->m_smptran->smp_tran_start = mptsas_smp_start;
2293 if (smp_hba_attach_setup(mpt->m_dip, mpt->m_smptran) != DDI_SUCCESS) {
2294 mptsas_log(mpt, CE_WARN, "smp attach setup failed");
2295 smp_hba_tran_free(mpt->m_smptran);
2296 mpt->m_smptran = NULL;
2297 return (FALSE);
2298 }
2299 /*
2300 * Initialize smp hash table
2301 */
2302 mpt->m_smp_targets = refhash_create(MPTSAS_SMP_BUCKET_COUNT,
2303 mptsas_target_addr_hash, mptsas_target_addr_cmp,
2304 mptsas_smp_free, sizeof (mptsas_smp_t),
2305 offsetof(mptsas_smp_t, m_link), offsetof(mptsas_smp_t, m_addr),
2306 KM_SLEEP);
2307 mpt->m_smp_devhdl = 0xFFFF;
2308
2309 return (TRUE);
2310 }
2311
2312 static void
2313 mptsas_smp_teardown(mptsas_t *mpt)
2314 {
2315 (void) smp_hba_detach(mpt->m_dip);
2316 if (mpt->m_smptran != NULL) {
2317 smp_hba_tran_free(mpt->m_smptran);
2318 mpt->m_smptran = NULL;
2319 }
2320 mpt->m_smp_devhdl = 0;
2321 }
2322
2323 static int
2324 mptsas_enc_setup(mptsas_t *mpt)
2325 {
2326 list_create(&mpt->m_enclosures, sizeof (mptsas_enclosure_t),
2327 offsetof(mptsas_enclosure_t, me_link));
2328 return (TRUE);
2329 }
2330
2331 static void
2332 mptsas_enc_teardown(mptsas_t *mpt)
2333 {
2334 mptsas_enclosure_t *mep;
2335
2336 while ((mep = list_remove_head(&mpt->m_enclosures)) != NULL) {
2337 kmem_free(mep, sizeof (mptsas_enclosure_t));
2338 }
2339 list_destroy(&mpt->m_enclosures);
2340 }
2341
2342 static mptsas_enclosure_t *
2343 mptsas_enc_lookup(mptsas_t *mpt, uint16_t hdl)
2344 {
2345 mptsas_enclosure_t *mep;
2346
2347 ASSERT(MUTEX_HELD(&mpt->m_mutex));
2348
2349 for (mep = list_head(&mpt->m_enclosures); mep != NULL;
2350 mep = list_next(&mpt->m_enclosures, mep)) {
2351 if (hdl == mep->me_enchdl) {
2352 return (mep);
2353 }
2354 }
2355
2356 return (NULL);
2357 }
2358
2359 static int
2360 mptsas_cache_create(mptsas_t *mpt)
2361 {
2362 int instance = mpt->m_instance;
2363 char buf[64];
2364
2365 /*
2366 * create kmem cache for packets
2367 */
2368 (void) sprintf(buf, "mptsas%d_cache", instance);
2369 mpt->m_kmem_cache = kmem_cache_create(buf,
2370 sizeof (struct mptsas_cmd) + scsi_pkt_size(), 8,
2371 mptsas_kmem_cache_constructor, mptsas_kmem_cache_destructor,
2372 NULL, (void *)mpt, NULL, 0);
2373
2374 if (mpt->m_kmem_cache == NULL) {
2375 mptsas_log(mpt, CE_WARN, "creating kmem cache failed");
2376 return (FALSE);
2377 }
2378
2379 /*
2380 * create kmem cache for extra SGL frames if SGL cannot
2381 * be accomodated into main request frame.
2382 */
2383 (void) sprintf(buf, "mptsas%d_cache_frames", instance);
2384 mpt->m_cache_frames = kmem_cache_create(buf,
2385 sizeof (mptsas_cache_frames_t), 8,
2386 mptsas_cache_frames_constructor, mptsas_cache_frames_destructor,
2387 NULL, (void *)mpt, NULL, 0);
2388
2389 if (mpt->m_cache_frames == NULL) {
2390 mptsas_log(mpt, CE_WARN, "creating cache for frames failed");
2391 return (FALSE);
2392 }
2393
2394 return (TRUE);
2395 }
2396
2397 static void
2398 mptsas_cache_destroy(mptsas_t *mpt)
2399 {
2400 /* deallocate in reverse order */
2401 if (mpt->m_cache_frames) {
2402 kmem_cache_destroy(mpt->m_cache_frames);
2403 mpt->m_cache_frames = NULL;
2404 }
2405 if (mpt->m_kmem_cache) {
2406 kmem_cache_destroy(mpt->m_kmem_cache);
2407 mpt->m_kmem_cache = NULL;
2408 }
2409 }
2410
2411 static int
2412 mptsas_power(dev_info_t *dip, int component, int level)
2413 {
2414 #ifndef __lock_lint
2415 _NOTE(ARGUNUSED(component))
2416 #endif
2417 mptsas_t *mpt;
2418 int rval = DDI_SUCCESS;
2419 int polls = 0;
2420 uint32_t ioc_status;
2421
2422 if (scsi_hba_iport_unit_address(dip) != 0)
2423 return (DDI_SUCCESS);
2424
2425 mpt = ddi_get_soft_state(mptsas_state, ddi_get_instance(dip));
2426 if (mpt == NULL) {
2427 return (DDI_FAILURE);
2428 }
2429
2430 mutex_enter(&mpt->m_mutex);
2431
2432 /*
2433 * If the device is busy, don't lower its power level
2434 */
2435 if (mpt->m_busy && (mpt->m_power_level > level)) {
2436 mutex_exit(&mpt->m_mutex);
2437 return (DDI_FAILURE);
2438 }
2439 switch (level) {
2440 case PM_LEVEL_D0:
2441 NDBG11(("mptsas%d: turning power ON.", mpt->m_instance));
2442 MPTSAS_POWER_ON(mpt);
2443 /*
2444 * Wait up to 30 seconds for IOC to come out of reset.
2445 */
2446 while (((ioc_status = ddi_get32(mpt->m_datap,
2447 &mpt->m_reg->Doorbell)) &
2448 MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_RESET) {
2449 if (polls++ > 3000) {
2450 break;
2451 }
2452 delay(drv_usectohz(10000));
2453 }
2454 /*
2455 * If IOC is not in operational state, try to hard reset it.
2456 */
2457 if ((ioc_status & MPI2_IOC_STATE_MASK) !=
2458 MPI2_IOC_STATE_OPERATIONAL) {
2459 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET;
2460 if (mptsas_restart_ioc(mpt) == DDI_FAILURE) {
2461 mptsas_log(mpt, CE_WARN,
2462 "mptsas_power: hard reset failed");
2463 mutex_exit(&mpt->m_mutex);
2464 return (DDI_FAILURE);
2465 }
2466 }
2467 mpt->m_power_level = PM_LEVEL_D0;
2468 break;
2469 case PM_LEVEL_D3:
2470 NDBG11(("mptsas%d: turning power OFF.", mpt->m_instance));
2471 MPTSAS_POWER_OFF(mpt);
2472 break;
2473 default:
2474 mptsas_log(mpt, CE_WARN, "mptsas%d: unknown power level <%x>.",
2475 mpt->m_instance, level);
2476 rval = DDI_FAILURE;
2477 break;
2478 }
2479 mutex_exit(&mpt->m_mutex);
2480 return (rval);
2481 }
2482
2483 /*
2484 * Initialize configuration space and figure out which
2485 * chip and revison of the chip the mpt driver is using.
2486 */
2487 static int
2488 mptsas_config_space_init(mptsas_t *mpt)
2489 {
2490 NDBG0(("mptsas_config_space_init"));
2491
2492 if (mpt->m_config_handle != NULL)
2493 return (TRUE);
2494
2495 if (pci_config_setup(mpt->m_dip,
2496 &mpt->m_config_handle) != DDI_SUCCESS) {
2497 mptsas_log(mpt, CE_WARN, "cannot map configuration space.");
2498 return (FALSE);
2499 }
2500
2501 /*
2502 * This is a workaround for a XMITS ASIC bug which does not
2503 * drive the CBE upper bits.
2504 */
2505 if (pci_config_get16(mpt->m_config_handle, PCI_CONF_STAT) &
2506 PCI_STAT_PERROR) {
2507 pci_config_put16(mpt->m_config_handle, PCI_CONF_STAT,
2508 PCI_STAT_PERROR);
2509 }
2510
2511 mptsas_setup_cmd_reg(mpt);
2512
2513 /*
2514 * Get the chip device id:
2515 */
2516 mpt->m_devid = pci_config_get16(mpt->m_config_handle, PCI_CONF_DEVID);
2517
2518 /*
2519 * Save the revision.
2520 */
2521 mpt->m_revid = pci_config_get8(mpt->m_config_handle, PCI_CONF_REVID);
2522
2523 /*
2524 * Save the SubSystem Vendor and Device IDs
2525 */
2526 mpt->m_svid = pci_config_get16(mpt->m_config_handle, PCI_CONF_SUBVENID);
2527 mpt->m_ssid = pci_config_get16(mpt->m_config_handle, PCI_CONF_SUBSYSID);
2528
2529 /*
2530 * Set the latency timer to 0x40 as specified by the upa -> pci
2531 * bridge chip design team. This may be done by the sparc pci
2532 * bus nexus driver, but the driver should make sure the latency
2533 * timer is correct for performance reasons.
2534 */
2535 pci_config_put8(mpt->m_config_handle, PCI_CONF_LATENCY_TIMER,
2536 MPTSAS_LATENCY_TIMER);
2537
2538 (void) mptsas_get_pci_cap(mpt);
2539 return (TRUE);
2540 }
2541
2542 static void
2543 mptsas_config_space_fini(mptsas_t *mpt)
2544 {
2545 if (mpt->m_config_handle != NULL) {
2546 mptsas_disable_bus_master(mpt);
2547 pci_config_teardown(&mpt->m_config_handle);
2548 mpt->m_config_handle = NULL;
2549 }
2550 }
2551
2552 static void
2553 mptsas_setup_cmd_reg(mptsas_t *mpt)
2554 {
2555 ushort_t cmdreg;
2556
2557 /*
2558 * Set the command register to the needed values.
2559 */
2560 cmdreg = pci_config_get16(mpt->m_config_handle, PCI_CONF_COMM);
2561 cmdreg |= (PCI_COMM_ME | PCI_COMM_SERR_ENABLE |
2562 PCI_COMM_PARITY_DETECT | PCI_COMM_MAE);
2563 cmdreg &= ~PCI_COMM_IO;
2564 pci_config_put16(mpt->m_config_handle, PCI_CONF_COMM, cmdreg);
2565 }
2566
2567 static void
2568 mptsas_disable_bus_master(mptsas_t *mpt)
2569 {
2570 ushort_t cmdreg;
2571
2572 /*
2573 * Clear the master enable bit in the PCI command register.
2574 * This prevents any bus mastering activity like DMA.
2575 */
2576 cmdreg = pci_config_get16(mpt->m_config_handle, PCI_CONF_COMM);
2577 cmdreg &= ~PCI_COMM_ME;
2578 pci_config_put16(mpt->m_config_handle, PCI_CONF_COMM, cmdreg);
2579 }
2580
2581 int
2582 mptsas_dma_alloc(mptsas_t *mpt, mptsas_dma_alloc_state_t *dma_statep)
2583 {
2584 ddi_dma_attr_t attrs;
2585
2586 attrs = mpt->m_io_dma_attr;
2587 attrs.dma_attr_sgllen = 1;
2588
2589 ASSERT(dma_statep != NULL);
2590
2591 if (mptsas_dma_addr_create(mpt, attrs, &dma_statep->handle,
2592 &dma_statep->accessp, &dma_statep->memp, dma_statep->size,
2593 &dma_statep->cookie) == FALSE) {
2594 return (DDI_FAILURE);
2595 }
2596
2597 return (DDI_SUCCESS);
2598 }
2599
2600 void
2601 mptsas_dma_free(mptsas_dma_alloc_state_t *dma_statep)
2602 {
2603 ASSERT(dma_statep != NULL);
2604 mptsas_dma_addr_destroy(&dma_statep->handle, &dma_statep->accessp);
2605 dma_statep->size = 0;
2606 }
2607
2608 int
2609 mptsas_do_dma(mptsas_t *mpt, uint32_t size, int var, int (*callback)())
2610 {
2611 ddi_dma_attr_t attrs;
2612 ddi_dma_handle_t dma_handle;
2613 caddr_t memp;
2614 ddi_acc_handle_t accessp;
2615 int rval;
2616
2617 ASSERT(mutex_owned(&mpt->m_mutex));
2618
2619 attrs = mpt->m_msg_dma_attr;
2620 attrs.dma_attr_sgllen = 1;
2621 attrs.dma_attr_granular = size;
2622
2623 if (mptsas_dma_addr_create(mpt, attrs, &dma_handle,
2624 &accessp, &memp, size, NULL) == FALSE) {
2625 return (DDI_FAILURE);
2626 }
2627
2628 rval = (*callback) (mpt, memp, var, accessp);
2629
2630 if ((mptsas_check_dma_handle(dma_handle) != DDI_SUCCESS) ||
2631 (mptsas_check_acc_handle(accessp) != DDI_SUCCESS)) {
2632 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
2633 rval = DDI_FAILURE;
2634 }
2635
2636 mptsas_dma_addr_destroy(&dma_handle, &accessp);
2637 return (rval);
2638
2639 }
2640
2641 static int
2642 mptsas_alloc_request_frames(mptsas_t *mpt)
2643 {
2644 ddi_dma_attr_t frame_dma_attrs;
2645 caddr_t memp;
2646 ddi_dma_cookie_t cookie;
2647 size_t mem_size;
2648
2649 /*
2650 * re-alloc when it has already alloced
2651 */
2652 if (mpt->m_dma_req_frame_hdl)
2653 mptsas_dma_addr_destroy(&mpt->m_dma_req_frame_hdl,
2654 &mpt->m_acc_req_frame_hdl);
2655
2656 /*
2657 * The size of the request frame pool is:
2658 * Number of Request Frames * Request Frame Size
2659 */
2660 mem_size = mpt->m_max_requests * mpt->m_req_frame_size;
2661
2662 /*
2663 * set the DMA attributes. System Request Message Frames must be
2664 * aligned on a 16-byte boundry.
2665 */
2666 frame_dma_attrs = mpt->m_msg_dma_attr;
2667 frame_dma_attrs.dma_attr_align = 16;
2668 frame_dma_attrs.dma_attr_sgllen = 1;
2669
2670 /*
2671 * allocate the request frame pool.
2672 */
2673 if (mptsas_dma_addr_create(mpt, frame_dma_attrs,
2674 &mpt->m_dma_req_frame_hdl, &mpt->m_acc_req_frame_hdl, &memp,
2675 mem_size, &cookie) == FALSE) {
2676 return (DDI_FAILURE);
2677 }
2678
2679 /*
2680 * Store the request frame memory address. This chip uses this
2681 * address to dma to and from the driver's frame. The second
2682 * address is the address mpt uses to fill in the frame.
2683 */
2684 mpt->m_req_frame_dma_addr = cookie.dmac_laddress;
2685 mpt->m_req_frame = memp;
2686
2687 /*
2688 * Clear the request frame pool.
2689 */
2690 bzero(mpt->m_req_frame, mem_size);
2691
2692 return (DDI_SUCCESS);
2693 }
2694
2695 static int
2696 mptsas_alloc_sense_bufs(mptsas_t *mpt)
2697 {
2698 ddi_dma_attr_t sense_dma_attrs;
2699 caddr_t memp;
2700 ddi_dma_cookie_t cookie;
2701 size_t mem_size;
2702 int num_extrqsense_bufs;
2703
2704 ASSERT(mpt->m_extreq_sense_refcount == 0);
2705
2706 /*
2707 * re-alloc when it has already alloced
2708 */
2709 if (mpt->m_dma_req_sense_hdl) {
2710 rmfreemap(mpt->m_erqsense_map);
2711 mptsas_dma_addr_destroy(&mpt->m_dma_req_sense_hdl,
2712 &mpt->m_acc_req_sense_hdl);
2713 }
2714
2715 /*
2716 * The size of the request sense pool is:
2717 * (Number of Request Frames - 2 ) * Request Sense Size +
2718 * extra memory for extended sense requests.
2719 */
2720 mem_size = ((mpt->m_max_requests - 2) * mpt->m_req_sense_size) +
2721 mptsas_extreq_sense_bufsize;
2722
2723 /*
2724 * set the DMA attributes. ARQ buffers
2725 * aligned on a 16-byte boundry.
2726 */
2727 sense_dma_attrs = mpt->m_msg_dma_attr;
2728 sense_dma_attrs.dma_attr_align = 16;
2729 sense_dma_attrs.dma_attr_sgllen = 1;
2730
2731 /*
2732 * allocate the request sense buffer pool.
2733 */
2734 if (mptsas_dma_addr_create(mpt, sense_dma_attrs,
2735 &mpt->m_dma_req_sense_hdl, &mpt->m_acc_req_sense_hdl, &memp,
2736 mem_size, &cookie) == FALSE) {
2737 return (DDI_FAILURE);
2738 }
2739
2740 /*
2741 * Store the request sense base memory address. This chip uses this
2742 * address to dma the request sense data. The second
2743 * address is the address mpt uses to access the data.
2744 * The third is the base for the extended rqsense buffers.
2745 */
2746 mpt->m_req_sense_dma_addr = cookie.dmac_laddress;
2747 mpt->m_req_sense = memp;
2748 memp += (mpt->m_max_requests - 2) * mpt->m_req_sense_size;
2749 mpt->m_extreq_sense = memp;
2750
2751 /*
2752 * The extra memory is divided up into multiples of the base
2753 * buffer size in order to allocate via rmalloc().
2754 * Note that the rmallocmap cannot start at zero!
2755 */
2756 num_extrqsense_bufs = mptsas_extreq_sense_bufsize /
2757 mpt->m_req_sense_size;
2758 mpt->m_erqsense_map = rmallocmap_wait(num_extrqsense_bufs);
2759 rmfree(mpt->m_erqsense_map, num_extrqsense_bufs, 1);
2760
2761 /*
2762 * Clear the pool.
2763 */
2764 bzero(mpt->m_req_sense, mem_size);
2765
2766 return (DDI_SUCCESS);
2767 }
2768
2769 static int
2770 mptsas_alloc_reply_frames(mptsas_t *mpt)
2771 {
2772 ddi_dma_attr_t frame_dma_attrs;
2773 caddr_t memp;
2774 ddi_dma_cookie_t cookie;
2775 size_t mem_size;
2776
2777 /*
2778 * re-alloc when it has already alloced
2779 */
2780 if (mpt->m_dma_reply_frame_hdl) {
2781 mptsas_dma_addr_destroy(&mpt->m_dma_reply_frame_hdl,
2782 &mpt->m_acc_reply_frame_hdl);
2783 }
2784
2785 /*
2786 * The size of the reply frame pool is:
2787 * Number of Reply Frames * Reply Frame Size
2788 */
2789 mem_size = mpt->m_max_replies * mpt->m_reply_frame_size;
2790
2791 /*
2792 * set the DMA attributes. System Reply Message Frames must be
2793 * aligned on a 4-byte boundry. This is the default.
2794 */
2795 frame_dma_attrs = mpt->m_msg_dma_attr;
2796 frame_dma_attrs.dma_attr_sgllen = 1;
2797
2798 /*
2799 * allocate the reply frame pool
2800 */
2801 if (mptsas_dma_addr_create(mpt, frame_dma_attrs,
2802 &mpt->m_dma_reply_frame_hdl, &mpt->m_acc_reply_frame_hdl, &memp,
2803 mem_size, &cookie) == FALSE) {
2804 return (DDI_FAILURE);
2805 }
2806
2807 /*
2808 * Store the reply frame memory address. This chip uses this
2809 * address to dma to and from the driver's frame. The second
2810 * address is the address mpt uses to process the frame.
2811 */
2812 mpt->m_reply_frame_dma_addr = cookie.dmac_laddress;
2813 mpt->m_reply_frame = memp;
2814
2815 /*
2816 * Clear the reply frame pool.
2817 */
2818 bzero(mpt->m_reply_frame, mem_size);
2819
2820 return (DDI_SUCCESS);
2821 }
2822
2823 static int
2824 mptsas_alloc_free_queue(mptsas_t *mpt)
2825 {
2826 ddi_dma_attr_t frame_dma_attrs;
2827 caddr_t memp;
2828 ddi_dma_cookie_t cookie;
2829 size_t mem_size;
2830
2831 /*
2832 * re-alloc when it has already alloced
2833 */
2834 if (mpt->m_dma_free_queue_hdl) {
2835 mptsas_dma_addr_destroy(&mpt->m_dma_free_queue_hdl,
2836 &mpt->m_acc_free_queue_hdl);
2837 }
2838
2839 /*
2840 * The reply free queue size is:
2841 * Reply Free Queue Depth * 4
2842 * The "4" is the size of one 32 bit address (low part of 64-bit
2843 * address)
2844 */
2845 mem_size = mpt->m_free_queue_depth * 4;
2846
2847 /*
2848 * set the DMA attributes The Reply Free Queue must be aligned on a
2849 * 16-byte boundry.
2850 */
2851 frame_dma_attrs = mpt->m_msg_dma_attr;
2852 frame_dma_attrs.dma_attr_align = 16;
2853 frame_dma_attrs.dma_attr_sgllen = 1;
2854
2855 /*
2856 * allocate the reply free queue
2857 */
2858 if (mptsas_dma_addr_create(mpt, frame_dma_attrs,
2859 &mpt->m_dma_free_queue_hdl, &mpt->m_acc_free_queue_hdl, &memp,
2860 mem_size, &cookie) == FALSE) {
2861 return (DDI_FAILURE);
2862 }
2863
2864 /*
2865 * Store the reply free queue memory address. This chip uses this
2866 * address to read from the reply free queue. The second address
2867 * is the address mpt uses to manage the queue.
2868 */
2869 mpt->m_free_queue_dma_addr = cookie.dmac_laddress;
2870 mpt->m_free_queue = memp;
2871
2872 /*
2873 * Clear the reply free queue memory.
2874 */
2875 bzero(mpt->m_free_queue, mem_size);
2876
2877 return (DDI_SUCCESS);
2878 }
2879
2880 static int
2881 mptsas_alloc_post_queue(mptsas_t *mpt)
2882 {
2883 ddi_dma_attr_t frame_dma_attrs;
2884 caddr_t memp;
2885 ddi_dma_cookie_t cookie;
2886 size_t mem_size;
2887
2888 /*
2889 * re-alloc when it has already alloced
2890 */
2891 if (mpt->m_dma_post_queue_hdl) {
2892 mptsas_dma_addr_destroy(&mpt->m_dma_post_queue_hdl,
2893 &mpt->m_acc_post_queue_hdl);
2894 }
2895
2896 /*
2897 * The reply descriptor post queue size is:
2898 * Reply Descriptor Post Queue Depth * 8
2899 * The "8" is the size of each descriptor (8 bytes or 64 bits).
2900 */
2901 mem_size = mpt->m_post_queue_depth * 8;
2902
2903 /*
2904 * set the DMA attributes. The Reply Descriptor Post Queue must be
2905 * aligned on a 16-byte boundry.
2906 */
2907 frame_dma_attrs = mpt->m_msg_dma_attr;
2908 frame_dma_attrs.dma_attr_align = 16;
2909 frame_dma_attrs.dma_attr_sgllen = 1;
2910
2911 /*
2912 * allocate the reply post queue
2913 */
2914 if (mptsas_dma_addr_create(mpt, frame_dma_attrs,
2915 &mpt->m_dma_post_queue_hdl, &mpt->m_acc_post_queue_hdl, &memp,
2916 mem_size, &cookie) == FALSE) {
2917 return (DDI_FAILURE);
2918 }
2919
2920 /*
2921 * Store the reply descriptor post queue memory address. This chip
2922 * uses this address to write to the reply descriptor post queue. The
2923 * second address is the address mpt uses to manage the queue.
2924 */
2925 mpt->m_post_queue_dma_addr = cookie.dmac_laddress;
2926 mpt->m_post_queue = memp;
2927
2928 /*
2929 * Clear the reply post queue memory.
2930 */
2931 bzero(mpt->m_post_queue, mem_size);
2932
2933 return (DDI_SUCCESS);
2934 }
2935
2936 static void
2937 mptsas_alloc_reply_args(mptsas_t *mpt)
2938 {
2939 if (mpt->m_replyh_args == NULL) {
2940 mpt->m_replyh_args = kmem_zalloc(sizeof (m_replyh_arg_t) *
2941 mpt->m_max_replies, KM_SLEEP);
2942 }
2943 }
2944
2945 static int
2946 mptsas_alloc_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd)
2947 {
2948 mptsas_cache_frames_t *frames = NULL;
2949 if (cmd->cmd_extra_frames == NULL) {
2950 frames = kmem_cache_alloc(mpt->m_cache_frames, KM_NOSLEEP);
2951 if (frames == NULL) {
2952 return (DDI_FAILURE);
2953 }
2954 cmd->cmd_extra_frames = frames;
2955 }
2956 return (DDI_SUCCESS);
2957 }
2958
2959 static void
2960 mptsas_free_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd)
2961 {
2962 if (cmd->cmd_extra_frames) {
2963 kmem_cache_free(mpt->m_cache_frames,
2964 (void *)cmd->cmd_extra_frames);
2965 cmd->cmd_extra_frames = NULL;
2966 }
2967 }
2968
2969 static void
2970 mptsas_cfg_fini(mptsas_t *mpt)
2971 {
2972 NDBG0(("mptsas_cfg_fini"));
2973 ddi_regs_map_free(&mpt->m_datap);
2974 }
2975
2976 static void
2977 mptsas_hba_fini(mptsas_t *mpt)
2978 {
2979 NDBG0(("mptsas_hba_fini"));
2980
2981 /*
2982 * Free up any allocated memory
2983 */
2984 if (mpt->m_dma_req_frame_hdl) {
2985 mptsas_dma_addr_destroy(&mpt->m_dma_req_frame_hdl,
2986 &mpt->m_acc_req_frame_hdl);
2987 }
2988
2989 if (mpt->m_dma_req_sense_hdl) {
2990 rmfreemap(mpt->m_erqsense_map);
2991 mptsas_dma_addr_destroy(&mpt->m_dma_req_sense_hdl,
2992 &mpt->m_acc_req_sense_hdl);
2993 }
2994
2995 if (mpt->m_dma_reply_frame_hdl) {
2996 mptsas_dma_addr_destroy(&mpt->m_dma_reply_frame_hdl,
2997 &mpt->m_acc_reply_frame_hdl);
2998 }
2999
3000 if (mpt->m_dma_free_queue_hdl) {
3001 mptsas_dma_addr_destroy(&mpt->m_dma_free_queue_hdl,
3002 &mpt->m_acc_free_queue_hdl);
3003 }
3004
3005 if (mpt->m_dma_post_queue_hdl) {
3006 mptsas_dma_addr_destroy(&mpt->m_dma_post_queue_hdl,
3007 &mpt->m_acc_post_queue_hdl);
3008 }
3009
3010 if (mpt->m_replyh_args != NULL) {
3011 kmem_free(mpt->m_replyh_args, sizeof (m_replyh_arg_t)
3012 * mpt->m_max_replies);
3013 }
3014 }
3015
3016 static int
3017 mptsas_name_child(dev_info_t *lun_dip, char *name, int len)
3018 {
3019 int lun = 0;
3020 char *sas_wwn = NULL;
3021 int phynum = -1;
3022 int reallen = 0;
3023
3024 /* Get the target num */
3025 lun = ddi_prop_get_int(DDI_DEV_T_ANY, lun_dip, DDI_PROP_DONTPASS,
3026 LUN_PROP, 0);
3027
3028 if ((phynum = ddi_prop_get_int(DDI_DEV_T_ANY, lun_dip,
3029 DDI_PROP_DONTPASS, "sata-phy", -1)) != -1) {
3030 /*
3031 * Stick in the address of form "pPHY,LUN"
3032 */
3033 reallen = snprintf(name, len, "p%x,%x", phynum, lun);
3034 } else if (ddi_prop_lookup_string(DDI_DEV_T_ANY, lun_dip,
3035 DDI_PROP_DONTPASS, SCSI_ADDR_PROP_TARGET_PORT, &sas_wwn)
3036 == DDI_PROP_SUCCESS) {
3037 /*
3038 * Stick in the address of the form "wWWN,LUN"
3039 */
3040 reallen = snprintf(name, len, "%s,%x", sas_wwn, lun);
3041 ddi_prop_free(sas_wwn);
3042 } else {
3043 return (DDI_FAILURE);
3044 }
3045
3046 ASSERT(reallen < len);
3047 if (reallen >= len) {
3048 mptsas_log(0, CE_WARN, "!mptsas_get_name: name parameter "
3049 "length too small, it needs to be %d bytes", reallen + 1);
3050 }
3051 return (DDI_SUCCESS);
3052 }
3053
3054 /*
3055 * tran_tgt_init(9E) - target device instance initialization
3056 */
3057 static int
3058 mptsas_scsi_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
3059 scsi_hba_tran_t *hba_tran, struct scsi_device *sd)
3060 {
3061 #ifndef __lock_lint
3062 _NOTE(ARGUNUSED(hba_tran))
3063 #endif
3064
3065 /*
3066 * At this point, the scsi_device structure already exists
3067 * and has been initialized.
3068 *
3069 * Use this function to allocate target-private data structures,
3070 * if needed by this HBA. Add revised flow-control and queue
3071 * properties for child here, if desired and if you can tell they
3072 * support tagged queueing by now.
3073 */
3074 mptsas_t *mpt;
3075 int lun = sd->sd_address.a_lun;
3076 mdi_pathinfo_t *pip = NULL;
3077 mptsas_tgt_private_t *tgt_private = NULL;
3078 mptsas_target_t *ptgt = NULL;
3079 char *psas_wwn = NULL;
3080 mptsas_phymask_t phymask = 0;
3081 uint64_t sas_wwn = 0;
3082 mptsas_target_addr_t addr;
3083 mpt = SDEV2MPT(sd);
3084
3085 ASSERT(scsi_hba_iport_unit_address(hba_dip) != 0);
3086
3087 NDBG0(("mptsas_scsi_tgt_init: hbadip=0x%p tgtdip=0x%p lun=%d",
3088 (void *)hba_dip, (void *)tgt_dip, lun));
3089
3090 if (ndi_dev_is_persistent_node(tgt_dip) == 0) {
3091 (void) ndi_merge_node(tgt_dip, mptsas_name_child);
3092 ddi_set_name_addr(tgt_dip, NULL);
3093 return (DDI_FAILURE);
3094 }
3095 /*
3096 * phymask is 0 means the virtual port for RAID
3097 */
3098 phymask = (mptsas_phymask_t)ddi_prop_get_int(DDI_DEV_T_ANY, hba_dip, 0,
3099 "phymask", 0);
3100 if (mdi_component_is_client(tgt_dip, NULL) == MDI_SUCCESS) {
3101 if ((pip = (void *)(sd->sd_private)) == NULL) {
3102 /*
3103 * Very bad news if this occurs. Somehow scsi_vhci has
3104 * lost the pathinfo node for this target.
3105 */
3106 return (DDI_NOT_WELL_FORMED);
3107 }
3108
3109 if (mdi_prop_lookup_int(pip, LUN_PROP, &lun) !=
3110 DDI_PROP_SUCCESS) {
3111 mptsas_log(mpt, CE_WARN, "Get lun property failed\n");
3112 return (DDI_FAILURE);
3113 }
3114
3115 if (mdi_prop_lookup_string(pip, SCSI_ADDR_PROP_TARGET_PORT,
3116 &psas_wwn) == MDI_SUCCESS) {
3117 if (scsi_wwnstr_to_wwn(psas_wwn, &sas_wwn)) {
3118 sas_wwn = 0;
3119 }
3120 (void) mdi_prop_free(psas_wwn);
3121 }
3122 } else {
3123 lun = ddi_prop_get_int(DDI_DEV_T_ANY, tgt_dip,
3124 DDI_PROP_DONTPASS, LUN_PROP, 0);
3125 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, tgt_dip,
3126 DDI_PROP_DONTPASS, SCSI_ADDR_PROP_TARGET_PORT, &psas_wwn) ==
3127 DDI_PROP_SUCCESS) {
3128 if (scsi_wwnstr_to_wwn(psas_wwn, &sas_wwn)) {
3129 sas_wwn = 0;
3130 }
3131 ddi_prop_free(psas_wwn);
3132 } else {
3133 sas_wwn = 0;
3134 }
3135 }
3136
3137 ASSERT((sas_wwn != 0) || (phymask != 0));
3138 addr.mta_wwn = sas_wwn;
3139 addr.mta_phymask = phymask;
3140 mutex_enter(&mpt->m_mutex);
3141 ptgt = refhash_lookup(mpt->m_targets, &addr);
3142 mutex_exit(&mpt->m_mutex);
3143 if (ptgt == NULL) {
3144 mptsas_log(mpt, CE_WARN, "!tgt_init: target doesn't exist or "
3145 "gone already! phymask:%x, saswwn %"PRIx64, phymask,
3146 sas_wwn);
3147 return (DDI_FAILURE);
3148 }
3149 if (hba_tran->tran_tgt_private == NULL) {
3150 tgt_private = kmem_zalloc(sizeof (mptsas_tgt_private_t),
3151 KM_SLEEP);
3152 tgt_private->t_lun = lun;
3153 tgt_private->t_private = ptgt;
3154 hba_tran->tran_tgt_private = tgt_private;
3155 }
3156
3157 if (mdi_component_is_client(tgt_dip, NULL) == MDI_SUCCESS) {
3158 return (DDI_SUCCESS);
3159 }
3160 mutex_enter(&mpt->m_mutex);
3161
3162 if (ptgt->m_deviceinfo &
3163 (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
3164 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
3165 uchar_t *inq89 = NULL;
3166 int inq89_len = 0x238;
3167 int reallen = 0;
3168 int rval = 0;
3169 struct sata_id *sid = NULL;
3170 char model[SATA_ID_MODEL_LEN + 1];
3171 char fw[SATA_ID_FW_LEN + 1];
3172 char *vid, *pid;
3173
3174 mutex_exit(&mpt->m_mutex);
3175 /*
3176 * According SCSI/ATA Translation -2 (SAT-2) revision 01a
3177 * chapter 12.4.2 VPD page 89h includes 512 bytes ATA IDENTIFY
3178 * DEVICE data or ATA IDENTIFY PACKET DEVICE data.
3179 */
3180 inq89 = kmem_zalloc(inq89_len, KM_SLEEP);
3181 rval = mptsas_inquiry(mpt, ptgt, 0, 0x89,
3182 inq89, inq89_len, &reallen, 1);
3183
3184 if (rval != 0) {
3185 if (inq89 != NULL) {
3186 kmem_free(inq89, inq89_len);
3187 }
3188
3189 mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page "
3190 "0x89 for SATA target:%x failed!", ptgt->m_devhdl);
3191 return (DDI_SUCCESS);
3192 }
3193 sid = (void *)(&inq89[60]);
3194
3195 swab(sid->ai_model, model, SATA_ID_MODEL_LEN);
3196 swab(sid->ai_fw, fw, SATA_ID_FW_LEN);
3197
3198 model[SATA_ID_MODEL_LEN] = 0;
3199 fw[SATA_ID_FW_LEN] = 0;
3200
3201 sata_split_model(model, &vid, &pid);
3202
3203 /*
3204 * override SCSA "inquiry-*" properties
3205 */
3206 if (vid)
3207 (void) scsi_device_prop_update_inqstring(sd,
3208 INQUIRY_VENDOR_ID, vid, strlen(vid));
3209 if (pid)
3210 (void) scsi_device_prop_update_inqstring(sd,
3211 INQUIRY_PRODUCT_ID, pid, strlen(pid));
3212 (void) scsi_device_prop_update_inqstring(sd,
3213 INQUIRY_REVISION_ID, fw, strlen(fw));
3214
3215 if (inq89 != NULL) {
3216 kmem_free(inq89, inq89_len);
3217 }
3218 } else {
3219 mutex_exit(&mpt->m_mutex);
3220 }
3221
3222 return (DDI_SUCCESS);
3223 }
3224 /*
3225 * tran_tgt_free(9E) - target device instance deallocation
3226 */
3227 static void
3228 mptsas_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip,
3229 scsi_hba_tran_t *hba_tran, struct scsi_device *sd)
3230 {
3231 #ifndef __lock_lint
3232 _NOTE(ARGUNUSED(hba_dip, tgt_dip, hba_tran, sd))
3233 #endif
3234
3235 mptsas_tgt_private_t *tgt_private = hba_tran->tran_tgt_private;
3236
3237 if (tgt_private != NULL) {
3238 kmem_free(tgt_private, sizeof (mptsas_tgt_private_t));
3239 hba_tran->tran_tgt_private = NULL;
3240 }
3241 }
3242
3243 /*
3244 * scsi_pkt handling
3245 *
3246 * Visible to the external world via the transport structure.
3247 */
3248
3249 /*
3250 * Notes:
3251 * - transport the command to the addressed SCSI target/lun device
3252 * - normal operation is to schedule the command to be transported,
3253 * and return TRAN_ACCEPT if this is successful.
3254 * - if NO_INTR, tran_start must poll device for command completion
3255 */
3256 static int
3257 mptsas_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt)
3258 {
3259 #ifndef __lock_lint
3260 _NOTE(ARGUNUSED(ap))
3261 #endif
3262 mptsas_t *mpt = PKT2MPT(pkt);
3263 mptsas_cmd_t *cmd = PKT2CMD(pkt);
3264 int rval;
3265 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
3266
3267 NDBG1(("mptsas_scsi_start: pkt=0x%p", (void *)pkt));
3268 ASSERT(ptgt);
3269 if (ptgt == NULL)
3270 return (TRAN_FATAL_ERROR);
3271
3272 /*
3273 * prepare the pkt before taking mutex.
3274 */
3275 rval = mptsas_prepare_pkt(cmd);
3276 if (rval != TRAN_ACCEPT) {
3277 return (rval);
3278 }
3279
3280 /*
3281 * Send the command to target/lun, however your HBA requires it.
3282 * If busy, return TRAN_BUSY; if there's some other formatting error
3283 * in the packet, return TRAN_BADPKT; otherwise, fall through to the
3284 * return of TRAN_ACCEPT.
3285 *
3286 * Remember that access to shared resources, including the mptsas_t
3287 * data structure and the HBA hardware registers, must be protected
3288 * with mutexes, here and everywhere.
3289 *
3290 * Also remember that at interrupt time, you'll get an argument
3291 * to the interrupt handler which is a pointer to your mptsas_t
3292 * structure; you'll have to remember which commands are outstanding
3293 * and which scsi_pkt is the currently-running command so the
3294 * interrupt handler can refer to the pkt to set completion
3295 * status, call the target driver back through pkt_comp, etc.
3296 *
3297 * If the instance lock is held by other thread, don't spin to wait
3298 * for it. Instead, queue the cmd and next time when the instance lock
3299 * is not held, accept all the queued cmd. A extra tx_waitq is
3300 * introduced to protect the queue.
3301 *
3302 * The polled cmd will not be queud and accepted as usual.
3303 *
3304 * Under the tx_waitq mutex, record whether a thread is draining
3305 * the tx_waitq. An IO requesting thread that finds the instance
3306 * mutex contended appends to the tx_waitq and while holding the
3307 * tx_wait mutex, if the draining flag is not set, sets it and then
3308 * proceeds to spin for the instance mutex. This scheme ensures that
3309 * the last cmd in a burst be processed.
3310 *
3311 * we enable this feature only when the helper threads are enabled,
3312 * at which we think the loads are heavy.
3313 *
3314 * per instance mutex m_tx_waitq_mutex is introduced to protect the
3315 * m_tx_waitqtail, m_tx_waitq, m_tx_draining.
3316 */
3317
3318 if (mpt->m_doneq_thread_n) {
3319 if (mutex_tryenter(&mpt->m_mutex) != 0) {
3320 rval = mptsas_accept_txwq_and_pkt(mpt, cmd);
3321 mutex_exit(&mpt->m_mutex);
3322 } else if (cmd->cmd_pkt_flags & FLAG_NOINTR) {
3323 mutex_enter(&mpt->m_mutex);
3324 rval = mptsas_accept_txwq_and_pkt(mpt, cmd);
3325 mutex_exit(&mpt->m_mutex);
3326 } else {
3327 mutex_enter(&mpt->m_tx_waitq_mutex);
3328 /*
3329 * ptgt->m_dr_flag is protected by m_mutex or
3330 * m_tx_waitq_mutex. In this case, m_tx_waitq_mutex
3331 * is acquired.
3332 */
3333 if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) {
3334 if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) {
3335 /*
3336 * The command should be allowed to
3337 * retry by returning TRAN_BUSY to
3338 * to stall the I/O's which come from
3339 * scsi_vhci since the device/path is
3340 * in unstable state now.
3341 */
3342 mutex_exit(&mpt->m_tx_waitq_mutex);
3343 return (TRAN_BUSY);
3344 } else {
3345 /*
3346 * The device is offline, just fail the
3347 * command by returning
3348 * TRAN_FATAL_ERROR.
3349 */
3350 mutex_exit(&mpt->m_tx_waitq_mutex);
3351 return (TRAN_FATAL_ERROR);
3352 }
3353 }
3354 if (mpt->m_tx_draining) {
3355 cmd->cmd_flags |= CFLAG_TXQ;
3356 *mpt->m_tx_waitqtail = cmd;
3357 mpt->m_tx_waitqtail = &cmd->cmd_linkp;
3358 mutex_exit(&mpt->m_tx_waitq_mutex);
3359 } else { /* drain the queue */
3360 mpt->m_tx_draining = 1;
3361 mutex_exit(&mpt->m_tx_waitq_mutex);
3362 mutex_enter(&mpt->m_mutex);
3363 rval = mptsas_accept_txwq_and_pkt(mpt, cmd);
3364 mutex_exit(&mpt->m_mutex);
3365 }
3366 }
3367 } else {
3368 mutex_enter(&mpt->m_mutex);
3369 /*
3370 * ptgt->m_dr_flag is protected by m_mutex or m_tx_waitq_mutex
3371 * in this case, m_mutex is acquired.
3372 */
3373 if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) {
3374 if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) {
3375 /*
3376 * commands should be allowed to retry by
3377 * returning TRAN_BUSY to stall the I/O's
3378 * which come from scsi_vhci since the device/
3379 * path is in unstable state now.
3380 */
3381 mutex_exit(&mpt->m_mutex);
3382 return (TRAN_BUSY);
3383 } else {
3384 /*
3385 * The device is offline, just fail the
3386 * command by returning TRAN_FATAL_ERROR.
3387 */
3388 mutex_exit(&mpt->m_mutex);
3389 return (TRAN_FATAL_ERROR);
3390 }
3391 }
3392 rval = mptsas_accept_pkt(mpt, cmd);
3393 mutex_exit(&mpt->m_mutex);
3394 }
3395
3396 return (rval);
3397 }
3398
3399 /*
3400 * Accept all the queued cmds(if any) before accept the current one.
3401 */
3402 static int
3403 mptsas_accept_txwq_and_pkt(mptsas_t *mpt, mptsas_cmd_t *cmd)
3404 {
3405 int rval;
3406 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
3407
3408 ASSERT(mutex_owned(&mpt->m_mutex));
3409 /*
3410 * The call to mptsas_accept_tx_waitq() must always be performed
3411 * because that is where mpt->m_tx_draining is cleared.
3412 */
3413 mutex_enter(&mpt->m_tx_waitq_mutex);
3414 mptsas_accept_tx_waitq(mpt);
3415 mutex_exit(&mpt->m_tx_waitq_mutex);
3416 /*
3417 * ptgt->m_dr_flag is protected by m_mutex or m_tx_waitq_mutex
3418 * in this case, m_mutex is acquired.
3419 */
3420 if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) {
3421 if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) {
3422 /*
3423 * The command should be allowed to retry by returning
3424 * TRAN_BUSY to stall the I/O's which come from
3425 * scsi_vhci since the device/path is in unstable state
3426 * now.
3427 */
3428 return (TRAN_BUSY);
3429 } else {
3430 /*
3431 * The device is offline, just fail the command by
3432 * return TRAN_FATAL_ERROR.
3433 */
3434 return (TRAN_FATAL_ERROR);
3435 }
3436 }
3437 rval = mptsas_accept_pkt(mpt, cmd);
3438
3439 return (rval);
3440 }
3441
3442 static int
3443 mptsas_accept_pkt(mptsas_t *mpt, mptsas_cmd_t *cmd)
3444 {
3445 int rval = TRAN_ACCEPT;
3446 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
3447
3448 NDBG1(("mptsas_accept_pkt: cmd=0x%p", (void *)cmd));
3449
3450 ASSERT(mutex_owned(&mpt->m_mutex));
3451
3452 if ((cmd->cmd_flags & CFLAG_PREPARED) == 0) {
3453 rval = mptsas_prepare_pkt(cmd);
3454 if (rval != TRAN_ACCEPT) {
3455 cmd->cmd_flags &= ~CFLAG_TRANFLAG;
3456 return (rval);
3457 }
3458 }
3459
3460 /*
3461 * reset the throttle if we were draining
3462 */
3463 if ((ptgt->m_t_ncmds == 0) &&
3464 (ptgt->m_t_throttle == DRAIN_THROTTLE)) {
3465 NDBG23(("reset throttle"));
3466 ASSERT(ptgt->m_reset_delay == 0);
3467 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
3468 }
3469
3470 /*
3471 * If HBA is being reset, the DevHandles are being re-initialized,
3472 * which means that they could be invalid even if the target is still
3473 * attached. Check if being reset and if DevHandle is being
3474 * re-initialized. If this is the case, return BUSY so the I/O can be
3475 * retried later.
3476 */
3477 if ((ptgt->m_devhdl == MPTSAS_INVALID_DEVHDL) && mpt->m_in_reset) {
3478 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET);
3479 if (cmd->cmd_flags & CFLAG_TXQ) {
3480 mptsas_doneq_add(mpt, cmd);
3481 mptsas_doneq_empty(mpt);
3482 return (rval);
3483 } else {
3484 return (TRAN_BUSY);
3485 }
3486 }
3487
3488 /*
3489 * If device handle has already been invalidated, just
3490 * fail the command. In theory, command from scsi_vhci
3491 * client is impossible send down command with invalid
3492 * devhdl since devhdl is set after path offline, target
3493 * driver is not suppose to select a offlined path.
3494 */
3495 if (ptgt->m_devhdl == MPTSAS_INVALID_DEVHDL) {
3496 NDBG3(("rejecting command, it might because invalid devhdl "
3497 "request."));
3498 mptsas_set_pkt_reason(mpt, cmd, CMD_DEV_GONE, STAT_TERMINATED);
3499 if (cmd->cmd_flags & CFLAG_TXQ) {
3500 mptsas_doneq_add(mpt, cmd);
3501 mptsas_doneq_empty(mpt);
3502 return (rval);
3503 } else {
3504 return (TRAN_FATAL_ERROR);
3505 }
3506 }
3507 /*
3508 * The first case is the normal case. mpt gets a command from the
3509 * target driver and starts it.
3510 * Since SMID 0 is reserved and the TM slot is reserved, the actual max
3511 * commands is m_max_requests - 2.
3512 */
3513 if ((mpt->m_ncmds <= (mpt->m_max_requests - 2)) &&
3514 (ptgt->m_t_throttle > HOLD_THROTTLE) &&
3515 (ptgt->m_t_ncmds < ptgt->m_t_throttle) &&
3516 (ptgt->m_reset_delay == 0) &&
3517 (ptgt->m_t_nwait == 0) &&
3518 ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0)) {
3519 if (mptsas_save_cmd(mpt, cmd) == TRUE) {
3520 (void) mptsas_start_cmd(mpt, cmd);
3521 } else {
3522 mptsas_waitq_add(mpt, cmd);
3523 }
3524 } else {
3525 /*
3526 * Add this pkt to the work queue
3527 */
3528 mptsas_waitq_add(mpt, cmd);
3529
3530 if (cmd->cmd_pkt_flags & FLAG_NOINTR) {
3531 (void) mptsas_poll(mpt, cmd, MPTSAS_POLL_TIME);
3532
3533 /*
3534 * Only flush the doneq if this is not a TM
3535 * cmd. For TM cmds the flushing of the
3536 * doneq will be done in those routines.
3537 */
3538 if ((cmd->cmd_flags & CFLAG_TM_CMD) == 0) {
3539 mptsas_doneq_empty(mpt);
3540 }
3541 }
3542 }
3543 return (rval);
3544 }
3545
3546 int
3547 mptsas_save_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
3548 {
3549 mptsas_slots_t *slots = mpt->m_active;
3550 uint_t slot, start_rotor;
3551 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
3552
3553 ASSERT(MUTEX_HELD(&mpt->m_mutex));
3554
3555 /*
3556 * Account for reserved TM request slot and reserved SMID of 0.
3557 */
3558 ASSERT(slots->m_n_normal == (mpt->m_max_requests - 2));
3559
3560 /*
3561 * Find the next available slot, beginning at m_rotor. If no slot is
3562 * available, we'll return FALSE to indicate that. This mechanism
3563 * considers only the normal slots, not the reserved slot 0 nor the
3564 * task management slot m_n_normal + 1. The rotor is left to point to
3565 * the normal slot after the one we select, unless we select the last
3566 * normal slot in which case it returns to slot 1.
3567 */
3568 start_rotor = slots->m_rotor;
3569 do {
3570 slot = slots->m_rotor++;
3571 if (slots->m_rotor > slots->m_n_normal)
3572 slots->m_rotor = 1;
3573
3574 if (slots->m_rotor == start_rotor)
3575 break;
3576 } while (slots->m_slot[slot] != NULL);
3577
3578 if (slots->m_slot[slot] != NULL)
3579 return (FALSE);
3580
3581 ASSERT(slot != 0 && slot <= slots->m_n_normal);
3582
3583 cmd->cmd_slot = slot;
3584 slots->m_slot[slot] = cmd;
3585 mpt->m_ncmds++;
3586
3587 /*
3588 * only increment per target ncmds if this is not a
3589 * command that has no target associated with it (i.e. a
3590 * event acknoledgment)
3591 */
3592 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) {
3593 /*
3594 * Expiration time is set in mptsas_start_cmd
3595 */
3596 ptgt->m_t_ncmds++;
3597 cmd->cmd_active_expiration = 0;
3598 } else {
3599 /*
3600 * Initialize expiration time for passthrough commands,
3601 */
3602 cmd->cmd_active_expiration = gethrtime() +
3603 (hrtime_t)cmd->cmd_pkt->pkt_time * NANOSEC;
3604 }
3605 return (TRUE);
3606 }
3607
3608 /*
3609 * prepare the pkt:
3610 * the pkt may have been resubmitted or just reused so
3611 * initialize some fields and do some checks.
3612 */
3613 static int
3614 mptsas_prepare_pkt(mptsas_cmd_t *cmd)
3615 {
3616 struct scsi_pkt *pkt = CMD2PKT(cmd);
3617
3618 NDBG1(("mptsas_prepare_pkt: cmd=0x%p", (void *)cmd));
3619
3620 /*
3621 * Reinitialize some fields that need it; the packet may
3622 * have been resubmitted
3623 */
3624 pkt->pkt_reason = CMD_CMPLT;
3625 pkt->pkt_state = 0;
3626 pkt->pkt_statistics = 0;
3627 pkt->pkt_resid = 0;
3628 cmd->cmd_age = 0;
3629 cmd->cmd_pkt_flags = pkt->pkt_flags;
3630
3631 /*
3632 * zero status byte.
3633 */
3634 *(pkt->pkt_scbp) = 0;
3635
3636 if (cmd->cmd_flags & CFLAG_DMAVALID) {
3637 pkt->pkt_resid = cmd->cmd_dmacount;
3638
3639 /*
3640 * consistent packets need to be sync'ed first
3641 * (only for data going out)
3642 */
3643 if ((cmd->cmd_flags & CFLAG_CMDIOPB) &&
3644 (cmd->cmd_flags & CFLAG_DMASEND)) {
3645 (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0,
3646 DDI_DMA_SYNC_FORDEV);
3647 }
3648 }
3649
3650 cmd->cmd_flags =
3651 (cmd->cmd_flags & ~(CFLAG_TRANFLAG)) |
3652 CFLAG_PREPARED | CFLAG_IN_TRANSPORT;
3653
3654 return (TRAN_ACCEPT);
3655 }
3656
3657 /*
3658 * tran_init_pkt(9E) - allocate scsi_pkt(9S) for command
3659 *
3660 * One of three possibilities:
3661 * - allocate scsi_pkt
3662 * - allocate scsi_pkt and DMA resources
3663 * - allocate DMA resources to an already-allocated pkt
3664 */
3665 static struct scsi_pkt *
3666 mptsas_scsi_init_pkt(struct scsi_address *ap, struct scsi_pkt *pkt,
3667 struct buf *bp, int cmdlen, int statuslen, int tgtlen, int flags,
3668 int (*callback)(), caddr_t arg)
3669 {
3670 mptsas_cmd_t *cmd, *new_cmd;
3671 mptsas_t *mpt = ADDR2MPT(ap);
3672 uint_t oldcookiec;
3673 mptsas_target_t *ptgt = NULL;
3674 int rval;
3675 mptsas_tgt_private_t *tgt_private;
3676 int kf;
3677
3678 kf = (callback == SLEEP_FUNC)? KM_SLEEP: KM_NOSLEEP;
3679
3680 tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran->
3681 tran_tgt_private;
3682 ASSERT(tgt_private != NULL);
3683 if (tgt_private == NULL) {
3684 return (NULL);
3685 }
3686 ptgt = tgt_private->t_private;
3687 ASSERT(ptgt != NULL);
3688 if (ptgt == NULL)
3689 return (NULL);
3690 ap->a_target = ptgt->m_devhdl;
3691 ap->a_lun = tgt_private->t_lun;
3692
3693 ASSERT(callback == NULL_FUNC || callback == SLEEP_FUNC);
3694 #ifdef MPTSAS_TEST_EXTRN_ALLOC
3695 statuslen *= 100; tgtlen *= 4;
3696 #endif
3697 NDBG3(("mptsas_scsi_init_pkt:\n"
3698 "\ttgt=%d in=0x%p bp=0x%p clen=%d slen=%d tlen=%d flags=%x",
3699 ap->a_target, (void *)pkt, (void *)bp,
3700 cmdlen, statuslen, tgtlen, flags));
3701
3702 /*
3703 * Allocate the new packet.
3704 */
3705 if (pkt == NULL) {
3706 ddi_dma_handle_t save_dma_handle;
3707
3708 cmd = kmem_cache_alloc(mpt->m_kmem_cache, kf);
3709 if (cmd == NULL)
3710 return (NULL);
3711
3712 save_dma_handle = cmd->cmd_dmahandle;
3713 bzero(cmd, sizeof (*cmd) + scsi_pkt_size());
3714 cmd->cmd_dmahandle = save_dma_handle;
3715
3716 pkt = (void *)((uchar_t *)cmd +
3717 sizeof (struct mptsas_cmd));
3718 pkt->pkt_ha_private = (opaque_t)cmd;
3719 pkt->pkt_address = *ap;
3720 pkt->pkt_private = (opaque_t)cmd->cmd_pkt_private;
3721 pkt->pkt_scbp = (opaque_t)&cmd->cmd_scb;
3722 pkt->pkt_cdbp = (opaque_t)&cmd->cmd_cdb;
3723 cmd->cmd_pkt = (struct scsi_pkt *)pkt;
3724 cmd->cmd_cdblen = (uchar_t)cmdlen;
3725 cmd->cmd_scblen = statuslen;
3726 cmd->cmd_rqslen = SENSE_LENGTH;
3727 cmd->cmd_tgt_addr = ptgt;
3728
3729 if ((cmdlen > sizeof (cmd->cmd_cdb)) ||
3730 (tgtlen > PKT_PRIV_LEN) ||
3731 (statuslen > EXTCMDS_STATUS_SIZE)) {
3732 int failure;
3733
3734 /*
3735 * We are going to allocate external packet space which
3736 * might include the sense data buffer for DMA so we
3737 * need to increase the reference counter here. In a
3738 * case the HBA is in reset we just simply free the
3739 * allocated packet and bail out.
3740 */
3741 mutex_enter(&mpt->m_mutex);
3742 if (mpt->m_in_reset) {
3743 mutex_exit(&mpt->m_mutex);
3744
3745 cmd->cmd_flags = CFLAG_FREE;
3746 kmem_cache_free(mpt->m_kmem_cache, cmd);
3747 return (NULL);
3748 }
3749 mpt->m_extreq_sense_refcount++;
3750 ASSERT(mpt->m_extreq_sense_refcount > 0);
3751 mutex_exit(&mpt->m_mutex);
3752
3753 /*
3754 * if extern alloc fails, all will be
3755 * deallocated, including cmd
3756 */
3757 failure = mptsas_pkt_alloc_extern(mpt, cmd,
3758 cmdlen, tgtlen, statuslen, kf);
3759
3760 if (failure != 0 || cmd->cmd_extrqslen == 0) {
3761 /*
3762 * If the external packet space allocation
3763 * failed, or we didn't allocate the sense
3764 * data buffer for DMA we need to decrease the
3765 * reference counter.
3766 */
3767 mutex_enter(&mpt->m_mutex);
3768 ASSERT(mpt->m_extreq_sense_refcount > 0);
3769 mpt->m_extreq_sense_refcount--;
3770 if (mpt->m_extreq_sense_refcount == 0)
3771 cv_broadcast(
3772 &mpt->m_extreq_sense_refcount_cv);
3773 mutex_exit(&mpt->m_mutex);
3774
3775 if (failure != 0) {
3776 /*
3777 * if extern allocation fails, it will
3778 * deallocate the new pkt as well
3779 */
3780 return (NULL);
3781 }
3782 }
3783 }
3784 new_cmd = cmd;
3785
3786 } else {
3787 cmd = PKT2CMD(pkt);
3788 new_cmd = NULL;
3789 }
3790
3791
3792 /* grab cmd->cmd_cookiec here as oldcookiec */
3793
3794 oldcookiec = cmd->cmd_cookiec;
3795
3796 /*
3797 * If the dma was broken up into PARTIAL transfers cmd_nwin will be
3798 * greater than 0 and we'll need to grab the next dma window
3799 */
3800 /*
3801 * SLM-not doing extra command frame right now; may add later
3802 */
3803
3804 if (cmd->cmd_nwin > 0) {
3805
3806 /*
3807 * Make sure we havn't gone past the the total number
3808 * of windows
3809 */
3810 if (++cmd->cmd_winindex >= cmd->cmd_nwin) {
3811 return (NULL);
3812 }
3813 if (ddi_dma_getwin(cmd->cmd_dmahandle, cmd->cmd_winindex,
3814 &cmd->cmd_dma_offset, &cmd->cmd_dma_len,
3815 &cmd->cmd_cookie, &cmd->cmd_cookiec) == DDI_FAILURE) {
3816 return (NULL);
3817 }
3818 goto get_dma_cookies;
3819 }
3820
3821
3822 if (flags & PKT_XARQ) {
3823 cmd->cmd_flags |= CFLAG_XARQ;
3824 }
3825
3826 /*
3827 * DMA resource allocation. This version assumes your
3828 * HBA has some sort of bus-mastering or onboard DMA capability, with a
3829 * scatter-gather list of length MPTSAS_MAX_DMA_SEGS, as given in the
3830 * ddi_dma_attr_t structure and passed to scsi_impl_dmaget.
3831 */
3832 if (bp && (bp->b_bcount != 0) &&
3833 (cmd->cmd_flags & CFLAG_DMAVALID) == 0) {
3834
3835 int cnt, dma_flags;
3836 mptti_t *dmap; /* ptr to the S/G list */
3837
3838 /*
3839 * Set up DMA memory and position to the next DMA segment.
3840 */
3841 ASSERT(cmd->cmd_dmahandle != NULL);
3842
3843 if (bp->b_flags & B_READ) {
3844 dma_flags = DDI_DMA_READ;
3845 cmd->cmd_flags &= ~CFLAG_DMASEND;
3846 } else {
3847 dma_flags = DDI_DMA_WRITE;
3848 cmd->cmd_flags |= CFLAG_DMASEND;
3849 }
3850 if (flags & PKT_CONSISTENT) {
3851 cmd->cmd_flags |= CFLAG_CMDIOPB;
3852 dma_flags |= DDI_DMA_CONSISTENT;
3853 }
3854
3855 if (flags & PKT_DMA_PARTIAL) {
3856 dma_flags |= DDI_DMA_PARTIAL;
3857 }
3858
3859 /*
3860 * workaround for byte hole issue on psycho and
3861 * schizo pre 2.1
3862 */
3863 if ((bp->b_flags & B_READ) && ((bp->b_flags &
3864 (B_PAGEIO|B_REMAPPED)) != B_PAGEIO) &&
3865 ((uintptr_t)bp->b_un.b_addr & 0x7)) {
3866 dma_flags |= DDI_DMA_CONSISTENT;
3867 }
3868
3869 rval = ddi_dma_buf_bind_handle(cmd->cmd_dmahandle, bp,
3870 dma_flags, callback, arg,
3871 &cmd->cmd_cookie, &cmd->cmd_cookiec);
3872 if (rval == DDI_DMA_PARTIAL_MAP) {
3873 (void) ddi_dma_numwin(cmd->cmd_dmahandle,
3874 &cmd->cmd_nwin);
3875 cmd->cmd_winindex = 0;
3876 (void) ddi_dma_getwin(cmd->cmd_dmahandle,
3877 cmd->cmd_winindex, &cmd->cmd_dma_offset,
3878 &cmd->cmd_dma_len, &cmd->cmd_cookie,
3879 &cmd->cmd_cookiec);
3880 } else if (rval && (rval != DDI_DMA_MAPPED)) {
3881 switch (rval) {
3882 case DDI_DMA_NORESOURCES:
3883 bioerror(bp, 0);
3884 break;
3885 case DDI_DMA_BADATTR:
3886 case DDI_DMA_NOMAPPING:
3887 bioerror(bp, EFAULT);
3888 break;
3889 case DDI_DMA_TOOBIG:
3890 default:
3891 bioerror(bp, EINVAL);
3892 break;
3893 }
3894 cmd->cmd_flags &= ~CFLAG_DMAVALID;
3895 if (new_cmd) {
3896 mptsas_scsi_destroy_pkt(ap, pkt);
3897 }
3898 return ((struct scsi_pkt *)NULL);
3899 }
3900
3901 get_dma_cookies:
3902 cmd->cmd_flags |= CFLAG_DMAVALID;
3903 ASSERT(cmd->cmd_cookiec > 0);
3904
3905 if (cmd->cmd_cookiec > MPTSAS_MAX_CMD_SEGS) {
3906 mptsas_log(mpt, CE_NOTE, "large cookiec received %d\n",
3907 cmd->cmd_cookiec);
3908 bioerror(bp, EINVAL);
3909 if (new_cmd) {
3910 mptsas_scsi_destroy_pkt(ap, pkt);
3911 }
3912 return ((struct scsi_pkt *)NULL);
3913 }
3914
3915 /*
3916 * Allocate extra SGL buffer if needed.
3917 */
3918 if ((cmd->cmd_cookiec > MPTSAS_MAX_FRAME_SGES64(mpt)) &&
3919 (cmd->cmd_extra_frames == NULL)) {
3920 if (mptsas_alloc_extra_sgl_frame(mpt, cmd) ==
3921 DDI_FAILURE) {
3922 mptsas_log(mpt, CE_WARN, "MPT SGL mem alloc "
3923 "failed");
3924 bioerror(bp, ENOMEM);
3925 if (new_cmd) {
3926 mptsas_scsi_destroy_pkt(ap, pkt);
3927 }
3928 return ((struct scsi_pkt *)NULL);
3929 }
3930 }
3931
3932 /*
3933 * Always use scatter-gather transfer
3934 * Use the loop below to store physical addresses of
3935 * DMA segments, from the DMA cookies, into your HBA's
3936 * scatter-gather list.
3937 * We need to ensure we have enough kmem alloc'd
3938 * for the sg entries since we are no longer using an
3939 * array inside mptsas_cmd_t.
3940 *
3941 * We check cmd->cmd_cookiec against oldcookiec so
3942 * the scatter-gather list is correctly allocated
3943 */
3944
3945 if (oldcookiec != cmd->cmd_cookiec) {
3946 if (cmd->cmd_sg != (mptti_t *)NULL) {
3947 kmem_free(cmd->cmd_sg, sizeof (mptti_t) *
3948 oldcookiec);
3949 cmd->cmd_sg = NULL;
3950 }
3951 }
3952
3953 if (cmd->cmd_sg == (mptti_t *)NULL) {
3954 cmd->cmd_sg = kmem_alloc((size_t)(sizeof (mptti_t)*
3955 cmd->cmd_cookiec), kf);
3956
3957 if (cmd->cmd_sg == (mptti_t *)NULL) {
3958 mptsas_log(mpt, CE_WARN,
3959 "unable to kmem_alloc enough memory "
3960 "for scatter/gather list");
3961 /*
3962 * if we have an ENOMEM condition we need to behave
3963 * the same way as the rest of this routine
3964 */
3965
3966 bioerror(bp, ENOMEM);
3967 if (new_cmd) {
3968 mptsas_scsi_destroy_pkt(ap, pkt);
3969 }
3970 return ((struct scsi_pkt *)NULL);
3971 }
3972 }
3973
3974 dmap = cmd->cmd_sg;
3975
3976 ASSERT(cmd->cmd_cookie.dmac_size != 0);
3977
3978 /*
3979 * store the first segment into the S/G list
3980 */
3981 dmap->count = cmd->cmd_cookie.dmac_size;
3982 dmap->addr.address64.Low = (uint32_t)
3983 (cmd->cmd_cookie.dmac_laddress & 0xffffffffull);
3984 dmap->addr.address64.High = (uint32_t)
3985 (cmd->cmd_cookie.dmac_laddress >> 32);
3986
3987 /*
3988 * dmacount counts the size of the dma for this window
3989 * (if partial dma is being used). totaldmacount
3990 * keeps track of the total amount of dma we have
3991 * transferred for all the windows (needed to calculate
3992 * the resid value below).
3993 */
3994 cmd->cmd_dmacount = cmd->cmd_cookie.dmac_size;
3995 cmd->cmd_totaldmacount += cmd->cmd_cookie.dmac_size;
3996
3997 /*
3998 * We already stored the first DMA scatter gather segment,
3999 * start at 1 if we need to store more.
4000 */
4001 for (cnt = 1; cnt < cmd->cmd_cookiec; cnt++) {
4002 /*
4003 * Get next DMA cookie
4004 */
4005 ddi_dma_nextcookie(cmd->cmd_dmahandle,
4006 &cmd->cmd_cookie);
4007 dmap++;
4008
4009 cmd->cmd_dmacount += cmd->cmd_cookie.dmac_size;
4010 cmd->cmd_totaldmacount += cmd->cmd_cookie.dmac_size;
4011
4012 /*
4013 * store the segment parms into the S/G list
4014 */
4015 dmap->count = cmd->cmd_cookie.dmac_size;
4016 dmap->addr.address64.Low = (uint32_t)
4017 (cmd->cmd_cookie.dmac_laddress & 0xffffffffull);
4018 dmap->addr.address64.High = (uint32_t)
4019 (cmd->cmd_cookie.dmac_laddress >> 32);
4020 }
4021
4022 /*
4023 * If this was partially allocated we set the resid
4024 * the amount of data NOT transferred in this window
4025 * If there is only one window, the resid will be 0
4026 */
4027 pkt->pkt_resid = (bp->b_bcount - cmd->cmd_totaldmacount);
4028 NDBG3(("mptsas_scsi_init_pkt: cmd_dmacount=%d.",
4029 cmd->cmd_dmacount));
4030 }
4031 return (pkt);
4032 }
4033
4034 /*
4035 * tran_destroy_pkt(9E) - scsi_pkt(9s) deallocation
4036 *
4037 * Notes:
4038 * - also frees DMA resources if allocated
4039 * - implicit DMA synchonization
4040 */
4041 static void
4042 mptsas_scsi_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
4043 {
4044 mptsas_cmd_t *cmd = PKT2CMD(pkt);
4045 mptsas_t *mpt = ADDR2MPT(ap);
4046
4047 NDBG3(("mptsas_scsi_destroy_pkt: target=%d pkt=0x%p",
4048 ap->a_target, (void *)pkt));
4049
4050 if (cmd->cmd_flags & CFLAG_DMAVALID) {
4051 (void) ddi_dma_unbind_handle(cmd->cmd_dmahandle);
4052 cmd->cmd_flags &= ~CFLAG_DMAVALID;
4053 }
4054
4055 if (cmd->cmd_sg) {
4056 kmem_free(cmd->cmd_sg, sizeof (mptti_t) * cmd->cmd_cookiec);
4057 cmd->cmd_sg = NULL;
4058 }
4059
4060 mptsas_free_extra_sgl_frame(mpt, cmd);
4061
4062 if ((cmd->cmd_flags &
4063 (CFLAG_FREE | CFLAG_CDBEXTERN | CFLAG_PRIVEXTERN |
4064 CFLAG_SCBEXTERN)) == 0) {
4065 cmd->cmd_flags = CFLAG_FREE;
4066 kmem_cache_free(mpt->m_kmem_cache, (void *)cmd);
4067 } else {
4068 boolean_t extrqslen = cmd->cmd_extrqslen != 0;
4069
4070 mptsas_pkt_destroy_extern(mpt, cmd);
4071
4072 /*
4073 * If the packet had the sense data buffer for DMA allocated we
4074 * need to decrease the reference counter.
4075 */
4076 if (extrqslen) {
4077 mutex_enter(&mpt->m_mutex);
4078 ASSERT(mpt->m_extreq_sense_refcount > 0);
4079 mpt->m_extreq_sense_refcount--;
4080 if (mpt->m_extreq_sense_refcount == 0)
4081 cv_broadcast(&mpt->m_extreq_sense_refcount_cv);
4082 mutex_exit(&mpt->m_mutex);
4083 }
4084 }
4085 }
4086
4087 /*
4088 * kmem cache constructor and destructor:
4089 * When constructing, we bzero the cmd and allocate the dma handle
4090 * When destructing, just free the dma handle
4091 */
4092 static int
4093 mptsas_kmem_cache_constructor(void *buf, void *cdrarg, int kmflags)
4094 {
4095 mptsas_cmd_t *cmd = buf;
4096 mptsas_t *mpt = cdrarg;
4097 int (*callback)(caddr_t);
4098
4099 callback = (kmflags == KM_SLEEP)? DDI_DMA_SLEEP: DDI_DMA_DONTWAIT;
4100
4101 NDBG4(("mptsas_kmem_cache_constructor"));
4102
4103 /*
4104 * allocate a dma handle
4105 */
4106 if ((ddi_dma_alloc_handle(mpt->m_dip, &mpt->m_io_dma_attr, callback,
4107 NULL, &cmd->cmd_dmahandle)) != DDI_SUCCESS) {
4108 cmd->cmd_dmahandle = NULL;
4109 return (-1);
4110 }
4111 return (0);
4112 }
4113
4114 static void
4115 mptsas_kmem_cache_destructor(void *buf, void *cdrarg)
4116 {
4117 #ifndef __lock_lint
4118 _NOTE(ARGUNUSED(cdrarg))
4119 #endif
4120 mptsas_cmd_t *cmd = buf;
4121
4122 NDBG4(("mptsas_kmem_cache_destructor"));
4123
4124 if (cmd->cmd_dmahandle) {
4125 ddi_dma_free_handle(&cmd->cmd_dmahandle);
4126 cmd->cmd_dmahandle = NULL;
4127 }
4128 }
4129
4130 static int
4131 mptsas_cache_frames_constructor(void *buf, void *cdrarg, int kmflags)
4132 {
4133 mptsas_cache_frames_t *p = buf;
4134 mptsas_t *mpt = cdrarg;
4135 ddi_dma_attr_t frame_dma_attr;
4136 size_t mem_size, alloc_len;
4137 ddi_dma_cookie_t cookie;
4138 uint_t ncookie;
4139 int (*callback)(caddr_t) = (kmflags == KM_SLEEP)
4140 ? DDI_DMA_SLEEP: DDI_DMA_DONTWAIT;
4141
4142 frame_dma_attr = mpt->m_msg_dma_attr;
4143 frame_dma_attr.dma_attr_align = 0x10;
4144 frame_dma_attr.dma_attr_sgllen = 1;
4145
4146 if (ddi_dma_alloc_handle(mpt->m_dip, &frame_dma_attr, callback, NULL,
4147 &p->m_dma_hdl) != DDI_SUCCESS) {
4148 mptsas_log(mpt, CE_WARN, "Unable to allocate dma handle for"
4149 " extra SGL.");
4150 return (DDI_FAILURE);
4151 }
4152
4153 mem_size = (mpt->m_max_request_frames - 1) * mpt->m_req_frame_size;
4154
4155 if (ddi_dma_mem_alloc(p->m_dma_hdl, mem_size, &mpt->m_dev_acc_attr,
4156 DDI_DMA_CONSISTENT, callback, NULL, (caddr_t *)&p->m_frames_addr,
4157 &alloc_len, &p->m_acc_hdl) != DDI_SUCCESS) {
4158 ddi_dma_free_handle(&p->m_dma_hdl);
4159 p->m_dma_hdl = NULL;
4160 mptsas_log(mpt, CE_WARN, "Unable to allocate dma memory for"
4161 " extra SGL.");
4162 return (DDI_FAILURE);
4163 }
4164
4165 if (ddi_dma_addr_bind_handle(p->m_dma_hdl, NULL, p->m_frames_addr,
4166 alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, callback, NULL,
4167 &cookie, &ncookie) != DDI_DMA_MAPPED) {
4168 (void) ddi_dma_mem_free(&p->m_acc_hdl);
4169 ddi_dma_free_handle(&p->m_dma_hdl);
4170 p->m_dma_hdl = NULL;
4171 mptsas_log(mpt, CE_WARN, "Unable to bind DMA resources for"
4172 " extra SGL");
4173 return (DDI_FAILURE);
4174 }
4175
4176 /*
4177 * Store the SGL memory address. This chip uses this
4178 * address to dma to and from the driver. The second
4179 * address is the address mpt uses to fill in the SGL.
4180 */
4181 p->m_phys_addr = cookie.dmac_laddress;
4182
4183 return (DDI_SUCCESS);
4184 }
4185
4186 static void
4187 mptsas_cache_frames_destructor(void *buf, void *cdrarg)
4188 {
4189 #ifndef __lock_lint
4190 _NOTE(ARGUNUSED(cdrarg))
4191 #endif
4192 mptsas_cache_frames_t *p = buf;
4193 if (p->m_dma_hdl != NULL) {
4194 (void) ddi_dma_unbind_handle(p->m_dma_hdl);
4195 (void) ddi_dma_mem_free(&p->m_acc_hdl);
4196 ddi_dma_free_handle(&p->m_dma_hdl);
4197 p->m_phys_addr = NULL;
4198 p->m_frames_addr = NULL;
4199 p->m_dma_hdl = NULL;
4200 p->m_acc_hdl = NULL;
4201 }
4202
4203 }
4204
4205 /*
4206 * Figure out if we need to use a different method for the request
4207 * sense buffer and allocate from the map if necessary.
4208 */
4209 static boolean_t
4210 mptsas_cmdarqsize(mptsas_t *mpt, mptsas_cmd_t *cmd, size_t senselength, int kf)
4211 {
4212 if (senselength > mpt->m_req_sense_size) {
4213 unsigned long i;
4214
4215 /* Sense length is limited to an 8 bit value in MPI Spec. */
4216 if (senselength > 255)
4217 senselength = 255;
4218 cmd->cmd_extrqschunks = (senselength +
4219 (mpt->m_req_sense_size - 1))/mpt->m_req_sense_size;
4220 i = (kf == KM_SLEEP ? rmalloc_wait : rmalloc)
4221 (mpt->m_erqsense_map, cmd->cmd_extrqschunks);
4222
4223 if (i == 0)
4224 return (B_FALSE);
4225
4226 cmd->cmd_extrqslen = (uint16_t)senselength;
4227 cmd->cmd_extrqsidx = i - 1;
4228 cmd->cmd_arq_buf = mpt->m_extreq_sense +
4229 (cmd->cmd_extrqsidx * mpt->m_req_sense_size);
4230 } else {
4231 cmd->cmd_rqslen = (uchar_t)senselength;
4232 }
4233
4234 return (B_TRUE);
4235 }
4236
4237 /*
4238 * allocate and deallocate external pkt space (ie. not part of mptsas_cmd)
4239 * for non-standard length cdb, pkt_private, status areas
4240 * if allocation fails, then deallocate all external space and the pkt
4241 */
4242 /* ARGSUSED */
4243 static int
4244 mptsas_pkt_alloc_extern(mptsas_t *mpt, mptsas_cmd_t *cmd,
4245 int cmdlen, int tgtlen, int statuslen, int kf)
4246 {
4247 caddr_t cdbp, scbp, tgt;
4248
4249 NDBG3(("mptsas_pkt_alloc_extern: "
4250 "cmd=0x%p cmdlen=%d tgtlen=%d statuslen=%d kf=%x",
4251 (void *)cmd, cmdlen, tgtlen, statuslen, kf));
4252
4253 tgt = cdbp = scbp = NULL;
4254 cmd->cmd_scblen = statuslen;
4255 cmd->cmd_privlen = (uchar_t)tgtlen;
4256
4257 if (cmdlen > sizeof (cmd->cmd_cdb)) {
4258 if ((cdbp = kmem_zalloc((size_t)cmdlen, kf)) == NULL) {
4259 goto fail;
4260 }
4261 cmd->cmd_pkt->pkt_cdbp = (opaque_t)cdbp;
4262 cmd->cmd_flags |= CFLAG_CDBEXTERN;
4263 }
4264 if (tgtlen > PKT_PRIV_LEN) {
4265 if ((tgt = kmem_zalloc((size_t)tgtlen, kf)) == NULL) {
4266 goto fail;
4267 }
4268 cmd->cmd_flags |= CFLAG_PRIVEXTERN;
4269 cmd->cmd_pkt->pkt_private = tgt;
4270 }
4271 if (statuslen > EXTCMDS_STATUS_SIZE) {
4272 if ((scbp = kmem_zalloc((size_t)statuslen, kf)) == NULL) {
4273 goto fail;
4274 }
4275 cmd->cmd_flags |= CFLAG_SCBEXTERN;
4276 cmd->cmd_pkt->pkt_scbp = (opaque_t)scbp;
4277
4278 /* allocate sense data buf for DMA */
4279 if (mptsas_cmdarqsize(mpt, cmd, statuslen -
4280 MPTSAS_GET_ITEM_OFF(struct scsi_arq_status, sts_sensedata),
4281 kf) == B_FALSE)
4282 goto fail;
4283 }
4284 return (0);
4285 fail:
4286 mptsas_pkt_destroy_extern(mpt, cmd);
4287 return (1);
4288 }
4289
4290 /*
4291 * deallocate external pkt space and deallocate the pkt
4292 */
4293 static void
4294 mptsas_pkt_destroy_extern(mptsas_t *mpt, mptsas_cmd_t *cmd)
4295 {
4296 NDBG3(("mptsas_pkt_destroy_extern: cmd=0x%p", (void *)cmd));
4297
4298 if (cmd->cmd_flags & CFLAG_FREE) {
4299 mptsas_log(mpt, CE_PANIC,
4300 "mptsas_pkt_destroy_extern: freeing free packet");
4301 _NOTE(NOT_REACHED)
4302 /* NOTREACHED */
4303 }
4304 if (cmd->cmd_extrqslen != 0) {
4305 rmfree(mpt->m_erqsense_map, cmd->cmd_extrqschunks,
4306 cmd->cmd_extrqsidx + 1);
4307 }
4308 if (cmd->cmd_flags & CFLAG_CDBEXTERN) {
4309 kmem_free(cmd->cmd_pkt->pkt_cdbp, (size_t)cmd->cmd_cdblen);
4310 }
4311 if (cmd->cmd_flags & CFLAG_SCBEXTERN) {
4312 kmem_free(cmd->cmd_pkt->pkt_scbp, (size_t)cmd->cmd_scblen);
4313 }
4314 if (cmd->cmd_flags & CFLAG_PRIVEXTERN) {
4315 kmem_free(cmd->cmd_pkt->pkt_private, (size_t)cmd->cmd_privlen);
4316 }
4317 cmd->cmd_flags = CFLAG_FREE;
4318 kmem_cache_free(mpt->m_kmem_cache, (void *)cmd);
4319 }
4320
4321 /*
4322 * tran_sync_pkt(9E) - explicit DMA synchronization
4323 */
4324 /*ARGSUSED*/
4325 static void
4326 mptsas_scsi_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
4327 {
4328 mptsas_cmd_t *cmd = PKT2CMD(pkt);
4329
4330 NDBG3(("mptsas_scsi_sync_pkt: target=%d, pkt=0x%p",
4331 ap->a_target, (void *)pkt));
4332
4333 if (cmd->cmd_dmahandle) {
4334 (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0,
4335 (cmd->cmd_flags & CFLAG_DMASEND) ?
4336 DDI_DMA_SYNC_FORDEV : DDI_DMA_SYNC_FORCPU);
4337 }
4338 }
4339
4340 /*
4341 * tran_dmafree(9E) - deallocate DMA resources allocated for command
4342 */
4343 /*ARGSUSED*/
4344 static void
4345 mptsas_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt)
4346 {
4347 mptsas_cmd_t *cmd = PKT2CMD(pkt);
4348 mptsas_t *mpt = ADDR2MPT(ap);
4349
4350 NDBG3(("mptsas_scsi_dmafree: target=%d pkt=0x%p",
4351 ap->a_target, (void *)pkt));
4352
4353 if (cmd->cmd_flags & CFLAG_DMAVALID) {
4354 (void) ddi_dma_unbind_handle(cmd->cmd_dmahandle);
4355 cmd->cmd_flags &= ~CFLAG_DMAVALID;
4356 }
4357
4358 mptsas_free_extra_sgl_frame(mpt, cmd);
4359 }
4360
4361 static void
4362 mptsas_pkt_comp(struct scsi_pkt *pkt, mptsas_cmd_t *cmd)
4363 {
4364 if ((cmd->cmd_flags & CFLAG_CMDIOPB) &&
4365 (!(cmd->cmd_flags & CFLAG_DMASEND))) {
4366 (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0,
4367 DDI_DMA_SYNC_FORCPU);
4368 }
4369 (*pkt->pkt_comp)(pkt);
4370 }
4371
4372 static void
4373 mptsas_sge_mainframe(mptsas_cmd_t *cmd, pMpi2SCSIIORequest_t frame,
4374 ddi_acc_handle_t acc_hdl, uint_t cookiec, uint32_t end_flags)
4375 {
4376 pMpi2SGESimple64_t sge;
4377 mptti_t *dmap;
4378 uint32_t flags;
4379
4380 dmap = cmd->cmd_sg;
4381
4382 sge = (pMpi2SGESimple64_t)(&frame->SGL);
4383 while (cookiec--) {
4384 ddi_put32(acc_hdl,
4385 &sge->Address.Low, dmap->addr.address64.Low);
4386 ddi_put32(acc_hdl,
4387 &sge->Address.High, dmap->addr.address64.High);
4388 ddi_put32(acc_hdl, &sge->FlagsLength,
4389 dmap->count);
4390 flags = ddi_get32(acc_hdl, &sge->FlagsLength);
4391 flags |= ((uint32_t)
4392 (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
4393 MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
4394 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
4395 MPI2_SGE_FLAGS_SHIFT);
4396
4397 /*
4398 * If this is the last cookie, we set the flags
4399 * to indicate so
4400 */
4401 if (cookiec == 0) {
4402 flags |= end_flags;
4403 }
4404 if (cmd->cmd_flags & CFLAG_DMASEND) {
4405 flags |= (MPI2_SGE_FLAGS_HOST_TO_IOC <<
4406 MPI2_SGE_FLAGS_SHIFT);
4407 } else {
4408 flags |= (MPI2_SGE_FLAGS_IOC_TO_HOST <<
4409 MPI2_SGE_FLAGS_SHIFT);
4410 }
4411 ddi_put32(acc_hdl, &sge->FlagsLength, flags);
4412 dmap++;
4413 sge++;
4414 }
4415 }
4416
4417 static void
4418 mptsas_sge_chain(mptsas_t *mpt, mptsas_cmd_t *cmd,
4419 pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl)
4420 {
4421 pMpi2SGESimple64_t sge;
4422 pMpi2SGEChain64_t sgechain;
4423 uint64_t nframe_phys_addr;
4424 uint_t cookiec;
4425 mptti_t *dmap;
4426 uint32_t flags;
4427
4428 /*
4429 * Save the number of entries in the DMA
4430 * Scatter/Gather list
4431 */
4432 cookiec = cmd->cmd_cookiec;
4433
4434 /*
4435 * Hereby we start to deal with multiple frames.
4436 * The process is as follows:
4437 * 1. Determine how many frames are needed for SGL element
4438 * storage; Note that all frames are stored in contiguous
4439 * memory space and in 64-bit DMA mode each element is
4440 * 3 double-words (12 bytes) long.
4441 * 2. Fill up the main frame. We need to do this separately
4442 * since it contains the SCSI IO request header and needs
4443 * dedicated processing. Note that the last 4 double-words
4444 * of the SCSI IO header is for SGL element storage
4445 * (MPI2_SGE_IO_UNION).
4446 * 3. Fill the chain element in the main frame, so the DMA
4447 * engine can use the following frames.
4448 * 4. Enter a loop to fill the remaining frames. Note that the
4449 * last frame contains no chain element. The remaining
4450 * frames go into the mpt SGL buffer allocated on the fly,
4451 * not immediately following the main message frame, as in
4452 * Gen1.
4453 * Some restrictions:
4454 * 1. For 64-bit DMA, the simple element and chain element
4455 * are both of 3 double-words (12 bytes) in size, even
4456 * though all frames are stored in the first 4G of mem
4457 * range and the higher 32-bits of the address are always 0.
4458 * 2. On some controllers (like the 1064/1068), a frame can
4459 * hold SGL elements with the last 1 or 2 double-words
4460 * (4 or 8 bytes) un-used. On these controllers, we should
4461 * recognize that there's not enough room for another SGL
4462 * element and move the sge pointer to the next frame.
4463 */
4464 int i, j, k, l, frames, sgemax;
4465 int temp;
4466 uint8_t chainflags;
4467 uint16_t chainlength;
4468 mptsas_cache_frames_t *p;
4469
4470 /*
4471 * Sgemax is the number of SGE's that will fit
4472 * each extra frame and frames is total
4473 * number of frames we'll need. 1 sge entry per
4474 * frame is reseverd for the chain element thus the -1 below.
4475 */
4476 sgemax = ((mpt->m_req_frame_size / sizeof (MPI2_SGE_SIMPLE64))
4477 - 1);
4478 temp = (cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) / sgemax;
4479
4480 /*
4481 * A little check to see if we need to round up the number
4482 * of frames we need
4483 */
4484 if ((cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) - (temp *
4485 sgemax) > 1) {
4486 frames = (temp + 1);
4487 } else {
4488 frames = temp;
4489 }
4490 dmap = cmd->cmd_sg;
4491 sge = (pMpi2SGESimple64_t)(&frame->SGL);
4492
4493 /*
4494 * First fill in the main frame
4495 */
4496 j = MPTSAS_MAX_FRAME_SGES64(mpt) - 1;
4497 mptsas_sge_mainframe(cmd, frame, acc_hdl, j,
4498 ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT) <<
4499 MPI2_SGE_FLAGS_SHIFT));
4500 dmap += j;
4501 sge += j;
4502 j++;
4503
4504 /*
4505 * Fill in the chain element in the main frame.
4506 * About calculation on ChainOffset:
4507 * 1. Struct msg_scsi_io_request has 4 double-words (16 bytes)
4508 * in the end reserved for SGL element storage
4509 * (MPI2_SGE_IO_UNION); we should count it in our
4510 * calculation. See its definition in the header file.
4511 * 2. Constant j is the counter of the current SGL element
4512 * that will be processed, and (j - 1) is the number of
4513 * SGL elements that have been processed (stored in the
4514 * main frame).
4515 * 3. ChainOffset value should be in units of double-words (4
4516 * bytes) so the last value should be divided by 4.
4517 */
4518 ddi_put8(acc_hdl, &frame->ChainOffset,
4519 (sizeof (MPI2_SCSI_IO_REQUEST) -
4520 sizeof (MPI2_SGE_IO_UNION) +
4521 (j - 1) * sizeof (MPI2_SGE_SIMPLE64)) >> 2);
4522 sgechain = (pMpi2SGEChain64_t)sge;
4523 chainflags = (MPI2_SGE_FLAGS_CHAIN_ELEMENT |
4524 MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
4525 MPI2_SGE_FLAGS_64_BIT_ADDRESSING);
4526 ddi_put8(acc_hdl, &sgechain->Flags, chainflags);
4527
4528 /*
4529 * The size of the next frame is the accurate size of space
4530 * (in bytes) used to store the SGL elements. j is the counter
4531 * of SGL elements. (j - 1) is the number of SGL elements that
4532 * have been processed (stored in frames).
4533 */
4534 if (frames >= 2) {
4535 ASSERT(mpt->m_req_frame_size >= sizeof (MPI2_SGE_SIMPLE64));
4536 chainlength = mpt->m_req_frame_size /
4537 sizeof (MPI2_SGE_SIMPLE64) *
4538 sizeof (MPI2_SGE_SIMPLE64);
4539 } else {
4540 chainlength = ((cookiec - (j - 1)) *
4541 sizeof (MPI2_SGE_SIMPLE64));
4542 }
4543
4544 p = cmd->cmd_extra_frames;
4545
4546 ddi_put16(acc_hdl, &sgechain->Length, chainlength);
4547 ddi_put32(acc_hdl, &sgechain->Address.Low, p->m_phys_addr);
4548 ddi_put32(acc_hdl, &sgechain->Address.High, p->m_phys_addr >> 32);
4549
4550 /*
4551 * If there are more than 2 frames left we have to
4552 * fill in the next chain offset to the location of
4553 * the chain element in the next frame.
4554 * sgemax is the number of simple elements in an extra
4555 * frame. Note that the value NextChainOffset should be
4556 * in double-words (4 bytes).
4557 */
4558 if (frames >= 2) {
4559 ddi_put8(acc_hdl, &sgechain->NextChainOffset,
4560 (sgemax * sizeof (MPI2_SGE_SIMPLE64)) >> 2);
4561 } else {
4562 ddi_put8(acc_hdl, &sgechain->NextChainOffset, 0);
4563 }
4564
4565 /*
4566 * Jump to next frame;
4567 * Starting here, chain buffers go into the per command SGL.
4568 * This buffer is allocated when chain buffers are needed.
4569 */
4570 sge = (pMpi2SGESimple64_t)p->m_frames_addr;
4571 i = cookiec;
4572
4573 /*
4574 * Start filling in frames with SGE's. If we
4575 * reach the end of frame and still have SGE's
4576 * to fill we need to add a chain element and
4577 * use another frame. j will be our counter
4578 * for what cookie we are at and i will be
4579 * the total cookiec. k is the current frame
4580 */
4581 for (k = 1; k <= frames; k++) {
4582 for (l = 1; (l <= (sgemax + 1)) && (j <= i); j++, l++) {
4583
4584 /*
4585 * If we have reached the end of frame
4586 * and we have more SGE's to fill in
4587 * we have to fill the final entry
4588 * with a chain element and then
4589 * continue to the next frame
4590 */
4591 if ((l == (sgemax + 1)) && (k != frames)) {
4592 sgechain = (pMpi2SGEChain64_t)sge;
4593 j--;
4594 chainflags = (
4595 MPI2_SGE_FLAGS_CHAIN_ELEMENT |
4596 MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
4597 MPI2_SGE_FLAGS_64_BIT_ADDRESSING);
4598 ddi_put8(p->m_acc_hdl,
4599 &sgechain->Flags, chainflags);
4600 /*
4601 * k is the frame counter and (k + 1)
4602 * is the number of the next frame.
4603 * Note that frames are in contiguous
4604 * memory space.
4605 */
4606 nframe_phys_addr = p->m_phys_addr +
4607 (mpt->m_req_frame_size * k);
4608 ddi_put32(p->m_acc_hdl,
4609 &sgechain->Address.Low,
4610 nframe_phys_addr);
4611 ddi_put32(p->m_acc_hdl,
4612 &sgechain->Address.High,
4613 nframe_phys_addr >> 32);
4614
4615 /*
4616 * If there are more than 2 frames left
4617 * we have to next chain offset to
4618 * the location of the chain element
4619 * in the next frame and fill in the
4620 * length of the next chain
4621 */
4622 if ((frames - k) >= 2) {
4623 ddi_put8(p->m_acc_hdl,
4624 &sgechain->NextChainOffset,
4625 (sgemax *
4626 sizeof (MPI2_SGE_SIMPLE64))
4627 >> 2);
4628 ddi_put16(p->m_acc_hdl,
4629 &sgechain->Length,
4630 mpt->m_req_frame_size /
4631 sizeof (MPI2_SGE_SIMPLE64) *
4632 sizeof (MPI2_SGE_SIMPLE64));
4633 } else {
4634 /*
4635 * This is the last frame. Set
4636 * the NextChainOffset to 0 and
4637 * Length is the total size of
4638 * all remaining simple elements
4639 */
4640 ddi_put8(p->m_acc_hdl,
4641 &sgechain->NextChainOffset,
4642 0);
4643 ddi_put16(p->m_acc_hdl,
4644 &sgechain->Length,
4645 (cookiec - j) *
4646 sizeof (MPI2_SGE_SIMPLE64));
4647 }
4648
4649 /* Jump to the next frame */
4650 sge = (pMpi2SGESimple64_t)
4651 ((char *)p->m_frames_addr +
4652 (int)mpt->m_req_frame_size * k);
4653
4654 continue;
4655 }
4656
4657 ddi_put32(p->m_acc_hdl,
4658 &sge->Address.Low,
4659 dmap->addr.address64.Low);
4660 ddi_put32(p->m_acc_hdl,
4661 &sge->Address.High,
4662 dmap->addr.address64.High);
4663 ddi_put32(p->m_acc_hdl,
4664 &sge->FlagsLength, dmap->count);
4665 flags = ddi_get32(p->m_acc_hdl,
4666 &sge->FlagsLength);
4667 flags |= ((uint32_t)(
4668 MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
4669 MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
4670 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
4671 MPI2_SGE_FLAGS_SHIFT);
4672
4673 /*
4674 * If we are at the end of the frame and
4675 * there is another frame to fill in
4676 * we set the last simple element as last
4677 * element
4678 */
4679 if ((l == sgemax) && (k != frames)) {
4680 flags |= ((uint32_t)
4681 (MPI2_SGE_FLAGS_LAST_ELEMENT) <<
4682 MPI2_SGE_FLAGS_SHIFT);
4683 }
4684
4685 /*
4686 * If this is the final cookie we
4687 * indicate it by setting the flags
4688 */
4689 if (j == i) {
4690 flags |= ((uint32_t)
4691 (MPI2_SGE_FLAGS_LAST_ELEMENT |
4692 MPI2_SGE_FLAGS_END_OF_BUFFER |
4693 MPI2_SGE_FLAGS_END_OF_LIST) <<
4694 MPI2_SGE_FLAGS_SHIFT);
4695 }
4696 if (cmd->cmd_flags & CFLAG_DMASEND) {
4697 flags |=
4698 (MPI2_SGE_FLAGS_HOST_TO_IOC <<
4699 MPI2_SGE_FLAGS_SHIFT);
4700 } else {
4701 flags |=
4702 (MPI2_SGE_FLAGS_IOC_TO_HOST <<
4703 MPI2_SGE_FLAGS_SHIFT);
4704 }
4705 ddi_put32(p->m_acc_hdl,
4706 &sge->FlagsLength, flags);
4707 dmap++;
4708 sge++;
4709 }
4710 }
4711
4712 /*
4713 * Sync DMA with the chain buffers that were just created
4714 */
4715 (void) ddi_dma_sync(p->m_dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
4716 }
4717
4718 static void
4719 mptsas_ieee_sge_mainframe(mptsas_cmd_t *cmd, pMpi2SCSIIORequest_t frame,
4720 ddi_acc_handle_t acc_hdl, uint_t cookiec, uint8_t end_flag)
4721 {
4722 pMpi2IeeeSgeSimple64_t ieeesge;
4723 mptti_t *dmap;
4724 uint8_t flags;
4725
4726 dmap = cmd->cmd_sg;
4727
4728 NDBG1(("mptsas_ieee_sge_mainframe: cookiec=%d, %s", cookiec,
4729 cmd->cmd_flags & CFLAG_DMASEND?"Out":"In"));
4730
4731 ieeesge = (pMpi2IeeeSgeSimple64_t)(&frame->SGL);
4732 while (cookiec--) {
4733 ddi_put32(acc_hdl,
4734 &ieeesge->Address.Low, dmap->addr.address64.Low);
4735 ddi_put32(acc_hdl,
4736 &ieeesge->Address.High, dmap->addr.address64.High);
4737 ddi_put32(acc_hdl, &ieeesge->Length,
4738 dmap->count);
4739 NDBG1(("mptsas_ieee_sge_mainframe: len=%d", dmap->count));
4740 flags = (MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT |
4741 MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR);
4742
4743 /*
4744 * If this is the last cookie, we set the flags
4745 * to indicate so
4746 */
4747 if (cookiec == 0) {
4748 flags |= end_flag;
4749 }
4750
4751 ddi_put8(acc_hdl, &ieeesge->Flags, flags);
4752 dmap++;
4753 ieeesge++;
4754 }
4755 }
4756
4757 static void
4758 mptsas_ieee_sge_chain(mptsas_t *mpt, mptsas_cmd_t *cmd,
4759 pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl)
4760 {
4761 pMpi2IeeeSgeSimple64_t ieeesge;
4762 pMpi25IeeeSgeChain64_t ieeesgechain;
4763 uint64_t nframe_phys_addr;
4764 uint_t cookiec;
4765 mptti_t *dmap;
4766 uint8_t flags;
4767
4768 /*
4769 * Save the number of entries in the DMA
4770 * Scatter/Gather list
4771 */
4772 cookiec = cmd->cmd_cookiec;
4773
4774 NDBG1(("mptsas_ieee_sge_chain: cookiec=%d", cookiec));
4775
4776 /*
4777 * Hereby we start to deal with multiple frames.
4778 * The process is as follows:
4779 * 1. Determine how many frames are needed for SGL element
4780 * storage; Note that all frames are stored in contiguous
4781 * memory space and in 64-bit DMA mode each element is
4782 * 4 double-words (16 bytes) long.
4783 * 2. Fill up the main frame. We need to do this separately
4784 * since it contains the SCSI IO request header and needs
4785 * dedicated processing. Note that the last 4 double-words
4786 * of the SCSI IO header is for SGL element storage
4787 * (MPI2_SGE_IO_UNION).
4788 * 3. Fill the chain element in the main frame, so the DMA
4789 * engine can use the following frames.
4790 * 4. Enter a loop to fill the remaining frames. Note that the
4791 * last frame contains no chain element. The remaining
4792 * frames go into the mpt SGL buffer allocated on the fly,
4793 * not immediately following the main message frame, as in
4794 * Gen1.
4795 * Restrictions:
4796 * For 64-bit DMA, the simple element and chain element
4797 * are both of 4 double-words (16 bytes) in size, even
4798 * though all frames are stored in the first 4G of mem
4799 * range and the higher 32-bits of the address are always 0.
4800 */
4801 int i, j, k, l, frames, sgemax;
4802 int temp;
4803 uint8_t chainflags;
4804 uint32_t chainlength;
4805 mptsas_cache_frames_t *p;
4806
4807 /*
4808 * Sgemax is the number of SGE's that will fit
4809 * each extra frame and frames is total
4810 * number of frames we'll need. 1 sge entry per
4811 * frame is reseverd for the chain element thus the -1 below.
4812 */
4813 sgemax = ((mpt->m_req_frame_size / sizeof (MPI2_IEEE_SGE_SIMPLE64))
4814 - 1);
4815 temp = (cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) / sgemax;
4816
4817 /*
4818 * A little check to see if we need to round up the number
4819 * of frames we need
4820 */
4821 if ((cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) - (temp *
4822 sgemax) > 1) {
4823 frames = (temp + 1);
4824 } else {
4825 frames = temp;
4826 }
4827 NDBG1(("mptsas_ieee_sge_chain: temp=%d, frames=%d", temp, frames));
4828 dmap = cmd->cmd_sg;
4829 ieeesge = (pMpi2IeeeSgeSimple64_t)(&frame->SGL);
4830
4831 /*
4832 * First fill in the main frame
4833 */
4834 j = MPTSAS_MAX_FRAME_SGES64(mpt) - 1;
4835 mptsas_ieee_sge_mainframe(cmd, frame, acc_hdl, j, 0);
4836 dmap += j;
4837 ieeesge += j;
4838 j++;
4839
4840 /*
4841 * Fill in the chain element in the main frame.
4842 * About calculation on ChainOffset:
4843 * 1. Struct msg_scsi_io_request has 4 double-words (16 bytes)
4844 * in the end reserved for SGL element storage
4845 * (MPI2_SGE_IO_UNION); we should count it in our
4846 * calculation. See its definition in the header file.
4847 * 2. Constant j is the counter of the current SGL element
4848 * that will be processed, and (j - 1) is the number of
4849 * SGL elements that have been processed (stored in the
4850 * main frame).
4851 * 3. ChainOffset value should be in units of quad-words (16
4852 * bytes) so the last value should be divided by 16.
4853 */
4854 ddi_put8(acc_hdl, &frame->ChainOffset,
4855 (sizeof (MPI2_SCSI_IO_REQUEST) -
4856 sizeof (MPI2_SGE_IO_UNION) +
4857 (j - 1) * sizeof (MPI2_IEEE_SGE_SIMPLE64)) >> 4);
4858 ieeesgechain = (pMpi25IeeeSgeChain64_t)ieeesge;
4859 chainflags = (MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT |
4860 MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR);
4861 ddi_put8(acc_hdl, &ieeesgechain->Flags, chainflags);
4862
4863 /*
4864 * The size of the next frame is the accurate size of space
4865 * (in bytes) used to store the SGL elements. j is the counter
4866 * of SGL elements. (j - 1) is the number of SGL elements that
4867 * have been processed (stored in frames).
4868 */
4869 if (frames >= 2) {
4870 ASSERT(mpt->m_req_frame_size >=
4871 sizeof (MPI2_IEEE_SGE_SIMPLE64));
4872 chainlength = mpt->m_req_frame_size /
4873 sizeof (MPI2_IEEE_SGE_SIMPLE64) *
4874 sizeof (MPI2_IEEE_SGE_SIMPLE64);
4875 } else {
4876 chainlength = ((cookiec - (j - 1)) *
4877 sizeof (MPI2_IEEE_SGE_SIMPLE64));
4878 }
4879
4880 p = cmd->cmd_extra_frames;
4881
4882 ddi_put32(acc_hdl, &ieeesgechain->Length, chainlength);
4883 ddi_put32(acc_hdl, &ieeesgechain->Address.Low, p->m_phys_addr);
4884 ddi_put32(acc_hdl, &ieeesgechain->Address.High, p->m_phys_addr >> 32);
4885
4886 /*
4887 * If there are more than 2 frames left we have to
4888 * fill in the next chain offset to the location of
4889 * the chain element in the next frame.
4890 * sgemax is the number of simple elements in an extra
4891 * frame. Note that the value NextChainOffset should be
4892 * in double-words (4 bytes).
4893 */
4894 if (frames >= 2) {
4895 ddi_put8(acc_hdl, &ieeesgechain->NextChainOffset,
4896 (sgemax * sizeof (MPI2_IEEE_SGE_SIMPLE64)) >> 4);
4897 } else {
4898 ddi_put8(acc_hdl, &ieeesgechain->NextChainOffset, 0);
4899 }
4900
4901 /*
4902 * Jump to next frame;
4903 * Starting here, chain buffers go into the per command SGL.
4904 * This buffer is allocated when chain buffers are needed.
4905 */
4906 ieeesge = (pMpi2IeeeSgeSimple64_t)p->m_frames_addr;
4907 i = cookiec;
4908
4909 /*
4910 * Start filling in frames with SGE's. If we
4911 * reach the end of frame and still have SGE's
4912 * to fill we need to add a chain element and
4913 * use another frame. j will be our counter
4914 * for what cookie we are at and i will be
4915 * the total cookiec. k is the current frame
4916 */
4917 for (k = 1; k <= frames; k++) {
4918 for (l = 1; (l <= (sgemax + 1)) && (j <= i); j++, l++) {
4919
4920 /*
4921 * If we have reached the end of frame
4922 * and we have more SGE's to fill in
4923 * we have to fill the final entry
4924 * with a chain element and then
4925 * continue to the next frame
4926 */
4927 if ((l == (sgemax + 1)) && (k != frames)) {
4928 ieeesgechain = (pMpi25IeeeSgeChain64_t)ieeesge;
4929 j--;
4930 chainflags =
4931 MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT |
4932 MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR;
4933 ddi_put8(p->m_acc_hdl,
4934 &ieeesgechain->Flags, chainflags);
4935 /*
4936 * k is the frame counter and (k + 1)
4937 * is the number of the next frame.
4938 * Note that frames are in contiguous
4939 * memory space.
4940 */
4941 nframe_phys_addr = p->m_phys_addr +
4942 (mpt->m_req_frame_size * k);
4943 ddi_put32(p->m_acc_hdl,
4944 &ieeesgechain->Address.Low,
4945 nframe_phys_addr);
4946 ddi_put32(p->m_acc_hdl,
4947 &ieeesgechain->Address.High,
4948 nframe_phys_addr >> 32);
4949
4950 /*
4951 * If there are more than 2 frames left
4952 * we have to next chain offset to
4953 * the location of the chain element
4954 * in the next frame and fill in the
4955 * length of the next chain
4956 */
4957 if ((frames - k) >= 2) {
4958 ddi_put8(p->m_acc_hdl,
4959 &ieeesgechain->NextChainOffset,
4960 (sgemax *
4961 sizeof (MPI2_IEEE_SGE_SIMPLE64))
4962 >> 4);
4963 ASSERT(mpt->m_req_frame_size >=
4964 sizeof (MPI2_IEEE_SGE_SIMPLE64));
4965 ddi_put32(p->m_acc_hdl,
4966 &ieeesgechain->Length,
4967 mpt->m_req_frame_size /
4968 sizeof (MPI2_IEEE_SGE_SIMPLE64) *
4969 sizeof (MPI2_IEEE_SGE_SIMPLE64));
4970 } else {
4971 /*
4972 * This is the last frame. Set
4973 * the NextChainOffset to 0 and
4974 * Length is the total size of
4975 * all remaining simple elements
4976 */
4977 ddi_put8(p->m_acc_hdl,
4978 &ieeesgechain->NextChainOffset,
4979 0);
4980 ddi_put32(p->m_acc_hdl,
4981 &ieeesgechain->Length,
4982 (cookiec - j) *
4983 sizeof (MPI2_IEEE_SGE_SIMPLE64));
4984 }
4985
4986 /* Jump to the next frame */
4987 ieeesge = (pMpi2IeeeSgeSimple64_t)
4988 ((char *)p->m_frames_addr +
4989 (int)mpt->m_req_frame_size * k);
4990
4991 continue;
4992 }
4993
4994 ddi_put32(p->m_acc_hdl,
4995 &ieeesge->Address.Low,
4996 dmap->addr.address64.Low);
4997 ddi_put32(p->m_acc_hdl,
4998 &ieeesge->Address.High,
4999 dmap->addr.address64.High);
5000 ddi_put32(p->m_acc_hdl,
5001 &ieeesge->Length, dmap->count);
5002 flags = (MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT |
5003 MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR);
5004
5005 /*
5006 * If we are at the end of the frame and
5007 * there is another frame to fill in
5008 * do we need to do anything?
5009 * if ((l == sgemax) && (k != frames)) {
5010 * }
5011 */
5012
5013 /*
5014 * If this is the final cookie set end of list.
5015 */
5016 if (j == i) {
5017 flags |= MPI25_IEEE_SGE_FLAGS_END_OF_LIST;
5018 }
5019
5020 ddi_put8(p->m_acc_hdl, &ieeesge->Flags, flags);
5021 dmap++;
5022 ieeesge++;
5023 }
5024 }
5025
5026 /*
5027 * Sync DMA with the chain buffers that were just created
5028 */
5029 (void) ddi_dma_sync(p->m_dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
5030 }
5031
5032 static void
5033 mptsas_sge_setup(mptsas_t *mpt, mptsas_cmd_t *cmd, uint32_t *control,
5034 pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl)
5035 {
5036 ASSERT(cmd->cmd_flags & CFLAG_DMAVALID);
5037
5038 NDBG1(("mptsas_sge_setup: cookiec=%d", cmd->cmd_cookiec));
5039
5040 /*
5041 * Set read/write bit in control.
5042 */
5043 if (cmd->cmd_flags & CFLAG_DMASEND) {
5044 *control |= MPI2_SCSIIO_CONTROL_WRITE;
5045 } else {
5046 *control |= MPI2_SCSIIO_CONTROL_READ;
5047 }
5048
5049 ddi_put32(acc_hdl, &frame->DataLength, cmd->cmd_dmacount);
5050
5051 /*
5052 * We have 4 cases here. First where we can fit all the
5053 * SG elements into the main frame, and the case
5054 * where we can't. The SG element is also different when using
5055 * MPI2.5 interface.
5056 * If we have more cookies than we can attach to a frame
5057 * we will need to use a chain element to point
5058 * a location of memory where the rest of the S/G
5059 * elements reside.
5060 */
5061 if (cmd->cmd_cookiec <= MPTSAS_MAX_FRAME_SGES64(mpt)) {
5062 if (mpt->m_MPI25) {
5063 mptsas_ieee_sge_mainframe(cmd, frame, acc_hdl,
5064 cmd->cmd_cookiec,
5065 MPI25_IEEE_SGE_FLAGS_END_OF_LIST);
5066 } else {
5067 mptsas_sge_mainframe(cmd, frame, acc_hdl,
5068 cmd->cmd_cookiec,
5069 ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT
5070 | MPI2_SGE_FLAGS_END_OF_BUFFER
5071 | MPI2_SGE_FLAGS_END_OF_LIST) <<
5072 MPI2_SGE_FLAGS_SHIFT));
5073 }
5074 } else {
5075 if (mpt->m_MPI25) {
5076 mptsas_ieee_sge_chain(mpt, cmd, frame, acc_hdl);
5077 } else {
5078 mptsas_sge_chain(mpt, cmd, frame, acc_hdl);
5079 }
5080 }
5081 }
5082
5083 /*
5084 * Interrupt handling
5085 * Utility routine. Poll for status of a command sent to HBA
5086 * without interrupts (a FLAG_NOINTR command).
5087 */
5088 int
5089 mptsas_poll(mptsas_t *mpt, mptsas_cmd_t *poll_cmd, int polltime)
5090 {
5091 int rval = TRUE;
5092
5093 NDBG5(("mptsas_poll: cmd=0x%p", (void *)poll_cmd));
5094
5095 if ((poll_cmd->cmd_flags & CFLAG_TM_CMD) == 0) {
5096 mptsas_restart_hba(mpt);
5097 }
5098
5099 /*
5100 * Wait, using drv_usecwait(), long enough for the command to
5101 * reasonably return from the target if the target isn't
5102 * "dead". A polled command may well be sent from scsi_poll, and
5103 * there are retries built in to scsi_poll if the transport
5104 * accepted the packet (TRAN_ACCEPT). scsi_poll waits 1 second
5105 * and retries the transport up to scsi_poll_busycnt times
5106 * (currently 60) if
5107 * 1. pkt_reason is CMD_INCOMPLETE and pkt_state is 0, or
5108 * 2. pkt_reason is CMD_CMPLT and *pkt_scbp has STATUS_BUSY
5109 *
5110 * limit the waiting to avoid a hang in the event that the
5111 * cmd never gets started but we are still receiving interrupts
5112 */
5113 while (!(poll_cmd->cmd_flags & CFLAG_FINISHED)) {
5114 if (mptsas_wait_intr(mpt, polltime) == FALSE) {
5115 NDBG5(("mptsas_poll: command incomplete"));
5116 rval = FALSE;
5117 break;
5118 }
5119 }
5120
5121 if (rval == FALSE) {
5122
5123 /*
5124 * this isn't supposed to happen, the hba must be wedged
5125 * Mark this cmd as a timeout.
5126 */
5127 mptsas_set_pkt_reason(mpt, poll_cmd, CMD_TIMEOUT,
5128 (STAT_TIMEOUT|STAT_ABORTED));
5129
5130 if (poll_cmd->cmd_queued == FALSE) {
5131
5132 NDBG5(("mptsas_poll: not on waitq"));
5133
5134 poll_cmd->cmd_pkt->pkt_state |=
5135 (STATE_GOT_BUS|STATE_GOT_TARGET|STATE_SENT_CMD);
5136 } else {
5137
5138 /* find and remove it from the waitq */
5139 NDBG5(("mptsas_poll: delete from waitq"));
5140 mptsas_waitq_delete(mpt, poll_cmd);
5141 }
5142
5143 }
5144 mptsas_fma_check(mpt, poll_cmd);
5145 NDBG5(("mptsas_poll: done"));
5146 return (rval);
5147 }
5148
5149 /*
5150 * Used for polling cmds and TM function
5151 */
5152 static int
5153 mptsas_wait_intr(mptsas_t *mpt, int polltime)
5154 {
5155 int cnt;
5156 pMpi2ReplyDescriptorsUnion_t reply_desc_union;
5157 uint32_t int_mask;
5158
5159 NDBG5(("mptsas_wait_intr"));
5160
5161 mpt->m_polled_intr = 1;
5162
5163 /*
5164 * Get the current interrupt mask and disable interrupts. When
5165 * re-enabling ints, set mask to saved value.
5166 */
5167 int_mask = ddi_get32(mpt->m_datap, &mpt->m_reg->HostInterruptMask);
5168 MPTSAS_DISABLE_INTR(mpt);
5169
5170 /*
5171 * Keep polling for at least (polltime * 1000) seconds
5172 */
5173 for (cnt = 0; cnt < polltime; cnt++) {
5174 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0,
5175 DDI_DMA_SYNC_FORCPU);
5176
5177 reply_desc_union = (pMpi2ReplyDescriptorsUnion_t)
5178 MPTSAS_GET_NEXT_REPLY(mpt, mpt->m_post_index);
5179
5180 if (ddi_get32(mpt->m_acc_post_queue_hdl,
5181 &reply_desc_union->Words.Low) == 0xFFFFFFFF ||
5182 ddi_get32(mpt->m_acc_post_queue_hdl,
5183 &reply_desc_union->Words.High) == 0xFFFFFFFF) {
5184 drv_usecwait(1000);
5185 continue;
5186 }
5187
5188 /*
5189 * The reply is valid, process it according to its
5190 * type.
5191 */
5192 mptsas_process_intr(mpt, reply_desc_union);
5193
5194 if (++mpt->m_post_index == mpt->m_post_queue_depth) {
5195 mpt->m_post_index = 0;
5196 }
5197
5198 /*
5199 * Update the global reply index
5200 */
5201 ddi_put32(mpt->m_datap,
5202 &mpt->m_reg->ReplyPostHostIndex, mpt->m_post_index);
5203 mpt->m_polled_intr = 0;
5204
5205 /*
5206 * Re-enable interrupts and quit.
5207 */
5208 ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptMask,
5209 int_mask);
5210 return (TRUE);
5211
5212 }
5213
5214 /*
5215 * Clear polling flag, re-enable interrupts and quit.
5216 */
5217 mpt->m_polled_intr = 0;
5218 ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptMask, int_mask);
5219 return (FALSE);
5220 }
5221
5222 static void
5223 mptsas_handle_scsi_io_success(mptsas_t *mpt,
5224 pMpi2ReplyDescriptorsUnion_t reply_desc)
5225 {
5226 pMpi2SCSIIOSuccessReplyDescriptor_t scsi_io_success;
5227 uint16_t SMID;
5228 mptsas_slots_t *slots = mpt->m_active;
5229 mptsas_cmd_t *cmd = NULL;
5230 struct scsi_pkt *pkt;
5231
5232 ASSERT(mutex_owned(&mpt->m_mutex));
5233
5234 scsi_io_success = (pMpi2SCSIIOSuccessReplyDescriptor_t)reply_desc;
5235 SMID = ddi_get16(mpt->m_acc_post_queue_hdl, &scsi_io_success->SMID);
5236
5237 /*
5238 * This is a success reply so just complete the IO. First, do a sanity
5239 * check on the SMID. The final slot is used for TM requests, which
5240 * would not come into this reply handler.
5241 */
5242 if ((SMID == 0) || (SMID > slots->m_n_normal)) {
5243 mptsas_log(mpt, CE_WARN, "?Received invalid SMID of %d\n",
5244 SMID);
5245 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
5246 return;
5247 }
5248
5249 cmd = slots->m_slot[SMID];
5250
5251 /*
5252 * print warning and return if the slot is empty
5253 */
5254 if (cmd == NULL) {
5255 mptsas_log(mpt, CE_WARN, "?NULL command for successful SCSI IO "
5256 "in slot %d", SMID);
5257 return;
5258 }
5259
5260 pkt = CMD2PKT(cmd);
5261 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD |
5262 STATE_GOT_STATUS);
5263 if (cmd->cmd_flags & CFLAG_DMAVALID) {
5264 pkt->pkt_state |= STATE_XFERRED_DATA;
5265 }
5266 pkt->pkt_resid = 0;
5267
5268 if (cmd->cmd_flags & CFLAG_PASSTHRU) {
5269 cmd->cmd_flags |= CFLAG_FINISHED;
5270 cv_broadcast(&mpt->m_passthru_cv);
5271 return;
5272 } else {
5273 mptsas_remove_cmd(mpt, cmd);
5274 }
5275
5276 if (cmd->cmd_flags & CFLAG_RETRY) {
5277 /*
5278 * The target returned QFULL or busy, do not add tihs
5279 * pkt to the doneq since the hba will retry
5280 * this cmd.
5281 *
5282 * The pkt has already been resubmitted in
5283 * mptsas_handle_qfull() or in mptsas_check_scsi_io_error().
5284 * Remove this cmd_flag here.
5285 */
5286 cmd->cmd_flags &= ~CFLAG_RETRY;
5287 } else {
5288 mptsas_doneq_add(mpt, cmd);
5289 }
5290 }
5291
5292 static void
5293 mptsas_handle_address_reply(mptsas_t *mpt,
5294 pMpi2ReplyDescriptorsUnion_t reply_desc)
5295 {
5296 pMpi2AddressReplyDescriptor_t address_reply;
5297 pMPI2DefaultReply_t reply;
5298 mptsas_fw_diagnostic_buffer_t *pBuffer;
5299 uint32_t reply_addr, reply_frame_dma_baseaddr;
5300 uint16_t SMID, iocstatus;
5301 mptsas_slots_t *slots = mpt->m_active;
5302 mptsas_cmd_t *cmd = NULL;
5303 uint8_t function, buffer_type;
5304 m_replyh_arg_t *args;
5305 int reply_frame_no;
5306
5307 ASSERT(mutex_owned(&mpt->m_mutex));
5308
5309 address_reply = (pMpi2AddressReplyDescriptor_t)reply_desc;
5310 reply_addr = ddi_get32(mpt->m_acc_post_queue_hdl,
5311 &address_reply->ReplyFrameAddress);
5312 SMID = ddi_get16(mpt->m_acc_post_queue_hdl, &address_reply->SMID);
5313
5314 /*
5315 * If reply frame is not in the proper range we should ignore this
5316 * message and exit the interrupt handler.
5317 */
5318 reply_frame_dma_baseaddr = mpt->m_reply_frame_dma_addr & 0xffffffffu;
5319 if ((reply_addr < reply_frame_dma_baseaddr) ||
5320 (reply_addr >= (reply_frame_dma_baseaddr +
5321 (mpt->m_reply_frame_size * mpt->m_max_replies))) ||
5322 ((reply_addr - reply_frame_dma_baseaddr) %
5323 mpt->m_reply_frame_size != 0)) {
5324 mptsas_log(mpt, CE_WARN, "?Received invalid reply frame "
5325 "address 0x%x\n", reply_addr);
5326 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
5327 return;
5328 }
5329
5330 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
5331 DDI_DMA_SYNC_FORCPU);
5332 reply = (pMPI2DefaultReply_t)(mpt->m_reply_frame + (reply_addr -
5333 reply_frame_dma_baseaddr));
5334 function = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->Function);
5335
5336 NDBG31(("mptsas_handle_address_reply: function 0x%x, reply_addr=0x%x",
5337 function, reply_addr));
5338
5339 /*
5340 * don't get slot information and command for events since these values
5341 * don't exist
5342 */
5343 if ((function != MPI2_FUNCTION_EVENT_NOTIFICATION) &&
5344 (function != MPI2_FUNCTION_DIAG_BUFFER_POST)) {
5345 /*
5346 * This could be a TM reply, which use the last allocated SMID,
5347 * so allow for that.
5348 */
5349 if ((SMID == 0) || (SMID > (slots->m_n_normal + 1))) {
5350 mptsas_log(mpt, CE_WARN, "?Received invalid SMID of "
5351 "%d\n", SMID);
5352 ddi_fm_service_impact(mpt->m_dip,
5353 DDI_SERVICE_UNAFFECTED);
5354 return;
5355 }
5356
5357 cmd = slots->m_slot[SMID];
5358
5359 /*
5360 * print warning and return if the slot is empty
5361 */
5362 if (cmd == NULL) {
5363 mptsas_log(mpt, CE_WARN, "?NULL command for address "
5364 "reply in slot %d", SMID);
5365 return;
5366 }
5367 if ((cmd->cmd_flags &
5368 (CFLAG_PASSTHRU | CFLAG_CONFIG | CFLAG_FW_DIAG))) {
5369 cmd->cmd_rfm = reply_addr;
5370 cmd->cmd_flags |= CFLAG_FINISHED;
5371 cv_broadcast(&mpt->m_passthru_cv);
5372 cv_broadcast(&mpt->m_config_cv);
5373 cv_broadcast(&mpt->m_fw_diag_cv);
5374 return;
5375 } else if (!(cmd->cmd_flags & CFLAG_FW_CMD)) {
5376 mptsas_remove_cmd(mpt, cmd);
5377 }
5378 NDBG31(("\t\tmptsas_process_intr: slot=%d", SMID));
5379 }
5380 /*
5381 * Depending on the function, we need to handle
5382 * the reply frame (and cmd) differently.
5383 */
5384 switch (function) {
5385 case MPI2_FUNCTION_SCSI_IO_REQUEST:
5386 mptsas_check_scsi_io_error(mpt, (pMpi2SCSIIOReply_t)reply, cmd);
5387 break;
5388 case MPI2_FUNCTION_SCSI_TASK_MGMT:
5389 cmd->cmd_rfm = reply_addr;
5390 mptsas_check_task_mgt(mpt, (pMpi2SCSIManagementReply_t)reply,
5391 cmd);
5392 break;
5393 case MPI2_FUNCTION_FW_DOWNLOAD:
5394 cmd->cmd_flags |= CFLAG_FINISHED;
5395 cv_signal(&mpt->m_fw_cv);
5396 break;
5397 case MPI2_FUNCTION_EVENT_NOTIFICATION:
5398 reply_frame_no = (reply_addr - reply_frame_dma_baseaddr) /
5399 mpt->m_reply_frame_size;
5400 args = &mpt->m_replyh_args[reply_frame_no];
5401 args->mpt = (void *)mpt;
5402 args->rfm = reply_addr;
5403
5404 /*
5405 * Record the event if its type is enabled in
5406 * this mpt instance by ioctl.
5407 */
5408 mptsas_record_event(args);
5409
5410 /*
5411 * Handle time critical events
5412 * NOT_RESPONDING/ADDED only now
5413 */
5414 if (mptsas_handle_event_sync(args) == DDI_SUCCESS) {
5415 /*
5416 * Would not return main process,
5417 * just let taskq resolve ack action
5418 * and ack would be sent in taskq thread
5419 */
5420 NDBG20(("send mptsas_handle_event_sync success"));
5421 }
5422
5423 if (mpt->m_in_reset) {
5424 NDBG20(("dropping event received during reset"));
5425 return;
5426 }
5427
5428 if ((ddi_taskq_dispatch(mpt->m_event_taskq, mptsas_handle_event,
5429 (void *)args, DDI_NOSLEEP)) != DDI_SUCCESS) {
5430 mptsas_log(mpt, CE_WARN, "No memory available"
5431 "for dispatch taskq");
5432 /*
5433 * Return the reply frame to the free queue.
5434 */
5435 ddi_put32(mpt->m_acc_free_queue_hdl,
5436 &((uint32_t *)(void *)
5437 mpt->m_free_queue)[mpt->m_free_index], reply_addr);
5438 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
5439 DDI_DMA_SYNC_FORDEV);
5440 if (++mpt->m_free_index == mpt->m_free_queue_depth) {
5441 mpt->m_free_index = 0;
5442 }
5443
5444 ddi_put32(mpt->m_datap,
5445 &mpt->m_reg->ReplyFreeHostIndex, mpt->m_free_index);
5446 }
5447 return;
5448 case MPI2_FUNCTION_DIAG_BUFFER_POST:
5449 /*
5450 * If SMID is 0, this implies that the reply is due to a
5451 * release function with a status that the buffer has been
5452 * released. Set the buffer flags accordingly.
5453 */
5454 if (SMID == 0) {
5455 iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
5456 &reply->IOCStatus);
5457 buffer_type = ddi_get8(mpt->m_acc_reply_frame_hdl,
5458 &(((pMpi2DiagBufferPostReply_t)reply)->BufferType));
5459 if (iocstatus == MPI2_IOCSTATUS_DIAGNOSTIC_RELEASED) {
5460 pBuffer =
5461 &mpt->m_fw_diag_buffer_list[buffer_type];
5462 pBuffer->valid_data = TRUE;
5463 pBuffer->owned_by_firmware = FALSE;
5464 pBuffer->immediate = FALSE;
5465 }
5466 } else {
5467 /*
5468 * Normal handling of diag post reply with SMID.
5469 */
5470 cmd = slots->m_slot[SMID];
5471
5472 /*
5473 * print warning and return if the slot is empty
5474 */
5475 if (cmd == NULL) {
5476 mptsas_log(mpt, CE_WARN, "?NULL command for "
5477 "address reply in slot %d", SMID);
5478 return;
5479 }
5480 cmd->cmd_rfm = reply_addr;
5481 cmd->cmd_flags |= CFLAG_FINISHED;
5482 cv_broadcast(&mpt->m_fw_diag_cv);
5483 }
5484 return;
5485 default:
5486 mptsas_log(mpt, CE_WARN, "Unknown function 0x%x ", function);
5487 break;
5488 }
5489
5490 /*
5491 * Return the reply frame to the free queue.
5492 */
5493 ddi_put32(mpt->m_acc_free_queue_hdl,
5494 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index],
5495 reply_addr);
5496 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
5497 DDI_DMA_SYNC_FORDEV);
5498 if (++mpt->m_free_index == mpt->m_free_queue_depth) {
5499 mpt->m_free_index = 0;
5500 }
5501 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
5502 mpt->m_free_index);
5503
5504 if (cmd->cmd_flags & CFLAG_FW_CMD)
5505 return;
5506
5507 if (cmd->cmd_flags & CFLAG_RETRY) {
5508 /*
5509 * The target returned QFULL or busy, do not add this
5510 * pkt to the doneq since the hba will retry
5511 * this cmd.
5512 *
5513 * The pkt has already been resubmitted in
5514 * mptsas_handle_qfull() or in mptsas_check_scsi_io_error().
5515 * Remove this cmd_flag here.
5516 */
5517 cmd->cmd_flags &= ~CFLAG_RETRY;
5518 } else {
5519 mptsas_doneq_add(mpt, cmd);
5520 }
5521 }
5522
5523 #ifdef MPTSAS_DEBUG
5524 static uint8_t mptsas_last_sense[256];
5525 #endif
5526
5527 static void
5528 mptsas_check_scsi_io_error(mptsas_t *mpt, pMpi2SCSIIOReply_t reply,
5529 mptsas_cmd_t *cmd)
5530 {
5531 uint8_t scsi_status, scsi_state;
5532 uint16_t ioc_status, cmd_rqs_len;
5533 uint32_t xferred, sensecount, responsedata, loginfo = 0;
5534 struct scsi_pkt *pkt;
5535 struct scsi_arq_status *arqstat;
5536 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
5537 uint8_t *sensedata = NULL;
5538 uint64_t sas_wwn;
5539 uint8_t phy;
5540 char wwn_str[MPTSAS_WWN_STRLEN];
5541
5542 scsi_status = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->SCSIStatus);
5543 ioc_status = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->IOCStatus);
5544 scsi_state = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->SCSIState);
5545 xferred = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->TransferCount);
5546 sensecount = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->SenseCount);
5547 responsedata = ddi_get32(mpt->m_acc_reply_frame_hdl,
5548 &reply->ResponseInfo);
5549
5550 if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
5551 sas_wwn = ptgt->m_addr.mta_wwn;
5552 phy = ptgt->m_phynum;
5553 if (sas_wwn == 0) {
5554 (void) sprintf(wwn_str, "p%x", phy);
5555 } else {
5556 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn);
5557 }
5558 loginfo = ddi_get32(mpt->m_acc_reply_frame_hdl,
5559 &reply->IOCLogInfo);
5560 mptsas_log(mpt, CE_NOTE,
5561 "?Log info 0x%x received for target %d %s.\n"
5562 "\tscsi_status=0x%x, ioc_status=0x%x, scsi_state=0x%x",
5563 loginfo, Tgt(cmd), wwn_str, scsi_status, ioc_status,
5564 scsi_state);
5565 }
5566
5567 NDBG31(("\t\tscsi_status=0x%x, ioc_status=0x%x, scsi_state=0x%x",
5568 scsi_status, ioc_status, scsi_state));
5569
5570 pkt = CMD2PKT(cmd);
5571 *(pkt->pkt_scbp) = scsi_status;
5572
5573 if (loginfo == 0x31170000) {
5574 /*
5575 * if loginfo PL_LOGINFO_CODE_IO_DEVICE_MISSING_DELAY_RETRY
5576 * 0x31170000 comes, that means the device missing delay
5577 * is in progressing, the command need retry later.
5578 */
5579 *(pkt->pkt_scbp) = STATUS_BUSY;
5580 return;
5581 }
5582
5583 if ((scsi_state & MPI2_SCSI_STATE_NO_SCSI_STATUS) &&
5584 ((ioc_status & MPI2_IOCSTATUS_MASK) ==
5585 MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE)) {
5586 pkt->pkt_reason = CMD_INCOMPLETE;
5587 pkt->pkt_state |= STATE_GOT_BUS;
5588 if (ptgt->m_reset_delay == 0) {
5589 mptsas_set_throttle(mpt, ptgt,
5590 DRAIN_THROTTLE);
5591 }
5592 return;
5593 }
5594
5595 if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) {
5596 responsedata &= 0x000000FF;
5597 if (responsedata & MPTSAS_SCSI_RESPONSE_CODE_TLR_OFF) {
5598 mptsas_log(mpt, CE_NOTE, "Do not support the TLR\n");
5599 pkt->pkt_reason = CMD_TLR_OFF;
5600 return;
5601 }
5602 }
5603
5604
5605 switch (scsi_status) {
5606 case MPI2_SCSI_STATUS_CHECK_CONDITION:
5607 pkt->pkt_resid = (cmd->cmd_dmacount - xferred);
5608 arqstat = (void*)(pkt->pkt_scbp);
5609 arqstat->sts_rqpkt_status = *((struct scsi_status *)
5610 (pkt->pkt_scbp));
5611 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET |
5612 STATE_SENT_CMD | STATE_GOT_STATUS | STATE_ARQ_DONE);
5613 if (cmd->cmd_flags & CFLAG_XARQ) {
5614 pkt->pkt_state |= STATE_XARQ_DONE;
5615 }
5616 if (pkt->pkt_resid != cmd->cmd_dmacount) {
5617 pkt->pkt_state |= STATE_XFERRED_DATA;
5618 }
5619 arqstat->sts_rqpkt_reason = pkt->pkt_reason;
5620 arqstat->sts_rqpkt_state = pkt->pkt_state;
5621 arqstat->sts_rqpkt_state |= STATE_XFERRED_DATA;
5622 arqstat->sts_rqpkt_statistics = pkt->pkt_statistics;
5623 sensedata = (uint8_t *)&arqstat->sts_sensedata;
5624 cmd_rqs_len = cmd->cmd_extrqslen ?
5625 cmd->cmd_extrqslen : cmd->cmd_rqslen;
5626 (void) ddi_dma_sync(mpt->m_dma_req_sense_hdl, 0, 0,
5627 DDI_DMA_SYNC_FORKERNEL);
5628 #ifdef MPTSAS_DEBUG
5629 bcopy(cmd->cmd_arq_buf, mptsas_last_sense,
5630 ((cmd_rqs_len >= sizeof (mptsas_last_sense)) ?
5631 sizeof (mptsas_last_sense):cmd_rqs_len));
5632 #endif
5633 bcopy((uchar_t *)cmd->cmd_arq_buf, sensedata,
5634 ((cmd_rqs_len >= sensecount) ? sensecount :
5635 cmd_rqs_len));
5636 arqstat->sts_rqpkt_resid = (cmd_rqs_len - sensecount);
5637 cmd->cmd_flags |= CFLAG_CMDARQ;
5638 /*
5639 * Set proper status for pkt if autosense was valid
5640 */
5641 if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) {
5642 struct scsi_status zero_status = { 0 };
5643 arqstat->sts_rqpkt_status = zero_status;
5644 }
5645
5646 /*
5647 * ASC=0x47 is parity error
5648 * ASC=0x48 is initiator detected error received
5649 */
5650 if ((scsi_sense_key(sensedata) == KEY_ABORTED_COMMAND) &&
5651 ((scsi_sense_asc(sensedata) == 0x47) ||
5652 (scsi_sense_asc(sensedata) == 0x48))) {
5653 mptsas_log(mpt, CE_NOTE, "Aborted_command!");
5654 }
5655
5656 /*
5657 * ASC/ASCQ=0x3F/0x0E means report_luns data changed
5658 * ASC/ASCQ=0x25/0x00 means invalid lun
5659 */
5660 if (((scsi_sense_key(sensedata) == KEY_UNIT_ATTENTION) &&
5661 (scsi_sense_asc(sensedata) == 0x3F) &&
5662 (scsi_sense_ascq(sensedata) == 0x0E)) ||
5663 ((scsi_sense_key(sensedata) == KEY_ILLEGAL_REQUEST) &&
5664 (scsi_sense_asc(sensedata) == 0x25) &&
5665 (scsi_sense_ascq(sensedata) == 0x00))) {
5666 mptsas_topo_change_list_t *topo_node = NULL;
5667
5668 topo_node = kmem_zalloc(
5669 sizeof (mptsas_topo_change_list_t),
5670 KM_NOSLEEP);
5671 if (topo_node == NULL) {
5672 mptsas_log(mpt, CE_NOTE, "No memory"
5673 "resource for handle SAS dynamic"
5674 "reconfigure.\n");
5675 break;
5676 }
5677 topo_node->mpt = mpt;
5678 topo_node->event = MPTSAS_DR_EVENT_RECONFIG_TARGET;
5679 topo_node->un.phymask = ptgt->m_addr.mta_phymask;
5680 topo_node->devhdl = ptgt->m_devhdl;
5681 topo_node->object = (void *)ptgt;
5682 topo_node->flags = MPTSAS_TOPO_FLAG_LUN_ASSOCIATED;
5683
5684 if ((ddi_taskq_dispatch(mpt->m_dr_taskq,
5685 mptsas_handle_dr,
5686 (void *)topo_node,
5687 DDI_NOSLEEP)) != DDI_SUCCESS) {
5688 kmem_free(topo_node,
5689 sizeof (mptsas_topo_change_list_t));
5690 mptsas_log(mpt, CE_NOTE, "mptsas start taskq"
5691 "for handle SAS dynamic reconfigure"
5692 "failed. \n");
5693 }
5694 }
5695 break;
5696 case MPI2_SCSI_STATUS_GOOD:
5697 switch (ioc_status & MPI2_IOCSTATUS_MASK) {
5698 case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
5699 pkt->pkt_reason = CMD_DEV_GONE;
5700 pkt->pkt_state |= STATE_GOT_BUS;
5701 if (ptgt->m_reset_delay == 0) {
5702 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
5703 }
5704 NDBG31(("lost disk for target%d, command:%x",
5705 Tgt(cmd), pkt->pkt_cdbp[0]));
5706 break;
5707 case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN:
5708 NDBG31(("data overrun: xferred=%d", xferred));
5709 NDBG31(("dmacount=%d", cmd->cmd_dmacount));
5710 pkt->pkt_reason = CMD_DATA_OVR;
5711 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET
5712 | STATE_SENT_CMD | STATE_GOT_STATUS
5713 | STATE_XFERRED_DATA);
5714 pkt->pkt_resid = 0;
5715 break;
5716 case MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:
5717 case MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN:
5718 NDBG31(("data underrun: xferred=%d", xferred));
5719 NDBG31(("dmacount=%d", cmd->cmd_dmacount));
5720 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET
5721 | STATE_SENT_CMD | STATE_GOT_STATUS);
5722 pkt->pkt_resid = (cmd->cmd_dmacount - xferred);
5723 if (pkt->pkt_resid != cmd->cmd_dmacount) {
5724 pkt->pkt_state |= STATE_XFERRED_DATA;
5725 }
5726 break;
5727 case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED:
5728 if (cmd->cmd_active_expiration <= gethrtime()) {
5729 /*
5730 * When timeout requested, propagate
5731 * proper reason and statistics to
5732 * target drivers.
5733 */
5734 mptsas_set_pkt_reason(mpt, cmd, CMD_TIMEOUT,
5735 STAT_BUS_RESET | STAT_TIMEOUT);
5736 } else {
5737 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET,
5738 STAT_BUS_RESET);
5739 }
5740 break;
5741 case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED:
5742 case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED:
5743 mptsas_set_pkt_reason(mpt,
5744 cmd, CMD_RESET, STAT_DEV_RESET);
5745 break;
5746 case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR:
5747 case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR:
5748 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET);
5749 mptsas_set_pkt_reason(mpt,
5750 cmd, CMD_TERMINATED, STAT_TERMINATED);
5751 break;
5752 case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES:
5753 case MPI2_IOCSTATUS_BUSY:
5754 /*
5755 * set throttles to drain
5756 */
5757 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
5758 ptgt = refhash_next(mpt->m_targets, ptgt)) {
5759 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
5760 }
5761
5762 /*
5763 * retry command
5764 */
5765 cmd->cmd_flags |= CFLAG_RETRY;
5766 cmd->cmd_pkt_flags |= FLAG_HEAD;
5767
5768 (void) mptsas_accept_pkt(mpt, cmd);
5769 break;
5770 default:
5771 mptsas_log(mpt, CE_WARN,
5772 "unknown ioc_status = %x\n", ioc_status);
5773 mptsas_log(mpt, CE_CONT, "scsi_state = %x, transfer "
5774 "count = %x, scsi_status = %x", scsi_state,
5775 xferred, scsi_status);
5776 break;
5777 }
5778 break;
5779 case MPI2_SCSI_STATUS_TASK_SET_FULL:
5780 mptsas_handle_qfull(mpt, cmd);
5781 break;
5782 case MPI2_SCSI_STATUS_BUSY:
5783 NDBG31(("scsi_status busy received"));
5784 break;
5785 case MPI2_SCSI_STATUS_RESERVATION_CONFLICT:
5786 NDBG31(("scsi_status reservation conflict received"));
5787 break;
5788 default:
5789 mptsas_log(mpt, CE_WARN, "scsi_status=%x, ioc_status=%x\n",
5790 scsi_status, ioc_status);
5791 mptsas_log(mpt, CE_WARN,
5792 "mptsas_process_intr: invalid scsi status\n");
5793 break;
5794 }
5795 }
5796
5797 static void
5798 mptsas_check_task_mgt(mptsas_t *mpt, pMpi2SCSIManagementReply_t reply,
5799 mptsas_cmd_t *cmd)
5800 {
5801 uint8_t task_type;
5802 uint16_t ioc_status;
5803 uint32_t log_info;
5804 uint16_t dev_handle;
5805 struct scsi_pkt *pkt = CMD2PKT(cmd);
5806
5807 task_type = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->TaskType);
5808 ioc_status = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->IOCStatus);
5809 log_info = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->IOCLogInfo);
5810 dev_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->DevHandle);
5811
5812 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
5813 mptsas_log(mpt, CE_WARN, "mptsas_check_task_mgt: Task 0x%x "
5814 "failed. IOCStatus=0x%x IOCLogInfo=0x%x target=%d\n",
5815 task_type, ioc_status, log_info, dev_handle);
5816 pkt->pkt_reason = CMD_INCOMPLETE;
5817 return;
5818 }
5819
5820 switch (task_type) {
5821 case MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK:
5822 case MPI2_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET:
5823 case MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK:
5824 case MPI2_SCSITASKMGMT_TASKTYPE_CLR_ACA:
5825 case MPI2_SCSITASKMGMT_TASKTYPE_QRY_TASK_SET:
5826 case MPI2_SCSITASKMGMT_TASKTYPE_QRY_UNIT_ATTENTION:
5827 break;
5828 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
5829 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
5830 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
5831 /*
5832 * Check for invalid DevHandle of 0 in case application
5833 * sends bad command. DevHandle of 0 could cause problems.
5834 */
5835 if (dev_handle == 0) {
5836 mptsas_log(mpt, CE_WARN, "!Can't flush target with"
5837 " DevHandle of 0.");
5838 } else {
5839 mptsas_flush_target(mpt, dev_handle, Lun(cmd),
5840 task_type);
5841 }
5842 break;
5843 default:
5844 mptsas_log(mpt, CE_WARN, "Unknown task management type %d.",
5845 task_type);
5846 mptsas_log(mpt, CE_WARN, "ioc status = %x", ioc_status);
5847 break;
5848 }
5849 }
5850
5851 static void
5852 mptsas_doneq_thread(mptsas_doneq_thread_arg_t *arg)
5853 {
5854 mptsas_t *mpt = arg->mpt;
5855 uint64_t t = arg->t;
5856 mptsas_cmd_t *cmd;
5857 struct scsi_pkt *pkt;
5858 mptsas_doneq_thread_list_t *item = &mpt->m_doneq_thread_id[t];
5859
5860 mutex_enter(&item->mutex);
5861 while (item->flag & MPTSAS_DONEQ_THREAD_ACTIVE) {
5862 if (!item->doneq) {
5863 cv_wait(&item->cv, &item->mutex);
5864 }
5865 pkt = NULL;
5866 if ((cmd = mptsas_doneq_thread_rm(mpt, t)) != NULL) {
5867 cmd->cmd_flags |= CFLAG_COMPLETED;
5868 pkt = CMD2PKT(cmd);
5869 }
5870 mutex_exit(&item->mutex);
5871 if (pkt) {
5872 mptsas_pkt_comp(pkt, cmd);
5873 }
5874 mutex_enter(&item->mutex);
5875 }
5876 mutex_exit(&item->mutex);
5877 mutex_enter(&mpt->m_doneq_mutex);
5878 mpt->m_doneq_thread_n--;
5879 cv_broadcast(&mpt->m_doneq_thread_cv);
5880 mutex_exit(&mpt->m_doneq_mutex);
5881 }
5882
5883
5884 /*
5885 * mpt interrupt handler.
5886 */
5887 static uint_t
5888 mptsas_intr(caddr_t arg1, caddr_t arg2)
5889 {
5890 mptsas_t *mpt = (void *)arg1;
5891 pMpi2ReplyDescriptorsUnion_t reply_desc_union;
5892 uchar_t did_reply = FALSE;
5893
5894 NDBG1(("mptsas_intr: arg1 0x%p arg2 0x%p", (void *)arg1, (void *)arg2));
5895
5896 mutex_enter(&mpt->m_mutex);
5897
5898 /*
5899 * If interrupts are shared by two channels then check whether this
5900 * interrupt is genuinely for this channel by making sure first the
5901 * chip is in high power state.
5902 */
5903 if ((mpt->m_options & MPTSAS_OPT_PM) &&
5904 (mpt->m_power_level != PM_LEVEL_D0)) {
5905 mutex_exit(&mpt->m_mutex);
5906 return (DDI_INTR_UNCLAIMED);
5907 }
5908
5909 /*
5910 * If polling, interrupt was triggered by some shared interrupt because
5911 * IOC interrupts are disabled during polling, so polling routine will
5912 * handle any replies. Considering this, if polling is happening,
5913 * return with interrupt unclaimed.
5914 */
5915 if (mpt->m_polled_intr) {
5916 mutex_exit(&mpt->m_mutex);
5917 mptsas_log(mpt, CE_WARN, "mpt_sas: Unclaimed interrupt");
5918 return (DDI_INTR_UNCLAIMED);
5919 }
5920
5921 /*
5922 * Read the istat register.
5923 */
5924 if ((INTPENDING(mpt)) != 0) {
5925 /*
5926 * read fifo until empty.
5927 */
5928 #ifndef __lock_lint
5929 _NOTE(CONSTCOND)
5930 #endif
5931 while (TRUE) {
5932 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0,
5933 DDI_DMA_SYNC_FORCPU);
5934 reply_desc_union = (pMpi2ReplyDescriptorsUnion_t)
5935 MPTSAS_GET_NEXT_REPLY(mpt, mpt->m_post_index);
5936
5937 if (ddi_get32(mpt->m_acc_post_queue_hdl,
5938 &reply_desc_union->Words.Low) == 0xFFFFFFFF ||
5939 ddi_get32(mpt->m_acc_post_queue_hdl,
5940 &reply_desc_union->Words.High) == 0xFFFFFFFF) {
5941 break;
5942 }
5943
5944 /*
5945 * The reply is valid, process it according to its
5946 * type. Also, set a flag for updating the reply index
5947 * after they've all been processed.
5948 */
5949 did_reply = TRUE;
5950
5951 mptsas_process_intr(mpt, reply_desc_union);
5952
5953 /*
5954 * Increment post index and roll over if needed.
5955 */
5956 if (++mpt->m_post_index == mpt->m_post_queue_depth) {
5957 mpt->m_post_index = 0;
5958 }
5959 }
5960
5961 /*
5962 * Update the global reply index if at least one reply was
5963 * processed.
5964 */
5965 if (did_reply) {
5966 ddi_put32(mpt->m_datap,
5967 &mpt->m_reg->ReplyPostHostIndex, mpt->m_post_index);
5968 }
5969 } else {
5970 mutex_exit(&mpt->m_mutex);
5971 return (DDI_INTR_UNCLAIMED);
5972 }
5973 NDBG1(("mptsas_intr complete"));
5974
5975 /*
5976 * If no helper threads are created, process the doneq in ISR. If
5977 * helpers are created, use the doneq length as a metric to measure the
5978 * load on the interrupt CPU. If it is long enough, which indicates the
5979 * load is heavy, then we deliver the IO completions to the helpers.
5980 * This measurement has some limitations, although it is simple and
5981 * straightforward and works well for most of the cases at present.
5982 */
5983 if (!mpt->m_doneq_thread_n ||
5984 (mpt->m_doneq_len <= mpt->m_doneq_length_threshold)) {
5985 mptsas_doneq_empty(mpt);
5986 } else {
5987 mptsas_deliver_doneq_thread(mpt);
5988 }
5989
5990 /*
5991 * If there are queued cmd, start them now.
5992 */
5993 if (mpt->m_waitq != NULL) {
5994 mptsas_restart_waitq(mpt);
5995 }
5996
5997 mutex_exit(&mpt->m_mutex);
5998 return (DDI_INTR_CLAIMED);
5999 }
6000
6001 static void
6002 mptsas_process_intr(mptsas_t *mpt,
6003 pMpi2ReplyDescriptorsUnion_t reply_desc_union)
6004 {
6005 uint8_t reply_type;
6006
6007 ASSERT(mutex_owned(&mpt->m_mutex));
6008
6009 /*
6010 * The reply is valid, process it according to its
6011 * type. Also, set a flag for updated the reply index
6012 * after they've all been processed.
6013 */
6014 reply_type = ddi_get8(mpt->m_acc_post_queue_hdl,
6015 &reply_desc_union->Default.ReplyFlags);
6016 reply_type &= MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
6017 if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS ||
6018 reply_type == MPI25_RPY_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO_SUCCESS) {
6019 mptsas_handle_scsi_io_success(mpt, reply_desc_union);
6020 } else if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) {
6021 mptsas_handle_address_reply(mpt, reply_desc_union);
6022 } else {
6023 mptsas_log(mpt, CE_WARN, "?Bad reply type %x", reply_type);
6024 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
6025 }
6026
6027 /*
6028 * Clear the reply descriptor for re-use and increment
6029 * index.
6030 */
6031 ddi_put64(mpt->m_acc_post_queue_hdl,
6032 &((uint64_t *)(void *)mpt->m_post_queue)[mpt->m_post_index],
6033 0xFFFFFFFFFFFFFFFF);
6034 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0,
6035 DDI_DMA_SYNC_FORDEV);
6036 }
6037
6038 /*
6039 * handle qfull condition
6040 */
6041 static void
6042 mptsas_handle_qfull(mptsas_t *mpt, mptsas_cmd_t *cmd)
6043 {
6044 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
6045
6046 if ((++cmd->cmd_qfull_retries > ptgt->m_qfull_retries) ||
6047 (ptgt->m_qfull_retries == 0)) {
6048 /*
6049 * We have exhausted the retries on QFULL, or,
6050 * the target driver has indicated that it
6051 * wants to handle QFULL itself by setting
6052 * qfull-retries capability to 0. In either case
6053 * we want the target driver's QFULL handling
6054 * to kick in. We do this by having pkt_reason
6055 * as CMD_CMPLT and pkt_scbp as STATUS_QFULL.
6056 */
6057 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
6058 } else {
6059 if (ptgt->m_reset_delay == 0) {
6060 ptgt->m_t_throttle =
6061 max((ptgt->m_t_ncmds - 2), 0);
6062 }
6063
6064 cmd->cmd_pkt_flags |= FLAG_HEAD;
6065 cmd->cmd_flags &= ~(CFLAG_TRANFLAG);
6066 cmd->cmd_flags |= CFLAG_RETRY;
6067
6068 (void) mptsas_accept_pkt(mpt, cmd);
6069
6070 /*
6071 * when target gives queue full status with no commands
6072 * outstanding (m_t_ncmds == 0), throttle is set to 0
6073 * (HOLD_THROTTLE), and the queue full handling start
6074 * (see psarc/1994/313); if there are commands outstanding,
6075 * throttle is set to (m_t_ncmds - 2)
6076 */
6077 if (ptgt->m_t_throttle == HOLD_THROTTLE) {
6078 /*
6079 * By setting throttle to QFULL_THROTTLE, we
6080 * avoid submitting new commands and in
6081 * mptsas_restart_cmd find out slots which need
6082 * their throttles to be cleared.
6083 */
6084 mptsas_set_throttle(mpt, ptgt, QFULL_THROTTLE);
6085 if (mpt->m_restart_cmd_timeid == 0) {
6086 mpt->m_restart_cmd_timeid =
6087 timeout(mptsas_restart_cmd, mpt,
6088 ptgt->m_qfull_retry_interval);
6089 }
6090 }
6091 }
6092 }
6093
6094 mptsas_phymask_t
6095 mptsas_physport_to_phymask(mptsas_t *mpt, uint8_t physport)
6096 {
6097 mptsas_phymask_t phy_mask = 0;
6098 uint8_t i = 0;
6099
6100 NDBG20(("mptsas%d physport_to_phymask enter", mpt->m_instance));
6101
6102 ASSERT(mutex_owned(&mpt->m_mutex));
6103
6104 /*
6105 * If physport is 0xFF, this is a RAID volume. Use phymask of 0.
6106 */
6107 if (physport == 0xFF) {
6108 return (0);
6109 }
6110
6111 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
6112 if (mpt->m_phy_info[i].attached_devhdl &&
6113 (mpt->m_phy_info[i].phy_mask != 0) &&
6114 (mpt->m_phy_info[i].port_num == physport)) {
6115 phy_mask = mpt->m_phy_info[i].phy_mask;
6116 break;
6117 }
6118 }
6119 NDBG20(("mptsas%d physport_to_phymask:physport :%x phymask :%x, ",
6120 mpt->m_instance, physport, phy_mask));
6121 return (phy_mask);
6122 }
6123
6124 /*
6125 * mpt free device handle after device gone, by use of passthrough
6126 */
6127 static int
6128 mptsas_free_devhdl(mptsas_t *mpt, uint16_t devhdl)
6129 {
6130 Mpi2SasIoUnitControlRequest_t req;
6131 Mpi2SasIoUnitControlReply_t rep;
6132 int ret;
6133
6134 ASSERT(mutex_owned(&mpt->m_mutex));
6135
6136 /*
6137 * Need to compose a SAS IO Unit Control request message
6138 * and call mptsas_do_passthru() function
6139 */
6140 bzero(&req, sizeof (req));
6141 bzero(&rep, sizeof (rep));
6142
6143 req.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
6144 req.Operation = MPI2_SAS_OP_REMOVE_DEVICE;
6145 req.DevHandle = LE_16(devhdl);
6146
6147 ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, NULL,
6148 sizeof (req), sizeof (rep), NULL, 0, NULL, 0, 60, FKIOCTL);
6149 if (ret != 0) {
6150 cmn_err(CE_WARN, "mptsas_free_devhdl: passthru SAS IO Unit "
6151 "Control error %d", ret);
6152 return (DDI_FAILURE);
6153 }
6154
6155 /* do passthrough success, check the ioc status */
6156 if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) {
6157 cmn_err(CE_WARN, "mptsas_free_devhdl: passthru SAS IO Unit "
6158 "Control IOCStatus %d", LE_16(rep.IOCStatus));
6159 return (DDI_FAILURE);
6160 }
6161
6162 return (DDI_SUCCESS);
6163 }
6164
6165 /*
6166 * We have a SATA target that has changed, which means the "bridge-port"
6167 * property must be updated to reflect the SAS WWN of the new attachment point.
6168 * This may change if a SATA device changes which bay, and therefore phy, it is
6169 * plugged into. This SATA device may be a multipath virtual device or may be a
6170 * physical device. We have to handle both cases.
6171 */
6172 static boolean_t
6173 mptsas_update_sata_bridge(mptsas_t *mpt, dev_info_t *parent,
6174 mptsas_target_t *ptgt)
6175 {
6176 int rval;
6177 uint16_t dev_hdl;
6178 uint16_t pdev_hdl;
6179 uint64_t dev_sas_wwn;
6180 uint8_t physport;
6181 uint8_t phy_id;
6182 uint32_t page_address;
6183 uint16_t bay_num, enclosure, io_flags;
6184 uint32_t dev_info;
6185 char uabuf[SCSI_WWN_BUFLEN];
6186 dev_info_t *dip;
6187 mdi_pathinfo_t *pip;
6188
6189 mutex_enter(&mpt->m_mutex);
6190 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
6191 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)ptgt->m_devhdl;
6192 rval = mptsas_get_sas_device_page0(mpt, page_address, &dev_hdl,
6193 &dev_sas_wwn, &dev_info, &physport, &phy_id, &pdev_hdl, &bay_num,
6194 &enclosure, &io_flags);
6195 mutex_exit(&mpt->m_mutex);
6196 if (rval != DDI_SUCCESS) {
6197 mptsas_log(mpt, CE_WARN, "unable to get SAS page 0 for "
6198 "handle %d", page_address);
6199 return (B_FALSE);
6200 }
6201
6202 if (scsi_wwn_to_wwnstr(dev_sas_wwn, 1, uabuf) == NULL) {
6203 mptsas_log(mpt, CE_WARN,
6204 "mptsas unable to format SATA bridge WWN");
6205 return (B_FALSE);
6206 }
6207
6208 if (mpt->m_mpxio_enable == TRUE && (pip = mptsas_find_path_addr(parent,
6209 ptgt->m_addr.mta_wwn, 0)) != NULL) {
6210 if (mdi_prop_update_string(pip, SCSI_ADDR_PROP_BRIDGE_PORT,
6211 uabuf) != DDI_SUCCESS) {
6212 mptsas_log(mpt, CE_WARN,
6213 "mptsas unable to create SCSI bridge port "
6214 "property for SATA device");
6215 return (B_FALSE);
6216 }
6217 return (B_TRUE);
6218 }
6219
6220 if ((dip = mptsas_find_child_addr(parent, ptgt->m_addr.mta_wwn,
6221 0)) != NULL) {
6222 if (ndi_prop_update_string(DDI_DEV_T_NONE, dip,
6223 SCSI_ADDR_PROP_BRIDGE_PORT, uabuf) != DDI_PROP_SUCCESS) {
6224 mptsas_log(mpt, CE_WARN,
6225 "mptsas unable to create SCSI bridge port "
6226 "property for SATA device");
6227 return (B_FALSE);
6228 }
6229 return (B_TRUE);
6230 }
6231
6232 mptsas_log(mpt, CE_WARN, "mptsas failed to find dev_info_t or "
6233 "mdi_pathinfo_t for target with WWN %016" PRIx64,
6234 ptgt->m_addr.mta_wwn);
6235
6236 return (B_FALSE);
6237 }
6238
6239 static void
6240 mptsas_update_phymask(mptsas_t *mpt)
6241 {
6242 mptsas_phymask_t mask = 0, phy_mask;
6243 char *phy_mask_name;
6244 uint8_t current_port;
6245 int i, j;
6246
6247 NDBG20(("mptsas%d update phymask ", mpt->m_instance));
6248
6249 ASSERT(mutex_owned(&mpt->m_mutex));
6250
6251 (void) mptsas_get_sas_io_unit_page(mpt);
6252
6253 phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP);
6254
6255 for (i = 0; i < mpt->m_num_phys; i++) {
6256 phy_mask = 0x00;
6257
6258 if (mpt->m_phy_info[i].attached_devhdl == 0)
6259 continue;
6260
6261 bzero(phy_mask_name, sizeof (phy_mask_name));
6262
6263 current_port = mpt->m_phy_info[i].port_num;
6264
6265 if ((mask & (1 << i)) != 0)
6266 continue;
6267
6268 for (j = 0; j < mpt->m_num_phys; j++) {
6269 if (mpt->m_phy_info[j].attached_devhdl &&
6270 (mpt->m_phy_info[j].port_num == current_port)) {
6271 phy_mask |= (1 << j);
6272 }
6273 }
6274 mask = mask | phy_mask;
6275
6276 for (j = 0; j < mpt->m_num_phys; j++) {
6277 if ((phy_mask >> j) & 0x01) {
6278 mpt->m_phy_info[j].phy_mask = phy_mask;
6279 }
6280 }
6281
6282 (void) sprintf(phy_mask_name, "%x", phy_mask);
6283
6284 mutex_exit(&mpt->m_mutex);
6285 /*
6286 * register a iport, if the port has already been existed
6287 * SCSA will do nothing and just return.
6288 */
6289 (void) scsi_hba_iport_register(mpt->m_dip, phy_mask_name);
6290 mutex_enter(&mpt->m_mutex);
6291 }
6292 kmem_free(phy_mask_name, MPTSAS_MAX_PHYS);
6293 NDBG20(("mptsas%d update phymask return", mpt->m_instance));
6294 }
6295
6296 /*
6297 * mptsas_handle_dr is a task handler for DR, the DR action includes:
6298 * 1. Directly attched Device Added/Removed.
6299 * 2. Expander Device Added/Removed.
6300 * 3. Indirectly Attached Device Added/Expander.
6301 * 4. LUNs of a existing device status change.
6302 * 5. RAID volume created/deleted.
6303 * 6. Member of RAID volume is released because of RAID deletion.
6304 * 7. Physical disks are removed because of RAID creation.
6305 */
6306 static void
6307 mptsas_handle_dr(void *args)
6308 {
6309 mptsas_topo_change_list_t *topo_node = NULL;
6310 mptsas_topo_change_list_t *save_node = NULL;
6311 mptsas_t *mpt;
6312 dev_info_t *parent = NULL;
6313 mptsas_phymask_t phymask = 0;
6314 char *phy_mask_name;
6315 uint8_t flags = 0, physport = 0xff;
6316 uint8_t port_update = 0;
6317 uint_t event;
6318
6319 topo_node = (mptsas_topo_change_list_t *)args;
6320
6321 mpt = topo_node->mpt;
6322 event = topo_node->event;
6323 flags = topo_node->flags;
6324
6325 phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP);
6326
6327 NDBG20(("mptsas%d handle_dr enter", mpt->m_instance));
6328
6329 switch (event) {
6330 case MPTSAS_DR_EVENT_RECONFIG_TARGET:
6331 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) ||
6332 (flags == MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE) ||
6333 (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED)) {
6334 /*
6335 * Direct attached or expander attached device added
6336 * into system or a Phys Disk that is being unhidden.
6337 */
6338 port_update = 1;
6339 }
6340 break;
6341 case MPTSAS_DR_EVENT_RECONFIG_SMP:
6342 /*
6343 * New expander added into system, it must be the head
6344 * of topo_change_list_t
6345 */
6346 port_update = 1;
6347 break;
6348 default:
6349 port_update = 0;
6350 break;
6351 }
6352 /*
6353 * All cases port_update == 1 may cause initiator port form change
6354 */
6355 mutex_enter(&mpt->m_mutex);
6356 if (mpt->m_port_chng && port_update) {
6357 /*
6358 * mpt->m_port_chng flag indicates some PHYs of initiator
6359 * port have changed to online. So when expander added or
6360 * directly attached device online event come, we force to
6361 * update port information by issueing SAS IO Unit Page and
6362 * update PHYMASKs.
6363 */
6364 (void) mptsas_update_phymask(mpt);
6365 mpt->m_port_chng = 0;
6366
6367 }
6368 mutex_exit(&mpt->m_mutex);
6369 while (topo_node) {
6370 phymask = 0;
6371 if (parent == NULL) {
6372 physport = topo_node->un.physport;
6373 event = topo_node->event;
6374 flags = topo_node->flags;
6375 if (event & (MPTSAS_DR_EVENT_OFFLINE_TARGET |
6376 MPTSAS_DR_EVENT_OFFLINE_SMP)) {
6377 /*
6378 * For all offline events, phymask is known
6379 */
6380 phymask = topo_node->un.phymask;
6381 goto find_parent;
6382 }
6383 if (event & MPTSAS_TOPO_FLAG_REMOVE_HANDLE) {
6384 goto handle_topo_change;
6385 }
6386 if (flags & MPTSAS_TOPO_FLAG_LUN_ASSOCIATED) {
6387 phymask = topo_node->un.phymask;
6388 goto find_parent;
6389 }
6390
6391 if ((flags ==
6392 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) &&
6393 (event == MPTSAS_DR_EVENT_RECONFIG_TARGET)) {
6394 /*
6395 * There is no any field in IR_CONFIG_CHANGE
6396 * event indicate physport/phynum, let's get
6397 * parent after SAS Device Page0 request.
6398 */
6399 goto handle_topo_change;
6400 }
6401
6402 mutex_enter(&mpt->m_mutex);
6403 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) {
6404 /*
6405 * If the direct attached device added or a
6406 * phys disk is being unhidden, argument
6407 * physport actually is PHY#, so we have to get
6408 * phymask according PHY#.
6409 */
6410 physport = mpt->m_phy_info[physport].port_num;
6411 }
6412
6413 /*
6414 * Translate physport to phymask so that we can search
6415 * parent dip.
6416 */
6417 phymask = mptsas_physport_to_phymask(mpt,
6418 physport);
6419 mutex_exit(&mpt->m_mutex);
6420
6421 find_parent:
6422 bzero(phy_mask_name, MPTSAS_MAX_PHYS);
6423 /*
6424 * For RAID topology change node, write the iport name
6425 * as v0.
6426 */
6427 if (flags & MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) {
6428 (void) sprintf(phy_mask_name, "v0");
6429 } else {
6430 /*
6431 * phymask can bo 0 if the drive has been
6432 * pulled by the time an add event is
6433 * processed. If phymask is 0, just skip this
6434 * event and continue.
6435 */
6436 if (phymask == 0) {
6437 mutex_enter(&mpt->m_mutex);
6438 save_node = topo_node;
6439 topo_node = topo_node->next;
6440 ASSERT(save_node);
6441 kmem_free(save_node,
6442 sizeof (mptsas_topo_change_list_t));
6443 mutex_exit(&mpt->m_mutex);
6444
6445 parent = NULL;
6446 continue;
6447 }
6448 (void) sprintf(phy_mask_name, "%x", phymask);
6449 }
6450 parent = scsi_hba_iport_find(mpt->m_dip,
6451 phy_mask_name);
6452 if (parent == NULL) {
6453 mptsas_log(mpt, CE_WARN, "Failed to find an "
6454 "iport, should not happen!");
6455 goto out;
6456 }
6457
6458 }
6459 ASSERT(parent);
6460 handle_topo_change:
6461
6462 mutex_enter(&mpt->m_mutex);
6463 /*
6464 * If HBA is being reset, don't perform operations depending
6465 * on the IOC. We must free the topo list, however.
6466 */
6467 if (!mpt->m_in_reset)
6468 mptsas_handle_topo_change(topo_node, parent);
6469 else
6470 NDBG20(("skipping topo change received during reset"));
6471 save_node = topo_node;
6472 topo_node = topo_node->next;
6473 ASSERT(save_node);
6474 kmem_free(save_node, sizeof (mptsas_topo_change_list_t));
6475 mutex_exit(&mpt->m_mutex);
6476
6477 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) ||
6478 (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) ||
6479 (flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED)) {
6480 /*
6481 * If direct attached device associated, make sure
6482 * reset the parent before start the next one. But
6483 * all devices associated with expander shares the
6484 * parent. Also, reset parent if this is for RAID.
6485 */
6486 parent = NULL;
6487 }
6488 }
6489 out:
6490 kmem_free(phy_mask_name, MPTSAS_MAX_PHYS);
6491 }
6492
6493 static void
6494 mptsas_handle_topo_change(mptsas_topo_change_list_t *topo_node,
6495 dev_info_t *parent)
6496 {
6497 mptsas_target_t *ptgt = NULL;
6498 mptsas_smp_t *psmp = NULL;
6499 mptsas_t *mpt = (void *)topo_node->mpt;
6500 uint16_t devhdl;
6501 uint16_t attached_devhdl;
6502 uint64_t sas_wwn = 0;
6503 int rval = 0;
6504 uint32_t page_address;
6505 uint8_t phy, flags;
6506 char *addr = NULL;
6507 dev_info_t *lundip;
6508 int circ = 0, circ1 = 0;
6509 char attached_wwnstr[MPTSAS_WWN_STRLEN];
6510
6511 NDBG20(("mptsas%d handle_topo_change enter, devhdl 0x%x,"
6512 "event 0x%x, flags 0x%x", mpt->m_instance, topo_node->devhdl,
6513 topo_node->event, topo_node->flags));
6514
6515 ASSERT(mutex_owned(&mpt->m_mutex));
6516
6517 switch (topo_node->event) {
6518 case MPTSAS_DR_EVENT_RECONFIG_TARGET:
6519 {
6520 char *phy_mask_name;
6521 mptsas_phymask_t phymask = 0;
6522
6523 if (topo_node->flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) {
6524 /*
6525 * Get latest RAID info.
6526 */
6527 (void) mptsas_get_raid_info(mpt);
6528 ptgt = refhash_linear_search(mpt->m_targets,
6529 mptsas_target_eval_devhdl, &topo_node->devhdl);
6530 if (ptgt == NULL)
6531 break;
6532 } else {
6533 ptgt = (void *)topo_node->object;
6534 }
6535
6536 if (ptgt == NULL) {
6537 /*
6538 * If a Phys Disk was deleted, RAID info needs to be
6539 * updated to reflect the new topology.
6540 */
6541 (void) mptsas_get_raid_info(mpt);
6542
6543 /*
6544 * Get sas device page 0 by DevHandle to make sure if
6545 * SSP/SATA end device exist.
6546 */
6547 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
6548 MPI2_SAS_DEVICE_PGAD_FORM_MASK) |
6549 topo_node->devhdl;
6550
6551 rval = mptsas_get_target_device_info(mpt, page_address,
6552 &devhdl, &ptgt);
6553 if (rval == DEV_INFO_WRONG_DEVICE_TYPE) {
6554 mptsas_log(mpt, CE_NOTE,
6555 "mptsas_handle_topo_change: target %d is "
6556 "not a SAS/SATA device. \n",
6557 topo_node->devhdl);
6558 } else if (rval == DEV_INFO_FAIL_ALLOC) {
6559 mptsas_log(mpt, CE_NOTE,
6560 "mptsas_handle_topo_change: could not "
6561 "allocate memory. \n");
6562 } else if (rval == DEV_INFO_FAIL_GUID) {
6563 mptsas_log(mpt, CE_NOTE,
6564 "mptsas_handle_topo_change: could not "
6565 "get SATA GUID for target %d. \n",
6566 topo_node->devhdl);
6567 }
6568 /*
6569 * If rval is DEV_INFO_PHYS_DISK or indicates failure
6570 * then there is nothing else to do, just leave.
6571 */
6572 if (rval != DEV_INFO_SUCCESS) {
6573 return;
6574 }
6575 }
6576
6577 ASSERT(ptgt->m_devhdl == topo_node->devhdl);
6578
6579 mutex_exit(&mpt->m_mutex);
6580 flags = topo_node->flags;
6581
6582 if (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) {
6583 phymask = ptgt->m_addr.mta_phymask;
6584 phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP);
6585 (void) sprintf(phy_mask_name, "%x", phymask);
6586 parent = scsi_hba_iport_find(mpt->m_dip,
6587 phy_mask_name);
6588 kmem_free(phy_mask_name, MPTSAS_MAX_PHYS);
6589 if (parent == NULL) {
6590 mptsas_log(mpt, CE_WARN, "Failed to find a "
6591 "iport for PD, should not happen!");
6592 mutex_enter(&mpt->m_mutex);
6593 break;
6594 }
6595 }
6596
6597 if (flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) {
6598 ndi_devi_enter(parent, &circ1);
6599 (void) mptsas_config_raid(parent, topo_node->devhdl,
6600 &lundip);
6601 ndi_devi_exit(parent, circ1);
6602 } else {
6603 /*
6604 * hold nexus for bus configure
6605 */
6606 ndi_devi_enter(scsi_vhci_dip, &circ);
6607 ndi_devi_enter(parent, &circ1);
6608 rval = mptsas_config_target(parent, ptgt);
6609 /*
6610 * release nexus for bus configure
6611 */
6612 ndi_devi_exit(parent, circ1);
6613 ndi_devi_exit(scsi_vhci_dip, circ);
6614
6615 /*
6616 * If this is a SATA device, make sure that the
6617 * bridge-port (the SAS WWN that the SATA device is
6618 * plugged into) is updated. This may change if a SATA
6619 * device changes which bay, and therefore phy, it is
6620 * plugged into.
6621 */
6622 if (IS_SATA_DEVICE(ptgt->m_deviceinfo)) {
6623 if (!mptsas_update_sata_bridge(mpt, parent,
6624 ptgt)) {
6625 mutex_enter(&mpt->m_mutex);
6626 return;
6627 }
6628 }
6629
6630 /*
6631 * Add parent's props for SMHBA support
6632 */
6633 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) {
6634 bzero(attached_wwnstr,
6635 sizeof (attached_wwnstr));
6636 (void) sprintf(attached_wwnstr, "w%016"PRIx64,
6637 ptgt->m_addr.mta_wwn);
6638 if (ddi_prop_update_string(DDI_DEV_T_NONE,
6639 parent,
6640 SCSI_ADDR_PROP_ATTACHED_PORT,
6641 attached_wwnstr)
6642 != DDI_PROP_SUCCESS) {
6643 (void) ddi_prop_remove(DDI_DEV_T_NONE,
6644 parent,
6645 SCSI_ADDR_PROP_ATTACHED_PORT);
6646 mptsas_log(mpt, CE_WARN, "Failed to"
6647 "attached-port props");
6648 mutex_enter(&mpt->m_mutex);
6649 return;
6650 }
6651 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6652 MPTSAS_NUM_PHYS, 1) !=
6653 DDI_PROP_SUCCESS) {
6654 (void) ddi_prop_remove(DDI_DEV_T_NONE,
6655 parent, MPTSAS_NUM_PHYS);
6656 mptsas_log(mpt, CE_WARN, "Failed to"
6657 " create num-phys props");
6658 mutex_enter(&mpt->m_mutex);
6659 return;
6660 }
6661
6662 /*
6663 * Update PHY info for smhba
6664 */
6665 mutex_enter(&mpt->m_mutex);
6666 if (mptsas_smhba_phy_init(mpt)) {
6667 mptsas_log(mpt, CE_WARN, "mptsas phy"
6668 " update failed");
6669 return;
6670 }
6671 mutex_exit(&mpt->m_mutex);
6672
6673 /*
6674 * topo_node->un.physport is really the PHY#
6675 * for direct attached devices
6676 */
6677 mptsas_smhba_set_one_phy_props(mpt, parent,
6678 topo_node->un.physport, &attached_devhdl);
6679
6680 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6681 MPTSAS_VIRTUAL_PORT, 0) !=
6682 DDI_PROP_SUCCESS) {
6683 (void) ddi_prop_remove(DDI_DEV_T_NONE,
6684 parent, MPTSAS_VIRTUAL_PORT);
6685 mptsas_log(mpt, CE_WARN,
6686 "mptsas virtual-port"
6687 "port prop update failed");
6688 mutex_enter(&mpt->m_mutex);
6689 return;
6690 }
6691 }
6692 }
6693 mutex_enter(&mpt->m_mutex);
6694
6695 NDBG20(("mptsas%d handle_topo_change to online devhdl:%x, "
6696 "phymask:%x.", mpt->m_instance, ptgt->m_devhdl,
6697 ptgt->m_addr.mta_phymask));
6698 break;
6699 }
6700 case MPTSAS_DR_EVENT_OFFLINE_TARGET:
6701 {
6702 devhdl = topo_node->devhdl;
6703 ptgt = refhash_linear_search(mpt->m_targets,
6704 mptsas_target_eval_devhdl, &devhdl);
6705 if (ptgt == NULL)
6706 break;
6707
6708 sas_wwn = ptgt->m_addr.mta_wwn;
6709 phy = ptgt->m_phynum;
6710
6711 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
6712
6713 if (sas_wwn) {
6714 (void) sprintf(addr, "w%016"PRIx64, sas_wwn);
6715 } else {
6716 (void) sprintf(addr, "p%x", phy);
6717 }
6718 ASSERT(ptgt->m_devhdl == devhdl);
6719
6720 if ((topo_node->flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) ||
6721 (topo_node->flags ==
6722 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED)) {
6723 /*
6724 * Get latest RAID info if RAID volume status changes
6725 * or Phys Disk status changes
6726 */
6727 (void) mptsas_get_raid_info(mpt);
6728 }
6729 /*
6730 * Abort all outstanding command on the device
6731 */
6732 rval = mptsas_do_scsi_reset(mpt, devhdl);
6733 if (rval) {
6734 NDBG20(("mptsas%d handle_topo_change to reset target "
6735 "before offline devhdl:%x, phymask:%x, rval:%x",
6736 mpt->m_instance, ptgt->m_devhdl,
6737 ptgt->m_addr.mta_phymask, rval));
6738 }
6739
6740 mutex_exit(&mpt->m_mutex);
6741
6742 ndi_devi_enter(scsi_vhci_dip, &circ);
6743 ndi_devi_enter(parent, &circ1);
6744 rval = mptsas_offline_target(parent, addr);
6745 ndi_devi_exit(parent, circ1);
6746 ndi_devi_exit(scsi_vhci_dip, circ);
6747 NDBG20(("mptsas%d handle_topo_change to offline devhdl:%x, "
6748 "phymask:%x, rval:%x", mpt->m_instance,
6749 ptgt->m_devhdl, ptgt->m_addr.mta_phymask, rval));
6750
6751 kmem_free(addr, SCSI_MAXNAMELEN);
6752
6753 /*
6754 * Clear parent's props for SMHBA support
6755 */
6756 flags = topo_node->flags;
6757 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) {
6758 bzero(attached_wwnstr, sizeof (attached_wwnstr));
6759 if (ddi_prop_update_string(DDI_DEV_T_NONE, parent,
6760 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) !=
6761 DDI_PROP_SUCCESS) {
6762 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6763 SCSI_ADDR_PROP_ATTACHED_PORT);
6764 mptsas_log(mpt, CE_WARN, "mptsas attached port "
6765 "prop update failed");
6766 mutex_enter(&mpt->m_mutex);
6767 break;
6768 }
6769 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6770 MPTSAS_NUM_PHYS, 0) !=
6771 DDI_PROP_SUCCESS) {
6772 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6773 MPTSAS_NUM_PHYS);
6774 mptsas_log(mpt, CE_WARN, "mptsas num phys "
6775 "prop update failed");
6776 mutex_enter(&mpt->m_mutex);
6777 break;
6778 }
6779 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6780 MPTSAS_VIRTUAL_PORT, 1) !=
6781 DDI_PROP_SUCCESS) {
6782 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6783 MPTSAS_VIRTUAL_PORT);
6784 mptsas_log(mpt, CE_WARN, "mptsas virtual port "
6785 "prop update failed");
6786 mutex_enter(&mpt->m_mutex);
6787 break;
6788 }
6789 }
6790
6791 mutex_enter(&mpt->m_mutex);
6792 ptgt->m_led_status = 0;
6793 (void) mptsas_flush_led_status(mpt, ptgt);
6794 if (rval == DDI_SUCCESS) {
6795 refhash_remove(mpt->m_targets, ptgt);
6796 ptgt = NULL;
6797 } else {
6798 /*
6799 * clean DR_INTRANSITION flag to allow I/O down to
6800 * PHCI driver since failover finished.
6801 * Invalidate the devhdl
6802 */
6803 ptgt->m_devhdl = MPTSAS_INVALID_DEVHDL;
6804 ptgt->m_tgt_unconfigured = 0;
6805 mutex_enter(&mpt->m_tx_waitq_mutex);
6806 ptgt->m_dr_flag = MPTSAS_DR_INACTIVE;
6807 mutex_exit(&mpt->m_tx_waitq_mutex);
6808 }
6809
6810 /*
6811 * Send SAS IO Unit Control to free the dev handle
6812 */
6813 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) ||
6814 (flags == MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE)) {
6815 rval = mptsas_free_devhdl(mpt, devhdl);
6816
6817 NDBG20(("mptsas%d handle_topo_change to remove "
6818 "devhdl:%x, rval:%x", mpt->m_instance, devhdl,
6819 rval));
6820 }
6821
6822 break;
6823 }
6824 case MPTSAS_TOPO_FLAG_REMOVE_HANDLE:
6825 {
6826 devhdl = topo_node->devhdl;
6827 /*
6828 * If this is the remove handle event, do a reset first.
6829 */
6830 if (topo_node->event == MPTSAS_TOPO_FLAG_REMOVE_HANDLE) {
6831 rval = mptsas_do_scsi_reset(mpt, devhdl);
6832 if (rval) {
6833 NDBG20(("mpt%d reset target before remove "
6834 "devhdl:%x, rval:%x", mpt->m_instance,
6835 devhdl, rval));
6836 }
6837 }
6838
6839 /*
6840 * Send SAS IO Unit Control to free the dev handle
6841 */
6842 rval = mptsas_free_devhdl(mpt, devhdl);
6843 NDBG20(("mptsas%d handle_topo_change to remove "
6844 "devhdl:%x, rval:%x", mpt->m_instance, devhdl,
6845 rval));
6846 break;
6847 }
6848 case MPTSAS_DR_EVENT_RECONFIG_SMP:
6849 {
6850 mptsas_smp_t smp;
6851 dev_info_t *smpdip;
6852
6853 devhdl = topo_node->devhdl;
6854
6855 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_HNDL &
6856 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)devhdl;
6857 rval = mptsas_get_sas_expander_page0(mpt, page_address, &smp);
6858 if (rval != DDI_SUCCESS) {
6859 mptsas_log(mpt, CE_WARN, "failed to online smp, "
6860 "handle %x", devhdl);
6861 return;
6862 }
6863
6864 psmp = mptsas_smp_alloc(mpt, &smp);
6865 if (psmp == NULL) {
6866 return;
6867 }
6868
6869 mutex_exit(&mpt->m_mutex);
6870 ndi_devi_enter(parent, &circ1);
6871 (void) mptsas_online_smp(parent, psmp, &smpdip);
6872 ndi_devi_exit(parent, circ1);
6873
6874 mutex_enter(&mpt->m_mutex);
6875 break;
6876 }
6877 case MPTSAS_DR_EVENT_OFFLINE_SMP:
6878 {
6879 devhdl = topo_node->devhdl;
6880 uint32_t dev_info;
6881
6882 psmp = refhash_linear_search(mpt->m_smp_targets,
6883 mptsas_smp_eval_devhdl, &devhdl);
6884 if (psmp == NULL)
6885 break;
6886 /*
6887 * The mptsas_smp_t data is released only if the dip is offlined
6888 * successfully.
6889 */
6890 mutex_exit(&mpt->m_mutex);
6891
6892 ndi_devi_enter(parent, &circ1);
6893 rval = mptsas_offline_smp(parent, psmp, NDI_DEVI_REMOVE);
6894 ndi_devi_exit(parent, circ1);
6895
6896 dev_info = psmp->m_deviceinfo;
6897 if ((dev_info & DEVINFO_DIRECT_ATTACHED) ==
6898 DEVINFO_DIRECT_ATTACHED) {
6899 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6900 MPTSAS_VIRTUAL_PORT, 1) !=
6901 DDI_PROP_SUCCESS) {
6902 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6903 MPTSAS_VIRTUAL_PORT);
6904 mptsas_log(mpt, CE_WARN, "mptsas virtual port "
6905 "prop update failed");
6906 return;
6907 }
6908 /*
6909 * Check whether the smp connected to the iport,
6910 */
6911 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6912 MPTSAS_NUM_PHYS, 0) !=
6913 DDI_PROP_SUCCESS) {
6914 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6915 MPTSAS_NUM_PHYS);
6916 mptsas_log(mpt, CE_WARN, "mptsas num phys"
6917 "prop update failed");
6918 return;
6919 }
6920 /*
6921 * Clear parent's attached-port props
6922 */
6923 bzero(attached_wwnstr, sizeof (attached_wwnstr));
6924 if (ddi_prop_update_string(DDI_DEV_T_NONE, parent,
6925 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) !=
6926 DDI_PROP_SUCCESS) {
6927 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6928 SCSI_ADDR_PROP_ATTACHED_PORT);
6929 mptsas_log(mpt, CE_WARN, "mptsas attached port "
6930 "prop update failed");
6931 return;
6932 }
6933 }
6934
6935 mutex_enter(&mpt->m_mutex);
6936 NDBG20(("mptsas%d handle_topo_change to remove devhdl:%x, "
6937 "rval:%x", mpt->m_instance, psmp->m_devhdl, rval));
6938 if (rval == DDI_SUCCESS) {
6939 refhash_remove(mpt->m_smp_targets, psmp);
6940 } else {
6941 psmp->m_devhdl = MPTSAS_INVALID_DEVHDL;
6942 }
6943
6944 bzero(attached_wwnstr, sizeof (attached_wwnstr));
6945
6946 break;
6947 }
6948 default:
6949 return;
6950 }
6951 }
6952
6953 /*
6954 * Record the event if its type is enabled in mpt instance by ioctl.
6955 */
6956 static void
6957 mptsas_record_event(void *args)
6958 {
6959 m_replyh_arg_t *replyh_arg;
6960 pMpi2EventNotificationReply_t eventreply;
6961 uint32_t event, rfm;
6962 mptsas_t *mpt;
6963 int i, j;
6964 uint16_t event_data_len;
6965 boolean_t sendAEN = FALSE;
6966
6967 replyh_arg = (m_replyh_arg_t *)args;
6968 rfm = replyh_arg->rfm;
6969 mpt = replyh_arg->mpt;
6970
6971 eventreply = (pMpi2EventNotificationReply_t)
6972 (mpt->m_reply_frame + (rfm -
6973 (mpt->m_reply_frame_dma_addr & 0xffffffffu)));
6974 event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event);
6975
6976
6977 /*
6978 * Generate a system event to let anyone who cares know that a
6979 * LOG_ENTRY_ADDED event has occurred. This is sent no matter what the
6980 * event mask is set to.
6981 */
6982 if (event == MPI2_EVENT_LOG_ENTRY_ADDED) {
6983 sendAEN = TRUE;
6984 }
6985
6986 /*
6987 * Record the event only if it is not masked. Determine which dword
6988 * and bit of event mask to test.
6989 */
6990 i = (uint8_t)(event / 32);
6991 j = (uint8_t)(event % 32);
6992 if ((i < 4) && ((1 << j) & mpt->m_event_mask[i])) {
6993 i = mpt->m_event_index;
6994 mpt->m_events[i].Type = event;
6995 mpt->m_events[i].Number = ++mpt->m_event_number;
6996 bzero(mpt->m_events[i].Data, MPTSAS_MAX_EVENT_DATA_LENGTH * 4);
6997 event_data_len = ddi_get16(mpt->m_acc_reply_frame_hdl,
6998 &eventreply->EventDataLength);
6999
7000 if (event_data_len > 0) {
7001 /*
7002 * Limit data to size in m_event entry
7003 */
7004 if (event_data_len > MPTSAS_MAX_EVENT_DATA_LENGTH) {
7005 event_data_len = MPTSAS_MAX_EVENT_DATA_LENGTH;
7006 }
7007 for (j = 0; j < event_data_len; j++) {
7008 mpt->m_events[i].Data[j] =
7009 ddi_get32(mpt->m_acc_reply_frame_hdl,
7010 &(eventreply->EventData[j]));
7011 }
7012
7013 /*
7014 * check for index wrap-around
7015 */
7016 if (++i == MPTSAS_EVENT_QUEUE_SIZE) {
7017 i = 0;
7018 }
7019 mpt->m_event_index = (uint8_t)i;
7020
7021 /*
7022 * Set flag to send the event.
7023 */
7024 sendAEN = TRUE;
7025 }
7026 }
7027
7028 /*
7029 * Generate a system event if flag is set to let anyone who cares know
7030 * that an event has occurred.
7031 */
7032 if (sendAEN) {
7033 (void) ddi_log_sysevent(mpt->m_dip, DDI_VENDOR_LSI, "MPT_SAS",
7034 "SAS", NULL, NULL, DDI_NOSLEEP);
7035 }
7036 }
7037
7038 #define SMP_RESET_IN_PROGRESS MPI2_EVENT_SAS_TOPO_LR_SMP_RESET_IN_PROGRESS
7039 /*
7040 * handle sync events from ioc in interrupt
7041 * return value:
7042 * DDI_SUCCESS: The event is handled by this func
7043 * DDI_FAILURE: Event is not handled
7044 */
7045 static int
7046 mptsas_handle_event_sync(void *args)
7047 {
7048 m_replyh_arg_t *replyh_arg;
7049 pMpi2EventNotificationReply_t eventreply;
7050 uint32_t event, rfm;
7051 mptsas_t *mpt;
7052 uint_t iocstatus;
7053
7054 replyh_arg = (m_replyh_arg_t *)args;
7055 rfm = replyh_arg->rfm;
7056 mpt = replyh_arg->mpt;
7057
7058 ASSERT(mutex_owned(&mpt->m_mutex));
7059
7060 eventreply = (pMpi2EventNotificationReply_t)
7061 (mpt->m_reply_frame + (rfm -
7062 (mpt->m_reply_frame_dma_addr & 0xffffffffu)));
7063 event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event);
7064
7065 if (iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
7066 &eventreply->IOCStatus)) {
7067 if (iocstatus == MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
7068 mptsas_log(mpt, CE_WARN,
7069 "!mptsas_handle_event_sync: event 0x%x, "
7070 "IOCStatus=0x%x, "
7071 "IOCLogInfo=0x%x", event, iocstatus,
7072 ddi_get32(mpt->m_acc_reply_frame_hdl,
7073 &eventreply->IOCLogInfo));
7074 } else {
7075 mptsas_log(mpt, CE_WARN,
7076 "mptsas_handle_event_sync: event 0x%x, "
7077 "IOCStatus=0x%x, "
7078 "(IOCLogInfo=0x%x)", event, iocstatus,
7079 ddi_get32(mpt->m_acc_reply_frame_hdl,
7080 &eventreply->IOCLogInfo));
7081 }
7082 }
7083
7084 /*
7085 * figure out what kind of event we got and handle accordingly
7086 */
7087 switch (event) {
7088 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
7089 {
7090 pMpi2EventDataSasTopologyChangeList_t sas_topo_change_list;
7091 uint8_t num_entries, expstatus, phy;
7092 uint8_t phystatus, physport, state, i;
7093 uint8_t start_phy_num, link_rate;
7094 uint16_t dev_handle, reason_code;
7095 uint16_t enc_handle, expd_handle;
7096 char string[80], curr[80], prev[80];
7097 mptsas_topo_change_list_t *topo_head = NULL;
7098 mptsas_topo_change_list_t *topo_tail = NULL;
7099 mptsas_topo_change_list_t *topo_node = NULL;
7100 mptsas_target_t *ptgt;
7101 mptsas_smp_t *psmp;
7102 uint8_t flags = 0, exp_flag;
7103 smhba_info_t *pSmhba = NULL;
7104
7105 NDBG20(("mptsas_handle_event_sync: SAS topology change"));
7106
7107 sas_topo_change_list = (pMpi2EventDataSasTopologyChangeList_t)
7108 eventreply->EventData;
7109
7110 enc_handle = ddi_get16(mpt->m_acc_reply_frame_hdl,
7111 &sas_topo_change_list->EnclosureHandle);
7112 expd_handle = ddi_get16(mpt->m_acc_reply_frame_hdl,
7113 &sas_topo_change_list->ExpanderDevHandle);
7114 num_entries = ddi_get8(mpt->m_acc_reply_frame_hdl,
7115 &sas_topo_change_list->NumEntries);
7116 start_phy_num = ddi_get8(mpt->m_acc_reply_frame_hdl,
7117 &sas_topo_change_list->StartPhyNum);
7118 expstatus = ddi_get8(mpt->m_acc_reply_frame_hdl,
7119 &sas_topo_change_list->ExpStatus);
7120 physport = ddi_get8(mpt->m_acc_reply_frame_hdl,
7121 &sas_topo_change_list->PhysicalPort);
7122
7123 string[0] = 0;
7124 if (expd_handle) {
7125 flags = MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED;
7126 switch (expstatus) {
7127 case MPI2_EVENT_SAS_TOPO_ES_ADDED:
7128 (void) sprintf(string, " added");
7129 /*
7130 * New expander device added
7131 */
7132 mpt->m_port_chng = 1;
7133 topo_node = kmem_zalloc(
7134 sizeof (mptsas_topo_change_list_t),
7135 KM_SLEEP);
7136 topo_node->mpt = mpt;
7137 topo_node->event = MPTSAS_DR_EVENT_RECONFIG_SMP;
7138 topo_node->un.physport = physport;
7139 topo_node->devhdl = expd_handle;
7140 topo_node->flags = flags;
7141 topo_node->object = NULL;
7142 if (topo_head == NULL) {
7143 topo_head = topo_tail = topo_node;
7144 } else {
7145 topo_tail->next = topo_node;
7146 topo_tail = topo_node;
7147 }
7148 break;
7149 case MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING:
7150 (void) sprintf(string, " not responding, "
7151 "removed");
7152 psmp = refhash_linear_search(mpt->m_smp_targets,
7153 mptsas_smp_eval_devhdl, &expd_handle);
7154 if (psmp == NULL)
7155 break;
7156
7157 topo_node = kmem_zalloc(
7158 sizeof (mptsas_topo_change_list_t),
7159 KM_SLEEP);
7160 topo_node->mpt = mpt;
7161 topo_node->un.phymask =
7162 psmp->m_addr.mta_phymask;
7163 topo_node->event = MPTSAS_DR_EVENT_OFFLINE_SMP;
7164 topo_node->devhdl = expd_handle;
7165 topo_node->flags = flags;
7166 topo_node->object = NULL;
7167 if (topo_head == NULL) {
7168 topo_head = topo_tail = topo_node;
7169 } else {
7170 topo_tail->next = topo_node;
7171 topo_tail = topo_node;
7172 }
7173 break;
7174 case MPI2_EVENT_SAS_TOPO_ES_RESPONDING:
7175 break;
7176 case MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING:
7177 (void) sprintf(string, " not responding, "
7178 "delaying removal");
7179 break;
7180 default:
7181 break;
7182 }
7183 } else {
7184 flags = MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE;
7185 }
7186
7187 NDBG20(("SAS TOPOLOGY CHANGE for enclosure %x expander %x%s\n",
7188 enc_handle, expd_handle, string));
7189 for (i = 0; i < num_entries; i++) {
7190 phy = i + start_phy_num;
7191 phystatus = ddi_get8(mpt->m_acc_reply_frame_hdl,
7192 &sas_topo_change_list->PHY[i].PhyStatus);
7193 dev_handle = ddi_get16(mpt->m_acc_reply_frame_hdl,
7194 &sas_topo_change_list->PHY[i].AttachedDevHandle);
7195 reason_code = phystatus & MPI2_EVENT_SAS_TOPO_RC_MASK;
7196 /*
7197 * Filter out processing of Phy Vacant Status unless
7198 * the reason code is "Not Responding". Process all
7199 * other combinations of Phy Status and Reason Codes.
7200 */
7201 if ((phystatus &
7202 MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT) &&
7203 (reason_code !=
7204 MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING)) {
7205 continue;
7206 }
7207 curr[0] = 0;
7208 prev[0] = 0;
7209 string[0] = 0;
7210 switch (reason_code) {
7211 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
7212 {
7213 NDBG20(("mptsas%d phy %d physical_port %d "
7214 "dev_handle %d added", mpt->m_instance, phy,
7215 physport, dev_handle));
7216 link_rate = ddi_get8(mpt->m_acc_reply_frame_hdl,
7217 &sas_topo_change_list->PHY[i].LinkRate);
7218 state = (link_rate &
7219 MPI2_EVENT_SAS_TOPO_LR_CURRENT_MASK) >>
7220 MPI2_EVENT_SAS_TOPO_LR_CURRENT_SHIFT;
7221 switch (state) {
7222 case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED:
7223 (void) sprintf(curr, "is disabled");
7224 break;
7225 case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED:
7226 (void) sprintf(curr, "is offline, "
7227 "failed speed negotiation");
7228 break;
7229 case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE:
7230 (void) sprintf(curr, "SATA OOB "
7231 "complete");
7232 break;
7233 case SMP_RESET_IN_PROGRESS:
7234 (void) sprintf(curr, "SMP reset in "
7235 "progress");
7236 break;
7237 case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5:
7238 (void) sprintf(curr, "is online at "
7239 "1.5 Gbps");
7240 break;
7241 case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0:
7242 (void) sprintf(curr, "is online at 3.0 "
7243 "Gbps");
7244 break;
7245 case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0:
7246 (void) sprintf(curr, "is online at 6.0 "
7247 "Gbps");
7248 break;
7249 case MPI25_EVENT_SAS_TOPO_LR_RATE_12_0:
7250 (void) sprintf(curr,
7251 "is online at 12.0 Gbps");
7252 break;
7253 default:
7254 (void) sprintf(curr, "state is "
7255 "unknown");
7256 break;
7257 }
7258 /*
7259 * New target device added into the system.
7260 * Set association flag according to if an
7261 * expander is used or not.
7262 */
7263 exp_flag =
7264 MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE;
7265 if (flags ==
7266 MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED) {
7267 flags = exp_flag;
7268 }
7269 topo_node = kmem_zalloc(
7270 sizeof (mptsas_topo_change_list_t),
7271 KM_SLEEP);
7272 topo_node->mpt = mpt;
7273 topo_node->event =
7274 MPTSAS_DR_EVENT_RECONFIG_TARGET;
7275 if (expd_handle == 0) {
7276 /*
7277 * Per MPI 2, if expander dev handle
7278 * is 0, it's a directly attached
7279 * device. So driver use PHY to decide
7280 * which iport is associated
7281 */
7282 physport = phy;
7283 mpt->m_port_chng = 1;
7284 }
7285 topo_node->un.physport = physport;
7286 topo_node->devhdl = dev_handle;
7287 topo_node->flags = flags;
7288 topo_node->object = NULL;
7289 if (topo_head == NULL) {
7290 topo_head = topo_tail = topo_node;
7291 } else {
7292 topo_tail->next = topo_node;
7293 topo_tail = topo_node;
7294 }
7295 break;
7296 }
7297 case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING:
7298 {
7299 NDBG20(("mptsas%d phy %d physical_port %d "
7300 "dev_handle %d removed", mpt->m_instance,
7301 phy, physport, dev_handle));
7302 /*
7303 * Set association flag according to if an
7304 * expander is used or not.
7305 */
7306 exp_flag =
7307 MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE;
7308 if (flags ==
7309 MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED) {
7310 flags = exp_flag;
7311 }
7312 /*
7313 * Target device is removed from the system
7314 * Before the device is really offline from
7315 * from system.
7316 */
7317 ptgt = refhash_linear_search(mpt->m_targets,
7318 mptsas_target_eval_devhdl, &dev_handle);
7319 /*
7320 * If ptgt is NULL here, it means that the
7321 * DevHandle is not in the hash table. This is
7322 * reasonable sometimes. For example, if a
7323 * disk was pulled, then added, then pulled
7324 * again, the disk will not have been put into
7325 * the hash table because the add event will
7326 * have an invalid phymask. BUT, this does not
7327 * mean that the DevHandle is invalid. The
7328 * controller will still have a valid DevHandle
7329 * that must be removed. To do this, use the
7330 * MPTSAS_TOPO_FLAG_REMOVE_HANDLE event.
7331 */
7332 if (ptgt == NULL) {
7333 topo_node = kmem_zalloc(
7334 sizeof (mptsas_topo_change_list_t),
7335 KM_SLEEP);
7336 topo_node->mpt = mpt;
7337 topo_node->un.phymask = 0;
7338 topo_node->event =
7339 MPTSAS_TOPO_FLAG_REMOVE_HANDLE;
7340 topo_node->devhdl = dev_handle;
7341 topo_node->flags = flags;
7342 topo_node->object = NULL;
7343 if (topo_head == NULL) {
7344 topo_head = topo_tail =
7345 topo_node;
7346 } else {
7347 topo_tail->next = topo_node;
7348 topo_tail = topo_node;
7349 }
7350 break;
7351 }
7352
7353 /*
7354 * Update DR flag immediately avoid I/O failure
7355 * before failover finish. Pay attention to the
7356 * mutex protect, we need grab m_tx_waitq_mutex
7357 * during set m_dr_flag because we won't add
7358 * the following command into waitq, instead,
7359 * we need return TRAN_BUSY in the tran_start
7360 * context.
7361 */
7362 mutex_enter(&mpt->m_tx_waitq_mutex);
7363 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION;
7364 mutex_exit(&mpt->m_tx_waitq_mutex);
7365
7366 topo_node = kmem_zalloc(
7367 sizeof (mptsas_topo_change_list_t),
7368 KM_SLEEP);
7369 topo_node->mpt = mpt;
7370 topo_node->un.phymask =
7371 ptgt->m_addr.mta_phymask;
7372 topo_node->event =
7373 MPTSAS_DR_EVENT_OFFLINE_TARGET;
7374 topo_node->devhdl = dev_handle;
7375 topo_node->flags = flags;
7376 topo_node->object = NULL;
7377 if (topo_head == NULL) {
7378 topo_head = topo_tail = topo_node;
7379 } else {
7380 topo_tail->next = topo_node;
7381 topo_tail = topo_node;
7382 }
7383 break;
7384 }
7385 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
7386 link_rate = ddi_get8(mpt->m_acc_reply_frame_hdl,
7387 &sas_topo_change_list->PHY[i].LinkRate);
7388 state = (link_rate &
7389 MPI2_EVENT_SAS_TOPO_LR_CURRENT_MASK) >>
7390 MPI2_EVENT_SAS_TOPO_LR_CURRENT_SHIFT;
7391 pSmhba = &mpt->m_phy_info[i].smhba_info;
7392 pSmhba->negotiated_link_rate = state;
7393 switch (state) {
7394 case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED:
7395 (void) sprintf(curr, "is disabled");
7396 mptsas_smhba_log_sysevent(mpt,
7397 ESC_SAS_PHY_EVENT,
7398 SAS_PHY_REMOVE,
7399 &mpt->m_phy_info[i].smhba_info);
7400 mpt->m_phy_info[i].smhba_info.
7401 negotiated_link_rate
7402 = 0x1;
7403 break;
7404 case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED:
7405 (void) sprintf(curr, "is offline, "
7406 "failed speed negotiation");
7407 mptsas_smhba_log_sysevent(mpt,
7408 ESC_SAS_PHY_EVENT,
7409 SAS_PHY_OFFLINE,
7410 &mpt->m_phy_info[i].smhba_info);
7411 break;
7412 case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE:
7413 (void) sprintf(curr, "SATA OOB "
7414 "complete");
7415 break;
7416 case SMP_RESET_IN_PROGRESS:
7417 (void) sprintf(curr, "SMP reset in "
7418 "progress");
7419 break;
7420 case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5:
7421 (void) sprintf(curr, "is online at "
7422 "1.5 Gbps");
7423 if ((expd_handle == 0) &&
7424 (enc_handle == 1)) {
7425 mpt->m_port_chng = 1;
7426 }
7427 mptsas_smhba_log_sysevent(mpt,
7428 ESC_SAS_PHY_EVENT,
7429 SAS_PHY_ONLINE,
7430 &mpt->m_phy_info[i].smhba_info);
7431 break;
7432 case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0:
7433 (void) sprintf(curr, "is online at 3.0 "
7434 "Gbps");
7435 if ((expd_handle == 0) &&
7436 (enc_handle == 1)) {
7437 mpt->m_port_chng = 1;
7438 }
7439 mptsas_smhba_log_sysevent(mpt,
7440 ESC_SAS_PHY_EVENT,
7441 SAS_PHY_ONLINE,
7442 &mpt->m_phy_info[i].smhba_info);
7443 break;
7444 case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0:
7445 (void) sprintf(curr, "is online at "
7446 "6.0 Gbps");
7447 if ((expd_handle == 0) &&
7448 (enc_handle == 1)) {
7449 mpt->m_port_chng = 1;
7450 }
7451 mptsas_smhba_log_sysevent(mpt,
7452 ESC_SAS_PHY_EVENT,
7453 SAS_PHY_ONLINE,
7454 &mpt->m_phy_info[i].smhba_info);
7455 break;
7456 case MPI25_EVENT_SAS_TOPO_LR_RATE_12_0:
7457 (void) sprintf(curr, "is online at "
7458 "12.0 Gbps");
7459 if ((expd_handle == 0) &&
7460 (enc_handle == 1)) {
7461 mpt->m_port_chng = 1;
7462 }
7463 mptsas_smhba_log_sysevent(mpt,
7464 ESC_SAS_PHY_EVENT,
7465 SAS_PHY_ONLINE,
7466 &mpt->m_phy_info[i].smhba_info);
7467 break;
7468 default:
7469 (void) sprintf(curr, "state is "
7470 "unknown");
7471 break;
7472 }
7473
7474 state = (link_rate &
7475 MPI2_EVENT_SAS_TOPO_LR_PREV_MASK) >>
7476 MPI2_EVENT_SAS_TOPO_LR_PREV_SHIFT;
7477 switch (state) {
7478 case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED:
7479 (void) sprintf(prev, ", was disabled");
7480 break;
7481 case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED:
7482 (void) sprintf(prev, ", was offline, "
7483 "failed speed negotiation");
7484 break;
7485 case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE:
7486 (void) sprintf(prev, ", was SATA OOB "
7487 "complete");
7488 break;
7489 case SMP_RESET_IN_PROGRESS:
7490 (void) sprintf(prev, ", was SMP reset "
7491 "in progress");
7492 break;
7493 case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5:
7494 (void) sprintf(prev, ", was online at "
7495 "1.5 Gbps");
7496 break;
7497 case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0:
7498 (void) sprintf(prev, ", was online at "
7499 "3.0 Gbps");
7500 break;
7501 case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0:
7502 (void) sprintf(prev, ", was online at "
7503 "6.0 Gbps");
7504 break;
7505 case MPI25_EVENT_SAS_TOPO_LR_RATE_12_0:
7506 (void) sprintf(prev, ", was online at "
7507 "12.0 Gbps");
7508 break;
7509 default:
7510 break;
7511 }
7512 (void) sprintf(&string[strlen(string)], "link "
7513 "changed, ");
7514 break;
7515 case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE:
7516 continue;
7517 case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING:
7518 (void) sprintf(&string[strlen(string)],
7519 "target not responding, delaying "
7520 "removal");
7521 break;
7522 }
7523 NDBG20(("mptsas%d phy %d DevHandle %x, %s%s%s\n",
7524 mpt->m_instance, phy, dev_handle, string, curr,
7525 prev));
7526 }
7527 if (topo_head != NULL) {
7528 /*
7529 * Launch DR taskq to handle topology change
7530 */
7531 if ((ddi_taskq_dispatch(mpt->m_dr_taskq,
7532 mptsas_handle_dr, (void *)topo_head,
7533 DDI_NOSLEEP)) != DDI_SUCCESS) {
7534 while (topo_head != NULL) {
7535 topo_node = topo_head;
7536 topo_head = topo_head->next;
7537 kmem_free(topo_node,
7538 sizeof (mptsas_topo_change_list_t));
7539 }
7540 mptsas_log(mpt, CE_NOTE, "mptsas start taskq "
7541 "for handle SAS DR event failed. \n");
7542 }
7543 }
7544 break;
7545 }
7546 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
7547 {
7548 Mpi2EventDataIrConfigChangeList_t *irChangeList;
7549 mptsas_topo_change_list_t *topo_head = NULL;
7550 mptsas_topo_change_list_t *topo_tail = NULL;
7551 mptsas_topo_change_list_t *topo_node = NULL;
7552 mptsas_target_t *ptgt;
7553 uint8_t num_entries, i, reason;
7554 uint16_t volhandle, diskhandle;
7555
7556 irChangeList = (pMpi2EventDataIrConfigChangeList_t)
7557 eventreply->EventData;
7558 num_entries = ddi_get8(mpt->m_acc_reply_frame_hdl,
7559 &irChangeList->NumElements);
7560
7561 NDBG20(("mptsas%d IR_CONFIGURATION_CHANGE_LIST event received",
7562 mpt->m_instance));
7563
7564 for (i = 0; i < num_entries; i++) {
7565 reason = ddi_get8(mpt->m_acc_reply_frame_hdl,
7566 &irChangeList->ConfigElement[i].ReasonCode);
7567 volhandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
7568 &irChangeList->ConfigElement[i].VolDevHandle);
7569 diskhandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
7570 &irChangeList->ConfigElement[i].PhysDiskDevHandle);
7571
7572 switch (reason) {
7573 case MPI2_EVENT_IR_CHANGE_RC_ADDED:
7574 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED:
7575 {
7576 NDBG20(("mptsas %d volume added\n",
7577 mpt->m_instance));
7578
7579 topo_node = kmem_zalloc(
7580 sizeof (mptsas_topo_change_list_t),
7581 KM_SLEEP);
7582
7583 topo_node->mpt = mpt;
7584 topo_node->event =
7585 MPTSAS_DR_EVENT_RECONFIG_TARGET;
7586 topo_node->un.physport = 0xff;
7587 topo_node->devhdl = volhandle;
7588 topo_node->flags =
7589 MPTSAS_TOPO_FLAG_RAID_ASSOCIATED;
7590 topo_node->object = NULL;
7591 if (topo_head == NULL) {
7592 topo_head = topo_tail = topo_node;
7593 } else {
7594 topo_tail->next = topo_node;
7595 topo_tail = topo_node;
7596 }
7597 break;
7598 }
7599 case MPI2_EVENT_IR_CHANGE_RC_REMOVED:
7600 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED:
7601 {
7602 NDBG20(("mptsas %d volume deleted\n",
7603 mpt->m_instance));
7604 ptgt = refhash_linear_search(mpt->m_targets,
7605 mptsas_target_eval_devhdl, &volhandle);
7606 if (ptgt == NULL)
7607 break;
7608
7609 /*
7610 * Clear any flags related to volume
7611 */
7612 (void) mptsas_delete_volume(mpt, volhandle);
7613
7614 /*
7615 * Update DR flag immediately avoid I/O failure
7616 */
7617 mutex_enter(&mpt->m_tx_waitq_mutex);
7618 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION;
7619 mutex_exit(&mpt->m_tx_waitq_mutex);
7620
7621 topo_node = kmem_zalloc(
7622 sizeof (mptsas_topo_change_list_t),
7623 KM_SLEEP);
7624 topo_node->mpt = mpt;
7625 topo_node->un.phymask =
7626 ptgt->m_addr.mta_phymask;
7627 topo_node->event =
7628 MPTSAS_DR_EVENT_OFFLINE_TARGET;
7629 topo_node->devhdl = volhandle;
7630 topo_node->flags =
7631 MPTSAS_TOPO_FLAG_RAID_ASSOCIATED;
7632 topo_node->object = (void *)ptgt;
7633 if (topo_head == NULL) {
7634 topo_head = topo_tail = topo_node;
7635 } else {
7636 topo_tail->next = topo_node;
7637 topo_tail = topo_node;
7638 }
7639 break;
7640 }
7641 case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED:
7642 case MPI2_EVENT_IR_CHANGE_RC_HIDE:
7643 {
7644 ptgt = refhash_linear_search(mpt->m_targets,
7645 mptsas_target_eval_devhdl, &diskhandle);
7646 if (ptgt == NULL)
7647 break;
7648
7649 /*
7650 * Update DR flag immediately avoid I/O failure
7651 */
7652 mutex_enter(&mpt->m_tx_waitq_mutex);
7653 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION;
7654 mutex_exit(&mpt->m_tx_waitq_mutex);
7655
7656 topo_node = kmem_zalloc(
7657 sizeof (mptsas_topo_change_list_t),
7658 KM_SLEEP);
7659 topo_node->mpt = mpt;
7660 topo_node->un.phymask =
7661 ptgt->m_addr.mta_phymask;
7662 topo_node->event =
7663 MPTSAS_DR_EVENT_OFFLINE_TARGET;
7664 topo_node->devhdl = diskhandle;
7665 topo_node->flags =
7666 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED;
7667 topo_node->object = (void *)ptgt;
7668 if (topo_head == NULL) {
7669 topo_head = topo_tail = topo_node;
7670 } else {
7671 topo_tail->next = topo_node;
7672 topo_tail = topo_node;
7673 }
7674 break;
7675 }
7676 case MPI2_EVENT_IR_CHANGE_RC_UNHIDE:
7677 case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED:
7678 {
7679 /*
7680 * The physical drive is released by a IR
7681 * volume. But we cannot get the the physport
7682 * or phynum from the event data, so we only
7683 * can get the physport/phynum after SAS
7684 * Device Page0 request for the devhdl.
7685 */
7686 topo_node = kmem_zalloc(
7687 sizeof (mptsas_topo_change_list_t),
7688 KM_SLEEP);
7689 topo_node->mpt = mpt;
7690 topo_node->un.phymask = 0;
7691 topo_node->event =
7692 MPTSAS_DR_EVENT_RECONFIG_TARGET;
7693 topo_node->devhdl = diskhandle;
7694 topo_node->flags =
7695 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED;
7696 topo_node->object = NULL;
7697 mpt->m_port_chng = 1;
7698 if (topo_head == NULL) {
7699 topo_head = topo_tail = topo_node;
7700 } else {
7701 topo_tail->next = topo_node;
7702 topo_tail = topo_node;
7703 }
7704 break;
7705 }
7706 default:
7707 break;
7708 }
7709 }
7710
7711 if (topo_head != NULL) {
7712 /*
7713 * Launch DR taskq to handle topology change
7714 */
7715 if ((ddi_taskq_dispatch(mpt->m_dr_taskq,
7716 mptsas_handle_dr, (void *)topo_head,
7717 DDI_NOSLEEP)) != DDI_SUCCESS) {
7718 while (topo_head != NULL) {
7719 topo_node = topo_head;
7720 topo_head = topo_head->next;
7721 kmem_free(topo_node,
7722 sizeof (mptsas_topo_change_list_t));
7723 }
7724 mptsas_log(mpt, CE_NOTE, "mptsas start taskq "
7725 "for handle SAS DR event failed. \n");
7726 }
7727 }
7728 break;
7729 }
7730 default:
7731 return (DDI_FAILURE);
7732 }
7733
7734 return (DDI_SUCCESS);
7735 }
7736
7737 /*
7738 * handle events from ioc
7739 */
7740 static void
7741 mptsas_handle_event(void *args)
7742 {
7743 m_replyh_arg_t *replyh_arg;
7744 pMpi2EventNotificationReply_t eventreply;
7745 uint32_t event, iocloginfo, rfm;
7746 uint32_t status;
7747 uint8_t port;
7748 mptsas_t *mpt;
7749 uint_t iocstatus;
7750
7751 replyh_arg = (m_replyh_arg_t *)args;
7752 rfm = replyh_arg->rfm;
7753 mpt = replyh_arg->mpt;
7754
7755 mutex_enter(&mpt->m_mutex);
7756 /*
7757 * If HBA is being reset, drop incoming event.
7758 */
7759 if (mpt->m_in_reset) {
7760 NDBG20(("dropping event received prior to reset"));
7761 mutex_exit(&mpt->m_mutex);
7762 return;
7763 }
7764
7765 eventreply = (pMpi2EventNotificationReply_t)
7766 (mpt->m_reply_frame + (rfm -
7767 (mpt->m_reply_frame_dma_addr & 0xffffffffu)));
7768 event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event);
7769
7770 if (iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
7771 &eventreply->IOCStatus)) {
7772 if (iocstatus == MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
7773 mptsas_log(mpt, CE_WARN,
7774 "!mptsas_handle_event: IOCStatus=0x%x, "
7775 "IOCLogInfo=0x%x", iocstatus,
7776 ddi_get32(mpt->m_acc_reply_frame_hdl,
7777 &eventreply->IOCLogInfo));
7778 } else {
7779 mptsas_log(mpt, CE_WARN,
7780 "mptsas_handle_event: IOCStatus=0x%x, "
7781 "IOCLogInfo=0x%x", iocstatus,
7782 ddi_get32(mpt->m_acc_reply_frame_hdl,
7783 &eventreply->IOCLogInfo));
7784 }
7785 }
7786
7787 /*
7788 * figure out what kind of event we got and handle accordingly
7789 */
7790 switch (event) {
7791 case MPI2_EVENT_LOG_ENTRY_ADDED:
7792 break;
7793 case MPI2_EVENT_LOG_DATA:
7794 iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl,
7795 &eventreply->IOCLogInfo);
7796 NDBG20(("mptsas %d log info %x received.\n", mpt->m_instance,
7797 iocloginfo));
7798 break;
7799 case MPI2_EVENT_STATE_CHANGE:
7800 NDBG20(("mptsas%d state change.", mpt->m_instance));
7801 break;
7802 case MPI2_EVENT_HARD_RESET_RECEIVED:
7803 NDBG20(("mptsas%d event change.", mpt->m_instance));
7804 break;
7805 case MPI2_EVENT_SAS_DISCOVERY:
7806 {
7807 MPI2_EVENT_DATA_SAS_DISCOVERY *sasdiscovery;
7808 char string[80];
7809 uint8_t rc;
7810
7811 sasdiscovery =
7812 (pMpi2EventDataSasDiscovery_t)eventreply->EventData;
7813
7814 rc = ddi_get8(mpt->m_acc_reply_frame_hdl,
7815 &sasdiscovery->ReasonCode);
7816 port = ddi_get8(mpt->m_acc_reply_frame_hdl,
7817 &sasdiscovery->PhysicalPort);
7818 status = ddi_get32(mpt->m_acc_reply_frame_hdl,
7819 &sasdiscovery->DiscoveryStatus);
7820
7821 string[0] = 0;
7822 switch (rc) {
7823 case MPI2_EVENT_SAS_DISC_RC_STARTED:
7824 (void) sprintf(string, "STARTING");
7825 break;
7826 case MPI2_EVENT_SAS_DISC_RC_COMPLETED:
7827 (void) sprintf(string, "COMPLETED");
7828 break;
7829 default:
7830 (void) sprintf(string, "UNKNOWN");
7831 break;
7832 }
7833
7834 NDBG20(("SAS DISCOVERY is %s for port %d, status %x", string,
7835 port, status));
7836
7837 break;
7838 }
7839 case MPI2_EVENT_EVENT_CHANGE:
7840 NDBG20(("mptsas%d event change.", mpt->m_instance));
7841 break;
7842 case MPI2_EVENT_TASK_SET_FULL:
7843 {
7844 pMpi2EventDataTaskSetFull_t taskfull;
7845
7846 taskfull = (pMpi2EventDataTaskSetFull_t)eventreply->EventData;
7847
7848 NDBG20(("TASK_SET_FULL received for mptsas%d, depth %d\n",
7849 mpt->m_instance, ddi_get16(mpt->m_acc_reply_frame_hdl,
7850 &taskfull->CurrentDepth)));
7851 break;
7852 }
7853 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
7854 {
7855 /*
7856 * SAS TOPOLOGY CHANGE LIST Event has already been handled
7857 * in mptsas_handle_event_sync() of interrupt context
7858 */
7859 break;
7860 }
7861 case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
7862 {
7863 pMpi2EventDataSasEnclDevStatusChange_t encstatus;
7864 uint8_t rc;
7865 uint16_t enchdl;
7866 char string[80];
7867 mptsas_enclosure_t *mep;
7868
7869 encstatus = (pMpi2EventDataSasEnclDevStatusChange_t)
7870 eventreply->EventData;
7871
7872 rc = ddi_get8(mpt->m_acc_reply_frame_hdl,
7873 &encstatus->ReasonCode);
7874 enchdl = ddi_get16(mpt->m_acc_reply_frame_hdl,
7875 &encstatus->EnclosureHandle);
7876
7877 switch (rc) {
7878 case MPI2_EVENT_SAS_ENCL_RC_ADDED:
7879 (void) sprintf(string, "added");
7880 break;
7881 case MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING:
7882 mep = mptsas_enc_lookup(mpt, enchdl);
7883 if (mep != NULL) {
7884 list_remove(&mpt->m_enclosures, mep);
7885 kmem_free(mep, sizeof (*mep));
7886 }
7887 (void) sprintf(string, ", not responding");
7888 break;
7889 default:
7890 break;
7891 }
7892 NDBG20(("mptsas%d ENCLOSURE STATUS CHANGE for enclosure "
7893 "%x%s\n", mpt->m_instance,
7894 ddi_get16(mpt->m_acc_reply_frame_hdl,
7895 &encstatus->EnclosureHandle), string));
7896
7897 /*
7898 * No matter what has happened, update all of our device state
7899 * for enclosures, by retriggering an evaluation.
7900 */
7901 mpt->m_done_traverse_enc = 0;
7902 mptsas_update_hashtab(mpt);
7903 break;
7904 }
7905
7906 /*
7907 * MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE is handled by
7908 * mptsas_handle_event_sync,in here just send ack message.
7909 */
7910 case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
7911 {
7912 pMpi2EventDataSasDeviceStatusChange_t statuschange;
7913 uint8_t rc;
7914 uint16_t devhdl;
7915 uint64_t wwn = 0;
7916 uint32_t wwn_lo, wwn_hi;
7917
7918 statuschange = (pMpi2EventDataSasDeviceStatusChange_t)
7919 eventreply->EventData;
7920 rc = ddi_get8(mpt->m_acc_reply_frame_hdl,
7921 &statuschange->ReasonCode);
7922 wwn_lo = ddi_get32(mpt->m_acc_reply_frame_hdl,
7923 (uint32_t *)(void *)&statuschange->SASAddress);
7924 wwn_hi = ddi_get32(mpt->m_acc_reply_frame_hdl,
7925 (uint32_t *)(void *)&statuschange->SASAddress + 1);
7926 wwn = ((uint64_t)wwn_hi << 32) | wwn_lo;
7927 devhdl = ddi_get16(mpt->m_acc_reply_frame_hdl,
7928 &statuschange->DevHandle);
7929
7930 NDBG13(("MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE wwn is %"PRIx64,
7931 wwn));
7932
7933 switch (rc) {
7934 case MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
7935 NDBG20(("SMART data received, ASC/ASCQ = %02x/%02x",
7936 ddi_get8(mpt->m_acc_reply_frame_hdl,
7937 &statuschange->ASC),
7938 ddi_get8(mpt->m_acc_reply_frame_hdl,
7939 &statuschange->ASCQ)));
7940 break;
7941
7942 case MPI2_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
7943 NDBG20(("Device not supported"));
7944 break;
7945
7946 case MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
7947 NDBG20(("IOC internally generated the Target Reset "
7948 "for devhdl:%x", devhdl));
7949 break;
7950
7951 case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET:
7952 NDBG20(("IOC's internally generated Target Reset "
7953 "completed for devhdl:%x", devhdl));
7954 break;
7955
7956 case MPI2_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
7957 NDBG20(("IOC internally generated Abort Task"));
7958 break;
7959
7960 case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_TASK_ABORT_INTERNAL:
7961 NDBG20(("IOC's internally generated Abort Task "
7962 "completed"));
7963 break;
7964
7965 case MPI2_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
7966 NDBG20(("IOC internally generated Abort Task Set"));
7967 break;
7968
7969 case MPI2_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
7970 NDBG20(("IOC internally generated Clear Task Set"));
7971 break;
7972
7973 case MPI2_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
7974 NDBG20(("IOC internally generated Query Task"));
7975 break;
7976
7977 case MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION:
7978 NDBG20(("Device sent an Asynchronous Notification"));
7979 break;
7980
7981 default:
7982 break;
7983 }
7984 break;
7985 }
7986 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
7987 {
7988 /*
7989 * IR TOPOLOGY CHANGE LIST Event has already been handled
7990 * in mpt_handle_event_sync() of interrupt context
7991 */
7992 break;
7993 }
7994 case MPI2_EVENT_IR_OPERATION_STATUS:
7995 {
7996 Mpi2EventDataIrOperationStatus_t *irOpStatus;
7997 char reason_str[80];
7998 uint8_t rc, percent;
7999 uint16_t handle;
8000
8001 irOpStatus = (pMpi2EventDataIrOperationStatus_t)
8002 eventreply->EventData;
8003 rc = ddi_get8(mpt->m_acc_reply_frame_hdl,
8004 &irOpStatus->RAIDOperation);
8005 percent = ddi_get8(mpt->m_acc_reply_frame_hdl,
8006 &irOpStatus->PercentComplete);
8007 handle = ddi_get16(mpt->m_acc_reply_frame_hdl,
8008 &irOpStatus->VolDevHandle);
8009
8010 switch (rc) {
8011 case MPI2_EVENT_IR_RAIDOP_RESYNC:
8012 (void) sprintf(reason_str, "resync");
8013 break;
8014 case MPI2_EVENT_IR_RAIDOP_ONLINE_CAP_EXPANSION:
8015 (void) sprintf(reason_str, "online capacity "
8016 "expansion");
8017 break;
8018 case MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK:
8019 (void) sprintf(reason_str, "consistency check");
8020 break;
8021 default:
8022 (void) sprintf(reason_str, "unknown reason %x",
8023 rc);
8024 }
8025
8026 NDBG20(("mptsas%d raid operational status: (%s)"
8027 "\thandle(0x%04x), percent complete(%d)\n",
8028 mpt->m_instance, reason_str, handle, percent));
8029 break;
8030 }
8031 case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE:
8032 {
8033 pMpi2EventDataSasBroadcastPrimitive_t sas_broadcast;
8034 uint8_t phy_num;
8035 uint8_t primitive;
8036
8037 sas_broadcast = (pMpi2EventDataSasBroadcastPrimitive_t)
8038 eventreply->EventData;
8039
8040 phy_num = ddi_get8(mpt->m_acc_reply_frame_hdl,
8041 &sas_broadcast->PhyNum);
8042 primitive = ddi_get8(mpt->m_acc_reply_frame_hdl,
8043 &sas_broadcast->Primitive);
8044
8045 switch (primitive) {
8046 case MPI2_EVENT_PRIMITIVE_CHANGE:
8047 mptsas_smhba_log_sysevent(mpt,
8048 ESC_SAS_HBA_PORT_BROADCAST,
8049 SAS_PORT_BROADCAST_CHANGE,
8050 &mpt->m_phy_info[phy_num].smhba_info);
8051 break;
8052 case MPI2_EVENT_PRIMITIVE_SES:
8053 mptsas_smhba_log_sysevent(mpt,
8054 ESC_SAS_HBA_PORT_BROADCAST,
8055 SAS_PORT_BROADCAST_SES,
8056 &mpt->m_phy_info[phy_num].smhba_info);
8057 break;
8058 case MPI2_EVENT_PRIMITIVE_EXPANDER:
8059 mptsas_smhba_log_sysevent(mpt,
8060 ESC_SAS_HBA_PORT_BROADCAST,
8061 SAS_PORT_BROADCAST_D01_4,
8062 &mpt->m_phy_info[phy_num].smhba_info);
8063 break;
8064 case MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT:
8065 mptsas_smhba_log_sysevent(mpt,
8066 ESC_SAS_HBA_PORT_BROADCAST,
8067 SAS_PORT_BROADCAST_D04_7,
8068 &mpt->m_phy_info[phy_num].smhba_info);
8069 break;
8070 case MPI2_EVENT_PRIMITIVE_RESERVED3:
8071 mptsas_smhba_log_sysevent(mpt,
8072 ESC_SAS_HBA_PORT_BROADCAST,
8073 SAS_PORT_BROADCAST_D16_7,
8074 &mpt->m_phy_info[phy_num].smhba_info);
8075 break;
8076 case MPI2_EVENT_PRIMITIVE_RESERVED4:
8077 mptsas_smhba_log_sysevent(mpt,
8078 ESC_SAS_HBA_PORT_BROADCAST,
8079 SAS_PORT_BROADCAST_D29_7,
8080 &mpt->m_phy_info[phy_num].smhba_info);
8081 break;
8082 case MPI2_EVENT_PRIMITIVE_CHANGE0_RESERVED:
8083 mptsas_smhba_log_sysevent(mpt,
8084 ESC_SAS_HBA_PORT_BROADCAST,
8085 SAS_PORT_BROADCAST_D24_0,
8086 &mpt->m_phy_info[phy_num].smhba_info);
8087 break;
8088 case MPI2_EVENT_PRIMITIVE_CHANGE1_RESERVED:
8089 mptsas_smhba_log_sysevent(mpt,
8090 ESC_SAS_HBA_PORT_BROADCAST,
8091 SAS_PORT_BROADCAST_D27_4,
8092 &mpt->m_phy_info[phy_num].smhba_info);
8093 break;
8094 default:
8095 NDBG16(("mptsas%d: unknown BROADCAST PRIMITIVE"
8096 " %x received",
8097 mpt->m_instance, primitive));
8098 break;
8099 }
8100 NDBG16(("mptsas%d sas broadcast primitive: "
8101 "\tprimitive(0x%04x), phy(%d) complete\n",
8102 mpt->m_instance, primitive, phy_num));
8103 break;
8104 }
8105 case MPI2_EVENT_IR_VOLUME:
8106 {
8107 Mpi2EventDataIrVolume_t *irVolume;
8108 uint16_t devhandle;
8109 uint32_t state;
8110 int config, vol;
8111 uint8_t found = FALSE;
8112
8113 irVolume = (pMpi2EventDataIrVolume_t)eventreply->EventData;
8114 state = ddi_get32(mpt->m_acc_reply_frame_hdl,
8115 &irVolume->NewValue);
8116 devhandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
8117 &irVolume->VolDevHandle);
8118
8119 NDBG20(("EVENT_IR_VOLUME event is received"));
8120
8121 /*
8122 * Get latest RAID info and then find the DevHandle for this
8123 * event in the configuration. If the DevHandle is not found
8124 * just exit the event.
8125 */
8126 (void) mptsas_get_raid_info(mpt);
8127 for (config = 0; (config < mpt->m_num_raid_configs) &&
8128 (!found); config++) {
8129 for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) {
8130 if (mpt->m_raidconfig[config].m_raidvol[vol].
8131 m_raidhandle == devhandle) {
8132 found = TRUE;
8133 break;
8134 }
8135 }
8136 }
8137 if (!found) {
8138 break;
8139 }
8140
8141 switch (irVolume->ReasonCode) {
8142 case MPI2_EVENT_IR_VOLUME_RC_SETTINGS_CHANGED:
8143 {
8144 uint32_t i;
8145 mpt->m_raidconfig[config].m_raidvol[vol].m_settings =
8146 state;
8147
8148 i = state & MPI2_RAIDVOL0_SETTING_MASK_WRITE_CACHING;
8149 mptsas_log(mpt, CE_NOTE, " Volume %d settings changed"
8150 ", auto-config of hot-swap drives is %s"
8151 ", write caching is %s"
8152 ", hot-spare pool mask is %02x\n",
8153 vol, state &
8154 MPI2_RAIDVOL0_SETTING_AUTO_CONFIG_HSWAP_DISABLE
8155 ? "disabled" : "enabled",
8156 i == MPI2_RAIDVOL0_SETTING_UNCHANGED
8157 ? "controlled by member disks" :
8158 i == MPI2_RAIDVOL0_SETTING_DISABLE_WRITE_CACHING
8159 ? "disabled" :
8160 i == MPI2_RAIDVOL0_SETTING_ENABLE_WRITE_CACHING
8161 ? "enabled" :
8162 "incorrectly set",
8163 (state >> 16) & 0xff);
8164 break;
8165 }
8166 case MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED:
8167 {
8168 mpt->m_raidconfig[config].m_raidvol[vol].m_state =
8169 (uint8_t)state;
8170
8171 mptsas_log(mpt, CE_NOTE,
8172 "Volume %d is now %s\n", vol,
8173 state == MPI2_RAID_VOL_STATE_OPTIMAL
8174 ? "optimal" :
8175 state == MPI2_RAID_VOL_STATE_DEGRADED
8176 ? "degraded" :
8177 state == MPI2_RAID_VOL_STATE_ONLINE
8178 ? "online" :
8179 state == MPI2_RAID_VOL_STATE_INITIALIZING
8180 ? "initializing" :
8181 state == MPI2_RAID_VOL_STATE_FAILED
8182 ? "failed" :
8183 state == MPI2_RAID_VOL_STATE_MISSING
8184 ? "missing" :
8185 "state unknown");
8186 break;
8187 }
8188 case MPI2_EVENT_IR_VOLUME_RC_STATUS_FLAGS_CHANGED:
8189 {
8190 mpt->m_raidconfig[config].m_raidvol[vol].
8191 m_statusflags = state;
8192
8193 mptsas_log(mpt, CE_NOTE,
8194 " Volume %d is now %s%s%s%s%s%s%s%s%s\n",
8195 vol,
8196 state & MPI2_RAIDVOL0_STATUS_FLAG_ENABLED
8197 ? ", enabled" : ", disabled",
8198 state & MPI2_RAIDVOL0_STATUS_FLAG_QUIESCED
8199 ? ", quiesced" : "",
8200 state & MPI2_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE
8201 ? ", inactive" : ", active",
8202 state &
8203 MPI2_RAIDVOL0_STATUS_FLAG_BAD_BLOCK_TABLE_FULL
8204 ? ", bad block table is full" : "",
8205 state &
8206 MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
8207 ? ", resync in progress" : "",
8208 state & MPI2_RAIDVOL0_STATUS_FLAG_BACKGROUND_INIT
8209 ? ", background initialization in progress" : "",
8210 state &
8211 MPI2_RAIDVOL0_STATUS_FLAG_CAPACITY_EXPANSION
8212 ? ", capacity expansion in progress" : "",
8213 state &
8214 MPI2_RAIDVOL0_STATUS_FLAG_CONSISTENCY_CHECK
8215 ? ", consistency check in progress" : "",
8216 state & MPI2_RAIDVOL0_STATUS_FLAG_DATA_SCRUB
8217 ? ", data scrub in progress" : "");
8218 break;
8219 }
8220 default:
8221 break;
8222 }
8223 break;
8224 }
8225 case MPI2_EVENT_IR_PHYSICAL_DISK:
8226 {
8227 Mpi2EventDataIrPhysicalDisk_t *irPhysDisk;
8228 uint16_t devhandle, enchandle, slot;
8229 uint32_t status, state;
8230 uint8_t physdisknum, reason;
8231
8232 irPhysDisk = (Mpi2EventDataIrPhysicalDisk_t *)
8233 eventreply->EventData;
8234 physdisknum = ddi_get8(mpt->m_acc_reply_frame_hdl,
8235 &irPhysDisk->PhysDiskNum);
8236 devhandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
8237 &irPhysDisk->PhysDiskDevHandle);
8238 enchandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
8239 &irPhysDisk->EnclosureHandle);
8240 slot = ddi_get16(mpt->m_acc_reply_frame_hdl,
8241 &irPhysDisk->Slot);
8242 state = ddi_get32(mpt->m_acc_reply_frame_hdl,
8243 &irPhysDisk->NewValue);
8244 reason = ddi_get8(mpt->m_acc_reply_frame_hdl,
8245 &irPhysDisk->ReasonCode);
8246
8247 NDBG20(("EVENT_IR_PHYSICAL_DISK event is received"));
8248
8249 switch (reason) {
8250 case MPI2_EVENT_IR_PHYSDISK_RC_SETTINGS_CHANGED:
8251 mptsas_log(mpt, CE_NOTE,
8252 " PhysDiskNum %d with DevHandle 0x%x in slot %d "
8253 "for enclosure with handle 0x%x is now in hot "
8254 "spare pool %d",
8255 physdisknum, devhandle, slot, enchandle,
8256 (state >> 16) & 0xff);
8257 break;
8258
8259 case MPI2_EVENT_IR_PHYSDISK_RC_STATUS_FLAGS_CHANGED:
8260 status = state;
8261 mptsas_log(mpt, CE_NOTE,
8262 " PhysDiskNum %d with DevHandle 0x%x in slot %d "
8263 "for enclosure with handle 0x%x is now "
8264 "%s%s%s%s%s\n", physdisknum, devhandle, slot,
8265 enchandle,
8266 status & MPI2_PHYSDISK0_STATUS_FLAG_INACTIVE_VOLUME
8267 ? ", inactive" : ", active",
8268 status & MPI2_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
8269 ? ", out of sync" : "",
8270 status & MPI2_PHYSDISK0_STATUS_FLAG_QUIESCED
8271 ? ", quiesced" : "",
8272 status &
8273 MPI2_PHYSDISK0_STATUS_FLAG_WRITE_CACHE_ENABLED
8274 ? ", write cache enabled" : "",
8275 status & MPI2_PHYSDISK0_STATUS_FLAG_OCE_TARGET
8276 ? ", capacity expansion target" : "");
8277 break;
8278
8279 case MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED:
8280 mptsas_log(mpt, CE_NOTE,
8281 " PhysDiskNum %d with DevHandle 0x%x in slot %d "
8282 "for enclosure with handle 0x%x is now %s\n",
8283 physdisknum, devhandle, slot, enchandle,
8284 state == MPI2_RAID_PD_STATE_OPTIMAL
8285 ? "optimal" :
8286 state == MPI2_RAID_PD_STATE_REBUILDING
8287 ? "rebuilding" :
8288 state == MPI2_RAID_PD_STATE_DEGRADED
8289 ? "degraded" :
8290 state == MPI2_RAID_PD_STATE_HOT_SPARE
8291 ? "a hot spare" :
8292 state == MPI2_RAID_PD_STATE_ONLINE
8293 ? "online" :
8294 state == MPI2_RAID_PD_STATE_OFFLINE
8295 ? "offline" :
8296 state == MPI2_RAID_PD_STATE_NOT_COMPATIBLE
8297 ? "not compatible" :
8298 state == MPI2_RAID_PD_STATE_NOT_CONFIGURED
8299 ? "not configured" :
8300 "state unknown");
8301 break;
8302 }
8303 break;
8304 }
8305 default:
8306 NDBG20(("mptsas%d: unknown event %x received",
8307 mpt->m_instance, event));
8308 break;
8309 }
8310
8311 /*
8312 * Return the reply frame to the free queue.
8313 */
8314 ddi_put32(mpt->m_acc_free_queue_hdl,
8315 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], rfm);
8316 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
8317 DDI_DMA_SYNC_FORDEV);
8318 if (++mpt->m_free_index == mpt->m_free_queue_depth) {
8319 mpt->m_free_index = 0;
8320 }
8321 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
8322 mpt->m_free_index);
8323 mutex_exit(&mpt->m_mutex);
8324 }
8325
8326 /*
8327 * invoked from timeout() to restart qfull cmds with throttle == 0
8328 */
8329 static void
8330 mptsas_restart_cmd(void *arg)
8331 {
8332 mptsas_t *mpt = arg;
8333 mptsas_target_t *ptgt = NULL;
8334
8335 mutex_enter(&mpt->m_mutex);
8336
8337 mpt->m_restart_cmd_timeid = 0;
8338
8339 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
8340 ptgt = refhash_next(mpt->m_targets, ptgt)) {
8341 if (ptgt->m_reset_delay == 0) {
8342 if (ptgt->m_t_throttle == QFULL_THROTTLE) {
8343 mptsas_set_throttle(mpt, ptgt,
8344 MAX_THROTTLE);
8345 }
8346 }
8347 }
8348 mptsas_restart_hba(mpt);
8349 mutex_exit(&mpt->m_mutex);
8350 }
8351
8352 void
8353 mptsas_remove_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
8354 {
8355 int slot;
8356 mptsas_slots_t *slots = mpt->m_active;
8357 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
8358
8359 ASSERT(cmd != NULL);
8360 ASSERT(cmd->cmd_queued == FALSE);
8361
8362 /*
8363 * Task Management cmds are removed in their own routines. Also,
8364 * we don't want to modify timeout based on TM cmds.
8365 */
8366 if (cmd->cmd_flags & CFLAG_TM_CMD) {
8367 return;
8368 }
8369
8370 slot = cmd->cmd_slot;
8371
8372 /*
8373 * remove the cmd.
8374 */
8375 if (cmd == slots->m_slot[slot]) {
8376 NDBG31(("mptsas_remove_cmd: removing cmd=0x%p, flags "
8377 "0x%x", (void *)cmd, cmd->cmd_flags));
8378 slots->m_slot[slot] = NULL;
8379 mpt->m_ncmds--;
8380
8381 /*
8382 * only decrement per target ncmds if command
8383 * has a target associated with it.
8384 */
8385 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) {
8386 ptgt->m_t_ncmds--;
8387 /*
8388 * reset throttle if we just ran an untagged command
8389 * to a tagged target
8390 */
8391 if ((ptgt->m_t_ncmds == 0) &&
8392 ((cmd->cmd_pkt_flags & FLAG_TAGMASK) == 0)) {
8393 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
8394 }
8395
8396 /*
8397 * Remove this command from the active queue.
8398 */
8399 if (cmd->cmd_active_expiration != 0) {
8400 TAILQ_REMOVE(&ptgt->m_active_cmdq, cmd,
8401 cmd_active_link);
8402 cmd->cmd_active_expiration = 0;
8403 }
8404 }
8405 }
8406
8407 /*
8408 * This is all we need to do for ioc commands.
8409 */
8410 if (cmd->cmd_flags & CFLAG_CMDIOC) {
8411 mptsas_return_to_pool(mpt, cmd);
8412 return;
8413 }
8414
8415 ASSERT(cmd != slots->m_slot[cmd->cmd_slot]);
8416 }
8417
8418 /*
8419 * accept all cmds on the tx_waitq if any and then
8420 * start a fresh request from the top of the device queue.
8421 *
8422 * since there are always cmds queued on the tx_waitq, and rare cmds on
8423 * the instance waitq, so this function should not be invoked in the ISR,
8424 * the mptsas_restart_waitq() is invoked in the ISR instead. otherwise, the
8425 * burden belongs to the IO dispatch CPUs is moved the interrupt CPU.
8426 */
8427 static void
8428 mptsas_restart_hba(mptsas_t *mpt)
8429 {
8430 ASSERT(mutex_owned(&mpt->m_mutex));
8431
8432 mutex_enter(&mpt->m_tx_waitq_mutex);
8433 if (mpt->m_tx_waitq) {
8434 mptsas_accept_tx_waitq(mpt);
8435 }
8436 mutex_exit(&mpt->m_tx_waitq_mutex);
8437 mptsas_restart_waitq(mpt);
8438 }
8439
8440 /*
8441 * start a fresh request from the top of the device queue
8442 */
8443 static void
8444 mptsas_restart_waitq(mptsas_t *mpt)
8445 {
8446 mptsas_cmd_t *cmd, *next_cmd;
8447 mptsas_target_t *ptgt = NULL;
8448
8449 NDBG1(("mptsas_restart_waitq: mpt=0x%p", (void *)mpt));
8450
8451 ASSERT(mutex_owned(&mpt->m_mutex));
8452
8453 /*
8454 * If there is a reset delay, don't start any cmds. Otherwise, start
8455 * as many cmds as possible.
8456 * Since SMID 0 is reserved and the TM slot is reserved, the actual max
8457 * commands is m_max_requests - 2.
8458 */
8459 cmd = mpt->m_waitq;
8460
8461 while (cmd != NULL) {
8462 next_cmd = cmd->cmd_linkp;
8463 if (cmd->cmd_flags & CFLAG_PASSTHRU) {
8464 if (mptsas_save_cmd(mpt, cmd) == TRUE) {
8465 /*
8466 * passthru command get slot need
8467 * set CFLAG_PREPARED.
8468 */
8469 cmd->cmd_flags |= CFLAG_PREPARED;
8470 mptsas_waitq_delete(mpt, cmd);
8471 mptsas_start_passthru(mpt, cmd);
8472 }
8473 cmd = next_cmd;
8474 continue;
8475 }
8476 if (cmd->cmd_flags & CFLAG_CONFIG) {
8477 if (mptsas_save_cmd(mpt, cmd) == TRUE) {
8478 /*
8479 * Send the config page request and delete it
8480 * from the waitq.
8481 */
8482 cmd->cmd_flags |= CFLAG_PREPARED;
8483 mptsas_waitq_delete(mpt, cmd);
8484 mptsas_start_config_page_access(mpt, cmd);
8485 }
8486 cmd = next_cmd;
8487 continue;
8488 }
8489 if (cmd->cmd_flags & CFLAG_FW_DIAG) {
8490 if (mptsas_save_cmd(mpt, cmd) == TRUE) {
8491 /*
8492 * Send the FW Diag request and delete if from
8493 * the waitq.
8494 */
8495 cmd->cmd_flags |= CFLAG_PREPARED;
8496 mptsas_waitq_delete(mpt, cmd);
8497 mptsas_start_diag(mpt, cmd);
8498 }
8499 cmd = next_cmd;
8500 continue;
8501 }
8502
8503 ptgt = cmd->cmd_tgt_addr;
8504 if (ptgt && (ptgt->m_t_throttle == DRAIN_THROTTLE) &&
8505 (ptgt->m_t_ncmds == 0)) {
8506 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
8507 }
8508 if ((mpt->m_ncmds <= (mpt->m_max_requests - 2)) &&
8509 (ptgt && (ptgt->m_reset_delay == 0)) &&
8510 (ptgt && (ptgt->m_t_ncmds <
8511 ptgt->m_t_throttle))) {
8512 if (mptsas_save_cmd(mpt, cmd) == TRUE) {
8513 mptsas_waitq_delete(mpt, cmd);
8514 (void) mptsas_start_cmd(mpt, cmd);
8515 }
8516 }
8517 cmd = next_cmd;
8518 }
8519 }
8520 /*
8521 * Cmds are queued if tran_start() doesn't get the m_mutexlock(no wait).
8522 * Accept all those queued cmds before new cmd is accept so that the
8523 * cmds are sent in order.
8524 */
8525 static void
8526 mptsas_accept_tx_waitq(mptsas_t *mpt)
8527 {
8528 mptsas_cmd_t *cmd;
8529
8530 ASSERT(mutex_owned(&mpt->m_mutex));
8531 ASSERT(mutex_owned(&mpt->m_tx_waitq_mutex));
8532
8533 /*
8534 * A Bus Reset could occur at any time and flush the tx_waitq,
8535 * so we cannot count on the tx_waitq to contain even one cmd.
8536 * And when the m_tx_waitq_mutex is released and run
8537 * mptsas_accept_pkt(), the tx_waitq may be flushed.
8538 */
8539 cmd = mpt->m_tx_waitq;
8540 for (;;) {
8541 if ((cmd = mpt->m_tx_waitq) == NULL) {
8542 mpt->m_tx_draining = 0;
8543 break;
8544 }
8545 if ((mpt->m_tx_waitq = cmd->cmd_linkp) == NULL) {
8546 mpt->m_tx_waitqtail = &mpt->m_tx_waitq;
8547 }
8548 cmd->cmd_linkp = NULL;
8549 mutex_exit(&mpt->m_tx_waitq_mutex);
8550 if (mptsas_accept_pkt(mpt, cmd) != TRAN_ACCEPT)
8551 cmn_err(CE_WARN, "mpt: mptsas_accept_tx_waitq: failed "
8552 "to accept cmd on queue\n");
8553 mutex_enter(&mpt->m_tx_waitq_mutex);
8554 }
8555 }
8556
8557
8558 /*
8559 * mpt tag type lookup
8560 */
8561 static char mptsas_tag_lookup[] =
8562 {0, MSG_HEAD_QTAG, MSG_ORDERED_QTAG, 0, MSG_SIMPLE_QTAG};
8563
8564 static int
8565 mptsas_start_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
8566 {
8567 struct scsi_pkt *pkt = CMD2PKT(cmd);
8568 uint32_t control = 0;
8569 caddr_t mem, arsbuf;
8570 pMpi2SCSIIORequest_t io_request;
8571 ddi_dma_handle_t dma_hdl = mpt->m_dma_req_frame_hdl;
8572 ddi_acc_handle_t acc_hdl = mpt->m_acc_req_frame_hdl;
8573 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
8574 uint16_t SMID, io_flags = 0;
8575 uint8_t ars_size;
8576 uint64_t request_desc;
8577 uint32_t ars_dmaaddrlow;
8578 mptsas_cmd_t *c;
8579
8580 NDBG1(("mptsas_start_cmd: cmd=0x%p, flags 0x%x", (void *)cmd,
8581 cmd->cmd_flags));
8582
8583 /*
8584 * Set SMID and increment index. Rollover to 1 instead of 0 if index
8585 * is at the max. 0 is an invalid SMID, so we call the first index 1.
8586 */
8587 SMID = cmd->cmd_slot;
8588
8589 /*
8590 * It is possible for back to back device reset to
8591 * happen before the reset delay has expired. That's
8592 * ok, just let the device reset go out on the bus.
8593 */
8594 if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) {
8595 ASSERT(ptgt->m_reset_delay == 0);
8596 }
8597
8598 /*
8599 * if a non-tagged cmd is submitted to an active tagged target
8600 * then drain before submitting this cmd; SCSI-2 allows RQSENSE
8601 * to be untagged
8602 */
8603 if (((cmd->cmd_pkt_flags & FLAG_TAGMASK) == 0) &&
8604 (ptgt->m_t_ncmds > 1) &&
8605 ((cmd->cmd_flags & CFLAG_TM_CMD) == 0) &&
8606 (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE)) {
8607 if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) {
8608 NDBG23(("target=%d, untagged cmd, start draining\n",
8609 ptgt->m_devhdl));
8610
8611 if (ptgt->m_reset_delay == 0) {
8612 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
8613 }
8614
8615 mptsas_remove_cmd(mpt, cmd);
8616 cmd->cmd_pkt_flags |= FLAG_HEAD;
8617 mptsas_waitq_add(mpt, cmd);
8618 }
8619 return (DDI_FAILURE);
8620 }
8621
8622 /*
8623 * Set correct tag bits.
8624 */
8625 if (cmd->cmd_pkt_flags & FLAG_TAGMASK) {
8626 switch (mptsas_tag_lookup[((cmd->cmd_pkt_flags &
8627 FLAG_TAGMASK) >> 12)]) {
8628 case MSG_SIMPLE_QTAG:
8629 control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
8630 break;
8631 case MSG_HEAD_QTAG:
8632 control |= MPI2_SCSIIO_CONTROL_HEADOFQ;
8633 break;
8634 case MSG_ORDERED_QTAG:
8635 control |= MPI2_SCSIIO_CONTROL_ORDEREDQ;
8636 break;
8637 default:
8638 mptsas_log(mpt, CE_WARN, "mpt: Invalid tag type\n");
8639 break;
8640 }
8641 } else {
8642 if (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE) {
8643 ptgt->m_t_throttle = 1;
8644 }
8645 control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
8646 }
8647
8648 if (cmd->cmd_pkt_flags & FLAG_TLR) {
8649 control |= MPI2_SCSIIO_CONTROL_TLR_ON;
8650 }
8651
8652 mem = mpt->m_req_frame + (mpt->m_req_frame_size * SMID);
8653 io_request = (pMpi2SCSIIORequest_t)mem;
8654 if (cmd->cmd_extrqslen != 0) {
8655 /*
8656 * Mapping of the buffer was done in mptsas_pkt_alloc_extern().
8657 * Calculate the DMA address with the same offset.
8658 */
8659 arsbuf = cmd->cmd_arq_buf;
8660 ars_size = cmd->cmd_extrqslen;
8661 ars_dmaaddrlow = (mpt->m_req_sense_dma_addr +
8662 ((uintptr_t)arsbuf - (uintptr_t)mpt->m_req_sense)) &
8663 0xffffffffu;
8664 } else {
8665 arsbuf = mpt->m_req_sense + (mpt->m_req_sense_size * (SMID-1));
8666 cmd->cmd_arq_buf = arsbuf;
8667 ars_size = mpt->m_req_sense_size;
8668 ars_dmaaddrlow = (mpt->m_req_sense_dma_addr +
8669 (mpt->m_req_sense_size * (SMID-1))) &
8670 0xffffffffu;
8671 }
8672 bzero(io_request, sizeof (Mpi2SCSIIORequest_t));
8673 bzero(arsbuf, ars_size);
8674
8675 ddi_put8(acc_hdl, &io_request->SGLOffset0, offsetof
8676 (MPI2_SCSI_IO_REQUEST, SGL) / 4);
8677 mptsas_init_std_hdr(acc_hdl, io_request, ptgt->m_devhdl, Lun(cmd), 0,
8678 MPI2_FUNCTION_SCSI_IO_REQUEST);
8679
8680 (void) ddi_rep_put8(acc_hdl, (uint8_t *)pkt->pkt_cdbp,
8681 io_request->CDB.CDB32, cmd->cmd_cdblen, DDI_DEV_AUTOINCR);
8682
8683 io_flags = cmd->cmd_cdblen;
8684 if (mptsas_use_fastpath &&
8685 ptgt->m_io_flags & MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH) {
8686 io_flags |= MPI25_SCSIIO_IOFLAGS_FAST_PATH;
8687 request_desc = MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO;
8688 } else {
8689 request_desc = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO;
8690 }
8691 ddi_put16(acc_hdl, &io_request->IoFlags, io_flags);
8692 /*
8693 * setup the Scatter/Gather DMA list for this request
8694 */
8695 if (cmd->cmd_cookiec > 0) {
8696 mptsas_sge_setup(mpt, cmd, &control, io_request, acc_hdl);
8697 } else {
8698 ddi_put32(acc_hdl, &io_request->SGL.MpiSimple.FlagsLength,
8699 ((uint32_t)MPI2_SGE_FLAGS_LAST_ELEMENT |
8700 MPI2_SGE_FLAGS_END_OF_BUFFER |
8701 MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
8702 MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT);
8703 }
8704
8705 /*
8706 * save ARQ information
8707 */
8708 ddi_put8(acc_hdl, &io_request->SenseBufferLength, ars_size);
8709 ddi_put32(acc_hdl, &io_request->SenseBufferLowAddress, ars_dmaaddrlow);
8710
8711 ddi_put32(acc_hdl, &io_request->Control, control);
8712
8713 NDBG31(("starting message=%d(0x%p), with cmd=0x%p",
8714 SMID, (void *)io_request, (void *)cmd));
8715
8716 (void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
8717 (void) ddi_dma_sync(mpt->m_dma_req_sense_hdl, 0, 0,
8718 DDI_DMA_SYNC_FORDEV);
8719
8720 /*
8721 * Build request descriptor and write it to the request desc post reg.
8722 */
8723 request_desc |= (SMID << 16);
8724 request_desc |= (uint64_t)ptgt->m_devhdl << 48;
8725 MPTSAS_START_CMD(mpt, request_desc);
8726
8727 /*
8728 * Start timeout.
8729 */
8730 cmd->cmd_active_expiration =
8731 gethrtime() + (hrtime_t)pkt->pkt_time * NANOSEC;
8732 #ifdef MPTSAS_TEST
8733 /*
8734 * Force timeouts to happen immediately.
8735 */
8736 if (mptsas_test_timeouts)
8737 cmd->cmd_active_expiration = gethrtime();
8738 #endif
8739 c = TAILQ_FIRST(&ptgt->m_active_cmdq);
8740 if (c == NULL ||
8741 c->cmd_active_expiration < cmd->cmd_active_expiration) {
8742 /*
8743 * Common case is that this is the last pending expiration
8744 * (or queue is empty). Insert at head of the queue.
8745 */
8746 TAILQ_INSERT_HEAD(&ptgt->m_active_cmdq, cmd, cmd_active_link);
8747 } else {
8748 /*
8749 * Queue is not empty and first element expires later than
8750 * this command. Search for element expiring sooner.
8751 */
8752 while ((c = TAILQ_NEXT(c, cmd_active_link)) != NULL) {
8753 if (c->cmd_active_expiration <
8754 cmd->cmd_active_expiration) {
8755 TAILQ_INSERT_BEFORE(c, cmd, cmd_active_link);
8756 break;
8757 }
8758 }
8759 if (c == NULL) {
8760 /*
8761 * No element found expiring sooner, append to
8762 * non-empty queue.
8763 */
8764 TAILQ_INSERT_TAIL(&ptgt->m_active_cmdq, cmd,
8765 cmd_active_link);
8766 }
8767 }
8768
8769 if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) ||
8770 (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) {
8771 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
8772 return (DDI_FAILURE);
8773 }
8774 return (DDI_SUCCESS);
8775 }
8776
8777 /*
8778 * Select a helper thread to handle current doneq
8779 */
8780 static void
8781 mptsas_deliver_doneq_thread(mptsas_t *mpt)
8782 {
8783 uint64_t t, i;
8784 uint32_t min = 0xffffffff;
8785 mptsas_doneq_thread_list_t *item;
8786
8787 for (i = 0; i < mpt->m_doneq_thread_n; i++) {
8788 item = &mpt->m_doneq_thread_id[i];
8789 /*
8790 * If the completed command on help thread[i] less than
8791 * doneq_thread_threshold, then pick the thread[i]. Otherwise
8792 * pick a thread which has least completed command.
8793 */
8794
8795 mutex_enter(&item->mutex);
8796 if (item->len < mpt->m_doneq_thread_threshold) {
8797 t = i;
8798 mutex_exit(&item->mutex);
8799 break;
8800 }
8801 if (item->len < min) {
8802 min = item->len;
8803 t = i;
8804 }
8805 mutex_exit(&item->mutex);
8806 }
8807 mutex_enter(&mpt->m_doneq_thread_id[t].mutex);
8808 mptsas_doneq_mv(mpt, t);
8809 cv_signal(&mpt->m_doneq_thread_id[t].cv);
8810 mutex_exit(&mpt->m_doneq_thread_id[t].mutex);
8811 }
8812
8813 /*
8814 * move the current global doneq to the doneq of thead[t]
8815 */
8816 static void
8817 mptsas_doneq_mv(mptsas_t *mpt, uint64_t t)
8818 {
8819 mptsas_cmd_t *cmd;
8820 mptsas_doneq_thread_list_t *item = &mpt->m_doneq_thread_id[t];
8821
8822 ASSERT(mutex_owned(&item->mutex));
8823 while ((cmd = mpt->m_doneq) != NULL) {
8824 if ((mpt->m_doneq = cmd->cmd_linkp) == NULL) {
8825 mpt->m_donetail = &mpt->m_doneq;
8826 }
8827 cmd->cmd_linkp = NULL;
8828 *item->donetail = cmd;
8829 item->donetail = &cmd->cmd_linkp;
8830 mpt->m_doneq_len--;
8831 item->len++;
8832 }
8833 }
8834
8835 void
8836 mptsas_fma_check(mptsas_t *mpt, mptsas_cmd_t *cmd)
8837 {
8838 struct scsi_pkt *pkt = CMD2PKT(cmd);
8839
8840 /* Check all acc and dma handles */
8841 if ((mptsas_check_acc_handle(mpt->m_datap) !=
8842 DDI_SUCCESS) ||
8843 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) !=
8844 DDI_SUCCESS) ||
8845 (mptsas_check_acc_handle(mpt->m_acc_req_sense_hdl) !=
8846 DDI_SUCCESS) ||
8847 (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl) !=
8848 DDI_SUCCESS) ||
8849 (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl) !=
8850 DDI_SUCCESS) ||
8851 (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl) !=
8852 DDI_SUCCESS) ||
8853 (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl) !=
8854 DDI_SUCCESS) ||
8855 (mptsas_check_acc_handle(mpt->m_config_handle) !=
8856 DDI_SUCCESS)) {
8857 ddi_fm_service_impact(mpt->m_dip,
8858 DDI_SERVICE_UNAFFECTED);
8859 ddi_fm_acc_err_clear(mpt->m_config_handle,
8860 DDI_FME_VER0);
8861 pkt->pkt_reason = CMD_TRAN_ERR;
8862 pkt->pkt_statistics = 0;
8863 }
8864 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) !=
8865 DDI_SUCCESS) ||
8866 (mptsas_check_dma_handle(mpt->m_dma_req_sense_hdl) !=
8867 DDI_SUCCESS) ||
8868 (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl) !=
8869 DDI_SUCCESS) ||
8870 (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl) !=
8871 DDI_SUCCESS) ||
8872 (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) !=
8873 DDI_SUCCESS) ||
8874 (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl) !=
8875 DDI_SUCCESS)) {
8876 ddi_fm_service_impact(mpt->m_dip,
8877 DDI_SERVICE_UNAFFECTED);
8878 pkt->pkt_reason = CMD_TRAN_ERR;
8879 pkt->pkt_statistics = 0;
8880 }
8881 if (cmd->cmd_dmahandle &&
8882 (mptsas_check_dma_handle(cmd->cmd_dmahandle) != DDI_SUCCESS)) {
8883 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
8884 pkt->pkt_reason = CMD_TRAN_ERR;
8885 pkt->pkt_statistics = 0;
8886 }
8887 if ((cmd->cmd_extra_frames &&
8888 ((mptsas_check_dma_handle(cmd->cmd_extra_frames->m_dma_hdl) !=
8889 DDI_SUCCESS) ||
8890 (mptsas_check_acc_handle(cmd->cmd_extra_frames->m_acc_hdl) !=
8891 DDI_SUCCESS)))) {
8892 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
8893 pkt->pkt_reason = CMD_TRAN_ERR;
8894 pkt->pkt_statistics = 0;
8895 }
8896 }
8897
8898 /*
8899 * These routines manipulate the queue of commands that
8900 * are waiting for their completion routines to be called.
8901 * The queue is usually in FIFO order but on an MP system
8902 * it's possible for the completion routines to get out
8903 * of order. If that's a problem you need to add a global
8904 * mutex around the code that calls the completion routine
8905 * in the interrupt handler.
8906 */
8907 static void
8908 mptsas_doneq_add(mptsas_t *mpt, mptsas_cmd_t *cmd)
8909 {
8910 struct scsi_pkt *pkt = CMD2PKT(cmd);
8911
8912 NDBG31(("mptsas_doneq_add: cmd=0x%p", (void *)cmd));
8913
8914 ASSERT((cmd->cmd_flags & CFLAG_COMPLETED) == 0);
8915 cmd->cmd_linkp = NULL;
8916 cmd->cmd_flags |= CFLAG_FINISHED;
8917 cmd->cmd_flags &= ~CFLAG_IN_TRANSPORT;
8918
8919 mptsas_fma_check(mpt, cmd);
8920
8921 /*
8922 * only add scsi pkts that have completion routines to
8923 * the doneq. no intr cmds do not have callbacks.
8924 */
8925 if (pkt && (pkt->pkt_comp)) {
8926 *mpt->m_donetail = cmd;
8927 mpt->m_donetail = &cmd->cmd_linkp;
8928 mpt->m_doneq_len++;
8929 }
8930 }
8931
8932 static mptsas_cmd_t *
8933 mptsas_doneq_thread_rm(mptsas_t *mpt, uint64_t t)
8934 {
8935 mptsas_cmd_t *cmd;
8936 mptsas_doneq_thread_list_t *item = &mpt->m_doneq_thread_id[t];
8937
8938 /* pop one off the done queue */
8939 if ((cmd = item->doneq) != NULL) {
8940 /* if the queue is now empty fix the tail pointer */
8941 NDBG31(("mptsas_doneq_thread_rm: cmd=0x%p", (void *)cmd));
8942 if ((item->doneq = cmd->cmd_linkp) == NULL) {
8943 item->donetail = &item->doneq;
8944 }
8945 cmd->cmd_linkp = NULL;
8946 item->len--;
8947 }
8948 return (cmd);
8949 }
8950
8951 static void
8952 mptsas_doneq_empty(mptsas_t *mpt)
8953 {
8954 if (mpt->m_doneq && !mpt->m_in_callback) {
8955 mptsas_cmd_t *cmd, *next;
8956 struct scsi_pkt *pkt;
8957
8958 mpt->m_in_callback = 1;
8959 cmd = mpt->m_doneq;
8960 mpt->m_doneq = NULL;
8961 mpt->m_donetail = &mpt->m_doneq;
8962 mpt->m_doneq_len = 0;
8963
8964 mutex_exit(&mpt->m_mutex);
8965 /*
8966 * run the completion routines of all the
8967 * completed commands
8968 */
8969 while (cmd != NULL) {
8970 next = cmd->cmd_linkp;
8971 cmd->cmd_linkp = NULL;
8972 /* run this command's completion routine */
8973 cmd->cmd_flags |= CFLAG_COMPLETED;
8974 pkt = CMD2PKT(cmd);
8975 mptsas_pkt_comp(pkt, cmd);
8976 cmd = next;
8977 }
8978 mutex_enter(&mpt->m_mutex);
8979 mpt->m_in_callback = 0;
8980 }
8981 }
8982
8983 /*
8984 * These routines manipulate the target's queue of pending requests
8985 */
8986 void
8987 mptsas_waitq_add(mptsas_t *mpt, mptsas_cmd_t *cmd)
8988 {
8989 NDBG7(("mptsas_waitq_add: cmd=0x%p", (void *)cmd));
8990 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
8991 cmd->cmd_queued = TRUE;
8992 if (ptgt)
8993 ptgt->m_t_nwait++;
8994 if (cmd->cmd_pkt_flags & FLAG_HEAD) {
8995 if ((cmd->cmd_linkp = mpt->m_waitq) == NULL) {
8996 mpt->m_waitqtail = &cmd->cmd_linkp;
8997 }
8998 mpt->m_waitq = cmd;
8999 } else {
9000 cmd->cmd_linkp = NULL;
9001 *(mpt->m_waitqtail) = cmd;
9002 mpt->m_waitqtail = &cmd->cmd_linkp;
9003 }
9004 }
9005
9006 static mptsas_cmd_t *
9007 mptsas_waitq_rm(mptsas_t *mpt)
9008 {
9009 mptsas_cmd_t *cmd;
9010 mptsas_target_t *ptgt;
9011 NDBG7(("mptsas_waitq_rm"));
9012
9013 MPTSAS_WAITQ_RM(mpt, cmd);
9014
9015 NDBG7(("mptsas_waitq_rm: cmd=0x%p", (void *)cmd));
9016 if (cmd) {
9017 ptgt = cmd->cmd_tgt_addr;
9018 if (ptgt) {
9019 ptgt->m_t_nwait--;
9020 ASSERT(ptgt->m_t_nwait >= 0);
9021 }
9022 }
9023 return (cmd);
9024 }
9025
9026 /*
9027 * remove specified cmd from the middle of the wait queue.
9028 */
9029 static void
9030 mptsas_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd)
9031 {
9032 mptsas_cmd_t *prevp = mpt->m_waitq;
9033 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
9034
9035 NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p",
9036 (void *)mpt, (void *)cmd));
9037 if (ptgt) {
9038 ptgt->m_t_nwait--;
9039 ASSERT(ptgt->m_t_nwait >= 0);
9040 }
9041
9042 if (prevp == cmd) {
9043 if ((mpt->m_waitq = cmd->cmd_linkp) == NULL)
9044 mpt->m_waitqtail = &mpt->m_waitq;
9045
9046 cmd->cmd_linkp = NULL;
9047 cmd->cmd_queued = FALSE;
9048 NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p",
9049 (void *)mpt, (void *)cmd));
9050 return;
9051 }
9052
9053 while (prevp != NULL) {
9054 if (prevp->cmd_linkp == cmd) {
9055 if ((prevp->cmd_linkp = cmd->cmd_linkp) == NULL)
9056 mpt->m_waitqtail = &prevp->cmd_linkp;
9057
9058 cmd->cmd_linkp = NULL;
9059 cmd->cmd_queued = FALSE;
9060 NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p",
9061 (void *)mpt, (void *)cmd));
9062 return;
9063 }
9064 prevp = prevp->cmd_linkp;
9065 }
9066 cmn_err(CE_PANIC, "mpt: mptsas_waitq_delete: queue botch");
9067 }
9068
9069 static mptsas_cmd_t *
9070 mptsas_tx_waitq_rm(mptsas_t *mpt)
9071 {
9072 mptsas_cmd_t *cmd;
9073 NDBG7(("mptsas_tx_waitq_rm"));
9074
9075 MPTSAS_TX_WAITQ_RM(mpt, cmd);
9076
9077 NDBG7(("mptsas_tx_waitq_rm: cmd=0x%p", (void *)cmd));
9078
9079 return (cmd);
9080 }
9081
9082 /*
9083 * remove specified cmd from the middle of the tx_waitq.
9084 */
9085 static void
9086 mptsas_tx_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd)
9087 {
9088 mptsas_cmd_t *prevp = mpt->m_tx_waitq;
9089
9090 NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p",
9091 (void *)mpt, (void *)cmd));
9092
9093 if (prevp == cmd) {
9094 if ((mpt->m_tx_waitq = cmd->cmd_linkp) == NULL)
9095 mpt->m_tx_waitqtail = &mpt->m_tx_waitq;
9096
9097 cmd->cmd_linkp = NULL;
9098 cmd->cmd_queued = FALSE;
9099 NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p",
9100 (void *)mpt, (void *)cmd));
9101 return;
9102 }
9103
9104 while (prevp != NULL) {
9105 if (prevp->cmd_linkp == cmd) {
9106 if ((prevp->cmd_linkp = cmd->cmd_linkp) == NULL)
9107 mpt->m_tx_waitqtail = &prevp->cmd_linkp;
9108
9109 cmd->cmd_linkp = NULL;
9110 cmd->cmd_queued = FALSE;
9111 NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p",
9112 (void *)mpt, (void *)cmd));
9113 return;
9114 }
9115 prevp = prevp->cmd_linkp;
9116 }
9117 cmn_err(CE_PANIC, "mpt: mptsas_tx_waitq_delete: queue botch");
9118 }
9119
9120 /*
9121 * device and bus reset handling
9122 *
9123 * Notes:
9124 * - RESET_ALL: reset the controller
9125 * - RESET_TARGET: reset the target specified in scsi_address
9126 */
9127 static int
9128 mptsas_scsi_reset(struct scsi_address *ap, int level)
9129 {
9130 mptsas_t *mpt = ADDR2MPT(ap);
9131 int rval;
9132 mptsas_tgt_private_t *tgt_private;
9133 mptsas_target_t *ptgt = NULL;
9134
9135 tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran->tran_tgt_private;
9136 ptgt = tgt_private->t_private;
9137 if (ptgt == NULL) {
9138 return (FALSE);
9139 }
9140 NDBG22(("mptsas_scsi_reset: target=%d level=%d", ptgt->m_devhdl,
9141 level));
9142
9143 mutex_enter(&mpt->m_mutex);
9144 /*
9145 * if we are not in panic set up a reset delay for this target
9146 */
9147 if (!ddi_in_panic()) {
9148 mptsas_setup_bus_reset_delay(mpt);
9149 } else {
9150 drv_usecwait(mpt->m_scsi_reset_delay * 1000);
9151 }
9152 rval = mptsas_do_scsi_reset(mpt, ptgt->m_devhdl);
9153 mutex_exit(&mpt->m_mutex);
9154
9155 /*
9156 * The transport layer expect to only see TRUE and
9157 * FALSE. Therefore, we will adjust the return value
9158 * if mptsas_do_scsi_reset returns FAILED.
9159 */
9160 if (rval == FAILED)
9161 rval = FALSE;
9162 return (rval);
9163 }
9164
9165 static int
9166 mptsas_do_scsi_reset(mptsas_t *mpt, uint16_t devhdl)
9167 {
9168 int rval = FALSE;
9169 uint8_t config, disk;
9170
9171 ASSERT(mutex_owned(&mpt->m_mutex));
9172
9173 if (mptsas_debug_resets) {
9174 mptsas_log(mpt, CE_WARN, "mptsas_do_scsi_reset: target=%d",
9175 devhdl);
9176 }
9177
9178 /*
9179 * Issue a Target Reset message to the target specified but not to a
9180 * disk making up a raid volume. Just look through the RAID config
9181 * Phys Disk list of DevHandles. If the target's DevHandle is in this
9182 * list, then don't reset this target.
9183 */
9184 for (config = 0; config < mpt->m_num_raid_configs; config++) {
9185 for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) {
9186 if (devhdl == mpt->m_raidconfig[config].
9187 m_physdisk_devhdl[disk]) {
9188 return (TRUE);
9189 }
9190 }
9191 }
9192
9193 rval = mptsas_ioc_task_management(mpt,
9194 MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, devhdl, 0, NULL, 0, 0);
9195
9196 mptsas_doneq_empty(mpt);
9197 return (rval);
9198 }
9199
9200 static int
9201 mptsas_scsi_reset_notify(struct scsi_address *ap, int flag,
9202 void (*callback)(caddr_t), caddr_t arg)
9203 {
9204 mptsas_t *mpt = ADDR2MPT(ap);
9205
9206 NDBG22(("mptsas_scsi_reset_notify: tgt=%d", ap->a_target));
9207
9208 return (scsi_hba_reset_notify_setup(ap, flag, callback, arg,
9209 &mpt->m_mutex, &mpt->m_reset_notify_listf));
9210 }
9211
9212 static int
9213 mptsas_get_name(struct scsi_device *sd, char *name, int len)
9214 {
9215 dev_info_t *lun_dip = NULL;
9216
9217 ASSERT(sd != NULL);
9218 ASSERT(name != NULL);
9219 lun_dip = sd->sd_dev;
9220 ASSERT(lun_dip != NULL);
9221
9222 if (mptsas_name_child(lun_dip, name, len) == DDI_SUCCESS) {
9223 return (1);
9224 } else {
9225 return (0);
9226 }
9227 }
9228
9229 static int
9230 mptsas_get_bus_addr(struct scsi_device *sd, char *name, int len)
9231 {
9232 return (mptsas_get_name(sd, name, len));
9233 }
9234
9235 void
9236 mptsas_set_throttle(mptsas_t *mpt, mptsas_target_t *ptgt, int what)
9237 {
9238
9239 NDBG25(("mptsas_set_throttle: throttle=%x", what));
9240
9241 /*
9242 * if the bus is draining/quiesced, no changes to the throttles
9243 * are allowed. Not allowing change of throttles during draining
9244 * limits error recovery but will reduce draining time
9245 *
9246 * all throttles should have been set to HOLD_THROTTLE
9247 */
9248 if (mpt->m_softstate & (MPTSAS_SS_QUIESCED | MPTSAS_SS_DRAINING)) {
9249 return;
9250 }
9251
9252 if (what == HOLD_THROTTLE) {
9253 ptgt->m_t_throttle = HOLD_THROTTLE;
9254 } else if (ptgt->m_reset_delay == 0) {
9255 ptgt->m_t_throttle = what;
9256 }
9257 }
9258
9259 /*
9260 * Clean up from a device reset.
9261 * For the case of target reset, this function clears the waitq of all
9262 * commands for a particular target. For the case of abort task set, this
9263 * function clears the waitq of all commonds for a particular target/lun.
9264 */
9265 static void
9266 mptsas_flush_target(mptsas_t *mpt, ushort_t target, int lun, uint8_t tasktype)
9267 {
9268 mptsas_slots_t *slots = mpt->m_active;
9269 mptsas_cmd_t *cmd, *next_cmd;
9270 int slot;
9271 uchar_t reason;
9272 uint_t stat;
9273 hrtime_t timestamp;
9274
9275 NDBG25(("mptsas_flush_target: target=%d lun=%d", target, lun));
9276
9277 timestamp = gethrtime();
9278
9279 /*
9280 * Make sure the I/O Controller has flushed all cmds
9281 * that are associated with this target for a target reset
9282 * and target/lun for abort task set.
9283 * Account for TM requests, which use the last SMID.
9284 */
9285 for (slot = 0; slot <= mpt->m_active->m_n_normal; slot++) {
9286 if ((cmd = slots->m_slot[slot]) == NULL)
9287 continue;
9288 reason = CMD_RESET;
9289 stat = STAT_DEV_RESET;
9290 switch (tasktype) {
9291 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
9292 if (Tgt(cmd) == target) {
9293 if (cmd->cmd_active_expiration <= timestamp) {
9294 /*
9295 * When timeout requested, propagate
9296 * proper reason and statistics to
9297 * target drivers.
9298 */
9299 reason = CMD_TIMEOUT;
9300 stat |= STAT_TIMEOUT;
9301 }
9302 NDBG25(("mptsas_flush_target discovered non-"
9303 "NULL cmd in slot %d, tasktype 0x%x", slot,
9304 tasktype));
9305 mptsas_dump_cmd(mpt, cmd);
9306 mptsas_remove_cmd(mpt, cmd);
9307 mptsas_set_pkt_reason(mpt, cmd, reason, stat);
9308 mptsas_doneq_add(mpt, cmd);
9309 }
9310 break;
9311 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
9312 reason = CMD_ABORTED;
9313 stat = STAT_ABORTED;
9314 /*FALLTHROUGH*/
9315 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
9316 if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) {
9317
9318 NDBG25(("mptsas_flush_target discovered non-"
9319 "NULL cmd in slot %d, tasktype 0x%x", slot,
9320 tasktype));
9321 mptsas_dump_cmd(mpt, cmd);
9322 mptsas_remove_cmd(mpt, cmd);
9323 mptsas_set_pkt_reason(mpt, cmd, reason,
9324 stat);
9325 mptsas_doneq_add(mpt, cmd);
9326 }
9327 break;
9328 default:
9329 break;
9330 }
9331 }
9332
9333 /*
9334 * Flush the waitq and tx_waitq of this target's cmds
9335 */
9336 cmd = mpt->m_waitq;
9337
9338 reason = CMD_RESET;
9339 stat = STAT_DEV_RESET;
9340
9341 switch (tasktype) {
9342 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
9343 while (cmd != NULL) {
9344 next_cmd = cmd->cmd_linkp;
9345 if (Tgt(cmd) == target) {
9346 mptsas_waitq_delete(mpt, cmd);
9347 mptsas_set_pkt_reason(mpt, cmd,
9348 reason, stat);
9349 mptsas_doneq_add(mpt, cmd);
9350 }
9351 cmd = next_cmd;
9352 }
9353 mutex_enter(&mpt->m_tx_waitq_mutex);
9354 cmd = mpt->m_tx_waitq;
9355 while (cmd != NULL) {
9356 next_cmd = cmd->cmd_linkp;
9357 if (Tgt(cmd) == target) {
9358 mptsas_tx_waitq_delete(mpt, cmd);
9359 mutex_exit(&mpt->m_tx_waitq_mutex);
9360 mptsas_set_pkt_reason(mpt, cmd,
9361 reason, stat);
9362 mptsas_doneq_add(mpt, cmd);
9363 mutex_enter(&mpt->m_tx_waitq_mutex);
9364 }
9365 cmd = next_cmd;
9366 }
9367 mutex_exit(&mpt->m_tx_waitq_mutex);
9368 break;
9369 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
9370 reason = CMD_ABORTED;
9371 stat = STAT_ABORTED;
9372 /*FALLTHROUGH*/
9373 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
9374 while (cmd != NULL) {
9375 next_cmd = cmd->cmd_linkp;
9376 if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) {
9377 mptsas_waitq_delete(mpt, cmd);
9378 mptsas_set_pkt_reason(mpt, cmd,
9379 reason, stat);
9380 mptsas_doneq_add(mpt, cmd);
9381 }
9382 cmd = next_cmd;
9383 }
9384 mutex_enter(&mpt->m_tx_waitq_mutex);
9385 cmd = mpt->m_tx_waitq;
9386 while (cmd != NULL) {
9387 next_cmd = cmd->cmd_linkp;
9388 if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) {
9389 mptsas_tx_waitq_delete(mpt, cmd);
9390 mutex_exit(&mpt->m_tx_waitq_mutex);
9391 mptsas_set_pkt_reason(mpt, cmd,
9392 reason, stat);
9393 mptsas_doneq_add(mpt, cmd);
9394 mutex_enter(&mpt->m_tx_waitq_mutex);
9395 }
9396 cmd = next_cmd;
9397 }
9398 mutex_exit(&mpt->m_tx_waitq_mutex);
9399 break;
9400 default:
9401 mptsas_log(mpt, CE_WARN, "Unknown task management type %d.",
9402 tasktype);
9403 break;
9404 }
9405 }
9406
9407 /*
9408 * Clean up hba state, abort all outstanding command and commands in waitq
9409 * reset timeout of all targets.
9410 */
9411 static void
9412 mptsas_flush_hba(mptsas_t *mpt)
9413 {
9414 mptsas_slots_t *slots = mpt->m_active;
9415 mptsas_cmd_t *cmd;
9416 int slot;
9417
9418 NDBG25(("mptsas_flush_hba"));
9419
9420 /*
9421 * The I/O Controller should have already sent back
9422 * all commands via the scsi I/O reply frame. Make
9423 * sure all commands have been flushed.
9424 * Account for TM request, which use the last SMID.
9425 */
9426 for (slot = 0; slot <= mpt->m_active->m_n_normal; slot++) {
9427 if ((cmd = slots->m_slot[slot]) == NULL)
9428 continue;
9429
9430 if (cmd->cmd_flags & CFLAG_CMDIOC) {
9431 /*
9432 * Need to make sure to tell everyone that might be
9433 * waiting on this command that it's going to fail. If
9434 * we get here, this command will never timeout because
9435 * the active command table is going to be re-allocated,
9436 * so there will be nothing to check against a time out.
9437 * Instead, mark the command as failed due to reset.
9438 */
9439 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET,
9440 STAT_BUS_RESET);
9441 if ((cmd->cmd_flags &
9442 (CFLAG_PASSTHRU | CFLAG_CONFIG | CFLAG_FW_DIAG))) {
9443 cmd->cmd_flags |= CFLAG_FINISHED;
9444 cv_broadcast(&mpt->m_passthru_cv);
9445 cv_broadcast(&mpt->m_config_cv);
9446 cv_broadcast(&mpt->m_fw_diag_cv);
9447 }
9448 continue;
9449 }
9450
9451 NDBG25(("mptsas_flush_hba discovered non-NULL cmd in slot %d",
9452 slot));
9453 mptsas_dump_cmd(mpt, cmd);
9454
9455 mptsas_remove_cmd(mpt, cmd);
9456 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET);
9457 mptsas_doneq_add(mpt, cmd);
9458 }
9459
9460 /*
9461 * Flush the waitq.
9462 */
9463 while ((cmd = mptsas_waitq_rm(mpt)) != NULL) {
9464 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET);
9465 if ((cmd->cmd_flags & CFLAG_PASSTHRU) ||
9466 (cmd->cmd_flags & CFLAG_CONFIG) ||
9467 (cmd->cmd_flags & CFLAG_FW_DIAG)) {
9468 cmd->cmd_flags |= CFLAG_FINISHED;
9469 cv_broadcast(&mpt->m_passthru_cv);
9470 cv_broadcast(&mpt->m_config_cv);
9471 cv_broadcast(&mpt->m_fw_diag_cv);
9472 } else {
9473 mptsas_doneq_add(mpt, cmd);
9474 }
9475 }
9476
9477 /*
9478 * Flush the tx_waitq
9479 */
9480 mutex_enter(&mpt->m_tx_waitq_mutex);
9481 while ((cmd = mptsas_tx_waitq_rm(mpt)) != NULL) {
9482 mutex_exit(&mpt->m_tx_waitq_mutex);
9483 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET);
9484 mptsas_doneq_add(mpt, cmd);
9485 mutex_enter(&mpt->m_tx_waitq_mutex);
9486 }
9487 mutex_exit(&mpt->m_tx_waitq_mutex);
9488
9489 /*
9490 * Drain the taskqs prior to reallocating resources. The thread
9491 * passing through here could be launched from either (dr)
9492 * or (event) taskqs so only wait on the 'other' queue since
9493 * waiting on 'this' queue is a deadlock condition.
9494 */
9495 mutex_exit(&mpt->m_mutex);
9496 if (!taskq_member((taskq_t *)mpt->m_event_taskq, curthread))
9497 ddi_taskq_wait(mpt->m_event_taskq);
9498 if (!taskq_member((taskq_t *)mpt->m_dr_taskq, curthread))
9499 ddi_taskq_wait(mpt->m_dr_taskq);
9500
9501 mutex_enter(&mpt->m_mutex);
9502 }
9503
9504 /*
9505 * set pkt_reason and OR in pkt_statistics flag
9506 */
9507 static void
9508 mptsas_set_pkt_reason(mptsas_t *mpt, mptsas_cmd_t *cmd, uchar_t reason,
9509 uint_t stat)
9510 {
9511 #ifndef __lock_lint
9512 _NOTE(ARGUNUSED(mpt))
9513 #endif
9514
9515 NDBG25(("mptsas_set_pkt_reason: cmd=0x%p reason=%x stat=%x",
9516 (void *)cmd, reason, stat));
9517
9518 if (cmd) {
9519 if (cmd->cmd_pkt->pkt_reason == CMD_CMPLT) {
9520 cmd->cmd_pkt->pkt_reason = reason;
9521 }
9522 cmd->cmd_pkt->pkt_statistics |= stat;
9523 }
9524 }
9525
9526 static void
9527 mptsas_start_watch_reset_delay()
9528 {
9529 NDBG22(("mptsas_start_watch_reset_delay"));
9530
9531 mutex_enter(&mptsas_global_mutex);
9532 if (mptsas_reset_watch == NULL && mptsas_timeouts_enabled) {
9533 mptsas_reset_watch = timeout(mptsas_watch_reset_delay, NULL,
9534 drv_usectohz((clock_t)
9535 MPTSAS_WATCH_RESET_DELAY_TICK * 1000));
9536 ASSERT(mptsas_reset_watch != NULL);
9537 }
9538 mutex_exit(&mptsas_global_mutex);
9539 }
9540
9541 static void
9542 mptsas_setup_bus_reset_delay(mptsas_t *mpt)
9543 {
9544 mptsas_target_t *ptgt = NULL;
9545
9546 ASSERT(MUTEX_HELD(&mpt->m_mutex));
9547
9548 NDBG22(("mptsas_setup_bus_reset_delay"));
9549 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
9550 ptgt = refhash_next(mpt->m_targets, ptgt)) {
9551 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
9552 ptgt->m_reset_delay = mpt->m_scsi_reset_delay;
9553 }
9554
9555 mptsas_start_watch_reset_delay();
9556 }
9557
9558 /*
9559 * mptsas_watch_reset_delay(_subr) is invoked by timeout() and checks every
9560 * mpt instance for active reset delays
9561 */
9562 static void
9563 mptsas_watch_reset_delay(void *arg)
9564 {
9565 #ifndef __lock_lint
9566 _NOTE(ARGUNUSED(arg))
9567 #endif
9568
9569 mptsas_t *mpt;
9570 int not_done = 0;
9571
9572 NDBG22(("mptsas_watch_reset_delay"));
9573
9574 mutex_enter(&mptsas_global_mutex);
9575 mptsas_reset_watch = 0;
9576 mutex_exit(&mptsas_global_mutex);
9577 rw_enter(&mptsas_global_rwlock, RW_READER);
9578 for (mpt = mptsas_head; mpt != NULL; mpt = mpt->m_next) {
9579 if (mpt->m_tran == 0) {
9580 continue;
9581 }
9582 mutex_enter(&mpt->m_mutex);
9583 not_done += mptsas_watch_reset_delay_subr(mpt);
9584 mutex_exit(&mpt->m_mutex);
9585 }
9586 rw_exit(&mptsas_global_rwlock);
9587
9588 if (not_done) {
9589 mptsas_start_watch_reset_delay();
9590 }
9591 }
9592
9593 static int
9594 mptsas_watch_reset_delay_subr(mptsas_t *mpt)
9595 {
9596 int done = 0;
9597 int restart = 0;
9598 mptsas_target_t *ptgt = NULL;
9599
9600 NDBG22(("mptsas_watch_reset_delay_subr: mpt=0x%p", (void *)mpt));
9601
9602 ASSERT(mutex_owned(&mpt->m_mutex));
9603
9604 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
9605 ptgt = refhash_next(mpt->m_targets, ptgt)) {
9606 if (ptgt->m_reset_delay != 0) {
9607 ptgt->m_reset_delay -=
9608 MPTSAS_WATCH_RESET_DELAY_TICK;
9609 if (ptgt->m_reset_delay <= 0) {
9610 ptgt->m_reset_delay = 0;
9611 mptsas_set_throttle(mpt, ptgt,
9612 MAX_THROTTLE);
9613 restart++;
9614 } else {
9615 done = -1;
9616 }
9617 }
9618 }
9619
9620 if (restart > 0) {
9621 mptsas_restart_hba(mpt);
9622 }
9623 return (done);
9624 }
9625
9626 #ifdef MPTSAS_TEST
9627 static void
9628 mptsas_test_reset(mptsas_t *mpt, int target)
9629 {
9630 mptsas_target_t *ptgt = NULL;
9631
9632 if (mptsas_rtest == target) {
9633 if (mptsas_do_scsi_reset(mpt, target) == TRUE) {
9634 mptsas_rtest = -1;
9635 }
9636 if (mptsas_rtest == -1) {
9637 NDBG22(("mptsas_test_reset success"));
9638 }
9639 }
9640 }
9641 #endif
9642
9643 /*
9644 * abort handling:
9645 *
9646 * Notes:
9647 * - if pkt is not NULL, abort just that command
9648 * - if pkt is NULL, abort all outstanding commands for target
9649 */
9650 static int
9651 mptsas_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt)
9652 {
9653 mptsas_t *mpt = ADDR2MPT(ap);
9654 int rval;
9655 mptsas_tgt_private_t *tgt_private;
9656 int target, lun;
9657
9658 tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran->
9659 tran_tgt_private;
9660 ASSERT(tgt_private != NULL);
9661 target = tgt_private->t_private->m_devhdl;
9662 lun = tgt_private->t_lun;
9663
9664 NDBG23(("mptsas_scsi_abort: target=%d.%d", target, lun));
9665
9666 mutex_enter(&mpt->m_mutex);
9667 rval = mptsas_do_scsi_abort(mpt, target, lun, pkt);
9668 mutex_exit(&mpt->m_mutex);
9669 return (rval);
9670 }
9671
9672 static int
9673 mptsas_do_scsi_abort(mptsas_t *mpt, int target, int lun, struct scsi_pkt *pkt)
9674 {
9675 mptsas_cmd_t *sp = NULL;
9676 mptsas_slots_t *slots = mpt->m_active;
9677 int rval = FALSE;
9678
9679 ASSERT(mutex_owned(&mpt->m_mutex));
9680
9681 /*
9682 * Abort the command pkt on the target/lun in ap. If pkt is
9683 * NULL, abort all outstanding commands on that target/lun.
9684 * If you can abort them, return 1, else return 0.
9685 * Each packet that's aborted should be sent back to the target
9686 * driver through the callback routine, with pkt_reason set to
9687 * CMD_ABORTED.
9688 *
9689 * abort cmd pkt on HBA hardware; clean out of outstanding
9690 * command lists, etc.
9691 */
9692 if (pkt != NULL) {
9693 /* abort the specified packet */
9694 sp = PKT2CMD(pkt);
9695
9696 if (sp->cmd_queued) {
9697 NDBG23(("mptsas_do_scsi_abort: queued sp=0x%p aborted",
9698 (void *)sp));
9699 mptsas_waitq_delete(mpt, sp);
9700 mptsas_set_pkt_reason(mpt, sp, CMD_ABORTED,
9701 STAT_ABORTED);
9702 mptsas_doneq_add(mpt, sp);
9703 rval = TRUE;
9704 goto done;
9705 }
9706
9707 /*
9708 * Have mpt firmware abort this command
9709 */
9710
9711 if (slots->m_slot[sp->cmd_slot] != NULL) {
9712 rval = mptsas_ioc_task_management(mpt,
9713 MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, target,
9714 lun, NULL, 0, 0);
9715
9716 /*
9717 * The transport layer expects only TRUE and FALSE.
9718 * Therefore, if mptsas_ioc_task_management returns
9719 * FAILED we will return FALSE.
9720 */
9721 if (rval == FAILED)
9722 rval = FALSE;
9723 goto done;
9724 }
9725 }
9726
9727 /*
9728 * If pkt is NULL then abort task set
9729 */
9730 rval = mptsas_ioc_task_management(mpt,
9731 MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET, target, lun, NULL, 0, 0);
9732
9733 /*
9734 * The transport layer expects only TRUE and FALSE.
9735 * Therefore, if mptsas_ioc_task_management returns
9736 * FAILED we will return FALSE.
9737 */
9738 if (rval == FAILED)
9739 rval = FALSE;
9740
9741 #ifdef MPTSAS_TEST
9742 if (rval && mptsas_test_stop) {
9743 debug_enter("mptsas_do_scsi_abort");
9744 }
9745 #endif
9746
9747 done:
9748 mptsas_doneq_empty(mpt);
9749 return (rval);
9750 }
9751
9752 /*
9753 * capability handling:
9754 * (*tran_getcap). Get the capability named, and return its value.
9755 */
9756 static int
9757 mptsas_scsi_getcap(struct scsi_address *ap, char *cap, int tgtonly)
9758 {
9759 mptsas_t *mpt = ADDR2MPT(ap);
9760 int ckey;
9761 int rval = FALSE;
9762
9763 NDBG24(("mptsas_scsi_getcap: target=%d, cap=%s tgtonly=%x",
9764 ap->a_target, cap, tgtonly));
9765
9766 mutex_enter(&mpt->m_mutex);
9767
9768 if ((mptsas_scsi_capchk(cap, tgtonly, &ckey)) != TRUE) {
9769 mutex_exit(&mpt->m_mutex);
9770 return (UNDEFINED);
9771 }
9772
9773 switch (ckey) {
9774 case SCSI_CAP_DMA_MAX:
9775 rval = (int)mpt->m_msg_dma_attr.dma_attr_maxxfer;
9776 break;
9777 case SCSI_CAP_ARQ:
9778 rval = TRUE;
9779 break;
9780 case SCSI_CAP_MSG_OUT:
9781 case SCSI_CAP_PARITY:
9782 case SCSI_CAP_UNTAGGED_QING:
9783 rval = TRUE;
9784 break;
9785 case SCSI_CAP_TAGGED_QING:
9786 rval = TRUE;
9787 break;
9788 case SCSI_CAP_RESET_NOTIFICATION:
9789 rval = TRUE;
9790 break;
9791 case SCSI_CAP_LINKED_CMDS:
9792 rval = FALSE;
9793 break;
9794 case SCSI_CAP_QFULL_RETRIES:
9795 rval = ((mptsas_tgt_private_t *)(ap->a_hba_tran->
9796 tran_tgt_private))->t_private->m_qfull_retries;
9797 break;
9798 case SCSI_CAP_QFULL_RETRY_INTERVAL:
9799 rval = drv_hztousec(((mptsas_tgt_private_t *)
9800 (ap->a_hba_tran->tran_tgt_private))->
9801 t_private->m_qfull_retry_interval) / 1000;
9802 break;
9803 case SCSI_CAP_CDB_LEN:
9804 rval = CDB_GROUP4;
9805 break;
9806 case SCSI_CAP_INTERCONNECT_TYPE:
9807 rval = INTERCONNECT_SAS;
9808 break;
9809 case SCSI_CAP_TRAN_LAYER_RETRIES:
9810 if (mpt->m_ioc_capabilities &
9811 MPI2_IOCFACTS_CAPABILITY_TLR)
9812 rval = TRUE;
9813 else
9814 rval = FALSE;
9815 break;
9816 default:
9817 rval = UNDEFINED;
9818 break;
9819 }
9820
9821 NDBG24(("mptsas_scsi_getcap: %s, rval=%x", cap, rval));
9822
9823 mutex_exit(&mpt->m_mutex);
9824 return (rval);
9825 }
9826
9827 /*
9828 * (*tran_setcap). Set the capability named to the value given.
9829 */
9830 static int
9831 mptsas_scsi_setcap(struct scsi_address *ap, char *cap, int value, int tgtonly)
9832 {
9833 mptsas_t *mpt = ADDR2MPT(ap);
9834 int ckey;
9835 int rval = FALSE;
9836
9837 NDBG24(("mptsas_scsi_setcap: target=%d, cap=%s value=%x tgtonly=%x",
9838 ap->a_target, cap, value, tgtonly));
9839
9840 if (!tgtonly) {
9841 return (rval);
9842 }
9843
9844 mutex_enter(&mpt->m_mutex);
9845
9846 if ((mptsas_scsi_capchk(cap, tgtonly, &ckey)) != TRUE) {
9847 mutex_exit(&mpt->m_mutex);
9848 return (UNDEFINED);
9849 }
9850
9851 switch (ckey) {
9852 case SCSI_CAP_DMA_MAX:
9853 case SCSI_CAP_MSG_OUT:
9854 case SCSI_CAP_PARITY:
9855 case SCSI_CAP_INITIATOR_ID:
9856 case SCSI_CAP_LINKED_CMDS:
9857 case SCSI_CAP_UNTAGGED_QING:
9858 case SCSI_CAP_RESET_NOTIFICATION:
9859 /*
9860 * None of these are settable via
9861 * the capability interface.
9862 */
9863 break;
9864 case SCSI_CAP_ARQ:
9865 /*
9866 * We cannot turn off arq so return false if asked to
9867 */
9868 if (value) {
9869 rval = TRUE;
9870 } else {
9871 rval = FALSE;
9872 }
9873 break;
9874 case SCSI_CAP_TAGGED_QING:
9875 mptsas_set_throttle(mpt, ((mptsas_tgt_private_t *)
9876 (ap->a_hba_tran->tran_tgt_private))->t_private,
9877 MAX_THROTTLE);
9878 rval = TRUE;
9879 break;
9880 case SCSI_CAP_QFULL_RETRIES:
9881 ((mptsas_tgt_private_t *)(ap->a_hba_tran->tran_tgt_private))->
9882 t_private->m_qfull_retries = (uchar_t)value;
9883 rval = TRUE;
9884 break;
9885 case SCSI_CAP_QFULL_RETRY_INTERVAL:
9886 ((mptsas_tgt_private_t *)(ap->a_hba_tran->tran_tgt_private))->
9887 t_private->m_qfull_retry_interval =
9888 drv_usectohz(value * 1000);
9889 rval = TRUE;
9890 break;
9891 default:
9892 rval = UNDEFINED;
9893 break;
9894 }
9895 mutex_exit(&mpt->m_mutex);
9896 return (rval);
9897 }
9898
9899 /*
9900 * Utility routine for mptsas_ifsetcap/ifgetcap
9901 */
9902 /*ARGSUSED*/
9903 static int
9904 mptsas_scsi_capchk(char *cap, int tgtonly, int *cidxp)
9905 {
9906 NDBG24(("mptsas_scsi_capchk: cap=%s", cap));
9907
9908 if (!cap)
9909 return (FALSE);
9910
9911 *cidxp = scsi_hba_lookup_capstr(cap);
9912 return (TRUE);
9913 }
9914
9915 static int
9916 mptsas_alloc_active_slots(mptsas_t *mpt, int flag)
9917 {
9918 mptsas_slots_t *old_active = mpt->m_active;
9919 mptsas_slots_t *new_active;
9920 size_t size;
9921
9922 /*
9923 * if there are active commands, then we cannot
9924 * change size of active slots array.
9925 */
9926 ASSERT(mpt->m_ncmds == 0);
9927
9928 size = MPTSAS_SLOTS_SIZE(mpt);
9929 new_active = kmem_zalloc(size, flag);
9930 if (new_active == NULL) {
9931 NDBG1(("new active alloc failed"));
9932 return (-1);
9933 }
9934 /*
9935 * Since SMID 0 is reserved and the TM slot is reserved, the
9936 * number of slots that can be used at any one time is
9937 * m_max_requests - 2.
9938 */
9939 new_active->m_n_normal = (mpt->m_max_requests - 2);
9940 new_active->m_size = size;
9941 new_active->m_rotor = 1;
9942 if (old_active)
9943 mptsas_free_active_slots(mpt);
9944 mpt->m_active = new_active;
9945
9946 return (0);
9947 }
9948
9949 static void
9950 mptsas_free_active_slots(mptsas_t *mpt)
9951 {
9952 mptsas_slots_t *active = mpt->m_active;
9953 size_t size;
9954
9955 if (active == NULL)
9956 return;
9957 size = active->m_size;
9958 kmem_free(active, size);
9959 mpt->m_active = NULL;
9960 }
9961
9962 /*
9963 * Error logging, printing, and debug print routines.
9964 */
9965 static char *mptsas_label = "mpt_sas";
9966
9967 /*PRINTFLIKE3*/
9968 void
9969 mptsas_log(mptsas_t *mpt, int level, char *fmt, ...)
9970 {
9971 dev_info_t *dev;
9972 va_list ap;
9973
9974 if (mpt) {
9975 dev = mpt->m_dip;
9976 } else {
9977 dev = 0;
9978 }
9979
9980 mutex_enter(&mptsas_log_mutex);
9981
9982 va_start(ap, fmt);
9983 (void) vsprintf(mptsas_log_buf, fmt, ap);
9984 va_end(ap);
9985
9986 if (level == CE_CONT) {
9987 scsi_log(dev, mptsas_label, level, "%s\n", mptsas_log_buf);
9988 } else {
9989 scsi_log(dev, mptsas_label, level, "%s", mptsas_log_buf);
9990 }
9991
9992 mutex_exit(&mptsas_log_mutex);
9993 }
9994
9995 #ifdef MPTSAS_DEBUG
9996 /*
9997 * Use a circular buffer to log messages to private memory.
9998 * Increment idx atomically to minimize risk to miss lines.
9999 * It's fast and does not hold up the proceedings too much.
10000 */
10001 static const size_t mptsas_dbglog_linecnt = MPTSAS_DBGLOG_LINECNT;
10002 static const size_t mptsas_dbglog_linelen = MPTSAS_DBGLOG_LINELEN;
10003 static char mptsas_dbglog_bufs[MPTSAS_DBGLOG_LINECNT][MPTSAS_DBGLOG_LINELEN];
10004 static uint32_t mptsas_dbglog_idx = 0;
10005
10006 /*PRINTFLIKE1*/
10007 void
10008 mptsas_debug_log(char *fmt, ...)
10009 {
10010 va_list ap;
10011 uint32_t idx;
10012
10013 idx = atomic_inc_32_nv(&mptsas_dbglog_idx) &
10014 (mptsas_dbglog_linecnt - 1);
10015
10016 va_start(ap, fmt);
10017 (void) vsnprintf(mptsas_dbglog_bufs[idx],
10018 mptsas_dbglog_linelen, fmt, ap);
10019 va_end(ap);
10020 }
10021
10022 /*PRINTFLIKE1*/
10023 void
10024 mptsas_printf(char *fmt, ...)
10025 {
10026 dev_info_t *dev = 0;
10027 va_list ap;
10028
10029 mutex_enter(&mptsas_log_mutex);
10030
10031 va_start(ap, fmt);
10032 (void) vsprintf(mptsas_log_buf, fmt, ap);
10033 va_end(ap);
10034
10035 #ifdef PROM_PRINTF
10036 prom_printf("%s:\t%s\n", mptsas_label, mptsas_log_buf);
10037 #else
10038 scsi_log(dev, mptsas_label, CE_CONT, "!%s\n", mptsas_log_buf);
10039 #endif
10040 mutex_exit(&mptsas_log_mutex);
10041 }
10042 #endif
10043
10044 /*
10045 * timeout handling
10046 */
10047 static void
10048 mptsas_watch(void *arg)
10049 {
10050 #ifndef __lock_lint
10051 _NOTE(ARGUNUSED(arg))
10052 #endif
10053
10054 mptsas_t *mpt;
10055 uint32_t doorbell;
10056
10057 NDBG30(("mptsas_watch"));
10058
10059 rw_enter(&mptsas_global_rwlock, RW_READER);
10060 for (mpt = mptsas_head; mpt != (mptsas_t *)NULL; mpt = mpt->m_next) {
10061
10062 mutex_enter(&mpt->m_mutex);
10063
10064 /* Skip device if not powered on */
10065 if (mpt->m_options & MPTSAS_OPT_PM) {
10066 if (mpt->m_power_level == PM_LEVEL_D0) {
10067 (void) pm_busy_component(mpt->m_dip, 0);
10068 mpt->m_busy = 1;
10069 } else {
10070 mutex_exit(&mpt->m_mutex);
10071 continue;
10072 }
10073 }
10074
10075 /*
10076 * Check if controller is in a FAULT state. If so, reset it.
10077 */
10078 doorbell = ddi_get32(mpt->m_datap, &mpt->m_reg->Doorbell);
10079 if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) {
10080 doorbell &= MPI2_DOORBELL_DATA_MASK;
10081 mptsas_log(mpt, CE_WARN, "MPT Firmware Fault, "
10082 "code: %04x", doorbell);
10083 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET;
10084 if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) {
10085 mptsas_log(mpt, CE_WARN, "Reset failed"
10086 "after fault was detected");
10087 }
10088 }
10089
10090 /*
10091 * For now, always call mptsas_watchsubr.
10092 */
10093 mptsas_watchsubr(mpt);
10094
10095 if (mpt->m_options & MPTSAS_OPT_PM) {
10096 mpt->m_busy = 0;
10097 (void) pm_idle_component(mpt->m_dip, 0);
10098 }
10099
10100 mutex_exit(&mpt->m_mutex);
10101 }
10102 rw_exit(&mptsas_global_rwlock);
10103
10104 mutex_enter(&mptsas_global_mutex);
10105 if (mptsas_timeouts_enabled)
10106 mptsas_timeout_id = timeout(mptsas_watch, NULL, mptsas_tick);
10107 mutex_exit(&mptsas_global_mutex);
10108 }
10109
10110 static void
10111 mptsas_watchsubr_tgt(mptsas_t *mpt, mptsas_target_t *ptgt, hrtime_t timestamp)
10112 {
10113 mptsas_cmd_t *cmd;
10114
10115 /*
10116 * If we were draining due to a qfull condition,
10117 * go back to full throttle.
10118 */
10119 if ((ptgt->m_t_throttle < MAX_THROTTLE) &&
10120 (ptgt->m_t_throttle > HOLD_THROTTLE) &&
10121 (ptgt->m_t_ncmds < ptgt->m_t_throttle)) {
10122 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
10123 mptsas_restart_hba(mpt);
10124 }
10125
10126 cmd = TAILQ_LAST(&ptgt->m_active_cmdq, mptsas_active_cmdq);
10127 if (cmd == NULL)
10128 return;
10129
10130 if (cmd->cmd_active_expiration <= timestamp) {
10131 /*
10132 * Earliest command timeout expired. Drain throttle.
10133 */
10134 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
10135
10136 /*
10137 * Check for remaining commands.
10138 */
10139 cmd = TAILQ_FIRST(&ptgt->m_active_cmdq);
10140 if (cmd->cmd_active_expiration > timestamp) {
10141 /*
10142 * Wait for remaining commands to complete or
10143 * time out.
10144 */
10145 NDBG23(("command timed out, pending drain"));
10146 return;
10147 }
10148
10149 /*
10150 * All command timeouts expired.
10151 */
10152 mptsas_log(mpt, CE_NOTE, "Timeout of %d seconds "
10153 "expired with %d commands on target %d lun %d.",
10154 cmd->cmd_pkt->pkt_time, ptgt->m_t_ncmds,
10155 ptgt->m_devhdl, Lun(cmd));
10156
10157 mptsas_cmd_timeout(mpt, ptgt);
10158 } else if (cmd->cmd_active_expiration <=
10159 timestamp + (hrtime_t)mptsas_scsi_watchdog_tick * NANOSEC) {
10160 NDBG23(("pending timeout"));
10161 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
10162 }
10163 }
10164
10165 static void
10166 mptsas_watchsubr(mptsas_t *mpt)
10167 {
10168 int i;
10169 mptsas_cmd_t *cmd;
10170 mptsas_target_t *ptgt = NULL;
10171 hrtime_t timestamp = gethrtime();
10172
10173 ASSERT(MUTEX_HELD(&mpt->m_mutex));
10174
10175 NDBG30(("mptsas_watchsubr: mpt=0x%p", (void *)mpt));
10176
10177 #ifdef MPTSAS_TEST
10178 if (mptsas_enable_untagged) {
10179 mptsas_test_untagged++;
10180 }
10181 #endif
10182
10183 /*
10184 * Check for commands stuck in active slot
10185 * Account for TM requests, which use the last SMID.
10186 */
10187 for (i = 0; i <= mpt->m_active->m_n_normal; i++) {
10188 if ((cmd = mpt->m_active->m_slot[i]) != NULL) {
10189 if (cmd->cmd_active_expiration <= timestamp) {
10190 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) {
10191 /*
10192 * There seems to be a command stuck
10193 * in the active slot. Drain throttle.
10194 */
10195 mptsas_set_throttle(mpt,
10196 cmd->cmd_tgt_addr,
10197 DRAIN_THROTTLE);
10198 } else if (cmd->cmd_flags &
10199 (CFLAG_PASSTHRU | CFLAG_CONFIG |
10200 CFLAG_FW_DIAG)) {
10201 /*
10202 * passthrough command timeout
10203 */
10204 cmd->cmd_flags |= (CFLAG_FINISHED |
10205 CFLAG_TIMEOUT);
10206 cv_broadcast(&mpt->m_passthru_cv);
10207 cv_broadcast(&mpt->m_config_cv);
10208 cv_broadcast(&mpt->m_fw_diag_cv);
10209 }
10210 }
10211 }
10212 }
10213
10214 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
10215 ptgt = refhash_next(mpt->m_targets, ptgt)) {
10216 mptsas_watchsubr_tgt(mpt, ptgt, timestamp);
10217 }
10218
10219 for (ptgt = refhash_first(mpt->m_tmp_targets); ptgt != NULL;
10220 ptgt = refhash_next(mpt->m_tmp_targets, ptgt)) {
10221 mptsas_watchsubr_tgt(mpt, ptgt, timestamp);
10222 }
10223 }
10224
10225 /*
10226 * timeout recovery
10227 */
10228 static void
10229 mptsas_cmd_timeout(mptsas_t *mpt, mptsas_target_t *ptgt)
10230 {
10231 uint16_t devhdl;
10232 uint64_t sas_wwn;
10233 uint8_t phy;
10234 char wwn_str[MPTSAS_WWN_STRLEN];
10235
10236 devhdl = ptgt->m_devhdl;
10237 sas_wwn = ptgt->m_addr.mta_wwn;
10238 phy = ptgt->m_phynum;
10239 if (sas_wwn == 0) {
10240 (void) sprintf(wwn_str, "p%x", phy);
10241 } else {
10242 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn);
10243 }
10244
10245 NDBG29(("mptsas_cmd_timeout: target=%d", devhdl));
10246 mptsas_log(mpt, CE_WARN, "Disconnected command timeout for "
10247 "target %d %s, enclosure %u", devhdl, wwn_str,
10248 ptgt->m_enclosure);
10249
10250 /*
10251 * Abort all outstanding commands on the device.
10252 */
10253 NDBG29(("mptsas_cmd_timeout: device reset"));
10254 if (mptsas_do_scsi_reset(mpt, devhdl) != TRUE) {
10255 mptsas_log(mpt, CE_WARN, "Target %d reset for command timeout "
10256 "recovery failed!", devhdl);
10257 }
10258 }
10259
10260 /*
10261 * Device / Hotplug control
10262 */
10263 static int
10264 mptsas_scsi_quiesce(dev_info_t *dip)
10265 {
10266 mptsas_t *mpt;
10267 scsi_hba_tran_t *tran;
10268
10269 tran = ddi_get_driver_private(dip);
10270 if (tran == NULL || (mpt = TRAN2MPT(tran)) == NULL)
10271 return (-1);
10272
10273 return (mptsas_quiesce_bus(mpt));
10274 }
10275
10276 static int
10277 mptsas_scsi_unquiesce(dev_info_t *dip)
10278 {
10279 mptsas_t *mpt;
10280 scsi_hba_tran_t *tran;
10281
10282 tran = ddi_get_driver_private(dip);
10283 if (tran == NULL || (mpt = TRAN2MPT(tran)) == NULL)
10284 return (-1);
10285
10286 return (mptsas_unquiesce_bus(mpt));
10287 }
10288
10289 static int
10290 mptsas_quiesce_bus(mptsas_t *mpt)
10291 {
10292 mptsas_target_t *ptgt = NULL;
10293
10294 NDBG28(("mptsas_quiesce_bus"));
10295 mutex_enter(&mpt->m_mutex);
10296
10297 /* Set all the throttles to zero */
10298 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
10299 ptgt = refhash_next(mpt->m_targets, ptgt)) {
10300 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
10301 }
10302
10303 /* If there are any outstanding commands in the queue */
10304 if (mpt->m_ncmds) {
10305 mpt->m_softstate |= MPTSAS_SS_DRAINING;
10306 mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain,
10307 mpt, (MPTSAS_QUIESCE_TIMEOUT * drv_usectohz(1000000)));
10308 if (cv_wait_sig(&mpt->m_cv, &mpt->m_mutex) == 0) {
10309 /*
10310 * Quiesce has been interrupted
10311 */
10312 mpt->m_softstate &= ~MPTSAS_SS_DRAINING;
10313 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
10314 ptgt = refhash_next(mpt->m_targets, ptgt)) {
10315 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
10316 }
10317 mptsas_restart_hba(mpt);
10318 if (mpt->m_quiesce_timeid != 0) {
10319 timeout_id_t tid = mpt->m_quiesce_timeid;
10320 mpt->m_quiesce_timeid = 0;
10321 mutex_exit(&mpt->m_mutex);
10322 (void) untimeout(tid);
10323 return (-1);
10324 }
10325 mutex_exit(&mpt->m_mutex);
10326 return (-1);
10327 } else {
10328 /* Bus has been quiesced */
10329 ASSERT(mpt->m_quiesce_timeid == 0);
10330 mpt->m_softstate &= ~MPTSAS_SS_DRAINING;
10331 mpt->m_softstate |= MPTSAS_SS_QUIESCED;
10332 mutex_exit(&mpt->m_mutex);
10333 return (0);
10334 }
10335 }
10336 /* Bus was not busy - QUIESCED */
10337 mutex_exit(&mpt->m_mutex);
10338
10339 return (0);
10340 }
10341
10342 static int
10343 mptsas_unquiesce_bus(mptsas_t *mpt)
10344 {
10345 mptsas_target_t *ptgt = NULL;
10346
10347 NDBG28(("mptsas_unquiesce_bus"));
10348 mutex_enter(&mpt->m_mutex);
10349 mpt->m_softstate &= ~MPTSAS_SS_QUIESCED;
10350 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
10351 ptgt = refhash_next(mpt->m_targets, ptgt)) {
10352 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
10353 }
10354 mptsas_restart_hba(mpt);
10355 mutex_exit(&mpt->m_mutex);
10356 return (0);
10357 }
10358
10359 static void
10360 mptsas_ncmds_checkdrain(void *arg)
10361 {
10362 mptsas_t *mpt = arg;
10363 mptsas_target_t *ptgt = NULL;
10364
10365 mutex_enter(&mpt->m_mutex);
10366 if (mpt->m_softstate & MPTSAS_SS_DRAINING) {
10367 mpt->m_quiesce_timeid = 0;
10368 if (mpt->m_ncmds == 0) {
10369 /* Command queue has been drained */
10370 cv_signal(&mpt->m_cv);
10371 } else {
10372 /*
10373 * The throttle may have been reset because
10374 * of a SCSI bus reset
10375 */
10376 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
10377 ptgt = refhash_next(mpt->m_targets, ptgt)) {
10378 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
10379 }
10380
10381 mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain,
10382 mpt, (MPTSAS_QUIESCE_TIMEOUT *
10383 drv_usectohz(1000000)));
10384 }
10385 }
10386 mutex_exit(&mpt->m_mutex);
10387 }
10388
10389 /*ARGSUSED*/
10390 static void
10391 mptsas_dump_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
10392 {
10393 int i;
10394 uint8_t *cp = (uchar_t *)cmd->cmd_pkt->pkt_cdbp;
10395 char buf[128];
10396
10397 buf[0] = '\0';
10398 NDBG25(("?Cmd (0x%p) dump for Target %d Lun %d:\n", (void *)cmd,
10399 Tgt(cmd), Lun(cmd)));
10400 (void) sprintf(&buf[0], "\tcdb=[");
10401 for (i = 0; i < (int)cmd->cmd_cdblen; i++) {
10402 (void) sprintf(&buf[strlen(buf)], " 0x%x", *cp++);
10403 }
10404 (void) sprintf(&buf[strlen(buf)], " ]");
10405 NDBG25(("?%s\n", buf));
10406 NDBG25(("?pkt_flags=0x%x pkt_statistics=0x%x pkt_state=0x%x\n",
10407 cmd->cmd_pkt->pkt_flags, cmd->cmd_pkt->pkt_statistics,
10408 cmd->cmd_pkt->pkt_state));
10409 NDBG25(("?pkt_scbp=0x%x cmd_flags=0x%x\n", cmd->cmd_pkt->pkt_scbp ?
10410 *(cmd->cmd_pkt->pkt_scbp) : 0, cmd->cmd_flags));
10411 }
10412
10413 static void
10414 mptsas_passthru_sge(ddi_acc_handle_t acc_hdl, mptsas_pt_request_t *pt,
10415 pMpi2SGESimple64_t sgep)
10416 {
10417 uint32_t sge_flags;
10418 uint32_t data_size, dataout_size;
10419 ddi_dma_cookie_t data_cookie;
10420 ddi_dma_cookie_t dataout_cookie;
10421
10422 data_size = pt->data_size;
10423 dataout_size = pt->dataout_size;
10424 data_cookie = pt->data_cookie;
10425 dataout_cookie = pt->dataout_cookie;
10426
10427 if (dataout_size) {
10428 sge_flags = dataout_size |
10429 ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
10430 MPI2_SGE_FLAGS_END_OF_BUFFER |
10431 MPI2_SGE_FLAGS_HOST_TO_IOC |
10432 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
10433 MPI2_SGE_FLAGS_SHIFT);
10434 ddi_put32(acc_hdl, &sgep->FlagsLength, sge_flags);
10435 ddi_put32(acc_hdl, &sgep->Address.Low,
10436 (uint32_t)(dataout_cookie.dmac_laddress &
10437 0xffffffffull));
10438 ddi_put32(acc_hdl, &sgep->Address.High,
10439 (uint32_t)(dataout_cookie.dmac_laddress
10440 >> 32));
10441 sgep++;
10442 }
10443 sge_flags = data_size;
10444 sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
10445 MPI2_SGE_FLAGS_LAST_ELEMENT |
10446 MPI2_SGE_FLAGS_END_OF_BUFFER |
10447 MPI2_SGE_FLAGS_END_OF_LIST |
10448 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
10449 MPI2_SGE_FLAGS_SHIFT);
10450 if (pt->direction == MPTSAS_PASS_THRU_DIRECTION_WRITE) {
10451 sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_HOST_TO_IOC) <<
10452 MPI2_SGE_FLAGS_SHIFT);
10453 } else {
10454 sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_IOC_TO_HOST) <<
10455 MPI2_SGE_FLAGS_SHIFT);
10456 }
10457 ddi_put32(acc_hdl, &sgep->FlagsLength,
10458 sge_flags);
10459 ddi_put32(acc_hdl, &sgep->Address.Low,
10460 (uint32_t)(data_cookie.dmac_laddress &
10461 0xffffffffull));
10462 ddi_put32(acc_hdl, &sgep->Address.High,
10463 (uint32_t)(data_cookie.dmac_laddress >> 32));
10464 }
10465
10466 static void
10467 mptsas_passthru_ieee_sge(ddi_acc_handle_t acc_hdl, mptsas_pt_request_t *pt,
10468 pMpi2IeeeSgeSimple64_t ieeesgep)
10469 {
10470 uint8_t sge_flags;
10471 uint32_t data_size, dataout_size;
10472 ddi_dma_cookie_t data_cookie;
10473 ddi_dma_cookie_t dataout_cookie;
10474
10475 data_size = pt->data_size;
10476 dataout_size = pt->dataout_size;
10477 data_cookie = pt->data_cookie;
10478 dataout_cookie = pt->dataout_cookie;
10479
10480 sge_flags = (MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT |
10481 MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR);
10482 if (dataout_size) {
10483 ddi_put32(acc_hdl, &ieeesgep->Length, dataout_size);
10484 ddi_put32(acc_hdl, &ieeesgep->Address.Low,
10485 (uint32_t)(dataout_cookie.dmac_laddress &
10486 0xffffffffull));
10487 ddi_put32(acc_hdl, &ieeesgep->Address.High,
10488 (uint32_t)(dataout_cookie.dmac_laddress >> 32));
10489 ddi_put8(acc_hdl, &ieeesgep->Flags, sge_flags);
10490 ieeesgep++;
10491 }
10492 sge_flags |= MPI25_IEEE_SGE_FLAGS_END_OF_LIST;
10493 ddi_put32(acc_hdl, &ieeesgep->Length, data_size);
10494 ddi_put32(acc_hdl, &ieeesgep->Address.Low,
10495 (uint32_t)(data_cookie.dmac_laddress & 0xffffffffull));
10496 ddi_put32(acc_hdl, &ieeesgep->Address.High,
10497 (uint32_t)(data_cookie.dmac_laddress >> 32));
10498 ddi_put8(acc_hdl, &ieeesgep->Flags, sge_flags);
10499 }
10500
10501 static void
10502 mptsas_start_passthru(mptsas_t *mpt, mptsas_cmd_t *cmd)
10503 {
10504 caddr_t memp;
10505 pMPI2RequestHeader_t request_hdrp;
10506 struct scsi_pkt *pkt = cmd->cmd_pkt;
10507 mptsas_pt_request_t *pt = pkt->pkt_ha_private;
10508 uint32_t request_size;
10509 uint32_t i;
10510 uint64_t request_desc = 0;
10511 uint8_t desc_type;
10512 uint16_t SMID;
10513 uint8_t *request, function;
10514 ddi_dma_handle_t dma_hdl = mpt->m_dma_req_frame_hdl;
10515 ddi_acc_handle_t acc_hdl = mpt->m_acc_req_frame_hdl;
10516
10517 desc_type = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
10518
10519 request = pt->request;
10520 request_size = pt->request_size;
10521
10522 SMID = cmd->cmd_slot;
10523
10524 /*
10525 * Store the passthrough message in memory location
10526 * corresponding to our slot number
10527 */
10528 memp = mpt->m_req_frame + (mpt->m_req_frame_size * SMID);
10529 request_hdrp = (pMPI2RequestHeader_t)memp;
10530 bzero(memp, mpt->m_req_frame_size);
10531
10532 for (i = 0; i < request_size; i++) {
10533 bcopy(request + i, memp + i, 1);
10534 }
10535
10536 NDBG15(("mptsas_start_passthru: Func 0x%x, MsgFlags 0x%x, "
10537 "size=%d, in %d, out %d, SMID %d", request_hdrp->Function,
10538 request_hdrp->MsgFlags, request_size,
10539 pt->data_size, pt->dataout_size, SMID));
10540
10541 /*
10542 * Add an SGE, even if the length is zero.
10543 */
10544 if (mpt->m_MPI25 && pt->simple == 0) {
10545 mptsas_passthru_ieee_sge(acc_hdl, pt,
10546 (pMpi2IeeeSgeSimple64_t)
10547 ((uint8_t *)request_hdrp + pt->sgl_offset));
10548 } else {
10549 mptsas_passthru_sge(acc_hdl, pt,
10550 (pMpi2SGESimple64_t)
10551 ((uint8_t *)request_hdrp + pt->sgl_offset));
10552 }
10553
10554 function = request_hdrp->Function;
10555 if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) ||
10556 (function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
10557 pMpi2SCSIIORequest_t scsi_io_req;
10558 caddr_t arsbuf;
10559 uint8_t ars_size;
10560 uint32_t ars_dmaaddrlow;
10561
10562 NDBG15(("mptsas_start_passthru: Is SCSI IO Req"));
10563 scsi_io_req = (pMpi2SCSIIORequest_t)request_hdrp;
10564
10565 if (cmd->cmd_extrqslen != 0) {
10566 /*
10567 * Mapping of the buffer was done in
10568 * mptsas_do_passthru().
10569 * Calculate the DMA address with the same offset.
10570 */
10571 arsbuf = cmd->cmd_arq_buf;
10572 ars_size = cmd->cmd_extrqslen;
10573 ars_dmaaddrlow = (mpt->m_req_sense_dma_addr +
10574 ((uintptr_t)arsbuf - (uintptr_t)mpt->m_req_sense)) &
10575 0xffffffffu;
10576 } else {
10577 arsbuf = mpt->m_req_sense +
10578 (mpt->m_req_sense_size * (SMID-1));
10579 cmd->cmd_arq_buf = arsbuf;
10580 ars_size = mpt->m_req_sense_size;
10581 ars_dmaaddrlow = (mpt->m_req_sense_dma_addr +
10582 (mpt->m_req_sense_size * (SMID-1))) &
10583 0xffffffffu;
10584 }
10585 bzero(arsbuf, ars_size);
10586
10587 ddi_put8(acc_hdl, &scsi_io_req->SenseBufferLength, ars_size);
10588 ddi_put32(acc_hdl, &scsi_io_req->SenseBufferLowAddress,
10589 ars_dmaaddrlow);
10590
10591 /*
10592 * Put SGE for data and data_out buffer at the end of
10593 * scsi_io_request message header.(64 bytes in total)
10594 * Set SGLOffset0 value
10595 */
10596 ddi_put8(acc_hdl, &scsi_io_req->SGLOffset0,
10597 offsetof(MPI2_SCSI_IO_REQUEST, SGL) / 4);
10598
10599 /*
10600 * Setup descriptor info. RAID passthrough must use the
10601 * default request descriptor which is already set, so if this
10602 * is a SCSI IO request, change the descriptor to SCSI IO.
10603 */
10604 if (function == MPI2_FUNCTION_SCSI_IO_REQUEST) {
10605 desc_type = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO;
10606 request_desc = ((uint64_t)ddi_get16(acc_hdl,
10607 &scsi_io_req->DevHandle) << 48);
10608 }
10609 (void) ddi_dma_sync(mpt->m_dma_req_sense_hdl, 0, 0,
10610 DDI_DMA_SYNC_FORDEV);
10611 }
10612
10613 /*
10614 * We must wait till the message has been completed before
10615 * beginning the next message so we wait for this one to
10616 * finish.
10617 */
10618 (void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
10619 request_desc |= (SMID << 16) + desc_type;
10620 cmd->cmd_rfm = NULL;
10621 MPTSAS_START_CMD(mpt, request_desc);
10622 if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) ||
10623 (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) {
10624 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
10625 }
10626 }
10627
10628 typedef void (mptsas_pre_f)(mptsas_t *, mptsas_pt_request_t *);
10629 static mptsas_pre_f mpi_pre_ioc_facts;
10630 static mptsas_pre_f mpi_pre_port_facts;
10631 static mptsas_pre_f mpi_pre_fw_download;
10632 static mptsas_pre_f mpi_pre_fw_25_download;
10633 static mptsas_pre_f mpi_pre_fw_upload;
10634 static mptsas_pre_f mpi_pre_fw_25_upload;
10635 static mptsas_pre_f mpi_pre_sata_passthrough;
10636 static mptsas_pre_f mpi_pre_smp_passthrough;
10637 static mptsas_pre_f mpi_pre_config;
10638 static mptsas_pre_f mpi_pre_sas_io_unit_control;
10639 static mptsas_pre_f mpi_pre_scsi_io_req;
10640
10641 /*
10642 * Prepare the pt for a SAS2 FW_DOWNLOAD request.
10643 */
10644 static void
10645 mpi_pre_fw_download(mptsas_t *mpt, mptsas_pt_request_t *pt)
10646 {
10647 pMpi2FWDownloadTCSGE_t tcsge;
10648 pMpi2FWDownloadRequest req;
10649
10650 /*
10651 * If SAS3, call separate function.
10652 */
10653 if (mpt->m_MPI25) {
10654 mpi_pre_fw_25_download(mpt, pt);
10655 return;
10656 }
10657
10658 /*
10659 * User requests should come in with the Transaction
10660 * context element where the SGL will go. Putting the
10661 * SGL after that seems to work, but don't really know
10662 * why. Other drivers tend to create an extra SGL and
10663 * refer to the TCE through that.
10664 */
10665 req = (pMpi2FWDownloadRequest)pt->request;
10666 tcsge = (pMpi2FWDownloadTCSGE_t)&req->SGL;
10667 if (tcsge->ContextSize != 0 || tcsge->DetailsLength != 12 ||
10668 tcsge->Flags != MPI2_SGE_FLAGS_TRANSACTION_ELEMENT) {
10669 mptsas_log(mpt, CE_WARN, "FW Download tce invalid!");
10670 }
10671
10672 pt->sgl_offset = offsetof(MPI2_FW_DOWNLOAD_REQUEST, SGL) +
10673 sizeof (*tcsge);
10674 if (pt->request_size != pt->sgl_offset)
10675 NDBG15(("mpi_pre_fw_download(): Incorrect req size, "
10676 "0x%x, should be 0x%x, dataoutsz 0x%x",
10677 (int)pt->request_size, (int)pt->sgl_offset,
10678 (int)pt->dataout_size));
10679 if (pt->data_size < sizeof (MPI2_FW_DOWNLOAD_REPLY))
10680 NDBG15(("mpi_pre_fw_download(): Incorrect rep size, "
10681 "0x%x, should be 0x%x", pt->data_size,
10682 (int)sizeof (MPI2_FW_DOWNLOAD_REPLY)));
10683 }
10684
10685 /*
10686 * Prepare the pt for a SAS3 FW_DOWNLOAD request.
10687 */
10688 static void
10689 mpi_pre_fw_25_download(mptsas_t *mpt, mptsas_pt_request_t *pt)
10690 {
10691 pMpi2FWDownloadTCSGE_t tcsge;
10692 pMpi2FWDownloadRequest req2;
10693 pMpi25FWDownloadRequest req25;
10694
10695 /*
10696 * User requests should come in with the Transaction
10697 * context element where the SGL will go. The new firmware
10698 * Doesn't use TCE and has space in the main request for
10699 * this information. So move to the right place.
10700 */
10701 req2 = (pMpi2FWDownloadRequest)pt->request;
10702 req25 = (pMpi25FWDownloadRequest)pt->request;
10703 tcsge = (pMpi2FWDownloadTCSGE_t)&req2->SGL;
10704 if (tcsge->ContextSize != 0 || tcsge->DetailsLength != 12 ||
10705 tcsge->Flags != MPI2_SGE_FLAGS_TRANSACTION_ELEMENT) {
10706 mptsas_log(mpt, CE_WARN, "FW Download tce invalid!");
10707 }
10708 req25->ImageOffset = tcsge->ImageOffset;
10709 req25->ImageSize = tcsge->ImageSize;
10710
10711 pt->sgl_offset = offsetof(MPI25_FW_DOWNLOAD_REQUEST, SGL);
10712 if (pt->request_size != pt->sgl_offset)
10713 NDBG15(("mpi_pre_fw_25_download(): Incorrect req size, "
10714 "0x%x, should be 0x%x, dataoutsz 0x%x",
10715 pt->request_size, pt->sgl_offset,
10716 pt->dataout_size));
10717 if (pt->data_size < sizeof (MPI2_FW_DOWNLOAD_REPLY))
10718 NDBG15(("mpi_pre_fw_25_download(): Incorrect rep size, "
10719 "0x%x, should be 0x%x", pt->data_size,
10720 (int)sizeof (MPI2_FW_UPLOAD_REPLY)));
10721 }
10722
10723 /*
10724 * Prepare the pt for a SAS2 FW_UPLOAD request.
10725 */
10726 static void
10727 mpi_pre_fw_upload(mptsas_t *mpt, mptsas_pt_request_t *pt)
10728 {
10729 pMpi2FWUploadTCSGE_t tcsge;
10730 pMpi2FWUploadRequest_t req;
10731
10732 /*
10733 * If SAS3, call separate function.
10734 */
10735 if (mpt->m_MPI25) {
10736 mpi_pre_fw_25_upload(mpt, pt);
10737 return;
10738 }
10739
10740 /*
10741 * User requests should come in with the Transaction
10742 * context element where the SGL will go. Putting the
10743 * SGL after that seems to work, but don't really know
10744 * why. Other drivers tend to create an extra SGL and
10745 * refer to the TCE through that.
10746 */
10747 req = (pMpi2FWUploadRequest_t)pt->request;
10748 tcsge = (pMpi2FWUploadTCSGE_t)&req->SGL;
10749 if (tcsge->ContextSize != 0 || tcsge->DetailsLength != 12 ||
10750 tcsge->Flags != MPI2_SGE_FLAGS_TRANSACTION_ELEMENT) {
10751 mptsas_log(mpt, CE_WARN, "FW Upload tce invalid!");
10752 }
10753
10754 pt->sgl_offset = offsetof(MPI2_FW_UPLOAD_REQUEST, SGL) +
10755 sizeof (*tcsge);
10756 if (pt->request_size != pt->sgl_offset)
10757 NDBG15(("mpi_pre_fw_upload(): Incorrect req size, "
10758 "0x%x, should be 0x%x, dataoutsz 0x%x",
10759 pt->request_size, pt->sgl_offset,
10760 pt->dataout_size));
10761 if (pt->data_size < sizeof (MPI2_FW_UPLOAD_REPLY))
10762 NDBG15(("mpi_pre_fw_upload(): Incorrect rep size, "
10763 "0x%x, should be 0x%x", pt->data_size,
10764 (int)sizeof (MPI2_FW_UPLOAD_REPLY)));
10765 }
10766
10767 /*
10768 * Prepare the pt a SAS3 FW_UPLOAD request.
10769 */
10770 static void
10771 mpi_pre_fw_25_upload(mptsas_t *mpt, mptsas_pt_request_t *pt)
10772 {
10773 pMpi2FWUploadTCSGE_t tcsge;
10774 pMpi2FWUploadRequest_t req2;
10775 pMpi25FWUploadRequest_t req25;
10776
10777 /*
10778 * User requests should come in with the Transaction
10779 * context element where the SGL will go. The new firmware
10780 * Doesn't use TCE and has space in the main request for
10781 * this information. So move to the right place.
10782 */
10783 req2 = (pMpi2FWUploadRequest_t)pt->request;
10784 req25 = (pMpi25FWUploadRequest_t)pt->request;
10785 tcsge = (pMpi2FWUploadTCSGE_t)&req2->SGL;
10786 if (tcsge->ContextSize != 0 || tcsge->DetailsLength != 12 ||
10787 tcsge->Flags != MPI2_SGE_FLAGS_TRANSACTION_ELEMENT) {
10788 mptsas_log(mpt, CE_WARN, "FW Upload tce invalid!");
10789 }
10790 req25->ImageOffset = tcsge->ImageOffset;
10791 req25->ImageSize = tcsge->ImageSize;
10792
10793 pt->sgl_offset = offsetof(MPI25_FW_UPLOAD_REQUEST, SGL);
10794 if (pt->request_size != pt->sgl_offset)
10795 NDBG15(("mpi_pre_fw_25_upload(): Incorrect req size, "
10796 "0x%x, should be 0x%x, dataoutsz 0x%x",
10797 pt->request_size, pt->sgl_offset,
10798 pt->dataout_size));
10799 if (pt->data_size < sizeof (MPI2_FW_UPLOAD_REPLY))
10800 NDBG15(("mpi_pre_fw_25_upload(): Incorrect rep size, "
10801 "0x%x, should be 0x%x", pt->data_size,
10802 (int)sizeof (MPI2_FW_UPLOAD_REPLY)));
10803 }
10804
10805 /*
10806 * Prepare the pt for an IOC_FACTS request.
10807 */
10808 static void
10809 mpi_pre_ioc_facts(mptsas_t *mpt, mptsas_pt_request_t *pt)
10810 {
10811 #ifndef __lock_lint
10812 _NOTE(ARGUNUSED(mpt))
10813 #endif
10814 if (pt->request_size != sizeof (MPI2_IOC_FACTS_REQUEST))
10815 NDBG15(("mpi_pre_ioc_facts(): Incorrect req size, "
10816 "0x%x, should be 0x%x, dataoutsz 0x%x",
10817 pt->request_size,
10818 (int)sizeof (MPI2_IOC_FACTS_REQUEST),
10819 pt->dataout_size));
10820 if (pt->data_size != sizeof (MPI2_IOC_FACTS_REPLY))
10821 NDBG15(("mpi_pre_ioc_facts(): Incorrect rep size, "
10822 "0x%x, should be 0x%x", pt->data_size,
10823 (int)sizeof (MPI2_IOC_FACTS_REPLY)));
10824 pt->sgl_offset = (uint16_t)pt->request_size;
10825 }
10826
10827 /*
10828 * Prepare the pt for a PORT_FACTS request.
10829 */
10830 static void
10831 mpi_pre_port_facts(mptsas_t *mpt, mptsas_pt_request_t *pt)
10832 {
10833 #ifndef __lock_lint
10834 _NOTE(ARGUNUSED(mpt))
10835 #endif
10836 if (pt->request_size != sizeof (MPI2_PORT_FACTS_REQUEST))
10837 NDBG15(("mpi_pre_port_facts(): Incorrect req size, "
10838 "0x%x, should be 0x%x, dataoutsz 0x%x",
10839 pt->request_size,
10840 (int)sizeof (MPI2_PORT_FACTS_REQUEST),
10841 pt->dataout_size));
10842 if (pt->data_size != sizeof (MPI2_PORT_FACTS_REPLY))
10843 NDBG15(("mpi_pre_port_facts(): Incorrect rep size, "
10844 "0x%x, should be 0x%x", pt->data_size,
10845 (int)sizeof (MPI2_PORT_FACTS_REPLY)));
10846 pt->sgl_offset = (uint16_t)pt->request_size;
10847 }
10848
10849 /*
10850 * Prepare pt for a SATA_PASSTHROUGH request.
10851 */
10852 static void
10853 mpi_pre_sata_passthrough(mptsas_t *mpt, mptsas_pt_request_t *pt)
10854 {
10855 #ifndef __lock_lint
10856 _NOTE(ARGUNUSED(mpt))
10857 #endif
10858 pt->sgl_offset = offsetof(MPI2_SATA_PASSTHROUGH_REQUEST, SGL);
10859 if (pt->request_size != pt->sgl_offset)
10860 NDBG15(("mpi_pre_sata_passthrough(): Incorrect req size, "
10861 "0x%x, should be 0x%x, dataoutsz 0x%x",
10862 pt->request_size, pt->sgl_offset,
10863 pt->dataout_size));
10864 if (pt->data_size != sizeof (MPI2_SATA_PASSTHROUGH_REPLY))
10865 NDBG15(("mpi_pre_sata_passthrough(): Incorrect rep size, "
10866 "0x%x, should be 0x%x", pt->data_size,
10867 (int)sizeof (MPI2_SATA_PASSTHROUGH_REPLY)));
10868 }
10869
10870 static void
10871 mpi_pre_smp_passthrough(mptsas_t *mpt, mptsas_pt_request_t *pt)
10872 {
10873 #ifndef __lock_lint
10874 _NOTE(ARGUNUSED(mpt))
10875 #endif
10876 pt->sgl_offset = offsetof(MPI2_SMP_PASSTHROUGH_REQUEST, SGL);
10877 if (pt->request_size != pt->sgl_offset)
10878 NDBG15(("mpi_pre_smp_passthrough(): Incorrect req size, "
10879 "0x%x, should be 0x%x, dataoutsz 0x%x",
10880 pt->request_size, pt->sgl_offset,
10881 pt->dataout_size));
10882 if (pt->data_size != sizeof (MPI2_SMP_PASSTHROUGH_REPLY))
10883 NDBG15(("mpi_pre_smp_passthrough(): Incorrect rep size, "
10884 "0x%x, should be 0x%x", pt->data_size,
10885 (int)sizeof (MPI2_SMP_PASSTHROUGH_REPLY)));
10886 }
10887
10888 /*
10889 * Prepare pt for a CONFIG request.
10890 */
10891 static void
10892 mpi_pre_config(mptsas_t *mpt, mptsas_pt_request_t *pt)
10893 {
10894 #ifndef __lock_lint
10895 _NOTE(ARGUNUSED(mpt))
10896 #endif
10897 pt->sgl_offset = offsetof(MPI2_CONFIG_REQUEST, PageBufferSGE);
10898 if (pt->request_size != pt->sgl_offset)
10899 NDBG15(("mpi_pre_config(): Incorrect req size, 0x%x, "
10900 "should be 0x%x, dataoutsz 0x%x", pt->request_size,
10901 pt->sgl_offset, pt->dataout_size));
10902 if (pt->data_size != sizeof (MPI2_CONFIG_REPLY))
10903 NDBG15(("mpi_pre_config(): Incorrect rep size, 0x%x, "
10904 "should be 0x%x", pt->data_size,
10905 (int)sizeof (MPI2_CONFIG_REPLY)));
10906 pt->simple = 1;
10907 }
10908
10909 /*
10910 * Prepare pt for a SCSI_IO_REQ request.
10911 */
10912 static void
10913 mpi_pre_scsi_io_req(mptsas_t *mpt, mptsas_pt_request_t *pt)
10914 {
10915 #ifndef __lock_lint
10916 _NOTE(ARGUNUSED(mpt))
10917 #endif
10918 pt->sgl_offset = offsetof(MPI2_SCSI_IO_REQUEST, SGL);
10919 if (pt->request_size != pt->sgl_offset)
10920 NDBG15(("mpi_pre_config(): Incorrect req size, 0x%x, "
10921 "should be 0x%x, dataoutsz 0x%x", pt->request_size,
10922 pt->sgl_offset,
10923 pt->dataout_size));
10924 if (pt->data_size != sizeof (MPI2_SCSI_IO_REPLY))
10925 NDBG15(("mpi_pre_config(): Incorrect rep size, 0x%x, "
10926 "should be 0x%x", pt->data_size,
10927 (int)sizeof (MPI2_SCSI_IO_REPLY)));
10928 }
10929
10930 /*
10931 * Prepare the mptsas_cmd for a SAS_IO_UNIT_CONTROL request.
10932 */
10933 static void
10934 mpi_pre_sas_io_unit_control(mptsas_t *mpt, mptsas_pt_request_t *pt)
10935 {
10936 #ifndef __lock_lint
10937 _NOTE(ARGUNUSED(mpt))
10938 #endif
10939 pt->sgl_offset = (uint16_t)pt->request_size;
10940 }
10941
10942 /*
10943 * A set of functions to prepare an mptsas_cmd for the various
10944 * supported requests.
10945 */
10946 static struct mptsas_func {
10947 U8 Function;
10948 char *Name;
10949 mptsas_pre_f *f_pre;
10950 } mptsas_func_list[] = {
10951 { MPI2_FUNCTION_IOC_FACTS, "IOC_FACTS", mpi_pre_ioc_facts },
10952 { MPI2_FUNCTION_PORT_FACTS, "PORT_FACTS", mpi_pre_port_facts },
10953 { MPI2_FUNCTION_FW_DOWNLOAD, "FW_DOWNLOAD", mpi_pre_fw_download },
10954 { MPI2_FUNCTION_FW_UPLOAD, "FW_UPLOAD", mpi_pre_fw_upload },
10955 { MPI2_FUNCTION_SATA_PASSTHROUGH, "SATA_PASSTHROUGH",
10956 mpi_pre_sata_passthrough },
10957 { MPI2_FUNCTION_SMP_PASSTHROUGH, "SMP_PASSTHROUGH",
10958 mpi_pre_smp_passthrough},
10959 { MPI2_FUNCTION_SCSI_IO_REQUEST, "SCSI_IO_REQUEST",
10960 mpi_pre_scsi_io_req},
10961 { MPI2_FUNCTION_CONFIG, "CONFIG", mpi_pre_config},
10962 { MPI2_FUNCTION_SAS_IO_UNIT_CONTROL, "SAS_IO_UNIT_CONTROL",
10963 mpi_pre_sas_io_unit_control },
10964 { 0xFF, NULL, NULL } /* list end */
10965 };
10966
10967 static void
10968 mptsas_prep_sgl_offset(mptsas_t *mpt, mptsas_pt_request_t *pt)
10969 {
10970 pMPI2RequestHeader_t hdr;
10971 struct mptsas_func *f;
10972
10973 hdr = (pMPI2RequestHeader_t)pt->request;
10974
10975 for (f = mptsas_func_list; f->f_pre != NULL; f++) {
10976 if (hdr->Function == f->Function) {
10977 f->f_pre(mpt, pt);
10978 NDBG15(("mptsas_prep_sgl_offset: Function %s,"
10979 " sgl_offset 0x%x", f->Name,
10980 pt->sgl_offset));
10981 return;
10982 }
10983 }
10984 NDBG15(("mptsas_prep_sgl_offset: Unknown Function 0x%02x,"
10985 " returning req_size 0x%x for sgl_offset",
10986 hdr->Function, pt->request_size));
10987 pt->sgl_offset = (uint16_t)pt->request_size;
10988 }
10989
10990
10991 static int
10992 mptsas_do_passthru(mptsas_t *mpt, uint8_t *request, uint8_t *reply,
10993 uint8_t *data, uint32_t request_size, uint32_t reply_size,
10994 uint32_t data_size, uint32_t direction, uint8_t *dataout,
10995 uint32_t dataout_size, short timeout, int mode)
10996 {
10997 mptsas_pt_request_t pt;
10998 mptsas_dma_alloc_state_t data_dma_state;
10999 mptsas_dma_alloc_state_t dataout_dma_state;
11000 caddr_t memp;
11001 mptsas_cmd_t *cmd = NULL;
11002 struct scsi_pkt *pkt;
11003 uint32_t reply_len = 0, sense_len = 0;
11004 pMPI2RequestHeader_t request_hdrp;
11005 pMPI2RequestHeader_t request_msg;
11006 pMPI2DefaultReply_t reply_msg;
11007 Mpi2SCSIIOReply_t rep_msg;
11008 int rvalue;
11009 int i, status = 0, pt_flags = 0, rv = 0;
11010 uint8_t function;
11011
11012 ASSERT(mutex_owned(&mpt->m_mutex));
11013
11014 reply_msg = (pMPI2DefaultReply_t)(&rep_msg);
11015 bzero(reply_msg, sizeof (MPI2_DEFAULT_REPLY));
11016 request_msg = kmem_zalloc(request_size, KM_SLEEP);
11017
11018 mutex_exit(&mpt->m_mutex);
11019 /*
11020 * copy in the request buffer since it could be used by
11021 * another thread when the pt request into waitq
11022 */
11023 if (ddi_copyin(request, request_msg, request_size, mode)) {
11024 mutex_enter(&mpt->m_mutex);
11025 status = EFAULT;
11026 mptsas_log(mpt, CE_WARN, "failed to copy request data");
11027 goto out;
11028 }
11029 NDBG27(("mptsas_do_passthru: mode 0x%x, size 0x%x, Func 0x%x",
11030 mode, request_size, request_msg->Function));
11031 mutex_enter(&mpt->m_mutex);
11032
11033 function = request_msg->Function;
11034 if (function == MPI2_FUNCTION_SCSI_TASK_MGMT) {
11035 pMpi2SCSITaskManagementRequest_t task;
11036 task = (pMpi2SCSITaskManagementRequest_t)request_msg;
11037 mptsas_setup_bus_reset_delay(mpt);
11038 rv = mptsas_ioc_task_management(mpt, task->TaskType,
11039 task->DevHandle, (int)task->LUN[1], reply, reply_size,
11040 mode);
11041
11042 if (rv != TRUE) {
11043 status = EIO;
11044 mptsas_log(mpt, CE_WARN, "task management failed");
11045 }
11046 goto out;
11047 }
11048
11049 if (data_size != 0) {
11050 data_dma_state.size = data_size;
11051 if (mptsas_dma_alloc(mpt, &data_dma_state) != DDI_SUCCESS) {
11052 status = ENOMEM;
11053 mptsas_log(mpt, CE_WARN, "failed to alloc DMA "
11054 "resource");
11055 goto out;
11056 }
11057 pt_flags |= MPTSAS_DATA_ALLOCATED;
11058 if (direction == MPTSAS_PASS_THRU_DIRECTION_WRITE) {
11059 mutex_exit(&mpt->m_mutex);
11060 for (i = 0; i < data_size; i++) {
11061 if (ddi_copyin(data + i, (uint8_t *)
11062 data_dma_state.memp + i, 1, mode)) {
11063 mutex_enter(&mpt->m_mutex);
11064 status = EFAULT;
11065 mptsas_log(mpt, CE_WARN, "failed to "
11066 "copy read data");
11067 goto out;
11068 }
11069 }
11070 mutex_enter(&mpt->m_mutex);
11071 }
11072 } else {
11073 bzero(&data_dma_state, sizeof (data_dma_state));
11074 }
11075
11076 if (dataout_size != 0) {
11077 dataout_dma_state.size = dataout_size;
11078 if (mptsas_dma_alloc(mpt, &dataout_dma_state) != DDI_SUCCESS) {
11079 status = ENOMEM;
11080 mptsas_log(mpt, CE_WARN, "failed to alloc DMA "
11081 "resource");
11082 goto out;
11083 }
11084 pt_flags |= MPTSAS_DATAOUT_ALLOCATED;
11085 mutex_exit(&mpt->m_mutex);
11086 for (i = 0; i < dataout_size; i++) {
11087 if (ddi_copyin(dataout + i, (uint8_t *)
11088 dataout_dma_state.memp + i, 1, mode)) {
11089 mutex_enter(&mpt->m_mutex);
11090 mptsas_log(mpt, CE_WARN, "failed to copy out"
11091 " data");
11092 status = EFAULT;
11093 goto out;
11094 }
11095 }
11096 mutex_enter(&mpt->m_mutex);
11097 } else {
11098 bzero(&dataout_dma_state, sizeof (dataout_dma_state));
11099 }
11100
11101 if ((rvalue = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) {
11102 status = EAGAIN;
11103 mptsas_log(mpt, CE_NOTE, "event ack command pool is full");
11104 goto out;
11105 }
11106 pt_flags |= MPTSAS_REQUEST_POOL_CMD;
11107
11108 bzero((caddr_t)cmd, sizeof (*cmd));
11109 bzero((caddr_t)pkt, scsi_pkt_size());
11110 bzero((caddr_t)&pt, sizeof (pt));
11111
11112 cmd->ioc_cmd_slot = (uint32_t)(rvalue);
11113
11114 pt.request = (uint8_t *)request_msg;
11115 pt.direction = direction;
11116 pt.simple = 0;
11117 pt.request_size = request_size;
11118 pt.data_size = data_size;
11119 pt.dataout_size = dataout_size;
11120 pt.data_cookie = data_dma_state.cookie;
11121 pt.dataout_cookie = dataout_dma_state.cookie;
11122 mptsas_prep_sgl_offset(mpt, &pt);
11123
11124 /*
11125 * Form a blank cmd/pkt to store the acknowledgement message
11126 */
11127 pkt->pkt_cdbp = (opaque_t)&cmd->cmd_cdb[0];
11128 pkt->pkt_scbp = (opaque_t)&cmd->cmd_scb;
11129 pkt->pkt_ha_private = (opaque_t)&pt;
11130 pkt->pkt_flags = FLAG_HEAD;
11131 pkt->pkt_time = timeout;
11132 cmd->cmd_pkt = pkt;
11133 cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_PASSTHRU;
11134
11135 if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) ||
11136 (function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
11137 uint8_t com, cdb_group_id;
11138 boolean_t ret;
11139
11140 pkt->pkt_cdbp = ((pMpi2SCSIIORequest_t)request_msg)->CDB.CDB32;
11141 com = pkt->pkt_cdbp[0];
11142 cdb_group_id = CDB_GROUPID(com);
11143 switch (cdb_group_id) {
11144 case CDB_GROUPID_0: cmd->cmd_cdblen = CDB_GROUP0; break;
11145 case CDB_GROUPID_1: cmd->cmd_cdblen = CDB_GROUP1; break;
11146 case CDB_GROUPID_2: cmd->cmd_cdblen = CDB_GROUP2; break;
11147 case CDB_GROUPID_4: cmd->cmd_cdblen = CDB_GROUP4; break;
11148 case CDB_GROUPID_5: cmd->cmd_cdblen = CDB_GROUP5; break;
11149 default:
11150 NDBG27(("mptsas_do_passthru: SCSI_IO, reserved "
11151 "CDBGROUP 0x%x requested!", cdb_group_id));
11152 break;
11153 }
11154
11155 reply_len = sizeof (MPI2_SCSI_IO_REPLY);
11156 sense_len = reply_size - reply_len;
11157 ret = mptsas_cmdarqsize(mpt, cmd, sense_len, KM_SLEEP);
11158 VERIFY(ret == B_TRUE);
11159 } else {
11160 reply_len = reply_size;
11161 sense_len = 0;
11162 }
11163
11164 NDBG27(("mptsas_do_passthru: %s, dsz 0x%x, dosz 0x%x, replen 0x%x, "
11165 "snslen 0x%x",
11166 (direction == MPTSAS_PASS_THRU_DIRECTION_WRITE)?"Write":"Read",
11167 data_size, dataout_size, reply_len, sense_len));
11168
11169 /*
11170 * Save the command in a slot
11171 */
11172 if (mptsas_save_cmd(mpt, cmd) == TRUE) {
11173 /*
11174 * Once passthru command get slot, set cmd_flags
11175 * CFLAG_PREPARED.
11176 */
11177 cmd->cmd_flags |= CFLAG_PREPARED;
11178 mptsas_start_passthru(mpt, cmd);
11179 } else {
11180 mptsas_waitq_add(mpt, cmd);
11181 }
11182
11183 while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) {
11184 cv_wait(&mpt->m_passthru_cv, &mpt->m_mutex);
11185 }
11186
11187 NDBG27(("mptsas_do_passthru: Cmd complete, flags 0x%x, rfm 0x%x "
11188 "pktreason 0x%x", cmd->cmd_flags, cmd->cmd_rfm,
11189 pkt->pkt_reason));
11190
11191 if (cmd->cmd_flags & CFLAG_PREPARED) {
11192 memp = mpt->m_req_frame + (mpt->m_req_frame_size *
11193 cmd->cmd_slot);
11194 request_hdrp = (pMPI2RequestHeader_t)memp;
11195 }
11196
11197 if (cmd->cmd_flags & CFLAG_TIMEOUT) {
11198 status = ETIMEDOUT;
11199 mptsas_log(mpt, CE_WARN, "passthrough command timeout");
11200 pt_flags |= MPTSAS_CMD_TIMEOUT;
11201 goto out;
11202 }
11203
11204 if (cmd->cmd_rfm) {
11205 /*
11206 * cmd_rfm is zero means the command reply is a CONTEXT
11207 * reply and no PCI Write to post the free reply SMFA
11208 * because no reply message frame is used.
11209 * cmd_rfm is non-zero means the reply is a ADDRESS
11210 * reply and reply message frame is used.
11211 */
11212 pt_flags |= MPTSAS_ADDRESS_REPLY;
11213 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
11214 DDI_DMA_SYNC_FORCPU);
11215 reply_msg = (pMPI2DefaultReply_t)
11216 (mpt->m_reply_frame + (cmd->cmd_rfm -
11217 (mpt->m_reply_frame_dma_addr & 0xffffffffu)));
11218 }
11219
11220 mptsas_fma_check(mpt, cmd);
11221 if (pkt->pkt_reason == CMD_TRAN_ERR) {
11222 status = EAGAIN;
11223 mptsas_log(mpt, CE_WARN, "passthru fma error");
11224 goto out;
11225 }
11226 if (pkt->pkt_reason == CMD_RESET) {
11227 status = EAGAIN;
11228 mptsas_log(mpt, CE_WARN, "ioc reset abort passthru");
11229 goto out;
11230 }
11231
11232 if (pkt->pkt_reason == CMD_INCOMPLETE) {
11233 status = EIO;
11234 mptsas_log(mpt, CE_WARN, "passthrough command incomplete");
11235 goto out;
11236 }
11237
11238 mutex_exit(&mpt->m_mutex);
11239 if (cmd->cmd_flags & CFLAG_PREPARED) {
11240 function = request_hdrp->Function;
11241 if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) ||
11242 (function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
11243 reply_len = sizeof (MPI2_SCSI_IO_REPLY);
11244 sense_len = cmd->cmd_extrqslen ?
11245 min(sense_len, cmd->cmd_extrqslen) :
11246 min(sense_len, cmd->cmd_rqslen);
11247 } else {
11248 reply_len = reply_size;
11249 sense_len = 0;
11250 }
11251
11252 for (i = 0; i < reply_len; i++) {
11253 if (ddi_copyout((uint8_t *)reply_msg + i, reply + i, 1,
11254 mode)) {
11255 mutex_enter(&mpt->m_mutex);
11256 status = EFAULT;
11257 mptsas_log(mpt, CE_WARN, "failed to copy out "
11258 "reply data");
11259 goto out;
11260 }
11261 }
11262 for (i = 0; i < sense_len; i++) {
11263 if (ddi_copyout((uint8_t *)request_hdrp + 64 + i,
11264 reply + reply_len + i, 1, mode)) {
11265 mutex_enter(&mpt->m_mutex);
11266 status = EFAULT;
11267 mptsas_log(mpt, CE_WARN, "failed to copy out "
11268 "sense data");
11269 goto out;
11270 }
11271 }
11272 }
11273
11274 if (data_size) {
11275 if (direction != MPTSAS_PASS_THRU_DIRECTION_WRITE) {
11276 (void) ddi_dma_sync(data_dma_state.handle, 0, 0,
11277 DDI_DMA_SYNC_FORCPU);
11278 for (i = 0; i < data_size; i++) {
11279 if (ddi_copyout((uint8_t *)(
11280 data_dma_state.memp + i), data + i, 1,
11281 mode)) {
11282 mutex_enter(&mpt->m_mutex);
11283 status = EFAULT;
11284 mptsas_log(mpt, CE_WARN, "failed to "
11285 "copy out the reply data");
11286 goto out;
11287 }
11288 }
11289 }
11290 }
11291 mutex_enter(&mpt->m_mutex);
11292 out:
11293 /*
11294 * Put the reply frame back on the free queue, increment the free
11295 * index, and write the new index to the free index register. But only
11296 * if this reply is an ADDRESS reply.
11297 */
11298 if (pt_flags & MPTSAS_ADDRESS_REPLY) {
11299 ddi_put32(mpt->m_acc_free_queue_hdl,
11300 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index],
11301 cmd->cmd_rfm);
11302 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
11303 DDI_DMA_SYNC_FORDEV);
11304 if (++mpt->m_free_index == mpt->m_free_queue_depth) {
11305 mpt->m_free_index = 0;
11306 }
11307 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
11308 mpt->m_free_index);
11309 }
11310 if (cmd) {
11311 if (cmd->cmd_extrqslen != 0) {
11312 rmfree(mpt->m_erqsense_map, cmd->cmd_extrqschunks,
11313 cmd->cmd_extrqsidx + 1);
11314 }
11315 if (cmd->cmd_flags & CFLAG_PREPARED) {
11316 mptsas_remove_cmd(mpt, cmd);
11317 pt_flags &= (~MPTSAS_REQUEST_POOL_CMD);
11318 }
11319 }
11320 if (pt_flags & MPTSAS_REQUEST_POOL_CMD)
11321 mptsas_return_to_pool(mpt, cmd);
11322 if (pt_flags & MPTSAS_DATA_ALLOCATED) {
11323 if (mptsas_check_dma_handle(data_dma_state.handle) !=
11324 DDI_SUCCESS) {
11325 ddi_fm_service_impact(mpt->m_dip,
11326 DDI_SERVICE_UNAFFECTED);
11327 status = EFAULT;
11328 }
11329 mptsas_dma_free(&data_dma_state);
11330 }
11331 if (pt_flags & MPTSAS_DATAOUT_ALLOCATED) {
11332 if (mptsas_check_dma_handle(dataout_dma_state.handle) !=
11333 DDI_SUCCESS) {
11334 ddi_fm_service_impact(mpt->m_dip,
11335 DDI_SERVICE_UNAFFECTED);
11336 status = EFAULT;
11337 }
11338 mptsas_dma_free(&dataout_dma_state);
11339 }
11340 if (pt_flags & MPTSAS_CMD_TIMEOUT) {
11341 if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) {
11342 mptsas_log(mpt, CE_WARN, "mptsas_restart_ioc failed");
11343 }
11344 }
11345 if (request_msg)
11346 kmem_free(request_msg, request_size);
11347 NDBG27(("mptsas_do_passthru: Done status 0x%x", status));
11348
11349 return (status);
11350 }
11351
11352 static int
11353 mptsas_pass_thru(mptsas_t *mpt, mptsas_pass_thru_t *data, int mode)
11354 {
11355 /*
11356 * If timeout is 0, set timeout to default of 60 seconds.
11357 */
11358 if (data->Timeout == 0) {
11359 data->Timeout = MPTSAS_PASS_THRU_TIME_DEFAULT;
11360 }
11361
11362 if (((data->DataSize == 0) &&
11363 (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_NONE)) ||
11364 ((data->DataSize != 0) &&
11365 ((data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_READ) ||
11366 (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_WRITE) ||
11367 ((data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_BOTH) &&
11368 (data->DataOutSize != 0))))) {
11369 if (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_BOTH) {
11370 data->DataDirection = MPTSAS_PASS_THRU_DIRECTION_READ;
11371 } else {
11372 data->DataOutSize = 0;
11373 }
11374 /*
11375 * Send passthru request messages
11376 */
11377 return (mptsas_do_passthru(mpt,
11378 (uint8_t *)((uintptr_t)data->PtrRequest),
11379 (uint8_t *)((uintptr_t)data->PtrReply),
11380 (uint8_t *)((uintptr_t)data->PtrData),
11381 data->RequestSize, data->ReplySize,
11382 data->DataSize, data->DataDirection,
11383 (uint8_t *)((uintptr_t)data->PtrDataOut),
11384 data->DataOutSize, data->Timeout, mode));
11385 } else {
11386 return (EINVAL);
11387 }
11388 }
11389
11390 static uint8_t
11391 mptsas_get_fw_diag_buffer_number(mptsas_t *mpt, uint32_t unique_id)
11392 {
11393 uint8_t index;
11394
11395 for (index = 0; index < MPI2_DIAG_BUF_TYPE_COUNT; index++) {
11396 if (mpt->m_fw_diag_buffer_list[index].unique_id == unique_id) {
11397 return (index);
11398 }
11399 }
11400
11401 return (MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND);
11402 }
11403
11404 static void
11405 mptsas_start_diag(mptsas_t *mpt, mptsas_cmd_t *cmd)
11406 {
11407 pMpi2DiagBufferPostRequest_t pDiag_post_msg;
11408 pMpi2DiagReleaseRequest_t pDiag_release_msg;
11409 struct scsi_pkt *pkt = cmd->cmd_pkt;
11410 mptsas_diag_request_t *diag = pkt->pkt_ha_private;
11411 uint32_t i;
11412 uint64_t request_desc;
11413
11414 ASSERT(mutex_owned(&mpt->m_mutex));
11415
11416 /*
11417 * Form the diag message depending on the post or release function.
11418 */
11419 if (diag->function == MPI2_FUNCTION_DIAG_BUFFER_POST) {
11420 pDiag_post_msg = (pMpi2DiagBufferPostRequest_t)
11421 (mpt->m_req_frame + (mpt->m_req_frame_size *
11422 cmd->cmd_slot));
11423 bzero(pDiag_post_msg, mpt->m_req_frame_size);
11424 ddi_put8(mpt->m_acc_req_frame_hdl, &pDiag_post_msg->Function,
11425 diag->function);
11426 ddi_put8(mpt->m_acc_req_frame_hdl, &pDiag_post_msg->BufferType,
11427 diag->pBuffer->buffer_type);
11428 ddi_put8(mpt->m_acc_req_frame_hdl,
11429 &pDiag_post_msg->ExtendedType,
11430 diag->pBuffer->extended_type);
11431 ddi_put32(mpt->m_acc_req_frame_hdl,
11432 &pDiag_post_msg->BufferLength,
11433 diag->pBuffer->buffer_data.size);
11434 for (i = 0; i < (sizeof (pDiag_post_msg->ProductSpecific) / 4);
11435 i++) {
11436 ddi_put32(mpt->m_acc_req_frame_hdl,
11437 &pDiag_post_msg->ProductSpecific[i],
11438 diag->pBuffer->product_specific[i]);
11439 }
11440 ddi_put32(mpt->m_acc_req_frame_hdl,
11441 &pDiag_post_msg->BufferAddress.Low,
11442 (uint32_t)(diag->pBuffer->buffer_data.cookie.dmac_laddress
11443 & 0xffffffffull));
11444 ddi_put32(mpt->m_acc_req_frame_hdl,
11445 &pDiag_post_msg->BufferAddress.High,
11446 (uint32_t)(diag->pBuffer->buffer_data.cookie.dmac_laddress
11447 >> 32));
11448 } else {
11449 pDiag_release_msg = (pMpi2DiagReleaseRequest_t)
11450 (mpt->m_req_frame + (mpt->m_req_frame_size *
11451 cmd->cmd_slot));
11452 bzero(pDiag_release_msg, mpt->m_req_frame_size);
11453 ddi_put8(mpt->m_acc_req_frame_hdl,
11454 &pDiag_release_msg->Function, diag->function);
11455 ddi_put8(mpt->m_acc_req_frame_hdl,
11456 &pDiag_release_msg->BufferType,
11457 diag->pBuffer->buffer_type);
11458 }
11459
11460 /*
11461 * Send the message
11462 */
11463 (void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0,
11464 DDI_DMA_SYNC_FORDEV);
11465 request_desc = (cmd->cmd_slot << 16) +
11466 MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
11467 cmd->cmd_rfm = NULL;
11468 MPTSAS_START_CMD(mpt, request_desc);
11469 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) !=
11470 DDI_SUCCESS) ||
11471 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) !=
11472 DDI_SUCCESS)) {
11473 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
11474 }
11475 }
11476
11477 static int
11478 mptsas_post_fw_diag_buffer(mptsas_t *mpt,
11479 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code)
11480 {
11481 mptsas_diag_request_t diag;
11482 int status, slot_num, post_flags = 0;
11483 mptsas_cmd_t *cmd = NULL;
11484 struct scsi_pkt *pkt;
11485 pMpi2DiagBufferPostReply_t reply;
11486 uint16_t iocstatus;
11487 uint32_t iocloginfo, transfer_length;
11488
11489 /*
11490 * If buffer is not enabled, just leave.
11491 */
11492 *return_code = MPTSAS_FW_DIAG_ERROR_POST_FAILED;
11493 if (!pBuffer->enabled) {
11494 status = DDI_FAILURE;
11495 goto out;
11496 }
11497
11498 /*
11499 * Clear some flags initially.
11500 */
11501 pBuffer->force_release = FALSE;
11502 pBuffer->valid_data = FALSE;
11503 pBuffer->owned_by_firmware = FALSE;
11504
11505 /*
11506 * Get a cmd buffer from the cmd buffer pool
11507 */
11508 if ((slot_num = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) {
11509 status = DDI_FAILURE;
11510 mptsas_log(mpt, CE_NOTE, "command pool is full: Post FW Diag");
11511 goto out;
11512 }
11513 post_flags |= MPTSAS_REQUEST_POOL_CMD;
11514
11515 bzero((caddr_t)cmd, sizeof (*cmd));
11516 bzero((caddr_t)pkt, scsi_pkt_size());
11517
11518 cmd->ioc_cmd_slot = (uint32_t)(slot_num);
11519
11520 diag.pBuffer = pBuffer;
11521 diag.function = MPI2_FUNCTION_DIAG_BUFFER_POST;
11522
11523 /*
11524 * Form a blank cmd/pkt to store the acknowledgement message
11525 */
11526 pkt->pkt_ha_private = (opaque_t)&diag;
11527 pkt->pkt_flags = FLAG_HEAD;
11528 pkt->pkt_time = 60;
11529 cmd->cmd_pkt = pkt;
11530 cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_FW_DIAG;
11531
11532 /*
11533 * Save the command in a slot
11534 */
11535 if (mptsas_save_cmd(mpt, cmd) == TRUE) {
11536 /*
11537 * Once passthru command get slot, set cmd_flags
11538 * CFLAG_PREPARED.
11539 */
11540 cmd->cmd_flags |= CFLAG_PREPARED;
11541 mptsas_start_diag(mpt, cmd);
11542 } else {
11543 mptsas_waitq_add(mpt, cmd);
11544 }
11545
11546 while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) {
11547 cv_wait(&mpt->m_fw_diag_cv, &mpt->m_mutex);
11548 }
11549
11550 if (cmd->cmd_flags & CFLAG_TIMEOUT) {
11551 status = DDI_FAILURE;
11552 mptsas_log(mpt, CE_WARN, "Post FW Diag command timeout");
11553 goto out;
11554 }
11555
11556 /*
11557 * cmd_rfm points to the reply message if a reply was given. Check the
11558 * IOCStatus to make sure everything went OK with the FW diag request
11559 * and set buffer flags.
11560 */
11561 if (cmd->cmd_rfm) {
11562 post_flags |= MPTSAS_ADDRESS_REPLY;
11563 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
11564 DDI_DMA_SYNC_FORCPU);
11565 reply = (pMpi2DiagBufferPostReply_t)(mpt->m_reply_frame +
11566 (cmd->cmd_rfm -
11567 (mpt->m_reply_frame_dma_addr & 0xffffffffu)));
11568
11569 /*
11570 * Get the reply message data
11571 */
11572 iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
11573 &reply->IOCStatus);
11574 iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl,
11575 &reply->IOCLogInfo);
11576 transfer_length = ddi_get32(mpt->m_acc_reply_frame_hdl,
11577 &reply->TransferLength);
11578
11579 /*
11580 * If post failed quit.
11581 */
11582 if (iocstatus != MPI2_IOCSTATUS_SUCCESS) {
11583 status = DDI_FAILURE;
11584 NDBG13(("post FW Diag Buffer failed: IOCStatus=0x%x, "
11585 "IOCLogInfo=0x%x, TransferLength=0x%x", iocstatus,
11586 iocloginfo, transfer_length));
11587 goto out;
11588 }
11589
11590 /*
11591 * Post was successful.
11592 */
11593 pBuffer->valid_data = TRUE;
11594 pBuffer->owned_by_firmware = TRUE;
11595 *return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS;
11596 status = DDI_SUCCESS;
11597 }
11598
11599 out:
11600 /*
11601 * Put the reply frame back on the free queue, increment the free
11602 * index, and write the new index to the free index register. But only
11603 * if this reply is an ADDRESS reply.
11604 */
11605 if (post_flags & MPTSAS_ADDRESS_REPLY) {
11606 ddi_put32(mpt->m_acc_free_queue_hdl,
11607 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index],
11608 cmd->cmd_rfm);
11609 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
11610 DDI_DMA_SYNC_FORDEV);
11611 if (++mpt->m_free_index == mpt->m_free_queue_depth) {
11612 mpt->m_free_index = 0;
11613 }
11614 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
11615 mpt->m_free_index);
11616 }
11617 if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) {
11618 mptsas_remove_cmd(mpt, cmd);
11619 post_flags &= (~MPTSAS_REQUEST_POOL_CMD);
11620 }
11621 if (post_flags & MPTSAS_REQUEST_POOL_CMD) {
11622 mptsas_return_to_pool(mpt, cmd);
11623 }
11624
11625 return (status);
11626 }
11627
11628 static int
11629 mptsas_release_fw_diag_buffer(mptsas_t *mpt,
11630 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code,
11631 uint32_t diag_type)
11632 {
11633 mptsas_diag_request_t diag;
11634 int status, slot_num, rel_flags = 0;
11635 mptsas_cmd_t *cmd = NULL;
11636 struct scsi_pkt *pkt;
11637 pMpi2DiagReleaseReply_t reply;
11638 uint16_t iocstatus;
11639 uint32_t iocloginfo;
11640
11641 /*
11642 * If buffer is not enabled, just leave.
11643 */
11644 *return_code = MPTSAS_FW_DIAG_ERROR_RELEASE_FAILED;
11645 if (!pBuffer->enabled) {
11646 mptsas_log(mpt, CE_NOTE, "This buffer type is not supported "
11647 "by the IOC");
11648 status = DDI_FAILURE;
11649 goto out;
11650 }
11651
11652 /*
11653 * Clear some flags initially.
11654 */
11655 pBuffer->force_release = FALSE;
11656 pBuffer->valid_data = FALSE;
11657 pBuffer->owned_by_firmware = FALSE;
11658
11659 /*
11660 * Get a cmd buffer from the cmd buffer pool
11661 */
11662 if ((slot_num = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) {
11663 status = DDI_FAILURE;
11664 mptsas_log(mpt, CE_NOTE, "command pool is full: Release FW "
11665 "Diag");
11666 goto out;
11667 }
11668 rel_flags |= MPTSAS_REQUEST_POOL_CMD;
11669
11670 bzero((caddr_t)cmd, sizeof (*cmd));
11671 bzero((caddr_t)pkt, scsi_pkt_size());
11672
11673 cmd->ioc_cmd_slot = (uint32_t)(slot_num);
11674
11675 diag.pBuffer = pBuffer;
11676 diag.function = MPI2_FUNCTION_DIAG_RELEASE;
11677
11678 /*
11679 * Form a blank cmd/pkt to store the acknowledgement message
11680 */
11681 pkt->pkt_ha_private = (opaque_t)&diag;
11682 pkt->pkt_flags = FLAG_HEAD;
11683 pkt->pkt_time = 60;
11684 cmd->cmd_pkt = pkt;
11685 cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_FW_DIAG;
11686
11687 /*
11688 * Save the command in a slot
11689 */
11690 if (mptsas_save_cmd(mpt, cmd) == TRUE) {
11691 /*
11692 * Once passthru command get slot, set cmd_flags
11693 * CFLAG_PREPARED.
11694 */
11695 cmd->cmd_flags |= CFLAG_PREPARED;
11696 mptsas_start_diag(mpt, cmd);
11697 } else {
11698 mptsas_waitq_add(mpt, cmd);
11699 }
11700
11701 while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) {
11702 cv_wait(&mpt->m_fw_diag_cv, &mpt->m_mutex);
11703 }
11704
11705 if (cmd->cmd_flags & CFLAG_TIMEOUT) {
11706 status = DDI_FAILURE;
11707 mptsas_log(mpt, CE_WARN, "Release FW Diag command timeout");
11708 goto out;
11709 }
11710
11711 /*
11712 * cmd_rfm points to the reply message if a reply was given. Check the
11713 * IOCStatus to make sure everything went OK with the FW diag request
11714 * and set buffer flags.
11715 */
11716 if (cmd->cmd_rfm) {
11717 rel_flags |= MPTSAS_ADDRESS_REPLY;
11718 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
11719 DDI_DMA_SYNC_FORCPU);
11720 reply = (pMpi2DiagReleaseReply_t)(mpt->m_reply_frame +
11721 (cmd->cmd_rfm -
11722 (mpt->m_reply_frame_dma_addr & 0xffffffffu)));
11723
11724 /*
11725 * Get the reply message data
11726 */
11727 iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
11728 &reply->IOCStatus);
11729 iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl,
11730 &reply->IOCLogInfo);
11731
11732 /*
11733 * If release failed quit.
11734 */
11735 if ((iocstatus != MPI2_IOCSTATUS_SUCCESS) ||
11736 pBuffer->owned_by_firmware) {
11737 status = DDI_FAILURE;
11738 NDBG13(("release FW Diag Buffer failed: "
11739 "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus,
11740 iocloginfo));
11741 goto out;
11742 }
11743
11744 /*
11745 * Release was successful.
11746 */
11747 *return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS;
11748 status = DDI_SUCCESS;
11749
11750 /*
11751 * If this was for an UNREGISTER diag type command, clear the
11752 * unique ID.
11753 */
11754 if (diag_type == MPTSAS_FW_DIAG_TYPE_UNREGISTER) {
11755 pBuffer->unique_id = MPTSAS_FW_DIAG_INVALID_UID;
11756 }
11757 }
11758
11759 out:
11760 /*
11761 * Put the reply frame back on the free queue, increment the free
11762 * index, and write the new index to the free index register. But only
11763 * if this reply is an ADDRESS reply.
11764 */
11765 if (rel_flags & MPTSAS_ADDRESS_REPLY) {
11766 ddi_put32(mpt->m_acc_free_queue_hdl,
11767 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index],
11768 cmd->cmd_rfm);
11769 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
11770 DDI_DMA_SYNC_FORDEV);
11771 if (++mpt->m_free_index == mpt->m_free_queue_depth) {
11772 mpt->m_free_index = 0;
11773 }
11774 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
11775 mpt->m_free_index);
11776 }
11777 if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) {
11778 mptsas_remove_cmd(mpt, cmd);
11779 rel_flags &= (~MPTSAS_REQUEST_POOL_CMD);
11780 }
11781 if (rel_flags & MPTSAS_REQUEST_POOL_CMD) {
11782 mptsas_return_to_pool(mpt, cmd);
11783 }
11784
11785 return (status);
11786 }
11787
11788 static int
11789 mptsas_diag_register(mptsas_t *mpt, mptsas_fw_diag_register_t *diag_register,
11790 uint32_t *return_code)
11791 {
11792 mptsas_fw_diagnostic_buffer_t *pBuffer;
11793 uint8_t extended_type, buffer_type, i;
11794 uint32_t buffer_size;
11795 uint32_t unique_id;
11796 int status;
11797
11798 ASSERT(mutex_owned(&mpt->m_mutex));
11799
11800 extended_type = diag_register->ExtendedType;
11801 buffer_type = diag_register->BufferType;
11802 buffer_size = diag_register->RequestedBufferSize;
11803 unique_id = diag_register->UniqueId;
11804
11805 /*
11806 * Check for valid buffer type
11807 */
11808 if (buffer_type >= MPI2_DIAG_BUF_TYPE_COUNT) {
11809 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
11810 return (DDI_FAILURE);
11811 }
11812
11813 /*
11814 * Get the current buffer and look up the unique ID. The unique ID
11815 * should not be found. If it is, the ID is already in use.
11816 */
11817 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id);
11818 pBuffer = &mpt->m_fw_diag_buffer_list[buffer_type];
11819 if (i != MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) {
11820 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
11821 return (DDI_FAILURE);
11822 }
11823
11824 /*
11825 * The buffer's unique ID should not be registered yet, and the given
11826 * unique ID cannot be 0.
11827 */
11828 if ((pBuffer->unique_id != MPTSAS_FW_DIAG_INVALID_UID) ||
11829 (unique_id == MPTSAS_FW_DIAG_INVALID_UID)) {
11830 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
11831 return (DDI_FAILURE);
11832 }
11833
11834 /*
11835 * If this buffer is already posted as immediate, just change owner.
11836 */
11837 if (pBuffer->immediate && pBuffer->owned_by_firmware &&
11838 (pBuffer->unique_id == MPTSAS_FW_DIAG_INVALID_UID)) {
11839 pBuffer->immediate = FALSE;
11840 pBuffer->unique_id = unique_id;
11841 return (DDI_SUCCESS);
11842 }
11843
11844 /*
11845 * Post a new buffer after checking if it's enabled. The DMA buffer
11846 * that is allocated will be contiguous (sgl_len = 1).
11847 */
11848 if (!pBuffer->enabled) {
11849 *return_code = MPTSAS_FW_DIAG_ERROR_NO_BUFFER;
11850 return (DDI_FAILURE);
11851 }
11852 bzero(&pBuffer->buffer_data, sizeof (mptsas_dma_alloc_state_t));
11853 pBuffer->buffer_data.size = buffer_size;
11854 if (mptsas_dma_alloc(mpt, &pBuffer->buffer_data) != DDI_SUCCESS) {
11855 mptsas_log(mpt, CE_WARN, "failed to alloc DMA resource for "
11856 "diag buffer: size = %d bytes", buffer_size);
11857 *return_code = MPTSAS_FW_DIAG_ERROR_NO_BUFFER;
11858 return (DDI_FAILURE);
11859 }
11860
11861 /*
11862 * Copy the given info to the diag buffer and post the buffer.
11863 */
11864 pBuffer->buffer_type = buffer_type;
11865 pBuffer->immediate = FALSE;
11866 if (buffer_type == MPI2_DIAG_BUF_TYPE_TRACE) {
11867 for (i = 0; i < (sizeof (pBuffer->product_specific) / 4);
11868 i++) {
11869 pBuffer->product_specific[i] =
11870 diag_register->ProductSpecific[i];
11871 }
11872 }
11873 pBuffer->extended_type = extended_type;
11874 pBuffer->unique_id = unique_id;
11875 status = mptsas_post_fw_diag_buffer(mpt, pBuffer, return_code);
11876
11877 if (mptsas_check_dma_handle(pBuffer->buffer_data.handle) !=
11878 DDI_SUCCESS) {
11879 mptsas_log(mpt, CE_WARN, "Check of DMA handle failed in "
11880 "mptsas_diag_register.");
11881 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
11882 status = DDI_FAILURE;
11883 }
11884
11885 /*
11886 * In case there was a failure, free the DMA buffer.
11887 */
11888 if (status == DDI_FAILURE) {
11889 mptsas_dma_free(&pBuffer->buffer_data);
11890 }
11891
11892 return (status);
11893 }
11894
11895 static int
11896 mptsas_diag_unregister(mptsas_t *mpt,
11897 mptsas_fw_diag_unregister_t *diag_unregister, uint32_t *return_code)
11898 {
11899 mptsas_fw_diagnostic_buffer_t *pBuffer;
11900 uint8_t i;
11901 uint32_t unique_id;
11902 int status;
11903
11904 ASSERT(mutex_owned(&mpt->m_mutex));
11905
11906 unique_id = diag_unregister->UniqueId;
11907
11908 /*
11909 * Get the current buffer and look up the unique ID. The unique ID
11910 * should be there.
11911 */
11912 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id);
11913 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) {
11914 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
11915 return (DDI_FAILURE);
11916 }
11917
11918 pBuffer = &mpt->m_fw_diag_buffer_list[i];
11919
11920 /*
11921 * Try to release the buffer from FW before freeing it. If release
11922 * fails, don't free the DMA buffer in case FW tries to access it
11923 * later. If buffer is not owned by firmware, can't release it.
11924 */
11925 if (!pBuffer->owned_by_firmware) {
11926 status = DDI_SUCCESS;
11927 } else {
11928 status = mptsas_release_fw_diag_buffer(mpt, pBuffer,
11929 return_code, MPTSAS_FW_DIAG_TYPE_UNREGISTER);
11930 }
11931
11932 /*
11933 * At this point, return the current status no matter what happens with
11934 * the DMA buffer.
11935 */
11936 pBuffer->unique_id = MPTSAS_FW_DIAG_INVALID_UID;
11937 if (status == DDI_SUCCESS) {
11938 if (mptsas_check_dma_handle(pBuffer->buffer_data.handle) !=
11939 DDI_SUCCESS) {
11940 mptsas_log(mpt, CE_WARN, "Check of DMA handle failed "
11941 "in mptsas_diag_unregister.");
11942 ddi_fm_service_impact(mpt->m_dip,
11943 DDI_SERVICE_UNAFFECTED);
11944 }
11945 mptsas_dma_free(&pBuffer->buffer_data);
11946 }
11947
11948 return (status);
11949 }
11950
11951 static int
11952 mptsas_diag_query(mptsas_t *mpt, mptsas_fw_diag_query_t *diag_query,
11953 uint32_t *return_code)
11954 {
11955 mptsas_fw_diagnostic_buffer_t *pBuffer;
11956 uint8_t i;
11957 uint32_t unique_id;
11958
11959 ASSERT(mutex_owned(&mpt->m_mutex));
11960
11961 unique_id = diag_query->UniqueId;
11962
11963 /*
11964 * If ID is valid, query on ID.
11965 * If ID is invalid, query on buffer type.
11966 */
11967 if (unique_id == MPTSAS_FW_DIAG_INVALID_UID) {
11968 i = diag_query->BufferType;
11969 if (i >= MPI2_DIAG_BUF_TYPE_COUNT) {
11970 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
11971 return (DDI_FAILURE);
11972 }
11973 } else {
11974 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id);
11975 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) {
11976 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
11977 return (DDI_FAILURE);
11978 }
11979 }
11980
11981 /*
11982 * Fill query structure with the diag buffer info.
11983 */
11984 pBuffer = &mpt->m_fw_diag_buffer_list[i];
11985 diag_query->BufferType = pBuffer->buffer_type;
11986 diag_query->ExtendedType = pBuffer->extended_type;
11987 if (diag_query->BufferType == MPI2_DIAG_BUF_TYPE_TRACE) {
11988 for (i = 0; i < (sizeof (diag_query->ProductSpecific) / 4);
11989 i++) {
11990 diag_query->ProductSpecific[i] =
11991 pBuffer->product_specific[i];
11992 }
11993 }
11994 diag_query->TotalBufferSize = pBuffer->buffer_data.size;
11995 diag_query->DriverAddedBufferSize = 0;
11996 diag_query->UniqueId = pBuffer->unique_id;
11997 diag_query->ApplicationFlags = 0;
11998 diag_query->DiagnosticFlags = 0;
11999
12000 /*
12001 * Set/Clear application flags
12002 */
12003 if (pBuffer->immediate) {
12004 diag_query->ApplicationFlags &= ~MPTSAS_FW_DIAG_FLAG_APP_OWNED;
12005 } else {
12006 diag_query->ApplicationFlags |= MPTSAS_FW_DIAG_FLAG_APP_OWNED;
12007 }
12008 if (pBuffer->valid_data || pBuffer->owned_by_firmware) {
12009 diag_query->ApplicationFlags |=
12010 MPTSAS_FW_DIAG_FLAG_BUFFER_VALID;
12011 } else {
12012 diag_query->ApplicationFlags &=
12013 ~MPTSAS_FW_DIAG_FLAG_BUFFER_VALID;
12014 }
12015 if (pBuffer->owned_by_firmware) {
12016 diag_query->ApplicationFlags |=
12017 MPTSAS_FW_DIAG_FLAG_FW_BUFFER_ACCESS;
12018 } else {
12019 diag_query->ApplicationFlags &=
12020 ~MPTSAS_FW_DIAG_FLAG_FW_BUFFER_ACCESS;
12021 }
12022
12023 return (DDI_SUCCESS);
12024 }
12025
12026 static int
12027 mptsas_diag_read_buffer(mptsas_t *mpt,
12028 mptsas_diag_read_buffer_t *diag_read_buffer, uint8_t *ioctl_buf,
12029 uint32_t *return_code, int ioctl_mode)
12030 {
12031 mptsas_fw_diagnostic_buffer_t *pBuffer;
12032 uint8_t i, *pData;
12033 uint32_t unique_id, byte;
12034 int status;
12035
12036 ASSERT(mutex_owned(&mpt->m_mutex));
12037
12038 unique_id = diag_read_buffer->UniqueId;
12039
12040 /*
12041 * Get the current buffer and look up the unique ID. The unique ID
12042 * should be there.
12043 */
12044 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id);
12045 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) {
12046 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
12047 return (DDI_FAILURE);
12048 }
12049
12050 pBuffer = &mpt->m_fw_diag_buffer_list[i];
12051
12052 /*
12053 * Make sure requested read is within limits
12054 */
12055 if (diag_read_buffer->StartingOffset + diag_read_buffer->BytesToRead >
12056 pBuffer->buffer_data.size) {
12057 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
12058 return (DDI_FAILURE);
12059 }
12060
12061 /*
12062 * Copy the requested data from DMA to the diag_read_buffer. The DMA
12063 * buffer that was allocated is one contiguous buffer.
12064 */
12065 pData = (uint8_t *)(pBuffer->buffer_data.memp +
12066 diag_read_buffer->StartingOffset);
12067 (void) ddi_dma_sync(pBuffer->buffer_data.handle, 0, 0,
12068 DDI_DMA_SYNC_FORCPU);
12069 for (byte = 0; byte < diag_read_buffer->BytesToRead; byte++) {
12070 if (ddi_copyout(pData + byte, ioctl_buf + byte, 1, ioctl_mode)
12071 != 0) {
12072 return (DDI_FAILURE);
12073 }
12074 }
12075 diag_read_buffer->Status = 0;
12076
12077 /*
12078 * Set or clear the Force Release flag.
12079 */
12080 if (pBuffer->force_release) {
12081 diag_read_buffer->Flags |= MPTSAS_FW_DIAG_FLAG_FORCE_RELEASE;
12082 } else {
12083 diag_read_buffer->Flags &= ~MPTSAS_FW_DIAG_FLAG_FORCE_RELEASE;
12084 }
12085
12086 /*
12087 * If buffer is to be reregistered, make sure it's not already owned by
12088 * firmware first.
12089 */
12090 status = DDI_SUCCESS;
12091 if (!pBuffer->owned_by_firmware) {
12092 if (diag_read_buffer->Flags & MPTSAS_FW_DIAG_FLAG_REREGISTER) {
12093 status = mptsas_post_fw_diag_buffer(mpt, pBuffer,
12094 return_code);
12095 }
12096 }
12097
12098 return (status);
12099 }
12100
12101 static int
12102 mptsas_diag_release(mptsas_t *mpt, mptsas_fw_diag_release_t *diag_release,
12103 uint32_t *return_code)
12104 {
12105 mptsas_fw_diagnostic_buffer_t *pBuffer;
12106 uint8_t i;
12107 uint32_t unique_id;
12108 int status;
12109
12110 ASSERT(mutex_owned(&mpt->m_mutex));
12111
12112 unique_id = diag_release->UniqueId;
12113
12114 /*
12115 * Get the current buffer and look up the unique ID. The unique ID
12116 * should be there.
12117 */
12118 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id);
12119 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) {
12120 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
12121 return (DDI_FAILURE);
12122 }
12123
12124 pBuffer = &mpt->m_fw_diag_buffer_list[i];
12125
12126 /*
12127 * If buffer is not owned by firmware, it's already been released.
12128 */
12129 if (!pBuffer->owned_by_firmware) {
12130 *return_code = MPTSAS_FW_DIAG_ERROR_ALREADY_RELEASED;
12131 return (DDI_FAILURE);
12132 }
12133
12134 /*
12135 * Release the buffer.
12136 */
12137 status = mptsas_release_fw_diag_buffer(mpt, pBuffer, return_code,
12138 MPTSAS_FW_DIAG_TYPE_RELEASE);
12139 return (status);
12140 }
12141
12142 static int
12143 mptsas_do_diag_action(mptsas_t *mpt, uint32_t action, uint8_t *diag_action,
12144 uint32_t length, uint32_t *return_code, int ioctl_mode)
12145 {
12146 mptsas_fw_diag_register_t diag_register;
12147 mptsas_fw_diag_unregister_t diag_unregister;
12148 mptsas_fw_diag_query_t diag_query;
12149 mptsas_diag_read_buffer_t diag_read_buffer;
12150 mptsas_fw_diag_release_t diag_release;
12151 int status = DDI_SUCCESS;
12152 uint32_t original_return_code, read_buf_len;
12153
12154 ASSERT(mutex_owned(&mpt->m_mutex));
12155
12156 original_return_code = *return_code;
12157 *return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS;
12158
12159 switch (action) {
12160 case MPTSAS_FW_DIAG_TYPE_REGISTER:
12161 if (!length) {
12162 *return_code =
12163 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
12164 status = DDI_FAILURE;
12165 break;
12166 }
12167 if (ddi_copyin(diag_action, &diag_register,
12168 sizeof (diag_register), ioctl_mode) != 0) {
12169 return (DDI_FAILURE);
12170 }
12171 status = mptsas_diag_register(mpt, &diag_register,
12172 return_code);
12173 break;
12174
12175 case MPTSAS_FW_DIAG_TYPE_UNREGISTER:
12176 if (length < sizeof (diag_unregister)) {
12177 *return_code =
12178 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
12179 status = DDI_FAILURE;
12180 break;
12181 }
12182 if (ddi_copyin(diag_action, &diag_unregister,
12183 sizeof (diag_unregister), ioctl_mode) != 0) {
12184 return (DDI_FAILURE);
12185 }
12186 status = mptsas_diag_unregister(mpt, &diag_unregister,
12187 return_code);
12188 break;
12189
12190 case MPTSAS_FW_DIAG_TYPE_QUERY:
12191 if (length < sizeof (diag_query)) {
12192 *return_code =
12193 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
12194 status = DDI_FAILURE;
12195 break;
12196 }
12197 if (ddi_copyin(diag_action, &diag_query,
12198 sizeof (diag_query), ioctl_mode) != 0) {
12199 return (DDI_FAILURE);
12200 }
12201 status = mptsas_diag_query(mpt, &diag_query,
12202 return_code);
12203 if (status == DDI_SUCCESS) {
12204 if (ddi_copyout(&diag_query, diag_action,
12205 sizeof (diag_query), ioctl_mode) != 0) {
12206 return (DDI_FAILURE);
12207 }
12208 }
12209 break;
12210
12211 case MPTSAS_FW_DIAG_TYPE_READ_BUFFER:
12212 if (ddi_copyin(diag_action, &diag_read_buffer,
12213 sizeof (diag_read_buffer) - 4, ioctl_mode) != 0) {
12214 return (DDI_FAILURE);
12215 }
12216 read_buf_len = sizeof (diag_read_buffer) -
12217 sizeof (diag_read_buffer.DataBuffer) +
12218 diag_read_buffer.BytesToRead;
12219 if (length < read_buf_len) {
12220 *return_code =
12221 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
12222 status = DDI_FAILURE;
12223 break;
12224 }
12225 status = mptsas_diag_read_buffer(mpt,
12226 &diag_read_buffer, diag_action +
12227 sizeof (diag_read_buffer) - 4, return_code,
12228 ioctl_mode);
12229 if (status == DDI_SUCCESS) {
12230 if (ddi_copyout(&diag_read_buffer, diag_action,
12231 sizeof (diag_read_buffer) - 4, ioctl_mode)
12232 != 0) {
12233 return (DDI_FAILURE);
12234 }
12235 }
12236 break;
12237
12238 case MPTSAS_FW_DIAG_TYPE_RELEASE:
12239 if (length < sizeof (diag_release)) {
12240 *return_code =
12241 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
12242 status = DDI_FAILURE;
12243 break;
12244 }
12245 if (ddi_copyin(diag_action, &diag_release,
12246 sizeof (diag_release), ioctl_mode) != 0) {
12247 return (DDI_FAILURE);
12248 }
12249 status = mptsas_diag_release(mpt, &diag_release,
12250 return_code);
12251 break;
12252
12253 default:
12254 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
12255 status = DDI_FAILURE;
12256 break;
12257 }
12258
12259 if ((status == DDI_FAILURE) &&
12260 (original_return_code == MPTSAS_FW_DIAG_NEW) &&
12261 (*return_code != MPTSAS_FW_DIAG_ERROR_SUCCESS)) {
12262 status = DDI_SUCCESS;
12263 }
12264
12265 return (status);
12266 }
12267
12268 static int
12269 mptsas_diag_action(mptsas_t *mpt, mptsas_diag_action_t *user_data, int mode)
12270 {
12271 int status;
12272 mptsas_diag_action_t driver_data;
12273
12274 ASSERT(mutex_owned(&mpt->m_mutex));
12275
12276 /*
12277 * Copy the user data to a driver data buffer.
12278 */
12279 if (ddi_copyin(user_data, &driver_data, sizeof (mptsas_diag_action_t),
12280 mode) == 0) {
12281 /*
12282 * Send diag action request if Action is valid
12283 */
12284 if (driver_data.Action == MPTSAS_FW_DIAG_TYPE_REGISTER ||
12285 driver_data.Action == MPTSAS_FW_DIAG_TYPE_UNREGISTER ||
12286 driver_data.Action == MPTSAS_FW_DIAG_TYPE_QUERY ||
12287 driver_data.Action == MPTSAS_FW_DIAG_TYPE_READ_BUFFER ||
12288 driver_data.Action == MPTSAS_FW_DIAG_TYPE_RELEASE) {
12289 status = mptsas_do_diag_action(mpt, driver_data.Action,
12290 (void *)(uintptr_t)driver_data.PtrDiagAction,
12291 driver_data.Length, &driver_data.ReturnCode,
12292 mode);
12293 if (status == DDI_SUCCESS) {
12294 if (ddi_copyout(&driver_data.ReturnCode,
12295 &user_data->ReturnCode,
12296 sizeof (user_data->ReturnCode), mode)
12297 != 0) {
12298 status = EFAULT;
12299 } else {
12300 status = 0;
12301 }
12302 } else {
12303 status = EIO;
12304 }
12305 } else {
12306 status = EINVAL;
12307 }
12308 } else {
12309 status = EFAULT;
12310 }
12311
12312 return (status);
12313 }
12314
12315 /*
12316 * This routine handles the "event query" ioctl.
12317 */
12318 static int
12319 mptsas_event_query(mptsas_t *mpt, mptsas_event_query_t *data, int mode,
12320 int *rval)
12321 {
12322 int status;
12323 mptsas_event_query_t driverdata;
12324 uint8_t i;
12325
12326 driverdata.Entries = MPTSAS_EVENT_QUEUE_SIZE;
12327
12328 mutex_enter(&mpt->m_mutex);
12329 for (i = 0; i < 4; i++) {
12330 driverdata.Types[i] = mpt->m_event_mask[i];
12331 }
12332 mutex_exit(&mpt->m_mutex);
12333
12334 if (ddi_copyout(&driverdata, data, sizeof (driverdata), mode) != 0) {
12335 status = EFAULT;
12336 } else {
12337 *rval = MPTIOCTL_STATUS_GOOD;
12338 status = 0;
12339 }
12340
12341 return (status);
12342 }
12343
12344 /*
12345 * This routine handles the "event enable" ioctl.
12346 */
12347 static int
12348 mptsas_event_enable(mptsas_t *mpt, mptsas_event_enable_t *data, int mode,
12349 int *rval)
12350 {
12351 int status;
12352 mptsas_event_enable_t driverdata;
12353 uint8_t i;
12354
12355 if (ddi_copyin(data, &driverdata, sizeof (driverdata), mode) == 0) {
12356 mutex_enter(&mpt->m_mutex);
12357 for (i = 0; i < 4; i++) {
12358 mpt->m_event_mask[i] = driverdata.Types[i];
12359 }
12360 mutex_exit(&mpt->m_mutex);
12361
12362 *rval = MPTIOCTL_STATUS_GOOD;
12363 status = 0;
12364 } else {
12365 status = EFAULT;
12366 }
12367 return (status);
12368 }
12369
12370 /*
12371 * This routine handles the "event report" ioctl.
12372 */
12373 static int
12374 mptsas_event_report(mptsas_t *mpt, mptsas_event_report_t *data, int mode,
12375 int *rval)
12376 {
12377 int status;
12378 mptsas_event_report_t driverdata;
12379
12380 mutex_enter(&mpt->m_mutex);
12381
12382 if (ddi_copyin(&data->Size, &driverdata.Size, sizeof (driverdata.Size),
12383 mode) == 0) {
12384 if (driverdata.Size >= sizeof (mpt->m_events)) {
12385 if (ddi_copyout(mpt->m_events, data->Events,
12386 sizeof (mpt->m_events), mode) != 0) {
12387 status = EFAULT;
12388 } else {
12389 if (driverdata.Size > sizeof (mpt->m_events)) {
12390 driverdata.Size =
12391 sizeof (mpt->m_events);
12392 if (ddi_copyout(&driverdata.Size,
12393 &data->Size,
12394 sizeof (driverdata.Size),
12395 mode) != 0) {
12396 status = EFAULT;
12397 } else {
12398 *rval = MPTIOCTL_STATUS_GOOD;
12399 status = 0;
12400 }
12401 } else {
12402 *rval = MPTIOCTL_STATUS_GOOD;
12403 status = 0;
12404 }
12405 }
12406 } else {
12407 *rval = MPTIOCTL_STATUS_LEN_TOO_SHORT;
12408 status = 0;
12409 }
12410 } else {
12411 status = EFAULT;
12412 }
12413
12414 mutex_exit(&mpt->m_mutex);
12415 return (status);
12416 }
12417
12418 static void
12419 mptsas_lookup_pci_data(mptsas_t *mpt, mptsas_adapter_data_t *adapter_data)
12420 {
12421 int *reg_data;
12422 uint_t reglen;
12423
12424 /*
12425 * Lookup the 'reg' property and extract the other data
12426 */
12427 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, mpt->m_dip,
12428 DDI_PROP_DONTPASS, "reg", ®_data, ®len) ==
12429 DDI_PROP_SUCCESS) {
12430 /*
12431 * Extract the PCI data from the 'reg' property first DWORD.
12432 * The entry looks like the following:
12433 * First DWORD:
12434 * Bits 0 - 7 8-bit Register number
12435 * Bits 8 - 10 3-bit Function number
12436 * Bits 11 - 15 5-bit Device number
12437 * Bits 16 - 23 8-bit Bus number
12438 * Bits 24 - 25 2-bit Address Space type identifier
12439 *
12440 */
12441 adapter_data->PciInformation.u.bits.BusNumber =
12442 (reg_data[0] & 0x00FF0000) >> 16;
12443 adapter_data->PciInformation.u.bits.DeviceNumber =
12444 (reg_data[0] & 0x0000F800) >> 11;
12445 adapter_data->PciInformation.u.bits.FunctionNumber =
12446 (reg_data[0] & 0x00000700) >> 8;
12447 ddi_prop_free((void *)reg_data);
12448 } else {
12449 /*
12450 * If we can't determine the PCI data then we fill in FF's for
12451 * the data to indicate this.
12452 */
12453 adapter_data->PCIDeviceHwId = 0xFFFFFFFF;
12454 adapter_data->MpiPortNumber = 0xFFFFFFFF;
12455 adapter_data->PciInformation.u.AsDWORD = 0xFFFFFFFF;
12456 }
12457
12458 /*
12459 * Saved in the mpt->m_fwversion
12460 */
12461 adapter_data->MpiFirmwareVersion = mpt->m_fwversion;
12462 }
12463
12464 static void
12465 mptsas_read_adapter_data(mptsas_t *mpt, mptsas_adapter_data_t *adapter_data)
12466 {
12467 char *driver_verstr = MPTSAS_MOD_STRING;
12468
12469 mptsas_lookup_pci_data(mpt, adapter_data);
12470 adapter_data->AdapterType = mpt->m_MPI25 ?
12471 MPTIOCTL_ADAPTER_TYPE_SAS3 :
12472 MPTIOCTL_ADAPTER_TYPE_SAS2;
12473 adapter_data->PCIDeviceHwId = (uint32_t)mpt->m_devid;
12474 adapter_data->PCIDeviceHwRev = (uint32_t)mpt->m_revid;
12475 adapter_data->SubSystemId = (uint32_t)mpt->m_ssid;
12476 adapter_data->SubsystemVendorId = (uint32_t)mpt->m_svid;
12477 (void) strcpy((char *)&adapter_data->DriverVersion[0], driver_verstr);
12478 adapter_data->BiosVersion = 0;
12479 (void) mptsas_get_bios_page3(mpt, &adapter_data->BiosVersion);
12480 }
12481
12482 static void
12483 mptsas_read_pci_info(mptsas_t *mpt, mptsas_pci_info_t *pci_info)
12484 {
12485 int *reg_data, i;
12486 uint_t reglen;
12487
12488 /*
12489 * Lookup the 'reg' property and extract the other data
12490 */
12491 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, mpt->m_dip,
12492 DDI_PROP_DONTPASS, "reg", ®_data, ®len) ==
12493 DDI_PROP_SUCCESS) {
12494 /*
12495 * Extract the PCI data from the 'reg' property first DWORD.
12496 * The entry looks like the following:
12497 * First DWORD:
12498 * Bits 8 - 10 3-bit Function number
12499 * Bits 11 - 15 5-bit Device number
12500 * Bits 16 - 23 8-bit Bus number
12501 */
12502 pci_info->BusNumber = (reg_data[0] & 0x00FF0000) >> 16;
12503 pci_info->DeviceNumber = (reg_data[0] & 0x0000F800) >> 11;
12504 pci_info->FunctionNumber = (reg_data[0] & 0x00000700) >> 8;
12505 ddi_prop_free((void *)reg_data);
12506 } else {
12507 /*
12508 * If we can't determine the PCI info then we fill in FF's for
12509 * the data to indicate this.
12510 */
12511 pci_info->BusNumber = 0xFFFFFFFF;
12512 pci_info->DeviceNumber = 0xFF;
12513 pci_info->FunctionNumber = 0xFF;
12514 }
12515
12516 /*
12517 * Now get the interrupt vector and the pci header. The vector can
12518 * only be 0 right now. The header is the first 256 bytes of config
12519 * space.
12520 */
12521 pci_info->InterruptVector = 0;
12522 for (i = 0; i < sizeof (pci_info->PciHeader); i++) {
12523 pci_info->PciHeader[i] = pci_config_get8(mpt->m_config_handle,
12524 i);
12525 }
12526 }
12527
12528 static int
12529 mptsas_reg_access(mptsas_t *mpt, mptsas_reg_access_t *data, int mode)
12530 {
12531 int status = 0;
12532 mptsas_reg_access_t driverdata;
12533
12534 mutex_enter(&mpt->m_mutex);
12535 if (ddi_copyin(data, &driverdata, sizeof (driverdata), mode) == 0) {
12536 switch (driverdata.Command) {
12537 /*
12538 * IO access is not supported.
12539 */
12540 case REG_IO_READ:
12541 case REG_IO_WRITE:
12542 mptsas_log(mpt, CE_WARN, "IO access is not "
12543 "supported. Use memory access.");
12544 status = EINVAL;
12545 break;
12546
12547 case REG_MEM_READ:
12548 driverdata.RegData = ddi_get32(mpt->m_datap,
12549 (uint32_t *)(void *)mpt->m_reg +
12550 driverdata.RegOffset);
12551 if (ddi_copyout(&driverdata.RegData,
12552 &data->RegData,
12553 sizeof (driverdata.RegData), mode) != 0) {
12554 mptsas_log(mpt, CE_WARN, "Register "
12555 "Read Failed");
12556 status = EFAULT;
12557 }
12558 break;
12559
12560 case REG_MEM_WRITE:
12561 ddi_put32(mpt->m_datap,
12562 (uint32_t *)(void *)mpt->m_reg +
12563 driverdata.RegOffset,
12564 driverdata.RegData);
12565 break;
12566
12567 default:
12568 status = EINVAL;
12569 break;
12570 }
12571 } else {
12572 status = EFAULT;
12573 }
12574
12575 mutex_exit(&mpt->m_mutex);
12576 return (status);
12577 }
12578
12579 static int
12580 led_control(mptsas_t *mpt, intptr_t data, int mode)
12581 {
12582 int ret = 0;
12583 mptsas_led_control_t lc;
12584 mptsas_target_t *ptgt;
12585
12586 if (ddi_copyin((void *)data, &lc, sizeof (lc), mode) != 0) {
12587 return (EFAULT);
12588 }
12589
12590 if ((lc.Command != MPTSAS_LEDCTL_FLAG_SET &&
12591 lc.Command != MPTSAS_LEDCTL_FLAG_GET) ||
12592 lc.Led < MPTSAS_LEDCTL_LED_MIN ||
12593 lc.Led > MPTSAS_LEDCTL_LED_MAX ||
12594 (lc.Command == MPTSAS_LEDCTL_FLAG_SET && lc.LedStatus != 0 &&
12595 lc.LedStatus != 1)) {
12596 return (EINVAL);
12597 }
12598
12599 if ((lc.Command == MPTSAS_LEDCTL_FLAG_SET && (mode & FWRITE) == 0) ||
12600 (lc.Command == MPTSAS_LEDCTL_FLAG_GET && (mode & FREAD) == 0))
12601 return (EACCES);
12602
12603 /* Locate the target we're interrogating... */
12604 mutex_enter(&mpt->m_mutex);
12605 ptgt = refhash_linear_search(mpt->m_targets,
12606 mptsas_target_eval_slot, &lc);
12607 if (ptgt == NULL) {
12608 /* We could not find a target for that enclosure/slot. */
12609 mutex_exit(&mpt->m_mutex);
12610 return (ENOENT);
12611 }
12612
12613 if (lc.Command == MPTSAS_LEDCTL_FLAG_SET) {
12614 /* Update our internal LED state. */
12615 ptgt->m_led_status &= ~(1 << (lc.Led - 1));
12616 ptgt->m_led_status |= lc.LedStatus << (lc.Led - 1);
12617
12618 /* Flush it to the controller. */
12619 ret = mptsas_flush_led_status(mpt, ptgt);
12620 mutex_exit(&mpt->m_mutex);
12621 return (ret);
12622 }
12623
12624 /* Return our internal LED state. */
12625 lc.LedStatus = (ptgt->m_led_status >> (lc.Led - 1)) & 1;
12626 mutex_exit(&mpt->m_mutex);
12627
12628 if (ddi_copyout(&lc, (void *)data, sizeof (lc), mode) != 0) {
12629 return (EFAULT);
12630 }
12631
12632 return (0);
12633 }
12634
12635 static int
12636 get_disk_info(mptsas_t *mpt, intptr_t data, int mode)
12637 {
12638 uint16_t i = 0;
12639 uint16_t count = 0;
12640 int ret = 0;
12641 mptsas_target_t *ptgt;
12642 mptsas_disk_info_t *di;
12643 STRUCT_DECL(mptsas_get_disk_info, gdi);
12644
12645 if ((mode & FREAD) == 0)
12646 return (EACCES);
12647
12648 STRUCT_INIT(gdi, get_udatamodel());
12649
12650 if (ddi_copyin((void *)data, STRUCT_BUF(gdi), STRUCT_SIZE(gdi),
12651 mode) != 0) {
12652 return (EFAULT);
12653 }
12654
12655 /* Find out how many targets there are. */
12656 mutex_enter(&mpt->m_mutex);
12657 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
12658 ptgt = refhash_next(mpt->m_targets, ptgt)) {
12659 count++;
12660 }
12661 mutex_exit(&mpt->m_mutex);
12662
12663 /*
12664 * If we haven't been asked to copy out information on each target,
12665 * then just return the count.
12666 */
12667 STRUCT_FSET(gdi, DiskCount, count);
12668 if (STRUCT_FGETP(gdi, PtrDiskInfoArray) == NULL)
12669 goto copy_out;
12670
12671 /*
12672 * If we haven't been given a large enough buffer to copy out into,
12673 * let the caller know.
12674 */
12675 if (STRUCT_FGET(gdi, DiskInfoArraySize) <
12676 count * sizeof (mptsas_disk_info_t)) {
12677 ret = ENOSPC;
12678 goto copy_out;
12679 }
12680
12681 di = kmem_zalloc(count * sizeof (mptsas_disk_info_t), KM_SLEEP);
12682
12683 mutex_enter(&mpt->m_mutex);
12684 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
12685 ptgt = refhash_next(mpt->m_targets, ptgt)) {
12686 if (i >= count) {
12687 /*
12688 * The number of targets changed while we weren't
12689 * looking, so give up.
12690 */
12691 refhash_rele(mpt->m_targets, ptgt);
12692 mutex_exit(&mpt->m_mutex);
12693 kmem_free(di, count * sizeof (mptsas_disk_info_t));
12694 return (EAGAIN);
12695 }
12696 di[i].Instance = mpt->m_instance;
12697 di[i].Enclosure = ptgt->m_enclosure;
12698 di[i].Slot = ptgt->m_slot_num;
12699 di[i].SasAddress = ptgt->m_addr.mta_wwn;
12700 i++;
12701 }
12702 mutex_exit(&mpt->m_mutex);
12703 STRUCT_FSET(gdi, DiskCount, i);
12704
12705 /* Copy out the disk information to the caller. */
12706 if (ddi_copyout((void *)di, STRUCT_FGETP(gdi, PtrDiskInfoArray),
12707 i * sizeof (mptsas_disk_info_t), mode) != 0) {
12708 ret = EFAULT;
12709 }
12710
12711 kmem_free(di, count * sizeof (mptsas_disk_info_t));
12712
12713 copy_out:
12714 if (ddi_copyout(STRUCT_BUF(gdi), (void *)data, STRUCT_SIZE(gdi),
12715 mode) != 0) {
12716 ret = EFAULT;
12717 }
12718
12719 return (ret);
12720 }
12721
12722 static int
12723 mptsas_ioctl(dev_t dev, int cmd, intptr_t data, int mode, cred_t *credp,
12724 int *rval)
12725 {
12726 int status = 0;
12727 mptsas_t *mpt;
12728 mptsas_update_flash_t flashdata;
12729 mptsas_pass_thru_t passthru_data;
12730 mptsas_adapter_data_t adapter_data;
12731 mptsas_pci_info_t pci_info;
12732 int copylen;
12733
12734 int iport_flag = 0;
12735 dev_info_t *dip = NULL;
12736 mptsas_phymask_t phymask = 0;
12737 struct devctl_iocdata *dcp = NULL;
12738 char *addr = NULL;
12739 mptsas_target_t *ptgt = NULL;
12740
12741 *rval = MPTIOCTL_STATUS_GOOD;
12742 if (secpolicy_sys_config(credp, B_FALSE) != 0) {
12743 return (EPERM);
12744 }
12745
12746 mpt = ddi_get_soft_state(mptsas_state, MINOR2INST(getminor(dev)));
12747 if (mpt == NULL) {
12748 /*
12749 * Called from iport node, get the states
12750 */
12751 iport_flag = 1;
12752 dip = mptsas_get_dip_from_dev(dev, &phymask);
12753 if (dip == NULL) {
12754 return (ENXIO);
12755 }
12756 mpt = DIP2MPT(dip);
12757 }
12758 /* Make sure power level is D0 before accessing registers */
12759 mutex_enter(&mpt->m_mutex);
12760 if (mpt->m_options & MPTSAS_OPT_PM) {
12761 (void) pm_busy_component(mpt->m_dip, 0);
12762 if (mpt->m_power_level != PM_LEVEL_D0) {
12763 mutex_exit(&mpt->m_mutex);
12764 if (pm_raise_power(mpt->m_dip, 0, PM_LEVEL_D0) !=
12765 DDI_SUCCESS) {
12766 mptsas_log(mpt, CE_WARN,
12767 "mptsas%d: mptsas_ioctl: Raise power "
12768 "request failed.", mpt->m_instance);
12769 (void) pm_idle_component(mpt->m_dip, 0);
12770 return (ENXIO);
12771 }
12772 } else {
12773 mutex_exit(&mpt->m_mutex);
12774 }
12775 } else {
12776 mutex_exit(&mpt->m_mutex);
12777 }
12778
12779 if (iport_flag) {
12780 status = scsi_hba_ioctl(dev, cmd, data, mode, credp, rval);
12781 if (status != 0) {
12782 goto out;
12783 }
12784 /*
12785 * The following code control the OK2RM LED, it doesn't affect
12786 * the ioctl return status.
12787 */
12788 if ((cmd == DEVCTL_DEVICE_ONLINE) ||
12789 (cmd == DEVCTL_DEVICE_OFFLINE)) {
12790 if (ndi_dc_allochdl((void *)data, &dcp) !=
12791 NDI_SUCCESS) {
12792 goto out;
12793 }
12794 addr = ndi_dc_getaddr(dcp);
12795 ptgt = mptsas_addr_to_ptgt(mpt, addr, phymask);
12796 if (ptgt == NULL) {
12797 NDBG14(("mptsas_ioctl led control: tgt %s not "
12798 "found", addr));
12799 ndi_dc_freehdl(dcp);
12800 goto out;
12801 }
12802 mutex_enter(&mpt->m_mutex);
12803 if (cmd == DEVCTL_DEVICE_ONLINE) {
12804 ptgt->m_tgt_unconfigured = 0;
12805 } else if (cmd == DEVCTL_DEVICE_OFFLINE) {
12806 ptgt->m_tgt_unconfigured = 1;
12807 }
12808 if (cmd == DEVCTL_DEVICE_OFFLINE) {
12809 ptgt->m_led_status |=
12810 (1 << (MPTSAS_LEDCTL_LED_OK2RM - 1));
12811 } else {
12812 ptgt->m_led_status &=
12813 ~(1 << (MPTSAS_LEDCTL_LED_OK2RM - 1));
12814 }
12815 (void) mptsas_flush_led_status(mpt, ptgt);
12816 mutex_exit(&mpt->m_mutex);
12817 ndi_dc_freehdl(dcp);
12818 }
12819 goto out;
12820 }
12821 switch (cmd) {
12822 case MPTIOCTL_GET_DISK_INFO:
12823 status = get_disk_info(mpt, data, mode);
12824 break;
12825 case MPTIOCTL_LED_CONTROL:
12826 status = led_control(mpt, data, mode);
12827 break;
12828 case MPTIOCTL_UPDATE_FLASH:
12829 if (ddi_copyin((void *)data, &flashdata,
12830 sizeof (struct mptsas_update_flash), mode)) {
12831 status = EFAULT;
12832 break;
12833 }
12834
12835 mutex_enter(&mpt->m_mutex);
12836 if (mptsas_update_flash(mpt,
12837 (caddr_t)(long)flashdata.PtrBuffer,
12838 flashdata.ImageSize, flashdata.ImageType, mode)) {
12839 status = EFAULT;
12840 }
12841
12842 /*
12843 * Reset the chip to start using the new
12844 * firmware. Reset if failed also.
12845 */
12846 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET;
12847 if (mptsas_restart_ioc(mpt) == DDI_FAILURE) {
12848 status = EFAULT;
12849 }
12850 mutex_exit(&mpt->m_mutex);
12851 break;
12852 case MPTIOCTL_PASS_THRU:
12853 /*
12854 * The user has requested to pass through a command to
12855 * be executed by the MPT firmware. Call our routine
12856 * which does this. Only allow one passthru IOCTL at
12857 * one time. Other threads will block on
12858 * m_passthru_mutex, which is of adaptive variant.
12859 */
12860 if (ddi_copyin((void *)data, &passthru_data,
12861 sizeof (mptsas_pass_thru_t), mode)) {
12862 status = EFAULT;
12863 break;
12864 }
12865 mutex_enter(&mpt->m_passthru_mutex);
12866 mutex_enter(&mpt->m_mutex);
12867 status = mptsas_pass_thru(mpt, &passthru_data, mode);
12868 mutex_exit(&mpt->m_mutex);
12869 mutex_exit(&mpt->m_passthru_mutex);
12870
12871 break;
12872 case MPTIOCTL_GET_ADAPTER_DATA:
12873 /*
12874 * The user has requested to read adapter data. Call
12875 * our routine which does this.
12876 */
12877 bzero(&adapter_data, sizeof (mptsas_adapter_data_t));
12878 if (ddi_copyin((void *)data, (void *)&adapter_data,
12879 sizeof (mptsas_adapter_data_t), mode)) {
12880 status = EFAULT;
12881 break;
12882 }
12883 if (adapter_data.StructureLength >=
12884 sizeof (mptsas_adapter_data_t)) {
12885 adapter_data.StructureLength = (uint32_t)
12886 sizeof (mptsas_adapter_data_t);
12887 copylen = sizeof (mptsas_adapter_data_t);
12888 mutex_enter(&mpt->m_mutex);
12889 mptsas_read_adapter_data(mpt, &adapter_data);
12890 mutex_exit(&mpt->m_mutex);
12891 } else {
12892 adapter_data.StructureLength = (uint32_t)
12893 sizeof (mptsas_adapter_data_t);
12894 copylen = sizeof (adapter_data.StructureLength);
12895 *rval = MPTIOCTL_STATUS_LEN_TOO_SHORT;
12896 }
12897 if (ddi_copyout((void *)(&adapter_data), (void *)data,
12898 copylen, mode) != 0) {
12899 status = EFAULT;
12900 }
12901 break;
12902 case MPTIOCTL_GET_PCI_INFO:
12903 /*
12904 * The user has requested to read pci info. Call
12905 * our routine which does this.
12906 */
12907 bzero(&pci_info, sizeof (mptsas_pci_info_t));
12908 mutex_enter(&mpt->m_mutex);
12909 mptsas_read_pci_info(mpt, &pci_info);
12910 mutex_exit(&mpt->m_mutex);
12911 if (ddi_copyout((void *)(&pci_info), (void *)data,
12912 sizeof (mptsas_pci_info_t), mode) != 0) {
12913 status = EFAULT;
12914 }
12915 break;
12916 case MPTIOCTL_RESET_ADAPTER:
12917 mutex_enter(&mpt->m_mutex);
12918 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET;
12919 if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) {
12920 mptsas_log(mpt, CE_WARN, "reset adapter IOCTL "
12921 "failed");
12922 status = EFAULT;
12923 }
12924 mutex_exit(&mpt->m_mutex);
12925 break;
12926 case MPTIOCTL_DIAG_ACTION:
12927 /*
12928 * The user has done a diag buffer action. Call our
12929 * routine which does this. Only allow one diag action
12930 * at one time.
12931 */
12932 mutex_enter(&mpt->m_mutex);
12933 if (mpt->m_diag_action_in_progress) {
12934 mutex_exit(&mpt->m_mutex);
12935 return (EBUSY);
12936 }
12937 mpt->m_diag_action_in_progress = 1;
12938 status = mptsas_diag_action(mpt,
12939 (mptsas_diag_action_t *)data, mode);
12940 mpt->m_diag_action_in_progress = 0;
12941 mutex_exit(&mpt->m_mutex);
12942 break;
12943 case MPTIOCTL_EVENT_QUERY:
12944 /*
12945 * The user has done an event query. Call our routine
12946 * which does this.
12947 */
12948 status = mptsas_event_query(mpt,
12949 (mptsas_event_query_t *)data, mode, rval);
12950 break;
12951 case MPTIOCTL_EVENT_ENABLE:
12952 /*
12953 * The user has done an event enable. Call our routine
12954 * which does this.
12955 */
12956 status = mptsas_event_enable(mpt,
12957 (mptsas_event_enable_t *)data, mode, rval);
12958 break;
12959 case MPTIOCTL_EVENT_REPORT:
12960 /*
12961 * The user has done an event report. Call our routine
12962 * which does this.
12963 */
12964 status = mptsas_event_report(mpt,
12965 (mptsas_event_report_t *)data, mode, rval);
12966 break;
12967 case MPTIOCTL_REG_ACCESS:
12968 /*
12969 * The user has requested register access. Call our
12970 * routine which does this.
12971 */
12972 status = mptsas_reg_access(mpt,
12973 (mptsas_reg_access_t *)data, mode);
12974 break;
12975 default:
12976 status = scsi_hba_ioctl(dev, cmd, data, mode, credp,
12977 rval);
12978 break;
12979 }
12980
12981 out:
12982 return (status);
12983 }
12984
12985 int
12986 mptsas_restart_ioc(mptsas_t *mpt)
12987 {
12988 int rval = DDI_SUCCESS;
12989 mptsas_target_t *ptgt = NULL;
12990
12991 ASSERT(mutex_owned(&mpt->m_mutex));
12992
12993 /*
12994 * Set a flag telling I/O path that we're processing a reset. This is
12995 * needed because after the reset is complete, the hash table still
12996 * needs to be rebuilt. If I/Os are started before the hash table is
12997 * rebuilt, I/O errors will occur. This flag allows I/Os to be marked
12998 * so that they can be retried.
12999 */
13000 mpt->m_in_reset = TRUE;
13001
13002 /*
13003 * Wait until all the allocated sense data buffers for DMA are freed.
13004 */
13005 while (mpt->m_extreq_sense_refcount > 0)
13006 cv_wait(&mpt->m_extreq_sense_refcount_cv, &mpt->m_mutex);
13007
13008 /*
13009 * Set all throttles to HOLD
13010 */
13011 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
13012 ptgt = refhash_next(mpt->m_targets, ptgt)) {
13013 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
13014 }
13015
13016 /*
13017 * Disable interrupts
13018 */
13019 MPTSAS_DISABLE_INTR(mpt);
13020
13021 /*
13022 * Abort all commands: outstanding commands, commands in waitq and
13023 * tx_waitq.
13024 */
13025 mptsas_flush_hba(mpt);
13026
13027 /*
13028 * Reinitialize the chip.
13029 */
13030 if (mptsas_init_chip(mpt, FALSE) == DDI_FAILURE) {
13031 rval = DDI_FAILURE;
13032 }
13033
13034 /*
13035 * Enable interrupts again
13036 */
13037 MPTSAS_ENABLE_INTR(mpt);
13038
13039 /*
13040 * If mptsas_init_chip was successful, update the driver data.
13041 */
13042 if (rval == DDI_SUCCESS) {
13043 mptsas_update_driver_data(mpt);
13044 }
13045
13046 /*
13047 * Reset the throttles
13048 */
13049 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
13050 ptgt = refhash_next(mpt->m_targets, ptgt)) {
13051 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
13052 }
13053
13054 mptsas_doneq_empty(mpt);
13055 mptsas_restart_hba(mpt);
13056
13057 if (rval != DDI_SUCCESS) {
13058 mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE);
13059 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST);
13060 }
13061
13062 /*
13063 * Clear the reset flag so that I/Os can continue.
13064 */
13065 mpt->m_in_reset = FALSE;
13066
13067 return (rval);
13068 }
13069
13070 static int
13071 mptsas_init_chip(mptsas_t *mpt, int first_time)
13072 {
13073 ddi_dma_cookie_t cookie;
13074 uint32_t i;
13075 int rval;
13076
13077 /*
13078 * Check to see if the firmware image is valid
13079 */
13080 if (ddi_get32(mpt->m_datap, &mpt->m_reg->HostDiagnostic) &
13081 MPI2_DIAG_FLASH_BAD_SIG) {
13082 mptsas_log(mpt, CE_WARN, "mptsas bad flash signature!");
13083 goto fail;
13084 }
13085
13086 /*
13087 * Reset the chip
13088 */
13089 rval = mptsas_ioc_reset(mpt, first_time);
13090 if (rval == MPTSAS_RESET_FAIL) {
13091 mptsas_log(mpt, CE_WARN, "hard reset failed!");
13092 goto fail;
13093 }
13094
13095 if ((rval == MPTSAS_SUCCESS_MUR) && (!first_time)) {
13096 goto mur;
13097 }
13098 /*
13099 * Setup configuration space
13100 */
13101 if (mptsas_config_space_init(mpt) == FALSE) {
13102 mptsas_log(mpt, CE_WARN, "mptsas_config_space_init "
13103 "failed!");
13104 goto fail;
13105 }
13106
13107 /*
13108 * IOC facts can change after a diag reset so all buffers that are
13109 * based on these numbers must be de-allocated and re-allocated. Get
13110 * new IOC facts each time chip is initialized.
13111 */
13112 if (mptsas_ioc_get_facts(mpt) == DDI_FAILURE) {
13113 mptsas_log(mpt, CE_WARN, "mptsas_ioc_get_facts failed");
13114 goto fail;
13115 }
13116
13117 if (mptsas_alloc_active_slots(mpt, KM_SLEEP)) {
13118 goto fail;
13119 }
13120 /*
13121 * Allocate request message frames, reply free queue, reply descriptor
13122 * post queue, and reply message frames using latest IOC facts.
13123 */
13124 if (mptsas_alloc_request_frames(mpt) == DDI_FAILURE) {
13125 mptsas_log(mpt, CE_WARN, "mptsas_alloc_request_frames failed");
13126 goto fail;
13127 }
13128 if (mptsas_alloc_sense_bufs(mpt) == DDI_FAILURE) {
13129 mptsas_log(mpt, CE_WARN, "mptsas_alloc_sense_bufs failed");
13130 goto fail;
13131 }
13132 if (mptsas_alloc_free_queue(mpt) == DDI_FAILURE) {
13133 mptsas_log(mpt, CE_WARN, "mptsas_alloc_free_queue failed!");
13134 goto fail;
13135 }
13136 if (mptsas_alloc_post_queue(mpt) == DDI_FAILURE) {
13137 mptsas_log(mpt, CE_WARN, "mptsas_alloc_post_queue failed!");
13138 goto fail;
13139 }
13140 if (mptsas_alloc_reply_frames(mpt) == DDI_FAILURE) {
13141 mptsas_log(mpt, CE_WARN, "mptsas_alloc_reply_frames failed!");
13142 goto fail;
13143 }
13144
13145 mur:
13146 /*
13147 * Re-Initialize ioc to operational state
13148 */
13149 if (mptsas_ioc_init(mpt) == DDI_FAILURE) {
13150 mptsas_log(mpt, CE_WARN, "mptsas_ioc_init failed");
13151 goto fail;
13152 }
13153
13154 mptsas_alloc_reply_args(mpt);
13155
13156 /*
13157 * Initialize reply post index. Reply free index is initialized after
13158 * the next loop.
13159 */
13160 mpt->m_post_index = 0;
13161
13162 /*
13163 * Initialize the Reply Free Queue with the physical addresses of our
13164 * reply frames.
13165 */
13166 cookie.dmac_address = mpt->m_reply_frame_dma_addr & 0xffffffffu;
13167 for (i = 0; i < mpt->m_max_replies; i++) {
13168 ddi_put32(mpt->m_acc_free_queue_hdl,
13169 &((uint32_t *)(void *)mpt->m_free_queue)[i],
13170 cookie.dmac_address);
13171 cookie.dmac_address += mpt->m_reply_frame_size;
13172 }
13173 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
13174 DDI_DMA_SYNC_FORDEV);
13175
13176 /*
13177 * Initialize the reply free index to one past the last frame on the
13178 * queue. This will signify that the queue is empty to start with.
13179 */
13180 mpt->m_free_index = i;
13181 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, i);
13182
13183 /*
13184 * Initialize the reply post queue to 0xFFFFFFFF,0xFFFFFFFF's.
13185 */
13186 for (i = 0; i < mpt->m_post_queue_depth; i++) {
13187 ddi_put64(mpt->m_acc_post_queue_hdl,
13188 &((uint64_t *)(void *)mpt->m_post_queue)[i],
13189 0xFFFFFFFFFFFFFFFF);
13190 }
13191 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0,
13192 DDI_DMA_SYNC_FORDEV);
13193
13194 /*
13195 * Enable ports
13196 */
13197 if (mptsas_ioc_enable_port(mpt) == DDI_FAILURE) {
13198 mptsas_log(mpt, CE_WARN, "mptsas_ioc_enable_port failed");
13199 goto fail;
13200 }
13201
13202 /*
13203 * enable events
13204 */
13205 if (mptsas_ioc_enable_event_notification(mpt)) {
13206 mptsas_log(mpt, CE_WARN,
13207 "mptsas_ioc_enable_event_notification failed");
13208 goto fail;
13209 }
13210
13211 /*
13212 * We need checks in attach and these.
13213 * chip_init is called in mult. places
13214 */
13215
13216 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) !=
13217 DDI_SUCCESS) ||
13218 (mptsas_check_dma_handle(mpt->m_dma_req_sense_hdl) !=
13219 DDI_SUCCESS) ||
13220 (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl) !=
13221 DDI_SUCCESS) ||
13222 (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl) !=
13223 DDI_SUCCESS) ||
13224 (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) !=
13225 DDI_SUCCESS) ||
13226 (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl) !=
13227 DDI_SUCCESS)) {
13228 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
13229 goto fail;
13230 }
13231
13232 /* Check all acc handles */
13233 if ((mptsas_check_acc_handle(mpt->m_datap) != DDI_SUCCESS) ||
13234 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) !=
13235 DDI_SUCCESS) ||
13236 (mptsas_check_acc_handle(mpt->m_acc_req_sense_hdl) !=
13237 DDI_SUCCESS) ||
13238 (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl) !=
13239 DDI_SUCCESS) ||
13240 (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl) !=
13241 DDI_SUCCESS) ||
13242 (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl) !=
13243 DDI_SUCCESS) ||
13244 (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl) !=
13245 DDI_SUCCESS) ||
13246 (mptsas_check_acc_handle(mpt->m_config_handle) !=
13247 DDI_SUCCESS)) {
13248 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
13249 goto fail;
13250 }
13251
13252 return (DDI_SUCCESS);
13253
13254 fail:
13255 return (DDI_FAILURE);
13256 }
13257
13258 static int
13259 mptsas_get_pci_cap(mptsas_t *mpt)
13260 {
13261 ushort_t caps_ptr, cap, cap_count;
13262
13263 if (mpt->m_config_handle == NULL)
13264 return (FALSE);
13265 /*
13266 * Check if capabilities list is supported and if so,
13267 * get initial capabilities pointer and clear bits 0,1.
13268 */
13269 if (pci_config_get16(mpt->m_config_handle, PCI_CONF_STAT)
13270 & PCI_STAT_CAP) {
13271 caps_ptr = P2ALIGN(pci_config_get8(mpt->m_config_handle,
13272 PCI_CONF_CAP_PTR), 4);
13273 } else {
13274 caps_ptr = PCI_CAP_NEXT_PTR_NULL;
13275 }
13276
13277 /*
13278 * Walk capabilities if supported.
13279 */
13280 for (cap_count = 0; caps_ptr != PCI_CAP_NEXT_PTR_NULL; ) {
13281
13282 /*
13283 * Check that we haven't exceeded the maximum number of
13284 * capabilities and that the pointer is in a valid range.
13285 */
13286 if (++cap_count > 48) {
13287 mptsas_log(mpt, CE_WARN,
13288 "too many device capabilities.\n");
13289 break;
13290 }
13291 if (caps_ptr < 64) {
13292 mptsas_log(mpt, CE_WARN,
13293 "capabilities pointer 0x%x out of range.\n",
13294 caps_ptr);
13295 break;
13296 }
13297
13298 /*
13299 * Get next capability and check that it is valid.
13300 * For now, we only support power management.
13301 */
13302 cap = pci_config_get8(mpt->m_config_handle, caps_ptr);
13303 switch (cap) {
13304 case PCI_CAP_ID_PM:
13305 mptsas_log(mpt, CE_NOTE,
13306 "?mptsas%d supports power management.\n",
13307 mpt->m_instance);
13308 mpt->m_options |= MPTSAS_OPT_PM;
13309
13310 /* Save PMCSR offset */
13311 mpt->m_pmcsr_offset = caps_ptr + PCI_PMCSR;
13312 break;
13313 /*
13314 * The following capabilities are valid. Any others
13315 * will cause a message to be logged.
13316 */
13317 case PCI_CAP_ID_VPD:
13318 case PCI_CAP_ID_MSI:
13319 case PCI_CAP_ID_PCIX:
13320 case PCI_CAP_ID_PCI_E:
13321 case PCI_CAP_ID_MSI_X:
13322 break;
13323 default:
13324 mptsas_log(mpt, CE_NOTE,
13325 "?mptsas%d unrecognized capability "
13326 "0x%x.\n", mpt->m_instance, cap);
13327 break;
13328 }
13329
13330 /*
13331 * Get next capabilities pointer and clear bits 0,1.
13332 */
13333 caps_ptr = P2ALIGN(pci_config_get8(mpt->m_config_handle,
13334 (caps_ptr + PCI_CAP_NEXT_PTR)), 4);
13335 }
13336 return (TRUE);
13337 }
13338
13339 static int
13340 mptsas_init_pm(mptsas_t *mpt)
13341 {
13342 char pmc_name[16];
13343 char *pmc[] = {
13344 NULL,
13345 "0=Off (PCI D3 State)",
13346 "3=On (PCI D0 State)",
13347 NULL
13348 };
13349 uint16_t pmcsr_stat;
13350
13351 if (mptsas_get_pci_cap(mpt) == FALSE) {
13352 return (DDI_FAILURE);
13353 }
13354 /*
13355 * If PCI's capability does not support PM, then don't need
13356 * to registe the pm-components
13357 */
13358 if (!(mpt->m_options & MPTSAS_OPT_PM))
13359 return (DDI_SUCCESS);
13360 /*
13361 * If power management is supported by this chip, create
13362 * pm-components property for the power management framework
13363 */
13364 (void) sprintf(pmc_name, "NAME=mptsas%d", mpt->m_instance);
13365 pmc[0] = pmc_name;
13366 if (ddi_prop_update_string_array(DDI_DEV_T_NONE, mpt->m_dip,
13367 "pm-components", pmc, 3) != DDI_PROP_SUCCESS) {
13368 mpt->m_options &= ~MPTSAS_OPT_PM;
13369 mptsas_log(mpt, CE_WARN,
13370 "mptsas%d: pm-component property creation failed.",
13371 mpt->m_instance);
13372 return (DDI_FAILURE);
13373 }
13374
13375 /*
13376 * Power on device.
13377 */
13378 (void) pm_busy_component(mpt->m_dip, 0);
13379 pmcsr_stat = pci_config_get16(mpt->m_config_handle,
13380 mpt->m_pmcsr_offset);
13381 if ((pmcsr_stat & PCI_PMCSR_STATE_MASK) != PCI_PMCSR_D0) {
13382 mptsas_log(mpt, CE_WARN, "mptsas%d: Power up the device",
13383 mpt->m_instance);
13384 pci_config_put16(mpt->m_config_handle, mpt->m_pmcsr_offset,
13385 PCI_PMCSR_D0);
13386 }
13387 if (pm_power_has_changed(mpt->m_dip, 0, PM_LEVEL_D0) != DDI_SUCCESS) {
13388 mptsas_log(mpt, CE_WARN, "pm_power_has_changed failed");
13389 return (DDI_FAILURE);
13390 }
13391 mpt->m_power_level = PM_LEVEL_D0;
13392 /*
13393 * Set pm idle delay.
13394 */
13395 mpt->m_pm_idle_delay = ddi_prop_get_int(DDI_DEV_T_ANY,
13396 mpt->m_dip, 0, "mptsas-pm-idle-delay", MPTSAS_PM_IDLE_TIMEOUT);
13397
13398 return (DDI_SUCCESS);
13399 }
13400
13401 static int
13402 mptsas_register_intrs(mptsas_t *mpt)
13403 {
13404 dev_info_t *dip;
13405 int intr_types;
13406
13407 dip = mpt->m_dip;
13408
13409 /* Get supported interrupt types */
13410 if (ddi_intr_get_supported_types(dip, &intr_types) != DDI_SUCCESS) {
13411 mptsas_log(mpt, CE_WARN, "ddi_intr_get_supported_types "
13412 "failed\n");
13413 return (FALSE);
13414 }
13415
13416 NDBG6(("ddi_intr_get_supported_types() returned: 0x%x", intr_types));
13417
13418 /*
13419 * Try MSI, but fall back to FIXED
13420 */
13421 if (mptsas_enable_msi && (intr_types & DDI_INTR_TYPE_MSI)) {
13422 if (mptsas_add_intrs(mpt, DDI_INTR_TYPE_MSI) == DDI_SUCCESS) {
13423 NDBG0(("Using MSI interrupt type"));
13424 mpt->m_intr_type = DDI_INTR_TYPE_MSI;
13425 return (TRUE);
13426 }
13427 }
13428 if (intr_types & DDI_INTR_TYPE_FIXED) {
13429 if (mptsas_add_intrs(mpt, DDI_INTR_TYPE_FIXED) == DDI_SUCCESS) {
13430 NDBG0(("Using FIXED interrupt type"));
13431 mpt->m_intr_type = DDI_INTR_TYPE_FIXED;
13432 return (TRUE);
13433 } else {
13434 NDBG0(("FIXED interrupt registration failed"));
13435 return (FALSE);
13436 }
13437 }
13438
13439 return (FALSE);
13440 }
13441
13442 static void
13443 mptsas_unregister_intrs(mptsas_t *mpt)
13444 {
13445 mptsas_rem_intrs(mpt);
13446 }
13447
13448 /*
13449 * mptsas_add_intrs:
13450 *
13451 * Register FIXED or MSI interrupts.
13452 */
13453 static int
13454 mptsas_add_intrs(mptsas_t *mpt, int intr_type)
13455 {
13456 dev_info_t *dip = mpt->m_dip;
13457 int avail, actual, count = 0;
13458 int i, flag, ret;
13459
13460 NDBG6(("mptsas_add_intrs:interrupt type 0x%x", intr_type));
13461
13462 /* Get number of interrupts */
13463 ret = ddi_intr_get_nintrs(dip, intr_type, &count);
13464 if ((ret != DDI_SUCCESS) || (count <= 0)) {
13465 mptsas_log(mpt, CE_WARN, "ddi_intr_get_nintrs() failed, "
13466 "ret %d count %d\n", ret, count);
13467
13468 return (DDI_FAILURE);
13469 }
13470
13471 /* Get number of available interrupts */
13472 ret = ddi_intr_get_navail(dip, intr_type, &avail);
13473 if ((ret != DDI_SUCCESS) || (avail == 0)) {
13474 mptsas_log(mpt, CE_WARN, "ddi_intr_get_navail() failed, "
13475 "ret %d avail %d\n", ret, avail);
13476
13477 return (DDI_FAILURE);
13478 }
13479
13480 if (avail < count) {
13481 mptsas_log(mpt, CE_NOTE, "ddi_intr_get_nvail returned %d, "
13482 "navail() returned %d", count, avail);
13483 }
13484
13485 /* Mpt only have one interrupt routine */
13486 if ((intr_type == DDI_INTR_TYPE_MSI) && (count > 1)) {
13487 count = 1;
13488 }
13489
13490 /* Allocate an array of interrupt handles */
13491 mpt->m_intr_size = count * sizeof (ddi_intr_handle_t);
13492 mpt->m_htable = kmem_alloc(mpt->m_intr_size, KM_SLEEP);
13493
13494 flag = DDI_INTR_ALLOC_NORMAL;
13495
13496 /* call ddi_intr_alloc() */
13497 ret = ddi_intr_alloc(dip, mpt->m_htable, intr_type, 0,
13498 count, &actual, flag);
13499
13500 if ((ret != DDI_SUCCESS) || (actual == 0)) {
13501 mptsas_log(mpt, CE_WARN, "ddi_intr_alloc() failed, ret %d\n",
13502 ret);
13503 kmem_free(mpt->m_htable, mpt->m_intr_size);
13504 return (DDI_FAILURE);
13505 }
13506
13507 /* use interrupt count returned or abort? */
13508 if (actual < count) {
13509 mptsas_log(mpt, CE_NOTE, "Requested: %d, Received: %d\n",
13510 count, actual);
13511 }
13512
13513 mpt->m_intr_cnt = actual;
13514
13515 /*
13516 * Get priority for first msi, assume remaining are all the same
13517 */
13518 if ((ret = ddi_intr_get_pri(mpt->m_htable[0],
13519 &mpt->m_intr_pri)) != DDI_SUCCESS) {
13520 mptsas_log(mpt, CE_WARN, "ddi_intr_get_pri() failed %d\n", ret);
13521
13522 /* Free already allocated intr */
13523 for (i = 0; i < actual; i++) {
13524 (void) ddi_intr_free(mpt->m_htable[i]);
13525 }
13526
13527 kmem_free(mpt->m_htable, mpt->m_intr_size);
13528 return (DDI_FAILURE);
13529 }
13530
13531 /* Test for high level mutex */
13532 if (mpt->m_intr_pri >= ddi_intr_get_hilevel_pri()) {
13533 mptsas_log(mpt, CE_WARN, "mptsas_add_intrs: "
13534 "Hi level interrupt not supported\n");
13535
13536 /* Free already allocated intr */
13537 for (i = 0; i < actual; i++) {
13538 (void) ddi_intr_free(mpt->m_htable[i]);
13539 }
13540
13541 kmem_free(mpt->m_htable, mpt->m_intr_size);
13542 return (DDI_FAILURE);
13543 }
13544
13545 /* Call ddi_intr_add_handler() */
13546 for (i = 0; i < actual; i++) {
13547 if ((ret = ddi_intr_add_handler(mpt->m_htable[i], mptsas_intr,
13548 (caddr_t)mpt, (caddr_t)(uintptr_t)i)) != DDI_SUCCESS) {
13549 mptsas_log(mpt, CE_WARN, "ddi_intr_add_handler() "
13550 "failed %d\n", ret);
13551
13552 /* Free already allocated intr */
13553 for (i = 0; i < actual; i++) {
13554 (void) ddi_intr_free(mpt->m_htable[i]);
13555 }
13556
13557 kmem_free(mpt->m_htable, mpt->m_intr_size);
13558 return (DDI_FAILURE);
13559 }
13560 }
13561
13562 if ((ret = ddi_intr_get_cap(mpt->m_htable[0], &mpt->m_intr_cap))
13563 != DDI_SUCCESS) {
13564 mptsas_log(mpt, CE_WARN, "ddi_intr_get_cap() failed %d\n", ret);
13565
13566 /* Free already allocated intr */
13567 for (i = 0; i < actual; i++) {
13568 (void) ddi_intr_free(mpt->m_htable[i]);
13569 }
13570
13571 kmem_free(mpt->m_htable, mpt->m_intr_size);
13572 return (DDI_FAILURE);
13573 }
13574
13575 /*
13576 * Enable interrupts
13577 */
13578 if (mpt->m_intr_cap & DDI_INTR_FLAG_BLOCK) {
13579 /* Call ddi_intr_block_enable() for MSI interrupts */
13580 (void) ddi_intr_block_enable(mpt->m_htable, mpt->m_intr_cnt);
13581 } else {
13582 /* Call ddi_intr_enable for MSI or FIXED interrupts */
13583 for (i = 0; i < mpt->m_intr_cnt; i++) {
13584 (void) ddi_intr_enable(mpt->m_htable[i]);
13585 }
13586 }
13587 return (DDI_SUCCESS);
13588 }
13589
13590 /*
13591 * mptsas_rem_intrs:
13592 *
13593 * Unregister FIXED or MSI interrupts
13594 */
13595 static void
13596 mptsas_rem_intrs(mptsas_t *mpt)
13597 {
13598 int i;
13599
13600 NDBG6(("mptsas_rem_intrs"));
13601
13602 /* Disable all interrupts */
13603 if (mpt->m_intr_cap & DDI_INTR_FLAG_BLOCK) {
13604 /* Call ddi_intr_block_disable() */
13605 (void) ddi_intr_block_disable(mpt->m_htable, mpt->m_intr_cnt);
13606 } else {
13607 for (i = 0; i < mpt->m_intr_cnt; i++) {
13608 (void) ddi_intr_disable(mpt->m_htable[i]);
13609 }
13610 }
13611
13612 /* Call ddi_intr_remove_handler() */
13613 for (i = 0; i < mpt->m_intr_cnt; i++) {
13614 (void) ddi_intr_remove_handler(mpt->m_htable[i]);
13615 (void) ddi_intr_free(mpt->m_htable[i]);
13616 }
13617
13618 kmem_free(mpt->m_htable, mpt->m_intr_size);
13619 }
13620
13621 /*
13622 * The IO fault service error handling callback function
13623 */
13624 /*ARGSUSED*/
13625 static int
13626 mptsas_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data)
13627 {
13628 /*
13629 * as the driver can always deal with an error in any dma or
13630 * access handle, we can just return the fme_status value.
13631 */
13632 pci_ereport_post(dip, err, NULL);
13633 return (err->fme_status);
13634 }
13635
13636 /*
13637 * mptsas_fm_init - initialize fma capabilities and register with IO
13638 * fault services.
13639 */
13640 static void
13641 mptsas_fm_init(mptsas_t *mpt)
13642 {
13643 /*
13644 * Need to change iblock to priority for new MSI intr
13645 */
13646 ddi_iblock_cookie_t fm_ibc;
13647
13648 /* Only register with IO Fault Services if we have some capability */
13649 if (mpt->m_fm_capabilities) {
13650 /* Adjust access and dma attributes for FMA */
13651 mpt->m_reg_acc_attr.devacc_attr_access = DDI_FLAGERR_ACC;
13652 mpt->m_msg_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
13653 mpt->m_io_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
13654
13655 /*
13656 * Register capabilities with IO Fault Services.
13657 * mpt->m_fm_capabilities will be updated to indicate
13658 * capabilities actually supported (not requested.)
13659 */
13660 ddi_fm_init(mpt->m_dip, &mpt->m_fm_capabilities, &fm_ibc);
13661
13662 /*
13663 * Initialize pci ereport capabilities if ereport
13664 * capable (should always be.)
13665 */
13666 if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities) ||
13667 DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) {
13668 pci_ereport_setup(mpt->m_dip);
13669 }
13670
13671 /*
13672 * Register error callback if error callback capable.
13673 */
13674 if (DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) {
13675 ddi_fm_handler_register(mpt->m_dip,
13676 mptsas_fm_error_cb, (void *) mpt);
13677 }
13678 }
13679 }
13680
13681 /*
13682 * mptsas_fm_fini - Releases fma capabilities and un-registers with IO
13683 * fault services.
13684 *
13685 */
13686 static void
13687 mptsas_fm_fini(mptsas_t *mpt)
13688 {
13689 /* Only unregister FMA capabilities if registered */
13690 if (mpt->m_fm_capabilities) {
13691
13692 /*
13693 * Un-register error callback if error callback capable.
13694 */
13695
13696 if (DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) {
13697 ddi_fm_handler_unregister(mpt->m_dip);
13698 }
13699
13700 /*
13701 * Release any resources allocated by pci_ereport_setup()
13702 */
13703
13704 if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities) ||
13705 DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) {
13706 pci_ereport_teardown(mpt->m_dip);
13707 }
13708
13709 /* Unregister from IO Fault Services */
13710 ddi_fm_fini(mpt->m_dip);
13711
13712 /* Adjust access and dma attributes for FMA */
13713 mpt->m_reg_acc_attr.devacc_attr_access = DDI_DEFAULT_ACC;
13714 mpt->m_msg_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
13715 mpt->m_io_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
13716
13717 }
13718 }
13719
13720 int
13721 mptsas_check_acc_handle(ddi_acc_handle_t handle)
13722 {
13723 ddi_fm_error_t de;
13724
13725 if (handle == NULL)
13726 return (DDI_FAILURE);
13727 ddi_fm_acc_err_get(handle, &de, DDI_FME_VER0);
13728 return (de.fme_status);
13729 }
13730
13731 int
13732 mptsas_check_dma_handle(ddi_dma_handle_t handle)
13733 {
13734 ddi_fm_error_t de;
13735
13736 if (handle == NULL)
13737 return (DDI_FAILURE);
13738 ddi_fm_dma_err_get(handle, &de, DDI_FME_VER0);
13739 return (de.fme_status);
13740 }
13741
13742 void
13743 mptsas_fm_ereport(mptsas_t *mpt, char *detail)
13744 {
13745 uint64_t ena;
13746 char buf[FM_MAX_CLASS];
13747
13748 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail);
13749 ena = fm_ena_generate(0, FM_ENA_FMT1);
13750 if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities)) {
13751 ddi_fm_ereport_post(mpt->m_dip, buf, ena, DDI_NOSLEEP,
13752 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, NULL);
13753 }
13754 }
13755
13756 static int
13757 mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address,
13758 uint16_t *dev_handle, mptsas_target_t **pptgt)
13759 {
13760 int rval;
13761 uint32_t dev_info;
13762 uint64_t sas_wwn;
13763 mptsas_phymask_t phymask;
13764 uint8_t physport, phynum, config, disk;
13765 uint64_t devicename;
13766 uint16_t pdev_hdl;
13767 mptsas_target_t *tmp_tgt = NULL;
13768 uint16_t bay_num, enclosure, io_flags;
13769
13770 ASSERT(*pptgt == NULL);
13771
13772 rval = mptsas_get_sas_device_page0(mpt, page_address, dev_handle,
13773 &sas_wwn, &dev_info, &physport, &phynum, &pdev_hdl,
13774 &bay_num, &enclosure, &io_flags);
13775 if (rval != DDI_SUCCESS) {
13776 rval = DEV_INFO_FAIL_PAGE0;
13777 return (rval);
13778 }
13779
13780 if ((dev_info & (MPI2_SAS_DEVICE_INFO_SSP_TARGET |
13781 MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
13782 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) == NULL) {
13783 rval = DEV_INFO_WRONG_DEVICE_TYPE;
13784 return (rval);
13785 }
13786
13787 /*
13788 * Check if the dev handle is for a Phys Disk. If so, set return value
13789 * and exit. Don't add Phys Disks to hash.
13790 */
13791 for (config = 0; config < mpt->m_num_raid_configs; config++) {
13792 for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) {
13793 if (*dev_handle == mpt->m_raidconfig[config].
13794 m_physdisk_devhdl[disk]) {
13795 rval = DEV_INFO_PHYS_DISK;
13796 return (rval);
13797 }
13798 }
13799 }
13800
13801 /*
13802 * Get SATA Device Name from SAS device page0 for
13803 * sata device, if device name doesn't exist, set mta_wwn to
13804 * 0 for direct attached SATA. For the device behind the expander
13805 * we still can use STP address assigned by expander.
13806 */
13807 if (dev_info & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
13808 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
13809 /* alloc a temporary target to send the cmd to */
13810 tmp_tgt = mptsas_tgt_alloc(mpt->m_tmp_targets, *dev_handle,
13811 0, dev_info, 0, 0);
13812 mutex_exit(&mpt->m_mutex);
13813
13814 devicename = mptsas_get_sata_guid(mpt, tmp_tgt, 0);
13815
13816 if (devicename == -1) {
13817 mutex_enter(&mpt->m_mutex);
13818 refhash_remove(mpt->m_tmp_targets, tmp_tgt);
13819 rval = DEV_INFO_FAIL_GUID;
13820 return (rval);
13821 }
13822
13823 if (devicename != 0 && (((devicename >> 56) & 0xf0) == 0x50)) {
13824 sas_wwn = devicename;
13825 } else if (dev_info & MPI2_SAS_DEVICE_INFO_DIRECT_ATTACH) {
13826 sas_wwn = 0;
13827 }
13828
13829 mutex_enter(&mpt->m_mutex);
13830 refhash_remove(mpt->m_tmp_targets, tmp_tgt);
13831 }
13832
13833 phymask = mptsas_physport_to_phymask(mpt, physport);
13834 *pptgt = mptsas_tgt_alloc(mpt->m_targets, *dev_handle, sas_wwn,
13835 dev_info, phymask, phynum);
13836 if (*pptgt == NULL) {
13837 mptsas_log(mpt, CE_WARN, "Failed to allocated target"
13838 "structure!");
13839 rval = DEV_INFO_FAIL_ALLOC;
13840 return (rval);
13841 }
13842 (*pptgt)->m_io_flags = io_flags;
13843 (*pptgt)->m_enclosure = enclosure;
13844 (*pptgt)->m_slot_num = bay_num;
13845 return (DEV_INFO_SUCCESS);
13846 }
13847
13848 uint64_t
13849 mptsas_get_sata_guid(mptsas_t *mpt, mptsas_target_t *ptgt, int lun)
13850 {
13851 uint64_t sata_guid = 0, *pwwn = NULL;
13852 int target = ptgt->m_devhdl;
13853 uchar_t *inq83 = NULL;
13854 int inq83_len = 0xFF;
13855 uchar_t *dblk = NULL;
13856 int inq83_retry = 3;
13857 int rval = DDI_FAILURE;
13858
13859 inq83 = kmem_zalloc(inq83_len, KM_SLEEP);
13860
13861 inq83_retry:
13862 rval = mptsas_inquiry(mpt, ptgt, lun, 0x83, inq83,
13863 inq83_len, NULL, 1);
13864 if (rval != DDI_SUCCESS) {
13865 mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page "
13866 "0x83 for target:%x, lun:%x failed!", target, lun);
13867 sata_guid = -1;
13868 goto out;
13869 }
13870 /* According to SAT2, the first descriptor is logic unit name */
13871 dblk = &inq83[4];
13872 if ((dblk[1] & 0x30) != 0) {
13873 mptsas_log(mpt, CE_WARN, "!Descriptor is not lun associated.");
13874 goto out;
13875 }
13876 pwwn = (uint64_t *)(void *)(&dblk[4]);
13877 if ((dblk[4] & 0xf0) == 0x50) {
13878 sata_guid = BE_64(*pwwn);
13879 goto out;
13880 } else if (dblk[4] == 'A') {
13881 NDBG20(("SATA drive has no NAA format GUID."));
13882 goto out;
13883 } else {
13884 /* The data is not ready, wait and retry */
13885 inq83_retry--;
13886 if (inq83_retry <= 0) {
13887 goto out;
13888 }
13889 NDBG20(("The GUID is not ready, retry..."));
13890 delay(1 * drv_usectohz(1000000));
13891 goto inq83_retry;
13892 }
13893 out:
13894 kmem_free(inq83, inq83_len);
13895 return (sata_guid);
13896 }
13897
13898 static int
13899 mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun, uchar_t page,
13900 unsigned char *buf, int len, int *reallen, uchar_t evpd)
13901 {
13902 uchar_t cdb[CDB_GROUP0];
13903 struct scsi_address ap;
13904 struct buf *data_bp = NULL;
13905 int resid = 0;
13906 int ret = DDI_FAILURE;
13907
13908 ASSERT(len <= 0xffff);
13909
13910 ap.a_target = MPTSAS_INVALID_DEVHDL;
13911 ap.a_lun = (uchar_t)(lun);
13912 ap.a_hba_tran = mpt->m_tran;
13913
13914 data_bp = scsi_alloc_consistent_buf(&ap,
13915 (struct buf *)NULL, len, B_READ, NULL_FUNC, NULL);
13916 if (data_bp == NULL) {
13917 return (ret);
13918 }
13919 bzero(cdb, CDB_GROUP0);
13920 cdb[0] = SCMD_INQUIRY;
13921 cdb[1] = evpd;
13922 cdb[2] = page;
13923 cdb[3] = (len & 0xff00) >> 8;
13924 cdb[4] = (len & 0x00ff);
13925 cdb[5] = 0;
13926
13927 ret = mptsas_send_scsi_cmd(mpt, &ap, ptgt, &cdb[0], CDB_GROUP0, data_bp,
13928 &resid);
13929 if (ret == DDI_SUCCESS) {
13930 if (reallen) {
13931 *reallen = len - resid;
13932 }
13933 bcopy((caddr_t)data_bp->b_un.b_addr, buf, len);
13934 }
13935 if (data_bp) {
13936 scsi_free_consistent_buf(data_bp);
13937 }
13938 return (ret);
13939 }
13940
13941 static int
13942 mptsas_send_scsi_cmd(mptsas_t *mpt, struct scsi_address *ap,
13943 mptsas_target_t *ptgt, uchar_t *cdb, int cdblen, struct buf *data_bp,
13944 int *resid)
13945 {
13946 struct scsi_pkt *pktp = NULL;
13947 scsi_hba_tran_t *tran_clone = NULL;
13948 mptsas_tgt_private_t *tgt_private = NULL;
13949 int ret = DDI_FAILURE;
13950
13951 /*
13952 * scsi_hba_tran_t->tran_tgt_private is used to pass the address
13953 * information to scsi_init_pkt, allocate a scsi_hba_tran structure
13954 * to simulate the cmds from sd
13955 */
13956 tran_clone = kmem_alloc(
13957 sizeof (scsi_hba_tran_t), KM_SLEEP);
13958 if (tran_clone == NULL) {
13959 goto out;
13960 }
13961 bcopy((caddr_t)mpt->m_tran,
13962 (caddr_t)tran_clone, sizeof (scsi_hba_tran_t));
13963 tgt_private = kmem_alloc(
13964 sizeof (mptsas_tgt_private_t), KM_SLEEP);
13965 if (tgt_private == NULL) {
13966 goto out;
13967 }
13968 tgt_private->t_lun = ap->a_lun;
13969 tgt_private->t_private = ptgt;
13970 tran_clone->tran_tgt_private = tgt_private;
13971 ap->a_hba_tran = tran_clone;
13972
13973 pktp = scsi_init_pkt(ap, (struct scsi_pkt *)NULL,
13974 data_bp, cdblen, sizeof (struct scsi_arq_status),
13975 0, PKT_CONSISTENT, NULL, NULL);
13976 if (pktp == NULL) {
13977 goto out;
13978 }
13979 bcopy(cdb, pktp->pkt_cdbp, cdblen);
13980 pktp->pkt_flags = FLAG_NOPARITY;
13981 if (scsi_poll(pktp) < 0) {
13982 goto out;
13983 }
13984 if (((struct scsi_status *)pktp->pkt_scbp)->sts_chk) {
13985 goto out;
13986 }
13987 if (resid != NULL) {
13988 *resid = pktp->pkt_resid;
13989 }
13990
13991 ret = DDI_SUCCESS;
13992 out:
13993 if (pktp) {
13994 scsi_destroy_pkt(pktp);
13995 }
13996 if (tran_clone) {
13997 kmem_free(tran_clone, sizeof (scsi_hba_tran_t));
13998 }
13999 if (tgt_private) {
14000 kmem_free(tgt_private, sizeof (mptsas_tgt_private_t));
14001 }
14002 return (ret);
14003 }
14004 static int
14005 mptsas_parse_address(char *name, uint64_t *wwid, uint8_t *phy, int *lun)
14006 {
14007 char *cp = NULL;
14008 char *ptr = NULL;
14009 size_t s = 0;
14010 char *wwid_str = NULL;
14011 char *lun_str = NULL;
14012 long lunnum;
14013 long phyid = -1;
14014 int rc = DDI_FAILURE;
14015
14016 ptr = name;
14017 ASSERT(ptr[0] == 'w' || ptr[0] == 'p');
14018 ptr++;
14019 if ((cp = strchr(ptr, ',')) == NULL) {
14020 return (DDI_FAILURE);
14021 }
14022
14023 wwid_str = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
14024 s = (uintptr_t)cp - (uintptr_t)ptr;
14025
14026 bcopy(ptr, wwid_str, s);
14027 wwid_str[s] = '\0';
14028
14029 ptr = ++cp;
14030
14031 if ((cp = strchr(ptr, '\0')) == NULL) {
14032 goto out;
14033 }
14034 lun_str = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
14035 s = (uintptr_t)cp - (uintptr_t)ptr;
14036
14037 bcopy(ptr, lun_str, s);
14038 lun_str[s] = '\0';
14039
14040 if (name[0] == 'p') {
14041 rc = ddi_strtol(wwid_str, NULL, 0x10, &phyid);
14042 } else {
14043 rc = scsi_wwnstr_to_wwn(wwid_str, wwid);
14044 }
14045 if (rc != DDI_SUCCESS)
14046 goto out;
14047
14048 if (phyid != -1) {
14049 ASSERT(phyid < MPTSAS_MAX_PHYS);
14050 *phy = (uint8_t)phyid;
14051 }
14052 rc = ddi_strtol(lun_str, NULL, 0x10, &lunnum);
14053 if (rc != 0)
14054 goto out;
14055
14056 *lun = (int)lunnum;
14057 rc = DDI_SUCCESS;
14058 out:
14059 if (wwid_str)
14060 kmem_free(wwid_str, SCSI_MAXNAMELEN);
14061 if (lun_str)
14062 kmem_free(lun_str, SCSI_MAXNAMELEN);
14063
14064 return (rc);
14065 }
14066
14067 /*
14068 * mptsas_parse_smp_name() is to parse sas wwn string
14069 * which format is "wWWN"
14070 */
14071 static int
14072 mptsas_parse_smp_name(char *name, uint64_t *wwn)
14073 {
14074 char *ptr = name;
14075
14076 if (*ptr != 'w') {
14077 return (DDI_FAILURE);
14078 }
14079
14080 ptr++;
14081 if (scsi_wwnstr_to_wwn(ptr, wwn)) {
14082 return (DDI_FAILURE);
14083 }
14084 return (DDI_SUCCESS);
14085 }
14086
14087 static int
14088 mptsas_bus_config(dev_info_t *pdip, uint_t flag,
14089 ddi_bus_config_op_t op, void *arg, dev_info_t **childp)
14090 {
14091 int ret = NDI_FAILURE;
14092 int circ = 0;
14093 int circ1 = 0;
14094 mptsas_t *mpt;
14095 char *ptr = NULL;
14096 char *devnm = NULL;
14097 uint64_t wwid = 0;
14098 uint8_t phy = 0xFF;
14099 int lun = 0;
14100 uint_t mflags = flag;
14101 int bconfig = TRUE;
14102
14103 if (scsi_hba_iport_unit_address(pdip) == 0) {
14104 return (DDI_FAILURE);
14105 }
14106
14107 mpt = DIP2MPT(pdip);
14108 if (!mpt) {
14109 return (DDI_FAILURE);
14110 }
14111 /*
14112 * Hold the nexus across the bus_config
14113 */
14114 ndi_devi_enter(scsi_vhci_dip, &circ);
14115 ndi_devi_enter(pdip, &circ1);
14116 switch (op) {
14117 case BUS_CONFIG_ONE:
14118 /* parse wwid/target name out of name given */
14119 if ((ptr = strchr((char *)arg, '@')) == NULL) {
14120 ret = NDI_FAILURE;
14121 break;
14122 }
14123 ptr++;
14124 if (strncmp((char *)arg, "smp", 3) == 0) {
14125 /*
14126 * This is a SMP target device
14127 */
14128 ret = mptsas_parse_smp_name(ptr, &wwid);
14129 if (ret != DDI_SUCCESS) {
14130 ret = NDI_FAILURE;
14131 break;
14132 }
14133 ret = mptsas_config_smp(pdip, wwid, childp);
14134 } else if ((ptr[0] == 'w') || (ptr[0] == 'p')) {
14135 /*
14136 * OBP could pass down a non-canonical form
14137 * bootpath without LUN part when LUN is 0.
14138 * So driver need adjust the string.
14139 */
14140 if (strchr(ptr, ',') == NULL) {
14141 devnm = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
14142 (void) sprintf(devnm, "%s,0", (char *)arg);
14143 ptr = strchr(devnm, '@');
14144 ptr++;
14145 }
14146
14147 /*
14148 * The device path is wWWID format and the device
14149 * is not SMP target device.
14150 */
14151 ret = mptsas_parse_address(ptr, &wwid, &phy, &lun);
14152 if (ret != DDI_SUCCESS) {
14153 ret = NDI_FAILURE;
14154 break;
14155 }
14156 *childp = NULL;
14157 if (ptr[0] == 'w') {
14158 ret = mptsas_config_one_addr(pdip, wwid,
14159 lun, childp);
14160 } else if (ptr[0] == 'p') {
14161 ret = mptsas_config_one_phy(pdip, phy, lun,
14162 childp);
14163 }
14164
14165 /*
14166 * If this is CD/DVD device in OBP path, the
14167 * ndi_busop_bus_config can be skipped as config one
14168 * operation is done above.
14169 */
14170 if ((ret == NDI_SUCCESS) && (*childp != NULL) &&
14171 (strcmp(ddi_node_name(*childp), "cdrom") == 0) &&
14172 (strncmp((char *)arg, "disk", 4) == 0)) {
14173 bconfig = FALSE;
14174 ndi_hold_devi(*childp);
14175 }
14176 } else {
14177 ret = NDI_FAILURE;
14178 break;
14179 }
14180
14181 /*
14182 * DDI group instructed us to use this flag.
14183 */
14184 mflags |= NDI_MDI_FALLBACK;
14185 break;
14186 case BUS_CONFIG_DRIVER:
14187 case BUS_CONFIG_ALL:
14188 mptsas_config_all(pdip);
14189 ret = NDI_SUCCESS;
14190 break;
14191 }
14192
14193 if ((ret == NDI_SUCCESS) && bconfig) {
14194 ret = ndi_busop_bus_config(pdip, mflags, op,
14195 (devnm == NULL) ? arg : devnm, childp, 0);
14196 }
14197
14198 ndi_devi_exit(pdip, circ1);
14199 ndi_devi_exit(scsi_vhci_dip, circ);
14200 if (devnm != NULL)
14201 kmem_free(devnm, SCSI_MAXNAMELEN);
14202 return (ret);
14203 }
14204
14205 static int
14206 mptsas_probe_lun(dev_info_t *pdip, int lun, dev_info_t **dip,
14207 mptsas_target_t *ptgt)
14208 {
14209 int rval = DDI_FAILURE;
14210 struct scsi_inquiry *sd_inq = NULL;
14211 mptsas_t *mpt = DIP2MPT(pdip);
14212
14213 sd_inq = (struct scsi_inquiry *)kmem_alloc(SUN_INQSIZE, KM_SLEEP);
14214
14215 rval = mptsas_inquiry(mpt, ptgt, lun, 0, (uchar_t *)sd_inq,
14216 SUN_INQSIZE, 0, (uchar_t)0);
14217
14218 if ((rval == DDI_SUCCESS) && MPTSAS_VALID_LUN(sd_inq)) {
14219 rval = mptsas_create_lun(pdip, sd_inq, dip, ptgt, lun);
14220 } else {
14221 rval = DDI_FAILURE;
14222 }
14223
14224 kmem_free(sd_inq, SUN_INQSIZE);
14225 return (rval);
14226 }
14227
14228 static int
14229 mptsas_config_one_addr(dev_info_t *pdip, uint64_t sasaddr, int lun,
14230 dev_info_t **lundip)
14231 {
14232 int rval;
14233 mptsas_t *mpt = DIP2MPT(pdip);
14234 int phymask;
14235 mptsas_target_t *ptgt = NULL;
14236
14237 /*
14238 * Get the physical port associated to the iport
14239 */
14240 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
14241 "phymask", 0);
14242
14243 ptgt = mptsas_wwid_to_ptgt(mpt, phymask, sasaddr);
14244 if (ptgt == NULL) {
14245 /*
14246 * didn't match any device by searching
14247 */
14248 return (DDI_FAILURE);
14249 }
14250 /*
14251 * If the LUN already exists and the status is online,
14252 * we just return the pointer to dev_info_t directly.
14253 * For the mdi_pathinfo node, we'll handle it in
14254 * mptsas_create_virt_lun()
14255 * TODO should be also in mptsas_handle_dr
14256 */
14257
14258 *lundip = mptsas_find_child_addr(pdip, sasaddr, lun);
14259 if (*lundip != NULL) {
14260 /*
14261 * TODO Another senario is, we hotplug the same disk
14262 * on the same slot, the devhdl changed, is this
14263 * possible?
14264 * tgt_private->t_private != ptgt
14265 */
14266 if (sasaddr != ptgt->m_addr.mta_wwn) {
14267 /*
14268 * The device has changed although the devhdl is the
14269 * same (Enclosure mapping mode, change drive on the
14270 * same slot)
14271 */
14272 return (DDI_FAILURE);
14273 }
14274 return (DDI_SUCCESS);
14275 }
14276
14277 if (phymask == 0) {
14278 /*
14279 * Configure IR volume
14280 */
14281 rval = mptsas_config_raid(pdip, ptgt->m_devhdl, lundip);
14282 return (rval);
14283 }
14284 rval = mptsas_probe_lun(pdip, lun, lundip, ptgt);
14285
14286 return (rval);
14287 }
14288
14289 static int
14290 mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun,
14291 dev_info_t **lundip)
14292 {
14293 int rval;
14294 mptsas_t *mpt = DIP2MPT(pdip);
14295 mptsas_phymask_t phymask;
14296 mptsas_target_t *ptgt = NULL;
14297
14298 /*
14299 * Get the physical port associated to the iport
14300 */
14301 phymask = (mptsas_phymask_t)ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
14302 "phymask", 0);
14303
14304 ptgt = mptsas_phy_to_tgt(mpt, phymask, phy);
14305 if (ptgt == NULL) {
14306 /*
14307 * didn't match any device by searching
14308 */
14309 return (DDI_FAILURE);
14310 }
14311
14312 /*
14313 * If the LUN already exists and the status is online,
14314 * we just return the pointer to dev_info_t directly.
14315 * For the mdi_pathinfo node, we'll handle it in
14316 * mptsas_create_virt_lun().
14317 */
14318
14319 *lundip = mptsas_find_child_phy(pdip, phy);
14320 if (*lundip != NULL) {
14321 return (DDI_SUCCESS);
14322 }
14323
14324 rval = mptsas_probe_lun(pdip, lun, lundip, ptgt);
14325
14326 return (rval);
14327 }
14328
14329 static int
14330 mptsas_retrieve_lundata(int lun_cnt, uint8_t *buf, uint16_t *lun_num,
14331 uint8_t *lun_addr_type)
14332 {
14333 uint32_t lun_idx = 0;
14334
14335 ASSERT(lun_num != NULL);
14336 ASSERT(lun_addr_type != NULL);
14337
14338 lun_idx = (lun_cnt + 1) * MPTSAS_SCSI_REPORTLUNS_ADDRESS_SIZE;
14339 /* determine report luns addressing type */
14340 switch (buf[lun_idx] & MPTSAS_SCSI_REPORTLUNS_ADDRESS_MASK) {
14341 /*
14342 * Vendors in the field have been found to be concatenating
14343 * bus/target/lun to equal the complete lun value instead
14344 * of switching to flat space addressing
14345 */
14346 /* 00b - peripheral device addressing method */
14347 case MPTSAS_SCSI_REPORTLUNS_ADDRESS_PERIPHERAL:
14348 /* FALLTHRU */
14349 /* 10b - logical unit addressing method */
14350 case MPTSAS_SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT:
14351 /* FALLTHRU */
14352 /* 01b - flat space addressing method */
14353 case MPTSAS_SCSI_REPORTLUNS_ADDRESS_FLAT_SPACE:
14354 /* byte0 bit0-5=msb lun byte1 bit0-7=lsb lun */
14355 *lun_addr_type = (buf[lun_idx] &
14356 MPTSAS_SCSI_REPORTLUNS_ADDRESS_MASK) >> 6;
14357 *lun_num = (buf[lun_idx] & 0x3F) << 8;
14358 *lun_num |= buf[lun_idx + 1];
14359 return (DDI_SUCCESS);
14360 default:
14361 return (DDI_FAILURE);
14362 }
14363 }
14364
14365 static int
14366 mptsas_config_luns(dev_info_t *pdip, mptsas_target_t *ptgt)
14367 {
14368 struct buf *repluns_bp = NULL;
14369 struct scsi_address ap;
14370 uchar_t cdb[CDB_GROUP5];
14371 int ret = DDI_FAILURE;
14372 int retry = 0;
14373 int lun_list_len = 0;
14374 uint16_t lun_num = 0;
14375 uint8_t lun_addr_type = 0;
14376 uint32_t lun_cnt = 0;
14377 uint32_t lun_total = 0;
14378 dev_info_t *cdip = NULL;
14379 uint16_t *saved_repluns = NULL;
14380 char *buffer = NULL;
14381 int buf_len = 128;
14382 mptsas_t *mpt = DIP2MPT(pdip);
14383 uint64_t sas_wwn = 0;
14384 uint8_t phy = 0xFF;
14385 uint32_t dev_info = 0;
14386
14387 mutex_enter(&mpt->m_mutex);
14388 sas_wwn = ptgt->m_addr.mta_wwn;
14389 phy = ptgt->m_phynum;
14390 dev_info = ptgt->m_deviceinfo;
14391 mutex_exit(&mpt->m_mutex);
14392
14393 if (sas_wwn == 0) {
14394 /*
14395 * It's a SATA without Device Name
14396 * So don't try multi-LUNs
14397 */
14398 if (mptsas_find_child_phy(pdip, phy)) {
14399 return (DDI_SUCCESS);
14400 } else {
14401 /*
14402 * need configure and create node
14403 */
14404 return (DDI_FAILURE);
14405 }
14406 }
14407
14408 /*
14409 * WWN (SAS address or Device Name exist)
14410 */
14411 if (dev_info & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
14412 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
14413 /*
14414 * SATA device with Device Name
14415 * So don't try multi-LUNs
14416 */
14417 if (mptsas_find_child_addr(pdip, sas_wwn, 0)) {
14418 return (DDI_SUCCESS);
14419 } else {
14420 return (DDI_FAILURE);
14421 }
14422 }
14423
14424 do {
14425 ap.a_target = MPTSAS_INVALID_DEVHDL;
14426 ap.a_lun = 0;
14427 ap.a_hba_tran = mpt->m_tran;
14428 repluns_bp = scsi_alloc_consistent_buf(&ap,
14429 (struct buf *)NULL, buf_len, B_READ, NULL_FUNC, NULL);
14430 if (repluns_bp == NULL) {
14431 retry++;
14432 continue;
14433 }
14434 bzero(cdb, CDB_GROUP5);
14435 cdb[0] = SCMD_REPORT_LUNS;
14436 cdb[6] = (buf_len & 0xff000000) >> 24;
14437 cdb[7] = (buf_len & 0x00ff0000) >> 16;
14438 cdb[8] = (buf_len & 0x0000ff00) >> 8;
14439 cdb[9] = (buf_len & 0x000000ff);
14440
14441 ret = mptsas_send_scsi_cmd(mpt, &ap, ptgt, &cdb[0], CDB_GROUP5,
14442 repluns_bp, NULL);
14443 if (ret != DDI_SUCCESS) {
14444 scsi_free_consistent_buf(repluns_bp);
14445 retry++;
14446 continue;
14447 }
14448 lun_list_len = BE_32(*(int *)((void *)(
14449 repluns_bp->b_un.b_addr)));
14450 if (buf_len >= lun_list_len + 8) {
14451 ret = DDI_SUCCESS;
14452 break;
14453 }
14454 scsi_free_consistent_buf(repluns_bp);
14455 buf_len = lun_list_len + 8;
14456
14457 } while (retry < 3);
14458
14459 if (ret != DDI_SUCCESS)
14460 return (ret);
14461 buffer = (char *)repluns_bp->b_un.b_addr;
14462 /*
14463 * find out the number of luns returned by the SCSI ReportLun call
14464 * and allocate buffer space
14465 */
14466 lun_total = lun_list_len / MPTSAS_SCSI_REPORTLUNS_ADDRESS_SIZE;
14467 saved_repluns = kmem_zalloc(sizeof (uint16_t) * lun_total, KM_SLEEP);
14468 if (saved_repluns == NULL) {
14469 scsi_free_consistent_buf(repluns_bp);
14470 return (DDI_FAILURE);
14471 }
14472 for (lun_cnt = 0; lun_cnt < lun_total; lun_cnt++) {
14473 if (mptsas_retrieve_lundata(lun_cnt, (uint8_t *)(buffer),
14474 &lun_num, &lun_addr_type) != DDI_SUCCESS) {
14475 continue;
14476 }
14477 saved_repluns[lun_cnt] = lun_num;
14478 if (cdip = mptsas_find_child_addr(pdip, sas_wwn, lun_num))
14479 ret = DDI_SUCCESS;
14480 else
14481 ret = mptsas_probe_lun(pdip, lun_num, &cdip,
14482 ptgt);
14483 if ((ret == DDI_SUCCESS) && (cdip != NULL)) {
14484 (void) ndi_prop_remove(DDI_DEV_T_NONE, cdip,
14485 MPTSAS_DEV_GONE);
14486 }
14487 }
14488 mptsas_offline_missed_luns(pdip, saved_repluns, lun_total, ptgt);
14489 kmem_free(saved_repluns, sizeof (uint16_t) * lun_total);
14490 scsi_free_consistent_buf(repluns_bp);
14491 return (DDI_SUCCESS);
14492 }
14493
14494 static int
14495 mptsas_config_raid(dev_info_t *pdip, uint16_t target, dev_info_t **dip)
14496 {
14497 int rval = DDI_FAILURE;
14498 struct scsi_inquiry *sd_inq = NULL;
14499 mptsas_t *mpt = DIP2MPT(pdip);
14500 mptsas_target_t *ptgt = NULL;
14501
14502 mutex_enter(&mpt->m_mutex);
14503 ptgt = refhash_linear_search(mpt->m_targets,
14504 mptsas_target_eval_devhdl, &target);
14505 mutex_exit(&mpt->m_mutex);
14506 if (ptgt == NULL) {
14507 mptsas_log(mpt, CE_WARN, "Volume with VolDevHandle of 0x%x "
14508 "not found.", target);
14509 return (rval);
14510 }
14511
14512 sd_inq = (struct scsi_inquiry *)kmem_alloc(SUN_INQSIZE, KM_SLEEP);
14513 rval = mptsas_inquiry(mpt, ptgt, 0, 0, (uchar_t *)sd_inq,
14514 SUN_INQSIZE, 0, (uchar_t)0);
14515
14516 if ((rval == DDI_SUCCESS) && MPTSAS_VALID_LUN(sd_inq)) {
14517 rval = mptsas_create_phys_lun(pdip, sd_inq, NULL, dip, ptgt,
14518 0);
14519 } else {
14520 rval = DDI_FAILURE;
14521 }
14522
14523 kmem_free(sd_inq, SUN_INQSIZE);
14524 return (rval);
14525 }
14526
14527 /*
14528 * configure all RAID volumes for virtual iport
14529 */
14530 static void
14531 mptsas_config_all_viport(dev_info_t *pdip)
14532 {
14533 mptsas_t *mpt = DIP2MPT(pdip);
14534 int config, vol;
14535 int target;
14536 dev_info_t *lundip = NULL;
14537
14538 /*
14539 * Get latest RAID info and search for any Volume DevHandles. If any
14540 * are found, configure the volume.
14541 */
14542 mutex_enter(&mpt->m_mutex);
14543 for (config = 0; config < mpt->m_num_raid_configs; config++) {
14544 for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) {
14545 if (mpt->m_raidconfig[config].m_raidvol[vol].m_israid
14546 == 1) {
14547 target = mpt->m_raidconfig[config].
14548 m_raidvol[vol].m_raidhandle;
14549 mutex_exit(&mpt->m_mutex);
14550 (void) mptsas_config_raid(pdip, target,
14551 &lundip);
14552 mutex_enter(&mpt->m_mutex);
14553 }
14554 }
14555 }
14556 mutex_exit(&mpt->m_mutex);
14557 }
14558
14559 static void
14560 mptsas_offline_missed_luns(dev_info_t *pdip, uint16_t *repluns,
14561 int lun_cnt, mptsas_target_t *ptgt)
14562 {
14563 dev_info_t *child = NULL, *savechild = NULL;
14564 mdi_pathinfo_t *pip = NULL, *savepip = NULL;
14565 uint64_t sas_wwn, wwid;
14566 uint8_t phy;
14567 int lun;
14568 int i;
14569 int find;
14570 char *addr;
14571 char *nodename;
14572 mptsas_t *mpt = DIP2MPT(pdip);
14573
14574 mutex_enter(&mpt->m_mutex);
14575 wwid = ptgt->m_addr.mta_wwn;
14576 mutex_exit(&mpt->m_mutex);
14577
14578 child = ddi_get_child(pdip);
14579 while (child) {
14580 find = 0;
14581 savechild = child;
14582 child = ddi_get_next_sibling(child);
14583
14584 nodename = ddi_node_name(savechild);
14585 if (strcmp(nodename, "smp") == 0) {
14586 continue;
14587 }
14588
14589 addr = ddi_get_name_addr(savechild);
14590 if (addr == NULL) {
14591 continue;
14592 }
14593
14594 if (mptsas_parse_address(addr, &sas_wwn, &phy, &lun) !=
14595 DDI_SUCCESS) {
14596 continue;
14597 }
14598
14599 if (wwid == sas_wwn) {
14600 for (i = 0; i < lun_cnt; i++) {
14601 if (repluns[i] == lun) {
14602 find = 1;
14603 break;
14604 }
14605 }
14606 } else {
14607 continue;
14608 }
14609 if (find == 0) {
14610 /*
14611 * The lun has not been there already
14612 */
14613 (void) mptsas_offline_lun(pdip, savechild, NULL,
14614 NDI_DEVI_REMOVE);
14615 }
14616 }
14617
14618 pip = mdi_get_next_client_path(pdip, NULL);
14619 while (pip) {
14620 find = 0;
14621 savepip = pip;
14622 addr = MDI_PI(pip)->pi_addr;
14623
14624 pip = mdi_get_next_client_path(pdip, pip);
14625
14626 if (addr == NULL) {
14627 continue;
14628 }
14629
14630 if (mptsas_parse_address(addr, &sas_wwn, &phy,
14631 &lun) != DDI_SUCCESS) {
14632 continue;
14633 }
14634
14635 if (sas_wwn == wwid) {
14636 for (i = 0; i < lun_cnt; i++) {
14637 if (repluns[i] == lun) {
14638 find = 1;
14639 break;
14640 }
14641 }
14642 } else {
14643 continue;
14644 }
14645
14646 if (find == 0) {
14647 /*
14648 * The lun has not been there already
14649 */
14650 (void) mptsas_offline_lun(pdip, NULL, savepip,
14651 NDI_DEVI_REMOVE);
14652 }
14653 }
14654 }
14655
14656 /*
14657 * If this enclosure doesn't exist in the enclosure list, add it. If it does,
14658 * update it.
14659 */
14660 static void
14661 mptsas_enclosure_update(mptsas_t *mpt, mptsas_enclosure_t *mep)
14662 {
14663 mptsas_enclosure_t *m;
14664
14665 ASSERT(MUTEX_HELD(&mpt->m_mutex));
14666 m = mptsas_enc_lookup(mpt, mep->me_enchdl);
14667 if (m != NULL) {
14668 m->me_flags = mep->me_flags;
14669 return;
14670 }
14671
14672 m = kmem_zalloc(sizeof (*m), KM_SLEEP);
14673 m->me_enchdl = mep->me_enchdl;
14674 m->me_flags = mep->me_flags;
14675 list_insert_tail(&mpt->m_enclosures, m);
14676 }
14677
14678 static void
14679 mptsas_update_hashtab(struct mptsas *mpt)
14680 {
14681 uint32_t page_address;
14682 int rval = 0;
14683 uint16_t dev_handle;
14684 mptsas_target_t *ptgt = NULL;
14685 mptsas_smp_t smp_node;
14686
14687 /*
14688 * Get latest RAID info.
14689 */
14690 (void) mptsas_get_raid_info(mpt);
14691
14692 dev_handle = mpt->m_smp_devhdl;
14693 while (mpt->m_done_traverse_smp == 0) {
14694 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL &
14695 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)dev_handle;
14696 if (mptsas_get_sas_expander_page0(mpt, page_address, &smp_node)
14697 != DDI_SUCCESS) {
14698 break;
14699 }
14700 mpt->m_smp_devhdl = dev_handle = smp_node.m_devhdl;
14701 (void) mptsas_smp_alloc(mpt, &smp_node);
14702 }
14703
14704 /*
14705 * Loop over enclosures so we can understand what's there.
14706 */
14707 dev_handle = MPTSAS_INVALID_DEVHDL;
14708 while (mpt->m_done_traverse_enc == 0) {
14709 mptsas_enclosure_t me;
14710
14711 page_address = (MPI2_SAS_ENCLOS_PGAD_FORM_GET_NEXT_HANDLE &
14712 MPI2_SAS_ENCLOS_PGAD_FORM_MASK) | (uint32_t)dev_handle;
14713
14714 if (mptsas_get_enclosure_page0(mpt, page_address, &me) !=
14715 DDI_SUCCESS) {
14716 break;
14717 }
14718 dev_handle = me.me_enchdl;
14719 mptsas_enclosure_update(mpt, &me);
14720 }
14721
14722 /*
14723 * Config target devices
14724 */
14725 dev_handle = mpt->m_dev_handle;
14726
14727 /*
14728 * Loop to get sas device page 0 by GetNextHandle till the
14729 * the last handle. If the sas device is a SATA/SSP target,
14730 * we try to config it.
14731 */
14732 while (mpt->m_done_traverse_dev == 0) {
14733 ptgt = NULL;
14734 page_address =
14735 (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE &
14736 MPI2_SAS_DEVICE_PGAD_FORM_MASK) |
14737 (uint32_t)dev_handle;
14738 rval = mptsas_get_target_device_info(mpt, page_address,
14739 &dev_handle, &ptgt);
14740 if ((rval == DEV_INFO_FAIL_PAGE0) ||
14741 (rval == DEV_INFO_FAIL_ALLOC) ||
14742 (rval == DEV_INFO_FAIL_GUID)) {
14743 break;
14744 }
14745
14746 mpt->m_dev_handle = dev_handle;
14747 }
14748
14749 }
14750
14751 void
14752 mptsas_update_driver_data(struct mptsas *mpt)
14753 {
14754 mptsas_target_t *tp;
14755 mptsas_smp_t *sp;
14756
14757 ASSERT(MUTEX_HELD(&mpt->m_mutex));
14758
14759 /*
14760 * TODO after hard reset, update the driver data structures
14761 * 1. update port/phymask mapping table mpt->m_phy_info
14762 * 2. invalid all the entries in hash table
14763 * m_devhdl = 0xffff and m_deviceinfo = 0
14764 * 3. call sas_device_page/expander_page to update hash table
14765 */
14766 mptsas_update_phymask(mpt);
14767
14768 /*
14769 * Remove all the devhdls for existing entries but leave their
14770 * addresses alone. In update_hashtab() below, we'll find all
14771 * targets that are still present and reassociate them with
14772 * their potentially new devhdls. Leaving the targets around in
14773 * this fashion allows them to be used on the tx waitq even
14774 * while IOC reset is occurring.
14775 */
14776 for (tp = refhash_first(mpt->m_targets); tp != NULL;
14777 tp = refhash_next(mpt->m_targets, tp)) {
14778 tp->m_devhdl = MPTSAS_INVALID_DEVHDL;
14779 tp->m_deviceinfo = 0;
14780 tp->m_dr_flag = MPTSAS_DR_INACTIVE;
14781 }
14782 for (sp = refhash_first(mpt->m_smp_targets); sp != NULL;
14783 sp = refhash_next(mpt->m_smp_targets, sp)) {
14784 sp->m_devhdl = MPTSAS_INVALID_DEVHDL;
14785 sp->m_deviceinfo = 0;
14786 }
14787 mpt->m_done_traverse_dev = 0;
14788 mpt->m_done_traverse_smp = 0;
14789 mpt->m_done_traverse_enc = 0;
14790 mpt->m_dev_handle = mpt->m_smp_devhdl = MPTSAS_INVALID_DEVHDL;
14791 mptsas_update_hashtab(mpt);
14792 }
14793
14794 static void
14795 mptsas_config_all(dev_info_t *pdip)
14796 {
14797 dev_info_t *smpdip = NULL;
14798 mptsas_t *mpt = DIP2MPT(pdip);
14799 int phymask = 0;
14800 mptsas_phymask_t phy_mask;
14801 mptsas_target_t *ptgt = NULL;
14802 mptsas_smp_t *psmp;
14803
14804 /*
14805 * Get the phymask associated to the iport
14806 */
14807 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
14808 "phymask", 0);
14809
14810 /*
14811 * Enumerate RAID volumes here (phymask == 0).
14812 */
14813 if (phymask == 0) {
14814 mptsas_config_all_viport(pdip);
14815 return;
14816 }
14817
14818 mutex_enter(&mpt->m_mutex);
14819
14820 if (!mpt->m_done_traverse_dev || !mpt->m_done_traverse_smp ||
14821 !mpt->m_done_traverse_enc) {
14822 mptsas_update_hashtab(mpt);
14823 }
14824
14825 for (psmp = refhash_first(mpt->m_smp_targets); psmp != NULL;
14826 psmp = refhash_next(mpt->m_smp_targets, psmp)) {
14827 phy_mask = psmp->m_addr.mta_phymask;
14828 if (phy_mask == phymask) {
14829 smpdip = NULL;
14830 mutex_exit(&mpt->m_mutex);
14831 (void) mptsas_online_smp(pdip, psmp, &smpdip);
14832 mutex_enter(&mpt->m_mutex);
14833 }
14834 }
14835
14836 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
14837 ptgt = refhash_next(mpt->m_targets, ptgt)) {
14838 phy_mask = ptgt->m_addr.mta_phymask;
14839 if (phy_mask == phymask) {
14840 mutex_exit(&mpt->m_mutex);
14841 (void) mptsas_config_target(pdip, ptgt);
14842 mutex_enter(&mpt->m_mutex);
14843 }
14844 }
14845 mutex_exit(&mpt->m_mutex);
14846 }
14847
14848 static int
14849 mptsas_config_target(dev_info_t *pdip, mptsas_target_t *ptgt)
14850 {
14851 int rval = DDI_FAILURE;
14852 dev_info_t *tdip;
14853
14854 rval = mptsas_config_luns(pdip, ptgt);
14855 if (rval != DDI_SUCCESS) {
14856 /*
14857 * The return value means the SCMD_REPORT_LUNS
14858 * did not execute successfully. The target maybe
14859 * doesn't support such command.
14860 */
14861 rval = mptsas_probe_lun(pdip, 0, &tdip, ptgt);
14862 }
14863 return (rval);
14864 }
14865
14866 /*
14867 * Return fail if not all the childs/paths are freed.
14868 * if there is any path under the HBA, the return value will be always fail
14869 * because we didn't call mdi_pi_free for path
14870 */
14871 static int
14872 mptsas_offline_target(dev_info_t *pdip, char *name)
14873 {
14874 dev_info_t *child = NULL, *prechild = NULL;
14875 mdi_pathinfo_t *pip = NULL, *savepip = NULL;
14876 int tmp_rval, rval = DDI_SUCCESS;
14877 char *addr, *cp;
14878 size_t s;
14879 mptsas_t *mpt = DIP2MPT(pdip);
14880
14881 child = ddi_get_child(pdip);
14882 while (child) {
14883 addr = ddi_get_name_addr(child);
14884 prechild = child;
14885 child = ddi_get_next_sibling(child);
14886
14887 if (addr == NULL) {
14888 continue;
14889 }
14890 if ((cp = strchr(addr, ',')) == NULL) {
14891 continue;
14892 }
14893
14894 s = (uintptr_t)cp - (uintptr_t)addr;
14895
14896 if (strncmp(addr, name, s) != 0) {
14897 continue;
14898 }
14899
14900 tmp_rval = mptsas_offline_lun(pdip, prechild, NULL,
14901 NDI_DEVI_REMOVE);
14902 if (tmp_rval != DDI_SUCCESS) {
14903 rval = DDI_FAILURE;
14904 if (ndi_prop_create_boolean(DDI_DEV_T_NONE,
14905 prechild, MPTSAS_DEV_GONE) !=
14906 DDI_PROP_SUCCESS) {
14907 mptsas_log(mpt, CE_WARN, "mptsas driver "
14908 "unable to create property for "
14909 "SAS %s (MPTSAS_DEV_GONE)", addr);
14910 }
14911 }
14912 }
14913
14914 pip = mdi_get_next_client_path(pdip, NULL);
14915 while (pip) {
14916 addr = MDI_PI(pip)->pi_addr;
14917 savepip = pip;
14918 pip = mdi_get_next_client_path(pdip, pip);
14919 if (addr == NULL) {
14920 continue;
14921 }
14922
14923 if ((cp = strchr(addr, ',')) == NULL) {
14924 continue;
14925 }
14926
14927 s = (uintptr_t)cp - (uintptr_t)addr;
14928
14929 if (strncmp(addr, name, s) != 0) {
14930 continue;
14931 }
14932
14933 (void) mptsas_offline_lun(pdip, NULL, savepip,
14934 NDI_DEVI_REMOVE);
14935 /*
14936 * driver will not invoke mdi_pi_free, so path will not
14937 * be freed forever, return DDI_FAILURE.
14938 */
14939 rval = DDI_FAILURE;
14940 }
14941 return (rval);
14942 }
14943
14944 static int
14945 mptsas_offline_lun(dev_info_t *pdip, dev_info_t *rdip,
14946 mdi_pathinfo_t *rpip, uint_t flags)
14947 {
14948 int rval = DDI_FAILURE;
14949 char *devname;
14950 dev_info_t *cdip, *parent;
14951
14952 if (rpip != NULL) {
14953 parent = scsi_vhci_dip;
14954 cdip = mdi_pi_get_client(rpip);
14955 } else if (rdip != NULL) {
14956 parent = pdip;
14957 cdip = rdip;
14958 } else {
14959 return (DDI_FAILURE);
14960 }
14961
14962 /*
14963 * Make sure node is attached otherwise
14964 * it won't have related cache nodes to
14965 * clean up. i_ddi_devi_attached is
14966 * similiar to i_ddi_node_state(cdip) >=
14967 * DS_ATTACHED.
14968 */
14969 if (i_ddi_devi_attached(cdip)) {
14970
14971 /* Get full devname */
14972 devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP);
14973 (void) ddi_deviname(cdip, devname);
14974 /* Clean cache */
14975 (void) devfs_clean(parent, devname + 1,
14976 DV_CLEAN_FORCE);
14977 kmem_free(devname, MAXNAMELEN + 1);
14978 }
14979 if (rpip != NULL) {
14980 if (MDI_PI_IS_OFFLINE(rpip)) {
14981 rval = DDI_SUCCESS;
14982 } else {
14983 rval = mdi_pi_offline(rpip, 0);
14984 }
14985 } else {
14986 rval = ndi_devi_offline(cdip, flags);
14987 }
14988
14989 return (rval);
14990 }
14991
14992 static dev_info_t *
14993 mptsas_find_smp_child(dev_info_t *parent, char *str_wwn)
14994 {
14995 dev_info_t *child = NULL;
14996 char *smp_wwn = NULL;
14997
14998 child = ddi_get_child(parent);
14999 while (child) {
15000 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child,
15001 DDI_PROP_DONTPASS, SMP_WWN, &smp_wwn)
15002 != DDI_SUCCESS) {
15003 child = ddi_get_next_sibling(child);
15004 continue;
15005 }
15006
15007 if (strcmp(smp_wwn, str_wwn) == 0) {
15008 ddi_prop_free(smp_wwn);
15009 break;
15010 }
15011 child = ddi_get_next_sibling(child);
15012 ddi_prop_free(smp_wwn);
15013 }
15014 return (child);
15015 }
15016
15017 static int
15018 mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, uint_t flags)
15019 {
15020 int rval = DDI_FAILURE;
15021 char *devname;
15022 char wwn_str[MPTSAS_WWN_STRLEN];
15023 dev_info_t *cdip;
15024
15025 (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_addr.mta_wwn);
15026
15027 cdip = mptsas_find_smp_child(pdip, wwn_str);
15028
15029 if (cdip == NULL)
15030 return (DDI_SUCCESS);
15031
15032 /*
15033 * Make sure node is attached otherwise
15034 * it won't have related cache nodes to
15035 * clean up. i_ddi_devi_attached is
15036 * similiar to i_ddi_node_state(cdip) >=
15037 * DS_ATTACHED.
15038 */
15039 if (i_ddi_devi_attached(cdip)) {
15040
15041 /* Get full devname */
15042 devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP);
15043 (void) ddi_deviname(cdip, devname);
15044 /* Clean cache */
15045 (void) devfs_clean(pdip, devname + 1,
15046 DV_CLEAN_FORCE);
15047 kmem_free(devname, MAXNAMELEN + 1);
15048 }
15049
15050 rval = ndi_devi_offline(cdip, flags);
15051
15052 return (rval);
15053 }
15054
15055 static dev_info_t *
15056 mptsas_find_child(dev_info_t *pdip, char *name)
15057 {
15058 dev_info_t *child = NULL;
15059 char *rname = NULL;
15060 int rval = DDI_FAILURE;
15061
15062 rname = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
15063
15064 child = ddi_get_child(pdip);
15065 while (child) {
15066 rval = mptsas_name_child(child, rname, SCSI_MAXNAMELEN);
15067 if (rval != DDI_SUCCESS) {
15068 child = ddi_get_next_sibling(child);
15069 bzero(rname, SCSI_MAXNAMELEN);
15070 continue;
15071 }
15072
15073 if (strcmp(rname, name) == 0) {
15074 break;
15075 }
15076 child = ddi_get_next_sibling(child);
15077 bzero(rname, SCSI_MAXNAMELEN);
15078 }
15079
15080 kmem_free(rname, SCSI_MAXNAMELEN);
15081
15082 return (child);
15083 }
15084
15085
15086 static dev_info_t *
15087 mptsas_find_child_addr(dev_info_t *pdip, uint64_t sasaddr, int lun)
15088 {
15089 dev_info_t *child = NULL;
15090 char *name = NULL;
15091 char *addr = NULL;
15092
15093 name = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
15094 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
15095 (void) sprintf(name, "%016"PRIx64, sasaddr);
15096 (void) sprintf(addr, "w%s,%x", name, lun);
15097 child = mptsas_find_child(pdip, addr);
15098 kmem_free(name, SCSI_MAXNAMELEN);
15099 kmem_free(addr, SCSI_MAXNAMELEN);
15100 return (child);
15101 }
15102
15103 static dev_info_t *
15104 mptsas_find_child_phy(dev_info_t *pdip, uint8_t phy)
15105 {
15106 dev_info_t *child;
15107 char *addr;
15108
15109 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
15110 (void) sprintf(addr, "p%x,0", phy);
15111 child = mptsas_find_child(pdip, addr);
15112 kmem_free(addr, SCSI_MAXNAMELEN);
15113 return (child);
15114 }
15115
15116 static mdi_pathinfo_t *
15117 mptsas_find_path_phy(dev_info_t *pdip, uint8_t phy)
15118 {
15119 mdi_pathinfo_t *path;
15120 char *addr = NULL;
15121
15122 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
15123 (void) sprintf(addr, "p%x,0", phy);
15124 path = mdi_pi_find(pdip, NULL, addr);
15125 kmem_free(addr, SCSI_MAXNAMELEN);
15126 return (path);
15127 }
15128
15129 static mdi_pathinfo_t *
15130 mptsas_find_path_addr(dev_info_t *parent, uint64_t sasaddr, int lun)
15131 {
15132 mdi_pathinfo_t *path;
15133 char *name = NULL;
15134 char *addr = NULL;
15135
15136 name = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
15137 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
15138 (void) sprintf(name, "%016"PRIx64, sasaddr);
15139 (void) sprintf(addr, "w%s,%x", name, lun);
15140 path = mdi_pi_find(parent, NULL, addr);
15141 kmem_free(name, SCSI_MAXNAMELEN);
15142 kmem_free(addr, SCSI_MAXNAMELEN);
15143
15144 return (path);
15145 }
15146
15147 static int
15148 mptsas_create_lun(dev_info_t *pdip, struct scsi_inquiry *sd_inq,
15149 dev_info_t **lun_dip, mptsas_target_t *ptgt, int lun)
15150 {
15151 int i = 0;
15152 uchar_t *inq83 = NULL;
15153 int inq83_len1 = 0xFF;
15154 int inq83_len = 0;
15155 int rval = DDI_FAILURE;
15156 ddi_devid_t devid;
15157 char *guid = NULL;
15158 int target = ptgt->m_devhdl;
15159 mdi_pathinfo_t *pip = NULL;
15160 mptsas_t *mpt = DIP2MPT(pdip);
15161
15162 /*
15163 * For DVD/CD ROM and tape devices and optical
15164 * devices, we won't try to enumerate them under
15165 * scsi_vhci, so no need to try page83
15166 */
15167 if (sd_inq && (sd_inq->inq_dtype == DTYPE_RODIRECT ||
15168 sd_inq->inq_dtype == DTYPE_OPTICAL ||
15169 sd_inq->inq_dtype == DTYPE_ESI))
15170 goto create_lun;
15171
15172 /*
15173 * The LCA returns good SCSI status, but corrupt page 83 data the first
15174 * time it is queried. The solution is to keep trying to request page83
15175 * and verify the GUID is not (DDI_NOT_WELL_FORMED) in
15176 * mptsas_inq83_retry_timeout seconds. If the timeout expires, driver
15177 * give up to get VPD page at this stage and fail the enumeration.
15178 */
15179
15180 inq83 = kmem_zalloc(inq83_len1, KM_SLEEP);
15181
15182 for (i = 0; i < mptsas_inq83_retry_timeout; i++) {
15183 rval = mptsas_inquiry(mpt, ptgt, lun, 0x83, inq83,
15184 inq83_len1, &inq83_len, 1);
15185 if (rval != 0) {
15186 mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page "
15187 "0x83 for target:%x, lun:%x failed!", target, lun);
15188 if (mptsas_physical_bind_failed_page_83 != B_FALSE)
15189 goto create_lun;
15190 goto out;
15191 }
15192 /*
15193 * create DEVID from inquiry data
15194 */
15195 if ((rval = ddi_devid_scsi_encode(
15196 DEVID_SCSI_ENCODE_VERSION_LATEST, NULL, (uchar_t *)sd_inq,
15197 sizeof (struct scsi_inquiry), NULL, 0, inq83,
15198 (size_t)inq83_len, &devid)) == DDI_SUCCESS) {
15199 /*
15200 * extract GUID from DEVID
15201 */
15202 guid = ddi_devid_to_guid(devid);
15203
15204 /*
15205 * Do not enable MPXIO if the strlen(guid) is greater
15206 * than MPTSAS_MAX_GUID_LEN, this constrain would be
15207 * handled by framework later.
15208 */
15209 if (guid && (strlen(guid) > MPTSAS_MAX_GUID_LEN)) {
15210 ddi_devid_free_guid(guid);
15211 guid = NULL;
15212 if (mpt->m_mpxio_enable == TRUE) {
15213 mptsas_log(mpt, CE_NOTE, "!Target:%x, "
15214 "lun:%x doesn't have a valid GUID, "
15215 "multipathing for this drive is "
15216 "not enabled", target, lun);
15217 }
15218 }
15219
15220 /*
15221 * devid no longer needed
15222 */
15223 ddi_devid_free(devid);
15224 break;
15225 } else if (rval == DDI_NOT_WELL_FORMED) {
15226 /*
15227 * return value of ddi_devid_scsi_encode equal to
15228 * DDI_NOT_WELL_FORMED means DEVID_RETRY, it worth
15229 * to retry inquiry page 0x83 and get GUID.
15230 */
15231 NDBG20(("Not well formed devid, retry..."));
15232 delay(1 * drv_usectohz(1000000));
15233 continue;
15234 } else {
15235 mptsas_log(mpt, CE_WARN, "!Encode devid failed for "
15236 "path target:%x, lun:%x", target, lun);
15237 rval = DDI_FAILURE;
15238 goto create_lun;
15239 }
15240 }
15241
15242 if (i == mptsas_inq83_retry_timeout) {
15243 mptsas_log(mpt, CE_WARN, "!Repeated page83 requests timeout "
15244 "for path target:%x, lun:%x", target, lun);
15245 }
15246
15247 rval = DDI_FAILURE;
15248
15249 create_lun:
15250 if ((guid != NULL) && (mpt->m_mpxio_enable == TRUE)) {
15251 rval = mptsas_create_virt_lun(pdip, sd_inq, guid, lun_dip, &pip,
15252 ptgt, lun);
15253 }
15254 if (rval != DDI_SUCCESS) {
15255 rval = mptsas_create_phys_lun(pdip, sd_inq, guid, lun_dip,
15256 ptgt, lun);
15257
15258 }
15259 out:
15260 if (guid != NULL) {
15261 /*
15262 * guid no longer needed
15263 */
15264 ddi_devid_free_guid(guid);
15265 }
15266 if (inq83 != NULL)
15267 kmem_free(inq83, inq83_len1);
15268 return (rval);
15269 }
15270
15271 static int
15272 mptsas_create_virt_lun(dev_info_t *pdip, struct scsi_inquiry *inq, char *guid,
15273 dev_info_t **lun_dip, mdi_pathinfo_t **pip, mptsas_target_t *ptgt, int lun)
15274 {
15275 int target;
15276 char *nodename = NULL;
15277 char **compatible = NULL;
15278 int ncompatible = 0;
15279 int mdi_rtn = MDI_FAILURE;
15280 int rval = DDI_FAILURE;
15281 char *old_guid = NULL;
15282 mptsas_t *mpt = DIP2MPT(pdip);
15283 char *lun_addr = NULL;
15284 char *wwn_str = NULL;
15285 char *attached_wwn_str = NULL;
15286 char *component = NULL;
15287 uint8_t phy = 0xFF;
15288 uint64_t sas_wwn;
15289 int64_t lun64 = 0;
15290 uint32_t devinfo;
15291 uint16_t dev_hdl;
15292 uint16_t pdev_hdl;
15293 uint64_t dev_sas_wwn;
15294 uint64_t pdev_sas_wwn;
15295 uint32_t pdev_info;
15296 uint8_t physport;
15297 uint8_t phy_id;
15298 uint32_t page_address;
15299 uint16_t bay_num, enclosure, io_flags;
15300 char pdev_wwn_str[MPTSAS_WWN_STRLEN];
15301 uint32_t dev_info;
15302
15303 mutex_enter(&mpt->m_mutex);
15304 target = ptgt->m_devhdl;
15305 sas_wwn = ptgt->m_addr.mta_wwn;
15306 devinfo = ptgt->m_deviceinfo;
15307 phy = ptgt->m_phynum;
15308 mutex_exit(&mpt->m_mutex);
15309
15310 if (sas_wwn) {
15311 *pip = mptsas_find_path_addr(pdip, sas_wwn, lun);
15312 } else {
15313 *pip = mptsas_find_path_phy(pdip, phy);
15314 }
15315
15316 if (*pip != NULL) {
15317 *lun_dip = MDI_PI(*pip)->pi_client->ct_dip;
15318 ASSERT(*lun_dip != NULL);
15319 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, *lun_dip,
15320 (DDI_PROP_DONTPASS | DDI_PROP_NOTPROM),
15321 MDI_CLIENT_GUID_PROP, &old_guid) == DDI_SUCCESS) {
15322 if (strncmp(guid, old_guid, strlen(guid)) == 0) {
15323 /*
15324 * Same path back online again.
15325 */
15326 (void) ddi_prop_free(old_guid);
15327 if ((!MDI_PI_IS_ONLINE(*pip)) &&
15328 (!MDI_PI_IS_STANDBY(*pip)) &&
15329 (ptgt->m_tgt_unconfigured == 0)) {
15330 rval = mdi_pi_online(*pip, 0);
15331 mutex_enter(&mpt->m_mutex);
15332 ptgt->m_led_status = 0;
15333 (void) mptsas_flush_led_status(mpt,
15334 ptgt);
15335 mutex_exit(&mpt->m_mutex);
15336 } else {
15337 rval = DDI_SUCCESS;
15338 }
15339 if (rval != DDI_SUCCESS) {
15340 mptsas_log(mpt, CE_WARN, "path:target: "
15341 "%x, lun:%x online failed!", target,
15342 lun);
15343 *pip = NULL;
15344 *lun_dip = NULL;
15345 }
15346 return (rval);
15347 } else {
15348 /*
15349 * The GUID of the LUN has changed which maybe
15350 * because customer mapped another volume to the
15351 * same LUN.
15352 */
15353 mptsas_log(mpt, CE_WARN, "The GUID of the "
15354 "target:%x, lun:%x was changed, maybe "
15355 "because someone mapped another volume "
15356 "to the same LUN", target, lun);
15357 (void) ddi_prop_free(old_guid);
15358 if (!MDI_PI_IS_OFFLINE(*pip)) {
15359 rval = mdi_pi_offline(*pip, 0);
15360 if (rval != MDI_SUCCESS) {
15361 mptsas_log(mpt, CE_WARN, "path:"
15362 "target:%x, lun:%x offline "
15363 "failed!", target, lun);
15364 *pip = NULL;
15365 *lun_dip = NULL;
15366 return (DDI_FAILURE);
15367 }
15368 }
15369 if (mdi_pi_free(*pip, 0) != MDI_SUCCESS) {
15370 mptsas_log(mpt, CE_WARN, "path:target:"
15371 "%x, lun:%x free failed!", target,
15372 lun);
15373 *pip = NULL;
15374 *lun_dip = NULL;
15375 return (DDI_FAILURE);
15376 }
15377 }
15378 } else {
15379 mptsas_log(mpt, CE_WARN, "Can't get client-guid "
15380 "property for path:target:%x, lun:%x", target, lun);
15381 *pip = NULL;
15382 *lun_dip = NULL;
15383 return (DDI_FAILURE);
15384 }
15385 }
15386 scsi_hba_nodename_compatible_get(inq, NULL,
15387 inq->inq_dtype, NULL, &nodename, &compatible, &ncompatible);
15388
15389 /*
15390 * if nodename can't be determined then print a message and skip it
15391 */
15392 if (nodename == NULL) {
15393 mptsas_log(mpt, CE_WARN, "mptsas driver found no compatible "
15394 "driver for target%d lun %d dtype:0x%02x", target, lun,
15395 inq->inq_dtype);
15396 return (DDI_FAILURE);
15397 }
15398
15399 wwn_str = kmem_zalloc(MPTSAS_WWN_STRLEN, KM_SLEEP);
15400 /* The property is needed by MPAPI */
15401 (void) sprintf(wwn_str, "%016"PRIx64, sas_wwn);
15402
15403 lun_addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
15404 if (guid) {
15405 (void) sprintf(lun_addr, "w%s,%x", wwn_str, lun);
15406 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn);
15407 } else {
15408 (void) sprintf(lun_addr, "p%x,%x", phy, lun);
15409 (void) sprintf(wwn_str, "p%x", phy);
15410 }
15411
15412 mdi_rtn = mdi_pi_alloc_compatible(pdip, nodename,
15413 guid, lun_addr, compatible, ncompatible,
15414 0, pip);
15415 if (mdi_rtn == MDI_SUCCESS) {
15416
15417 if (mdi_prop_update_string(*pip, MDI_GUID,
15418 guid) != DDI_SUCCESS) {
15419 mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
15420 "create prop for target %d lun %d (MDI_GUID)",
15421 target, lun);
15422 mdi_rtn = MDI_FAILURE;
15423 goto virt_create_done;
15424 }
15425
15426 if (mdi_prop_update_int(*pip, LUN_PROP,
15427 lun) != DDI_SUCCESS) {
15428 mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
15429 "create prop for target %d lun %d (LUN_PROP)",
15430 target, lun);
15431 mdi_rtn = MDI_FAILURE;
15432 goto virt_create_done;
15433 }
15434 lun64 = (int64_t)lun;
15435 if (mdi_prop_update_int64(*pip, LUN64_PROP,
15436 lun64) != DDI_SUCCESS) {
15437 mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
15438 "create prop for target %d (LUN64_PROP)",
15439 target);
15440 mdi_rtn = MDI_FAILURE;
15441 goto virt_create_done;
15442 }
15443 if (mdi_prop_update_string_array(*pip, "compatible",
15444 compatible, ncompatible) !=
15445 DDI_PROP_SUCCESS) {
15446 mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
15447 "create prop for target %d lun %d (COMPATIBLE)",
15448 target, lun);
15449 mdi_rtn = MDI_FAILURE;
15450 goto virt_create_done;
15451 }
15452 if (sas_wwn && (mdi_prop_update_string(*pip,
15453 SCSI_ADDR_PROP_TARGET_PORT, wwn_str) != DDI_PROP_SUCCESS)) {
15454 mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
15455 "create prop for target %d lun %d "
15456 "(target-port)", target, lun);
15457 mdi_rtn = MDI_FAILURE;
15458 goto virt_create_done;
15459 } else if ((sas_wwn == 0) && (mdi_prop_update_int(*pip,
15460 "sata-phy", phy) != DDI_PROP_SUCCESS)) {
15461 /*
15462 * Direct attached SATA device without DeviceName
15463 */
15464 mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
15465 "create prop for SAS target %d lun %d "
15466 "(sata-phy)", target, lun);
15467 mdi_rtn = MDI_FAILURE;
15468 goto virt_create_done;
15469 }
15470 mutex_enter(&mpt->m_mutex);
15471
15472 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
15473 MPI2_SAS_DEVICE_PGAD_FORM_MASK) |
15474 (uint32_t)ptgt->m_devhdl;
15475 rval = mptsas_get_sas_device_page0(mpt, page_address,
15476 &dev_hdl, &dev_sas_wwn, &dev_info, &physport,
15477 &phy_id, &pdev_hdl, &bay_num, &enclosure, &io_flags);
15478 if (rval != DDI_SUCCESS) {
15479 mutex_exit(&mpt->m_mutex);
15480 mptsas_log(mpt, CE_WARN, "mptsas unable to get "
15481 "parent device for handle %d", page_address);
15482 mdi_rtn = MDI_FAILURE;
15483 goto virt_create_done;
15484 }
15485
15486 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
15487 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)pdev_hdl;
15488 rval = mptsas_get_sas_device_page0(mpt, page_address,
15489 &dev_hdl, &pdev_sas_wwn, &pdev_info, &physport,
15490 &phy_id, &pdev_hdl, &bay_num, &enclosure, &io_flags);
15491 if (rval != DDI_SUCCESS) {
15492 mutex_exit(&mpt->m_mutex);
15493 mptsas_log(mpt, CE_WARN, "mptsas unable to get"
15494 "device info for handle %d", page_address);
15495 mdi_rtn = MDI_FAILURE;
15496 goto virt_create_done;
15497 }
15498
15499 mutex_exit(&mpt->m_mutex);
15500
15501 /*
15502 * If this device direct attached to the controller
15503 * set the attached-port to the base wwid
15504 */
15505 if ((ptgt->m_deviceinfo & DEVINFO_DIRECT_ATTACHED)
15506 != DEVINFO_DIRECT_ATTACHED) {
15507 (void) sprintf(pdev_wwn_str, "w%016"PRIx64,
15508 pdev_sas_wwn);
15509 } else {
15510 /*
15511 * Update the iport's attached-port to guid
15512 */
15513 if (sas_wwn == 0) {
15514 (void) sprintf(wwn_str, "p%x", phy);
15515 } else {
15516 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn);
15517 }
15518 if (ddi_prop_update_string(DDI_DEV_T_NONE,
15519 pdip, SCSI_ADDR_PROP_ATTACHED_PORT, wwn_str) !=
15520 DDI_PROP_SUCCESS) {
15521 mptsas_log(mpt, CE_WARN,
15522 "mptsas unable to create "
15523 "property for iport target-port"
15524 " %s (sas_wwn)",
15525 wwn_str);
15526 mdi_rtn = MDI_FAILURE;
15527 goto virt_create_done;
15528 }
15529
15530 (void) sprintf(pdev_wwn_str, "w%016"PRIx64,
15531 mpt->un.m_base_wwid);
15532 }
15533
15534 if (IS_SATA_DEVICE(ptgt->m_deviceinfo)) {
15535 char uabuf[SCSI_WWN_BUFLEN];
15536
15537 if (scsi_wwn_to_wwnstr(dev_sas_wwn, 1, uabuf) == NULL) {
15538 mptsas_log(mpt, CE_WARN,
15539 "mptsas unable to format SATA bridge WWN");
15540 mdi_rtn = MDI_FAILURE;
15541 goto virt_create_done;
15542 }
15543
15544 if (mdi_prop_update_string(*pip,
15545 SCSI_ADDR_PROP_BRIDGE_PORT, uabuf) !=
15546 DDI_SUCCESS) {
15547 mptsas_log(mpt, CE_WARN,
15548 "mptsas unable to create SCSI bridge port "
15549 "property for SATA device");
15550 mdi_rtn = MDI_FAILURE;
15551 goto virt_create_done;
15552 }
15553 }
15554
15555 if (mdi_prop_update_string(*pip,
15556 SCSI_ADDR_PROP_ATTACHED_PORT, pdev_wwn_str) !=
15557 DDI_PROP_SUCCESS) {
15558 mptsas_log(mpt, CE_WARN, "mptsas unable to create "
15559 "property for iport attached-port %s (sas_wwn)",
15560 attached_wwn_str);
15561 mdi_rtn = MDI_FAILURE;
15562 goto virt_create_done;
15563 }
15564
15565
15566 if (inq->inq_dtype == 0) {
15567 component = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
15568 /*
15569 * set obp path for pathinfo
15570 */
15571 (void) snprintf(component, MAXPATHLEN,
15572 "disk@%s", lun_addr);
15573
15574 if (mdi_pi_pathname_obp_set(*pip, component) !=
15575 DDI_SUCCESS) {
15576 mptsas_log(mpt, CE_WARN, "mpt_sas driver "
15577 "unable to set obp-path for object %s",
15578 component);
15579 mdi_rtn = MDI_FAILURE;
15580 goto virt_create_done;
15581 }
15582 }
15583
15584 *lun_dip = MDI_PI(*pip)->pi_client->ct_dip;
15585 if (devinfo & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
15586 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
15587 if ((ndi_prop_update_int(DDI_DEV_T_NONE, *lun_dip,
15588 "pm-capable", 1)) !=
15589 DDI_PROP_SUCCESS) {
15590 mptsas_log(mpt, CE_WARN, "mptsas driver"
15591 "failed to create pm-capable "
15592 "property, target %d", target);
15593 mdi_rtn = MDI_FAILURE;
15594 goto virt_create_done;
15595 }
15596 }
15597 /*
15598 * Create the phy-num property
15599 */
15600 if (mdi_prop_update_int(*pip, "phy-num",
15601 ptgt->m_phynum) != DDI_SUCCESS) {
15602 mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
15603 "create phy-num property for target %d lun %d",
15604 target, lun);
15605 mdi_rtn = MDI_FAILURE;
15606 goto virt_create_done;
15607 }
15608 NDBG20(("new path:%s onlining,", MDI_PI(*pip)->pi_addr));
15609 mdi_rtn = mdi_pi_online(*pip, 0);
15610 if (mdi_rtn == MDI_SUCCESS) {
15611 mutex_enter(&mpt->m_mutex);
15612 ptgt->m_led_status = 0;
15613 (void) mptsas_flush_led_status(mpt, ptgt);
15614 mutex_exit(&mpt->m_mutex);
15615 }
15616 if (mdi_rtn == MDI_NOT_SUPPORTED) {
15617 mdi_rtn = MDI_FAILURE;
15618 }
15619 virt_create_done:
15620 if (*pip && mdi_rtn != MDI_SUCCESS) {
15621 (void) mdi_pi_free(*pip, 0);
15622 *pip = NULL;
15623 *lun_dip = NULL;
15624 }
15625 }
15626
15627 scsi_hba_nodename_compatible_free(nodename, compatible);
15628 if (lun_addr != NULL) {
15629 kmem_free(lun_addr, SCSI_MAXNAMELEN);
15630 }
15631 if (wwn_str != NULL) {
15632 kmem_free(wwn_str, MPTSAS_WWN_STRLEN);
15633 }
15634 if (component != NULL) {
15635 kmem_free(component, MAXPATHLEN);
15636 }
15637
15638 return ((mdi_rtn == MDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
15639 }
15640
15641 static int
15642 mptsas_create_phys_lun(dev_info_t *pdip, struct scsi_inquiry *inq,
15643 char *guid, dev_info_t **lun_dip, mptsas_target_t *ptgt, int lun)
15644 {
15645 int target;
15646 int rval;
15647 int ndi_rtn = NDI_FAILURE;
15648 uint64_t be_sas_wwn;
15649 char *nodename = NULL;
15650 char **compatible = NULL;
15651 int ncompatible = 0;
15652 int instance = 0;
15653 mptsas_t *mpt = DIP2MPT(pdip);
15654 char *wwn_str = NULL;
15655 char *component = NULL;
15656 char *attached_wwn_str = NULL;
15657 uint8_t phy = 0xFF;
15658 uint64_t sas_wwn;
15659 uint32_t devinfo;
15660 uint16_t dev_hdl;
15661 uint16_t pdev_hdl;
15662 uint64_t pdev_sas_wwn;
15663 uint64_t dev_sas_wwn;
15664 uint32_t pdev_info;
15665 uint8_t physport;
15666 uint8_t phy_id;
15667 uint32_t page_address;
15668 uint16_t bay_num, enclosure, io_flags;
15669 char pdev_wwn_str[MPTSAS_WWN_STRLEN];
15670 uint32_t dev_info;
15671 int64_t lun64 = 0;
15672
15673 mutex_enter(&mpt->m_mutex);
15674 target = ptgt->m_devhdl;
15675 sas_wwn = ptgt->m_addr.mta_wwn;
15676 devinfo = ptgt->m_deviceinfo;
15677 phy = ptgt->m_phynum;
15678 mutex_exit(&mpt->m_mutex);
15679
15680 /*
15681 * generate compatible property with binding-set "mpt"
15682 */
15683 scsi_hba_nodename_compatible_get(inq, NULL, inq->inq_dtype, NULL,
15684 &nodename, &compatible, &ncompatible);
15685
15686 /*
15687 * if nodename can't be determined then print a message and skip it
15688 */
15689 if (nodename == NULL) {
15690 mptsas_log(mpt, CE_WARN, "mptsas found no compatible driver "
15691 "for target %d lun %d", target, lun);
15692 return (DDI_FAILURE);
15693 }
15694
15695 ndi_rtn = ndi_devi_alloc(pdip, nodename,
15696 DEVI_SID_NODEID, lun_dip);
15697
15698 /*
15699 * if lun alloc success, set props
15700 */
15701 if (ndi_rtn == NDI_SUCCESS) {
15702
15703 if (ndi_prop_update_int(DDI_DEV_T_NONE,
15704 *lun_dip, LUN_PROP, lun) !=
15705 DDI_PROP_SUCCESS) {
15706 mptsas_log(mpt, CE_WARN, "mptsas unable to create "
15707 "property for target %d lun %d (LUN_PROP)",
15708 target, lun);
15709 ndi_rtn = NDI_FAILURE;
15710 goto phys_create_done;
15711 }
15712
15713 lun64 = (int64_t)lun;
15714 if (ndi_prop_update_int64(DDI_DEV_T_NONE,
15715 *lun_dip, LUN64_PROP, lun64) !=
15716 DDI_PROP_SUCCESS) {
15717 mptsas_log(mpt, CE_WARN, "mptsas unable to create "
15718 "property for target %d lun64 %d (LUN64_PROP)",
15719 target, lun);
15720 ndi_rtn = NDI_FAILURE;
15721 goto phys_create_done;
15722 }
15723 if (ndi_prop_update_string_array(DDI_DEV_T_NONE,
15724 *lun_dip, "compatible", compatible, ncompatible)
15725 != DDI_PROP_SUCCESS) {
15726 mptsas_log(mpt, CE_WARN, "mptsas unable to create "
15727 "property for target %d lun %d (COMPATIBLE)",
15728 target, lun);
15729 ndi_rtn = NDI_FAILURE;
15730 goto phys_create_done;
15731 }
15732
15733 /*
15734 * We need the SAS WWN for non-multipath devices, so
15735 * we'll use the same property as that multipathing
15736 * devices need to present for MPAPI. If we don't have
15737 * a WWN (e.g. parallel SCSI), don't create the prop.
15738 */
15739 wwn_str = kmem_zalloc(MPTSAS_WWN_STRLEN, KM_SLEEP);
15740 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn);
15741 if (sas_wwn && ndi_prop_update_string(DDI_DEV_T_NONE,
15742 *lun_dip, SCSI_ADDR_PROP_TARGET_PORT, wwn_str)
15743 != DDI_PROP_SUCCESS) {
15744 mptsas_log(mpt, CE_WARN, "mptsas unable to "
15745 "create property for SAS target %d lun %d "
15746 "(target-port)", target, lun);
15747 ndi_rtn = NDI_FAILURE;
15748 goto phys_create_done;
15749 }
15750
15751 be_sas_wwn = BE_64(sas_wwn);
15752 if (sas_wwn && ndi_prop_update_byte_array(
15753 DDI_DEV_T_NONE, *lun_dip, "port-wwn",
15754 (uchar_t *)&be_sas_wwn, 8) != DDI_PROP_SUCCESS) {
15755 mptsas_log(mpt, CE_WARN, "mptsas unable to "
15756 "create property for SAS target %d lun %d "
15757 "(port-wwn)", target, lun);
15758 ndi_rtn = NDI_FAILURE;
15759 goto phys_create_done;
15760 } else if ((sas_wwn == 0) && (ndi_prop_update_int(
15761 DDI_DEV_T_NONE, *lun_dip, "sata-phy", phy) !=
15762 DDI_PROP_SUCCESS)) {
15763 /*
15764 * Direct attached SATA device without DeviceName
15765 */
15766 mptsas_log(mpt, CE_WARN, "mptsas unable to "
15767 "create property for SAS target %d lun %d "
15768 "(sata-phy)", target, lun);
15769 ndi_rtn = NDI_FAILURE;
15770 goto phys_create_done;
15771 }
15772
15773 if (ndi_prop_create_boolean(DDI_DEV_T_NONE,
15774 *lun_dip, SAS_PROP) != DDI_PROP_SUCCESS) {
15775 mptsas_log(mpt, CE_WARN, "mptsas unable to"
15776 "create property for SAS target %d lun %d"
15777 " (SAS_PROP)", target, lun);
15778 ndi_rtn = NDI_FAILURE;
15779 goto phys_create_done;
15780 }
15781 if (guid && (ndi_prop_update_string(DDI_DEV_T_NONE,
15782 *lun_dip, NDI_GUID, guid) != DDI_SUCCESS)) {
15783 mptsas_log(mpt, CE_WARN, "mptsas unable "
15784 "to create guid property for target %d "
15785 "lun %d", target, lun);
15786 ndi_rtn = NDI_FAILURE;
15787 goto phys_create_done;
15788 }
15789
15790 /*
15791 * The following code is to set properties for SM-HBA support,
15792 * it doesn't apply to RAID volumes
15793 */
15794 if (ptgt->m_addr.mta_phymask == 0)
15795 goto phys_raid_lun;
15796
15797 mutex_enter(&mpt->m_mutex);
15798
15799 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
15800 MPI2_SAS_DEVICE_PGAD_FORM_MASK) |
15801 (uint32_t)ptgt->m_devhdl;
15802 rval = mptsas_get_sas_device_page0(mpt, page_address,
15803 &dev_hdl, &dev_sas_wwn, &dev_info,
15804 &physport, &phy_id, &pdev_hdl,
15805 &bay_num, &enclosure, &io_flags);
15806 if (rval != DDI_SUCCESS) {
15807 mutex_exit(&mpt->m_mutex);
15808 mptsas_log(mpt, CE_WARN, "mptsas unable to get"
15809 "parent device for handle %d.", page_address);
15810 ndi_rtn = NDI_FAILURE;
15811 goto phys_create_done;
15812 }
15813
15814 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
15815 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)pdev_hdl;
15816 rval = mptsas_get_sas_device_page0(mpt, page_address,
15817 &dev_hdl, &pdev_sas_wwn, &pdev_info, &physport,
15818 &phy_id, &pdev_hdl, &bay_num, &enclosure, &io_flags);
15819 if (rval != DDI_SUCCESS) {
15820 mutex_exit(&mpt->m_mutex);
15821 mptsas_log(mpt, CE_WARN, "mptsas unable to create "
15822 "device for handle %d.", page_address);
15823 ndi_rtn = NDI_FAILURE;
15824 goto phys_create_done;
15825 }
15826
15827 mutex_exit(&mpt->m_mutex);
15828
15829 /*
15830 * If this device direct attached to the controller
15831 * set the attached-port to the base wwid
15832 */
15833 if ((ptgt->m_deviceinfo & DEVINFO_DIRECT_ATTACHED)
15834 != DEVINFO_DIRECT_ATTACHED) {
15835 (void) sprintf(pdev_wwn_str, "w%016"PRIx64,
15836 pdev_sas_wwn);
15837 } else {
15838 /*
15839 * Update the iport's attached-port to guid
15840 */
15841 if (sas_wwn == 0) {
15842 (void) sprintf(wwn_str, "p%x", phy);
15843 } else {
15844 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn);
15845 }
15846 if (ddi_prop_update_string(DDI_DEV_T_NONE,
15847 pdip, SCSI_ADDR_PROP_ATTACHED_PORT, wwn_str) !=
15848 DDI_PROP_SUCCESS) {
15849 mptsas_log(mpt, CE_WARN,
15850 "mptsas unable to create "
15851 "property for iport target-port"
15852 " %s (sas_wwn)",
15853 wwn_str);
15854 ndi_rtn = NDI_FAILURE;
15855 goto phys_create_done;
15856 }
15857
15858 (void) sprintf(pdev_wwn_str, "w%016"PRIx64,
15859 mpt->un.m_base_wwid);
15860 }
15861
15862 if (ndi_prop_update_string(DDI_DEV_T_NONE,
15863 *lun_dip, SCSI_ADDR_PROP_ATTACHED_PORT, pdev_wwn_str) !=
15864 DDI_PROP_SUCCESS) {
15865 mptsas_log(mpt, CE_WARN,
15866 "mptsas unable to create "
15867 "property for iport attached-port %s (sas_wwn)",
15868 attached_wwn_str);
15869 ndi_rtn = NDI_FAILURE;
15870 goto phys_create_done;
15871 }
15872
15873 if (IS_SATA_DEVICE(dev_info)) {
15874 char uabuf[SCSI_WWN_BUFLEN];
15875
15876 if (ndi_prop_update_string(DDI_DEV_T_NONE,
15877 *lun_dip, MPTSAS_VARIANT, "sata") !=
15878 DDI_PROP_SUCCESS) {
15879 mptsas_log(mpt, CE_WARN,
15880 "mptsas unable to create "
15881 "property for device variant ");
15882 ndi_rtn = NDI_FAILURE;
15883 goto phys_create_done;
15884 }
15885
15886 if (scsi_wwn_to_wwnstr(dev_sas_wwn, 1, uabuf) == NULL) {
15887 mptsas_log(mpt, CE_WARN,
15888 "mptsas unable to format SATA bridge WWN");
15889 ndi_rtn = NDI_FAILURE;
15890 goto phys_create_done;
15891 }
15892
15893 if (ndi_prop_update_string(DDI_DEV_T_NONE, *lun_dip,
15894 SCSI_ADDR_PROP_BRIDGE_PORT, uabuf) !=
15895 DDI_PROP_SUCCESS) {
15896 mptsas_log(mpt, CE_WARN,
15897 "mptsas unable to create SCSI bridge port "
15898 "property for SATA device");
15899 ndi_rtn = NDI_FAILURE;
15900 goto phys_create_done;
15901 }
15902 }
15903
15904 if (IS_ATAPI_DEVICE(dev_info)) {
15905 if (ndi_prop_update_string(DDI_DEV_T_NONE,
15906 *lun_dip, MPTSAS_VARIANT, "atapi") !=
15907 DDI_PROP_SUCCESS) {
15908 mptsas_log(mpt, CE_WARN,
15909 "mptsas unable to create "
15910 "property for device variant ");
15911 ndi_rtn = NDI_FAILURE;
15912 goto phys_create_done;
15913 }
15914 }
15915
15916 phys_raid_lun:
15917 /*
15918 * if this is a SAS controller, and the target is a SATA
15919 * drive, set the 'pm-capable' property for sd and if on
15920 * an OPL platform, also check if this is an ATAPI
15921 * device.
15922 */
15923 instance = ddi_get_instance(mpt->m_dip);
15924 if (devinfo & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
15925 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
15926 NDBG2(("mptsas%d: creating pm-capable property, "
15927 "target %d", instance, target));
15928
15929 if ((ndi_prop_update_int(DDI_DEV_T_NONE,
15930 *lun_dip, "pm-capable", 1)) !=
15931 DDI_PROP_SUCCESS) {
15932 mptsas_log(mpt, CE_WARN, "mptsas "
15933 "failed to create pm-capable "
15934 "property, target %d", target);
15935 ndi_rtn = NDI_FAILURE;
15936 goto phys_create_done;
15937 }
15938
15939 }
15940
15941 if ((inq->inq_dtype == 0) || (inq->inq_dtype == 5)) {
15942 /*
15943 * add 'obp-path' properties for devinfo
15944 */
15945 bzero(wwn_str, sizeof (wwn_str));
15946 (void) sprintf(wwn_str, "%016"PRIx64, sas_wwn);
15947 component = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
15948 if (guid) {
15949 (void) snprintf(component, MAXPATHLEN,
15950 "disk@w%s,%x", wwn_str, lun);
15951 } else {
15952 (void) snprintf(component, MAXPATHLEN,
15953 "disk@p%x,%x", phy, lun);
15954 }
15955 if (ddi_pathname_obp_set(*lun_dip, component)
15956 != DDI_SUCCESS) {
15957 mptsas_log(mpt, CE_WARN, "mpt_sas driver "
15958 "unable to set obp-path for SAS "
15959 "object %s", component);
15960 ndi_rtn = NDI_FAILURE;
15961 goto phys_create_done;
15962 }
15963 }
15964 /*
15965 * Create the phy-num property for non-raid disk
15966 */
15967 if (ptgt->m_addr.mta_phymask != 0) {
15968 if (ndi_prop_update_int(DDI_DEV_T_NONE,
15969 *lun_dip, "phy-num", ptgt->m_phynum) !=
15970 DDI_PROP_SUCCESS) {
15971 mptsas_log(mpt, CE_WARN, "mptsas driver "
15972 "failed to create phy-num property for "
15973 "target %d", target);
15974 ndi_rtn = NDI_FAILURE;
15975 goto phys_create_done;
15976 }
15977 }
15978 phys_create_done:
15979 /*
15980 * If props were setup ok, online the lun
15981 */
15982 if (ndi_rtn == NDI_SUCCESS) {
15983 /*
15984 * Try to online the new node
15985 */
15986 ndi_rtn = ndi_devi_online(*lun_dip, NDI_ONLINE_ATTACH);
15987 }
15988 if (ndi_rtn == NDI_SUCCESS) {
15989 mutex_enter(&mpt->m_mutex);
15990 ptgt->m_led_status = 0;
15991 (void) mptsas_flush_led_status(mpt, ptgt);
15992 mutex_exit(&mpt->m_mutex);
15993 }
15994
15995 /*
15996 * If success set rtn flag, else unwire alloc'd lun
15997 */
15998 if (ndi_rtn != NDI_SUCCESS) {
15999 NDBG12(("mptsas driver unable to online "
16000 "target %d lun %d", target, lun));
16001 ndi_prop_remove_all(*lun_dip);
16002 (void) ndi_devi_free(*lun_dip);
16003 *lun_dip = NULL;
16004 }
16005 }
16006
16007 scsi_hba_nodename_compatible_free(nodename, compatible);
16008
16009 if (wwn_str != NULL) {
16010 kmem_free(wwn_str, MPTSAS_WWN_STRLEN);
16011 }
16012 if (component != NULL) {
16013 kmem_free(component, MAXPATHLEN);
16014 }
16015
16016
16017 return ((ndi_rtn == NDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
16018 }
16019
16020 static int
16021 mptsas_probe_smp(dev_info_t *pdip, uint64_t wwn)
16022 {
16023 mptsas_t *mpt = DIP2MPT(pdip);
16024 struct smp_device smp_sd;
16025
16026 /* XXX An HBA driver should not be allocating an smp_device. */
16027 bzero(&smp_sd, sizeof (struct smp_device));
16028 smp_sd.smp_sd_address.smp_a_hba_tran = mpt->m_smptran;
16029 bcopy(&wwn, smp_sd.smp_sd_address.smp_a_wwn, SAS_WWN_BYTE_SIZE);
16030
16031 if (smp_probe(&smp_sd) != DDI_PROBE_SUCCESS)
16032 return (NDI_FAILURE);
16033 return (NDI_SUCCESS);
16034 }
16035
16036 static int
16037 mptsas_config_smp(dev_info_t *pdip, uint64_t sas_wwn, dev_info_t **smp_dip)
16038 {
16039 mptsas_t *mpt = DIP2MPT(pdip);
16040 mptsas_smp_t *psmp = NULL;
16041 int rval;
16042 int phymask;
16043
16044 /*
16045 * Get the physical port associated to the iport
16046 * PHYMASK TODO
16047 */
16048 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
16049 "phymask", 0);
16050 /*
16051 * Find the smp node in hash table with specified sas address and
16052 * physical port
16053 */
16054 psmp = mptsas_wwid_to_psmp(mpt, phymask, sas_wwn);
16055 if (psmp == NULL) {
16056 return (DDI_FAILURE);
16057 }
16058
16059 rval = mptsas_online_smp(pdip, psmp, smp_dip);
16060
16061 return (rval);
16062 }
16063
16064 static int
16065 mptsas_online_smp(dev_info_t *pdip, mptsas_smp_t *smp_node,
16066 dev_info_t **smp_dip)
16067 {
16068 char wwn_str[MPTSAS_WWN_STRLEN];
16069 char attached_wwn_str[MPTSAS_WWN_STRLEN];
16070 int ndi_rtn = NDI_FAILURE;
16071 int rval = 0;
16072 mptsas_smp_t dev_info;
16073 uint32_t page_address;
16074 mptsas_t *mpt = DIP2MPT(pdip);
16075 uint16_t dev_hdl;
16076 uint64_t sas_wwn;
16077 uint64_t smp_sas_wwn;
16078 uint8_t physport;
16079 uint8_t phy_id;
16080 uint16_t pdev_hdl;
16081 uint8_t numphys = 0;
16082 uint16_t i = 0;
16083 char phymask[MPTSAS_MAX_PHYS];
16084 char *iport = NULL;
16085 mptsas_phymask_t phy_mask = 0;
16086 uint16_t attached_devhdl;
16087 uint16_t bay_num, enclosure, io_flags;
16088
16089 (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_addr.mta_wwn);
16090
16091 /*
16092 * Probe smp device, prevent the node of removed device from being
16093 * configured succesfully
16094 */
16095 if (mptsas_probe_smp(pdip, smp_node->m_addr.mta_wwn) != NDI_SUCCESS) {
16096 return (DDI_FAILURE);
16097 }
16098
16099 if ((*smp_dip = mptsas_find_smp_child(pdip, wwn_str)) != NULL) {
16100 return (DDI_SUCCESS);
16101 }
16102
16103 ndi_rtn = ndi_devi_alloc(pdip, "smp", DEVI_SID_NODEID, smp_dip);
16104
16105 /*
16106 * if lun alloc success, set props
16107 */
16108 if (ndi_rtn == NDI_SUCCESS) {
16109 /*
16110 * Set the flavor of the child to be SMP flavored
16111 */
16112 ndi_flavor_set(*smp_dip, SCSA_FLAVOR_SMP);
16113
16114 if (ndi_prop_update_string(DDI_DEV_T_NONE,
16115 *smp_dip, SMP_WWN, wwn_str) !=
16116 DDI_PROP_SUCCESS) {
16117 mptsas_log(mpt, CE_WARN, "mptsas unable to create "
16118 "property for smp device %s (sas_wwn)",
16119 wwn_str);
16120 ndi_rtn = NDI_FAILURE;
16121 goto smp_create_done;
16122 }
16123 (void) sprintf(wwn_str, "w%"PRIx64, smp_node->m_addr.mta_wwn);
16124 if (ndi_prop_update_string(DDI_DEV_T_NONE,
16125 *smp_dip, SCSI_ADDR_PROP_TARGET_PORT, wwn_str) !=
16126 DDI_PROP_SUCCESS) {
16127 mptsas_log(mpt, CE_WARN, "mptsas unable to create "
16128 "property for iport target-port %s (sas_wwn)",
16129 wwn_str);
16130 ndi_rtn = NDI_FAILURE;
16131 goto smp_create_done;
16132 }
16133
16134 mutex_enter(&mpt->m_mutex);
16135
16136 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_HNDL &
16137 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | smp_node->m_devhdl;
16138 rval = mptsas_get_sas_expander_page0(mpt, page_address,
16139 &dev_info);
16140 if (rval != DDI_SUCCESS) {
16141 mutex_exit(&mpt->m_mutex);
16142 mptsas_log(mpt, CE_WARN,
16143 "mptsas unable to get expander "
16144 "parent device info for %x", page_address);
16145 ndi_rtn = NDI_FAILURE;
16146 goto smp_create_done;
16147 }
16148
16149 smp_node->m_pdevhdl = dev_info.m_pdevhdl;
16150 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
16151 MPI2_SAS_DEVICE_PGAD_FORM_MASK) |
16152 (uint32_t)dev_info.m_pdevhdl;
16153 rval = mptsas_get_sas_device_page0(mpt, page_address,
16154 &dev_hdl, &sas_wwn, &smp_node->m_pdevinfo, &physport,
16155 &phy_id, &pdev_hdl, &bay_num, &enclosure, &io_flags);
16156 if (rval != DDI_SUCCESS) {
16157 mutex_exit(&mpt->m_mutex);
16158 mptsas_log(mpt, CE_WARN, "mptsas unable to get "
16159 "device info for %x", page_address);
16160 ndi_rtn = NDI_FAILURE;
16161 goto smp_create_done;
16162 }
16163
16164 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
16165 MPI2_SAS_DEVICE_PGAD_FORM_MASK) |
16166 (uint32_t)dev_info.m_devhdl;
16167 rval = mptsas_get_sas_device_page0(mpt, page_address,
16168 &dev_hdl, &smp_sas_wwn, &smp_node->m_deviceinfo,
16169 &physport, &phy_id, &pdev_hdl, &bay_num, &enclosure,
16170 &io_flags);
16171 if (rval != DDI_SUCCESS) {
16172 mutex_exit(&mpt->m_mutex);
16173 mptsas_log(mpt, CE_WARN, "mptsas unable to get "
16174 "device info for %x", page_address);
16175 ndi_rtn = NDI_FAILURE;
16176 goto smp_create_done;
16177 }
16178 mutex_exit(&mpt->m_mutex);
16179
16180 /*
16181 * If this smp direct attached to the controller
16182 * set the attached-port to the base wwid
16183 */
16184 if ((smp_node->m_deviceinfo & DEVINFO_DIRECT_ATTACHED)
16185 != DEVINFO_DIRECT_ATTACHED) {
16186 (void) sprintf(attached_wwn_str, "w%016"PRIx64,
16187 sas_wwn);
16188 } else {
16189 (void) sprintf(attached_wwn_str, "w%016"PRIx64,
16190 mpt->un.m_base_wwid);
16191 }
16192
16193 if (ndi_prop_update_string(DDI_DEV_T_NONE,
16194 *smp_dip, SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwn_str) !=
16195 DDI_PROP_SUCCESS) {
16196 mptsas_log(mpt, CE_WARN, "mptsas unable to create "
16197 "property for smp attached-port %s (sas_wwn)",
16198 attached_wwn_str);
16199 ndi_rtn = NDI_FAILURE;
16200 goto smp_create_done;
16201 }
16202
16203 if (ndi_prop_create_boolean(DDI_DEV_T_NONE,
16204 *smp_dip, SMP_PROP) != DDI_PROP_SUCCESS) {
16205 mptsas_log(mpt, CE_WARN, "mptsas unable to "
16206 "create property for SMP %s (SMP_PROP) ",
16207 wwn_str);
16208 ndi_rtn = NDI_FAILURE;
16209 goto smp_create_done;
16210 }
16211
16212 /*
16213 * check the smp to see whether it direct
16214 * attached to the controller
16215 */
16216 if ((smp_node->m_deviceinfo & DEVINFO_DIRECT_ATTACHED)
16217 != DEVINFO_DIRECT_ATTACHED) {
16218 goto smp_create_done;
16219 }
16220 numphys = ddi_prop_get_int(DDI_DEV_T_ANY, pdip,
16221 DDI_PROP_DONTPASS, MPTSAS_NUM_PHYS, -1);
16222 if (numphys > 0) {
16223 goto smp_create_done;
16224 }
16225 /*
16226 * this iport is an old iport, we need to
16227 * reconfig the props for it.
16228 */
16229 if (ddi_prop_update_int(DDI_DEV_T_NONE, pdip,
16230 MPTSAS_VIRTUAL_PORT, 0) !=
16231 DDI_PROP_SUCCESS) {
16232 (void) ddi_prop_remove(DDI_DEV_T_NONE, pdip,
16233 MPTSAS_VIRTUAL_PORT);
16234 mptsas_log(mpt, CE_WARN, "mptsas virtual port "
16235 "prop update failed");
16236 goto smp_create_done;
16237 }
16238
16239 mutex_enter(&mpt->m_mutex);
16240 numphys = 0;
16241 iport = ddi_get_name_addr(pdip);
16242 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
16243 bzero(phymask, sizeof (phymask));
16244 (void) sprintf(phymask,
16245 "%x", mpt->m_phy_info[i].phy_mask);
16246 if (strcmp(phymask, iport) == 0) {
16247 phy_mask = mpt->m_phy_info[i].phy_mask;
16248 break;
16249 }
16250 }
16251
16252 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
16253 if ((phy_mask >> i) & 0x01) {
16254 numphys++;
16255 }
16256 }
16257 /*
16258 * Update PHY info for smhba
16259 */
16260 if (mptsas_smhba_phy_init(mpt)) {
16261 mutex_exit(&mpt->m_mutex);
16262 mptsas_log(mpt, CE_WARN, "mptsas phy update "
16263 "failed");
16264 goto smp_create_done;
16265 }
16266 mutex_exit(&mpt->m_mutex);
16267
16268 mptsas_smhba_set_all_phy_props(mpt, pdip, numphys, phy_mask,
16269 &attached_devhdl);
16270
16271 if (ddi_prop_update_int(DDI_DEV_T_NONE, pdip,
16272 MPTSAS_NUM_PHYS, numphys) !=
16273 DDI_PROP_SUCCESS) {
16274 (void) ddi_prop_remove(DDI_DEV_T_NONE, pdip,
16275 MPTSAS_NUM_PHYS);
16276 mptsas_log(mpt, CE_WARN, "mptsas update "
16277 "num phys props failed");
16278 goto smp_create_done;
16279 }
16280 /*
16281 * Add parent's props for SMHBA support
16282 */
16283 if (ddi_prop_update_string(DDI_DEV_T_NONE, pdip,
16284 SCSI_ADDR_PROP_ATTACHED_PORT, wwn_str) !=
16285 DDI_PROP_SUCCESS) {
16286 (void) ddi_prop_remove(DDI_DEV_T_NONE, pdip,
16287 SCSI_ADDR_PROP_ATTACHED_PORT);
16288 mptsas_log(mpt, CE_WARN, "mptsas update iport"
16289 "attached-port failed");
16290 goto smp_create_done;
16291 }
16292
16293 smp_create_done:
16294 /*
16295 * If props were setup ok, online the lun
16296 */
16297 if (ndi_rtn == NDI_SUCCESS) {
16298 /*
16299 * Try to online the new node
16300 */
16301 ndi_rtn = ndi_devi_online(*smp_dip, NDI_ONLINE_ATTACH);
16302 }
16303
16304 /*
16305 * If success set rtn flag, else unwire alloc'd lun
16306 */
16307 if (ndi_rtn != NDI_SUCCESS) {
16308 NDBG12(("mptsas unable to online "
16309 "SMP target %s", wwn_str));
16310 ndi_prop_remove_all(*smp_dip);
16311 (void) ndi_devi_free(*smp_dip);
16312 }
16313 }
16314
16315 return ((ndi_rtn == NDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
16316 }
16317
16318 /* smp transport routine */
16319 static int mptsas_smp_start(struct smp_pkt *smp_pkt)
16320 {
16321 uint64_t wwn;
16322 Mpi2SmpPassthroughRequest_t req;
16323 Mpi2SmpPassthroughReply_t rep;
16324 uint32_t direction = 0;
16325 mptsas_t *mpt;
16326 int ret;
16327 uint64_t tmp64;
16328
16329 mpt = (mptsas_t *)smp_pkt->smp_pkt_address->
16330 smp_a_hba_tran->smp_tran_hba_private;
16331
16332 bcopy(smp_pkt->smp_pkt_address->smp_a_wwn, &wwn, SAS_WWN_BYTE_SIZE);
16333 /*
16334 * Need to compose a SMP request message
16335 * and call mptsas_do_passthru() function
16336 */
16337 bzero(&req, sizeof (req));
16338 bzero(&rep, sizeof (rep));
16339 req.PassthroughFlags = 0;
16340 req.PhysicalPort = 0xff;
16341 req.ChainOffset = 0;
16342 req.Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
16343
16344 if ((smp_pkt->smp_pkt_reqsize & 0xffff0000ul) != 0) {
16345 smp_pkt->smp_pkt_reason = ERANGE;
16346 return (DDI_FAILURE);
16347 }
16348 req.RequestDataLength = LE_16((uint16_t)(smp_pkt->smp_pkt_reqsize - 4));
16349
16350 req.MsgFlags = 0;
16351 tmp64 = LE_64(wwn);
16352 bcopy(&tmp64, &req.SASAddress, SAS_WWN_BYTE_SIZE);
16353 if (smp_pkt->smp_pkt_rspsize > 0) {
16354 direction |= MPTSAS_PASS_THRU_DIRECTION_READ;
16355 }
16356 if (smp_pkt->smp_pkt_reqsize > 0) {
16357 direction |= MPTSAS_PASS_THRU_DIRECTION_WRITE;
16358 }
16359
16360 mutex_enter(&mpt->m_mutex);
16361 ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep,
16362 (uint8_t *)smp_pkt->smp_pkt_rsp,
16363 offsetof(Mpi2SmpPassthroughRequest_t, SGL), sizeof (rep),
16364 smp_pkt->smp_pkt_rspsize - 4, direction,
16365 (uint8_t *)smp_pkt->smp_pkt_req, smp_pkt->smp_pkt_reqsize - 4,
16366 smp_pkt->smp_pkt_timeout, FKIOCTL);
16367 mutex_exit(&mpt->m_mutex);
16368 if (ret != 0) {
16369 cmn_err(CE_WARN, "smp_start do passthru error %d", ret);
16370 smp_pkt->smp_pkt_reason = (uchar_t)(ret);
16371 return (DDI_FAILURE);
16372 }
16373 /* do passthrough success, check the smp status */
16374 if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) {
16375 switch (LE_16(rep.IOCStatus)) {
16376 case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
16377 smp_pkt->smp_pkt_reason = ENODEV;
16378 break;
16379 case MPI2_IOCSTATUS_SAS_SMP_DATA_OVERRUN:
16380 smp_pkt->smp_pkt_reason = EOVERFLOW;
16381 break;
16382 case MPI2_IOCSTATUS_SAS_SMP_REQUEST_FAILED:
16383 smp_pkt->smp_pkt_reason = EIO;
16384 break;
16385 default:
16386 mptsas_log(mpt, CE_NOTE, "smp_start: get unknown ioc"
16387 "status:%x", LE_16(rep.IOCStatus));
16388 smp_pkt->smp_pkt_reason = EIO;
16389 break;
16390 }
16391 return (DDI_FAILURE);
16392 }
16393 if (rep.SASStatus != MPI2_SASSTATUS_SUCCESS) {
16394 mptsas_log(mpt, CE_NOTE, "smp_start: get error SAS status:%x",
16395 rep.SASStatus);
16396 smp_pkt->smp_pkt_reason = EIO;
16397 return (DDI_FAILURE);
16398 }
16399
16400 return (DDI_SUCCESS);
16401 }
16402
16403 /*
16404 * If we didn't get a match, we need to get sas page0 for each device, and
16405 * untill we get a match. If failed, return NULL
16406 */
16407 static mptsas_target_t *
16408 mptsas_phy_to_tgt(mptsas_t *mpt, mptsas_phymask_t phymask, uint8_t phy)
16409 {
16410 int i, j = 0;
16411 int rval = 0;
16412 uint16_t cur_handle;
16413 uint32_t page_address;
16414 mptsas_target_t *ptgt = NULL;
16415
16416 /*
16417 * PHY named device must be direct attached and attaches to
16418 * narrow port, if the iport is not parent of the device which
16419 * we are looking for.
16420 */
16421 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
16422 if ((1 << i) & phymask)
16423 j++;
16424 }
16425
16426 if (j > 1)
16427 return (NULL);
16428
16429 /*
16430 * Must be a narrow port and single device attached to the narrow port
16431 * So the physical port num of device which is equal to the iport's
16432 * port num is the device what we are looking for.
16433 */
16434
16435 if (mpt->m_phy_info[phy].phy_mask != phymask)
16436 return (NULL);
16437
16438 mutex_enter(&mpt->m_mutex);
16439
16440 ptgt = refhash_linear_search(mpt->m_targets, mptsas_target_eval_nowwn,
16441 &phy);
16442 if (ptgt != NULL) {
16443 mutex_exit(&mpt->m_mutex);
16444 return (ptgt);
16445 }
16446
16447 if (mpt->m_done_traverse_dev) {
16448 mutex_exit(&mpt->m_mutex);
16449 return (NULL);
16450 }
16451
16452 /* If didn't get a match, come here */
16453 cur_handle = mpt->m_dev_handle;
16454 for (; ; ) {
16455 ptgt = NULL;
16456 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE &
16457 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)cur_handle;
16458 rval = mptsas_get_target_device_info(mpt, page_address,
16459 &cur_handle, &ptgt);
16460 if ((rval == DEV_INFO_FAIL_PAGE0) ||
16461 (rval == DEV_INFO_FAIL_ALLOC) ||
16462 (rval == DEV_INFO_FAIL_GUID)) {
16463 break;
16464 }
16465 if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) ||
16466 (rval == DEV_INFO_PHYS_DISK)) {
16467 continue;
16468 }
16469 mpt->m_dev_handle = cur_handle;
16470
16471 if ((ptgt->m_addr.mta_wwn == 0) && (ptgt->m_phynum == phy)) {
16472 break;
16473 }
16474 }
16475
16476 mutex_exit(&mpt->m_mutex);
16477 return (ptgt);
16478 }
16479
16480 /*
16481 * The ptgt->m_addr.mta_wwn contains the wwid for each disk.
16482 * For Raid volumes, we need to check m_raidvol[x].m_raidwwid
16483 * If we didn't get a match, we need to get sas page0 for each device, and
16484 * untill we get a match
16485 * If failed, return NULL
16486 */
16487 static mptsas_target_t *
16488 mptsas_wwid_to_ptgt(mptsas_t *mpt, mptsas_phymask_t phymask, uint64_t wwid)
16489 {
16490 int rval = 0;
16491 uint16_t cur_handle;
16492 uint32_t page_address;
16493 mptsas_target_t *tmp_tgt = NULL;
16494 mptsas_target_addr_t addr;
16495
16496 addr.mta_wwn = wwid;
16497 addr.mta_phymask = phymask;
16498 mutex_enter(&mpt->m_mutex);
16499 tmp_tgt = refhash_lookup(mpt->m_targets, &addr);
16500 if (tmp_tgt != NULL) {
16501 mutex_exit(&mpt->m_mutex);
16502 return (tmp_tgt);
16503 }
16504
16505 if (phymask == 0) {
16506 /*
16507 * It's IR volume
16508 */
16509 rval = mptsas_get_raid_info(mpt);
16510 if (rval) {
16511 tmp_tgt = refhash_lookup(mpt->m_targets, &addr);
16512 }
16513 mutex_exit(&mpt->m_mutex);
16514 return (tmp_tgt);
16515 }
16516
16517 if (mpt->m_done_traverse_dev) {
16518 mutex_exit(&mpt->m_mutex);
16519 return (NULL);
16520 }
16521
16522 /* If didn't get a match, come here */
16523 cur_handle = mpt->m_dev_handle;
16524 for (;;) {
16525 tmp_tgt = NULL;
16526 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE &
16527 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | cur_handle;
16528 rval = mptsas_get_target_device_info(mpt, page_address,
16529 &cur_handle, &tmp_tgt);
16530 if ((rval == DEV_INFO_FAIL_PAGE0) ||
16531 (rval == DEV_INFO_FAIL_ALLOC) ||
16532 (rval == DEV_INFO_FAIL_GUID)) {
16533 tmp_tgt = NULL;
16534 break;
16535 }
16536 if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) ||
16537 (rval == DEV_INFO_PHYS_DISK)) {
16538 continue;
16539 }
16540 mpt->m_dev_handle = cur_handle;
16541 if ((tmp_tgt->m_addr.mta_wwn) &&
16542 (tmp_tgt->m_addr.mta_wwn == wwid) &&
16543 (tmp_tgt->m_addr.mta_phymask == phymask)) {
16544 break;
16545 }
16546 }
16547
16548 mutex_exit(&mpt->m_mutex);
16549 return (tmp_tgt);
16550 }
16551
16552 static mptsas_smp_t *
16553 mptsas_wwid_to_psmp(mptsas_t *mpt, mptsas_phymask_t phymask, uint64_t wwid)
16554 {
16555 int rval = 0;
16556 uint16_t cur_handle;
16557 uint32_t page_address;
16558 mptsas_smp_t smp_node, *psmp = NULL;
16559 mptsas_target_addr_t addr;
16560
16561 addr.mta_wwn = wwid;
16562 addr.mta_phymask = phymask;
16563 mutex_enter(&mpt->m_mutex);
16564 psmp = refhash_lookup(mpt->m_smp_targets, &addr);
16565 if (psmp != NULL) {
16566 mutex_exit(&mpt->m_mutex);
16567 return (psmp);
16568 }
16569
16570 if (mpt->m_done_traverse_smp) {
16571 mutex_exit(&mpt->m_mutex);
16572 return (NULL);
16573 }
16574
16575 /* If didn't get a match, come here */
16576 cur_handle = mpt->m_smp_devhdl;
16577 for (;;) {
16578 psmp = NULL;
16579 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL &
16580 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)cur_handle;
16581 rval = mptsas_get_sas_expander_page0(mpt, page_address,
16582 &smp_node);
16583 if (rval != DDI_SUCCESS) {
16584 break;
16585 }
16586 mpt->m_smp_devhdl = cur_handle = smp_node.m_devhdl;
16587 psmp = mptsas_smp_alloc(mpt, &smp_node);
16588 ASSERT(psmp);
16589 if ((psmp->m_addr.mta_wwn) && (psmp->m_addr.mta_wwn == wwid) &&
16590 (psmp->m_addr.mta_phymask == phymask)) {
16591 break;
16592 }
16593 }
16594
16595 mutex_exit(&mpt->m_mutex);
16596 return (psmp);
16597 }
16598
16599 mptsas_target_t *
16600 mptsas_tgt_alloc(refhash_t *refhash, uint16_t devhdl, uint64_t wwid,
16601 uint32_t devinfo, mptsas_phymask_t phymask, uint8_t phynum)
16602 {
16603 mptsas_target_t *tmp_tgt = NULL;
16604 mptsas_target_addr_t addr;
16605
16606 addr.mta_wwn = wwid;
16607 addr.mta_phymask = phymask;
16608 tmp_tgt = refhash_lookup(refhash, &addr);
16609 if (tmp_tgt != NULL) {
16610 NDBG20(("Hash item already exist"));
16611 tmp_tgt->m_deviceinfo = devinfo;
16612 tmp_tgt->m_devhdl = devhdl; /* XXX - duplicate? */
16613 return (tmp_tgt);
16614 }
16615 tmp_tgt = kmem_zalloc(sizeof (struct mptsas_target), KM_SLEEP);
16616 if (tmp_tgt == NULL) {
16617 cmn_err(CE_WARN, "Fatal, allocated tgt failed");
16618 return (NULL);
16619 }
16620 tmp_tgt->m_devhdl = devhdl;
16621 tmp_tgt->m_addr.mta_wwn = wwid;
16622 tmp_tgt->m_deviceinfo = devinfo;
16623 tmp_tgt->m_addr.mta_phymask = phymask;
16624 tmp_tgt->m_phynum = phynum;
16625 /* Initialized the tgt structure */
16626 tmp_tgt->m_qfull_retries = QFULL_RETRIES;
16627 tmp_tgt->m_qfull_retry_interval =
16628 drv_usectohz(QFULL_RETRY_INTERVAL * 1000);
16629 tmp_tgt->m_t_throttle = MAX_THROTTLE;
16630 TAILQ_INIT(&tmp_tgt->m_active_cmdq);
16631
16632 refhash_insert(refhash, tmp_tgt);
16633
16634 return (tmp_tgt);
16635 }
16636
16637 static void
16638 mptsas_smp_target_copy(mptsas_smp_t *src, mptsas_smp_t *dst)
16639 {
16640 dst->m_devhdl = src->m_devhdl;
16641 dst->m_deviceinfo = src->m_deviceinfo;
16642 dst->m_pdevhdl = src->m_pdevhdl;
16643 dst->m_pdevinfo = src->m_pdevinfo;
16644 }
16645
16646 static mptsas_smp_t *
16647 mptsas_smp_alloc(mptsas_t *mpt, mptsas_smp_t *data)
16648 {
16649 mptsas_target_addr_t addr;
16650 mptsas_smp_t *ret_data;
16651
16652 addr.mta_wwn = data->m_addr.mta_wwn;
16653 addr.mta_phymask = data->m_addr.mta_phymask;
16654 ret_data = refhash_lookup(mpt->m_smp_targets, &addr);
16655 /*
16656 * If there's already a matching SMP target, update its fields
16657 * in place. Since the address is not changing, it's safe to do
16658 * this. We cannot just bcopy() here because the structure we've
16659 * been given has invalid hash links.
16660 */
16661 if (ret_data != NULL) {
16662 mptsas_smp_target_copy(data, ret_data);
16663 return (ret_data);
16664 }
16665
16666 ret_data = kmem_alloc(sizeof (mptsas_smp_t), KM_SLEEP);
16667 bcopy(data, ret_data, sizeof (mptsas_smp_t));
16668 refhash_insert(mpt->m_smp_targets, ret_data);
16669 return (ret_data);
16670 }
16671
16672 /*
16673 * Functions for SGPIO LED support
16674 */
16675 static dev_info_t *
16676 mptsas_get_dip_from_dev(dev_t dev, mptsas_phymask_t *phymask)
16677 {
16678 dev_info_t *dip;
16679 int prop;
16680 dip = e_ddi_hold_devi_by_dev(dev, 0);
16681 if (dip == NULL)
16682 return (dip);
16683 prop = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0,
16684 "phymask", 0);
16685 *phymask = (mptsas_phymask_t)prop;
16686 ddi_release_devi(dip);
16687 return (dip);
16688 }
16689 static mptsas_target_t *
16690 mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr, mptsas_phymask_t phymask)
16691 {
16692 uint8_t phynum;
16693 uint64_t wwn;
16694 int lun;
16695 mptsas_target_t *ptgt = NULL;
16696
16697 if (mptsas_parse_address(addr, &wwn, &phynum, &lun) != DDI_SUCCESS) {
16698 return (NULL);
16699 }
16700 if (addr[0] == 'w') {
16701 ptgt = mptsas_wwid_to_ptgt(mpt, (int)phymask, wwn);
16702 } else {
16703 ptgt = mptsas_phy_to_tgt(mpt, (int)phymask, phynum);
16704 }
16705 return (ptgt);
16706 }
16707
16708 static int
16709 mptsas_flush_led_status(mptsas_t *mpt, mptsas_target_t *ptgt)
16710 {
16711 uint32_t slotstatus = 0;
16712
16713 /* Build an MPI2 Slot Status based on our view of the world */
16714 if (ptgt->m_led_status & (1 << (MPTSAS_LEDCTL_LED_IDENT - 1)))
16715 slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_IDENTIFY_REQUEST;
16716 if (ptgt->m_led_status & (1 << (MPTSAS_LEDCTL_LED_FAIL - 1)))
16717 slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT;
16718 if (ptgt->m_led_status & (1 << (MPTSAS_LEDCTL_LED_OK2RM - 1)))
16719 slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE;
16720
16721 /* Write it to the controller */
16722 NDBG14(("mptsas_ioctl: set LED status %x for slot %x",
16723 slotstatus, ptgt->m_slot_num));
16724 return (mptsas_send_sep(mpt, ptgt, &slotstatus,
16725 MPI2_SEP_REQ_ACTION_WRITE_STATUS));
16726 }
16727
16728 /*
16729 * send sep request, use enclosure/slot addressing
16730 */
16731 static int
16732 mptsas_send_sep(mptsas_t *mpt, mptsas_target_t *ptgt,
16733 uint32_t *status, uint8_t act)
16734 {
16735 Mpi2SepRequest_t req;
16736 Mpi2SepReply_t rep;
16737 int ret;
16738 mptsas_enclosure_t *mep;
16739 uint16_t enctype;
16740
16741 ASSERT(mutex_owned(&mpt->m_mutex));
16742
16743 /*
16744 * We only support SEP control of directly-attached targets, in which
16745 * case the "SEP" we're talking to is a virtual one contained within
16746 * the HBA itself. This is necessary because DA targets typically have
16747 * no other mechanism for LED control. Targets for which a separate
16748 * enclosure service processor exists should be controlled via ses(7d)
16749 * or sgen(7d). Furthermore, since such requests can time out, they
16750 * should be made in user context rather than in response to
16751 * asynchronous fabric changes.
16752 *
16753 * In addition, we do not support this operation for RAID volumes,
16754 * since there is no slot associated with them.
16755 */
16756 if (!(ptgt->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) ||
16757 ptgt->m_addr.mta_phymask == 0) {
16758 return (ENOTTY);
16759 }
16760
16761 /*
16762 * Look through the enclosures and make sure that this enclosure is
16763 * something that is directly attached device. If we didn't find an
16764 * enclosure for this device, don't send the ioctl.
16765 */
16766 mep = mptsas_enc_lookup(mpt, ptgt->m_enclosure);
16767 if (mep == NULL)
16768 return (ENOTTY);
16769 enctype = mep->me_flags & MPI2_SAS_ENCLS0_FLAGS_MNG_MASK;
16770 if (enctype != MPI2_SAS_ENCLS0_FLAGS_MNG_IOC_SES &&
16771 enctype != MPI2_SAS_ENCLS0_FLAGS_MNG_IOC_SGPIO &&
16772 enctype != MPI2_SAS_ENCLS0_FLAGS_MNG_IOC_GPIO) {
16773 return (ENOTTY);
16774 }
16775
16776 bzero(&req, sizeof (req));
16777 bzero(&rep, sizeof (rep));
16778
16779 req.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
16780 req.Action = act;
16781 req.Flags = MPI2_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS;
16782 req.EnclosureHandle = LE_16(ptgt->m_enclosure);
16783 req.Slot = LE_16(ptgt->m_slot_num);
16784 if (act == MPI2_SEP_REQ_ACTION_WRITE_STATUS) {
16785 req.SlotStatus = LE_32(*status);
16786 }
16787 ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, NULL,
16788 sizeof (req), sizeof (rep), NULL, 0, NULL, 0, 60, FKIOCTL);
16789 if (ret != 0) {
16790 mptsas_log(mpt, CE_NOTE, "mptsas_send_sep: passthru SEP "
16791 "Processor Request message error %d", ret);
16792 return (ret);
16793 }
16794 /* do passthrough success, check the ioc status */
16795 if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) {
16796 mptsas_log(mpt, CE_NOTE, "send_sep act %x: ioc "
16797 "status:%x loginfo %x", act, LE_16(rep.IOCStatus),
16798 LE_32(rep.IOCLogInfo));
16799 switch (LE_16(rep.IOCStatus) & MPI2_IOCSTATUS_MASK) {
16800 case MPI2_IOCSTATUS_INVALID_FUNCTION:
16801 case MPI2_IOCSTATUS_INVALID_VPID:
16802 case MPI2_IOCSTATUS_INVALID_FIELD:
16803 case MPI2_IOCSTATUS_INVALID_STATE:
16804 case MPI2_IOCSTATUS_OP_STATE_NOT_SUPPORTED:
16805 case MPI2_IOCSTATUS_CONFIG_INVALID_ACTION:
16806 case MPI2_IOCSTATUS_CONFIG_INVALID_TYPE:
16807 case MPI2_IOCSTATUS_CONFIG_INVALID_PAGE:
16808 case MPI2_IOCSTATUS_CONFIG_INVALID_DATA:
16809 case MPI2_IOCSTATUS_CONFIG_NO_DEFAULTS:
16810 return (EINVAL);
16811 case MPI2_IOCSTATUS_BUSY:
16812 return (EBUSY);
16813 case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES:
16814 return (EAGAIN);
16815 case MPI2_IOCSTATUS_INVALID_SGL:
16816 case MPI2_IOCSTATUS_INTERNAL_ERROR:
16817 case MPI2_IOCSTATUS_CONFIG_CANT_COMMIT:
16818 default:
16819 return (EIO);
16820 }
16821 }
16822 if (act != MPI2_SEP_REQ_ACTION_WRITE_STATUS) {
16823 *status = LE_32(rep.SlotStatus);
16824 }
16825
16826 return (0);
16827 }
16828
16829 int
16830 mptsas_dma_addr_create(mptsas_t *mpt, ddi_dma_attr_t dma_attr,
16831 ddi_dma_handle_t *dma_hdp, ddi_acc_handle_t *acc_hdp, caddr_t *dma_memp,
16832 uint32_t alloc_size, ddi_dma_cookie_t *cookiep)
16833 {
16834 ddi_dma_cookie_t new_cookie;
16835 size_t alloc_len;
16836 uint_t ncookie;
16837
16838 if (cookiep == NULL)
16839 cookiep = &new_cookie;
16840
16841 if (ddi_dma_alloc_handle(mpt->m_dip, &dma_attr, DDI_DMA_SLEEP,
16842 NULL, dma_hdp) != DDI_SUCCESS) {
16843 return (FALSE);
16844 }
16845
16846 if (ddi_dma_mem_alloc(*dma_hdp, alloc_size, &mpt->m_dev_acc_attr,
16847 DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, dma_memp, &alloc_len,
16848 acc_hdp) != DDI_SUCCESS) {
16849 ddi_dma_free_handle(dma_hdp);
16850 *dma_hdp = NULL;
16851 return (FALSE);
16852 }
16853
16854 if (ddi_dma_addr_bind_handle(*dma_hdp, NULL, *dma_memp, alloc_len,
16855 (DDI_DMA_RDWR | DDI_DMA_CONSISTENT), DDI_DMA_SLEEP, NULL,
16856 cookiep, &ncookie) != DDI_DMA_MAPPED) {
16857 (void) ddi_dma_mem_free(acc_hdp);
16858 ddi_dma_free_handle(dma_hdp);
16859 *dma_hdp = NULL;
16860 return (FALSE);
16861 }
16862
16863 return (TRUE);
16864 }
16865
16866 void
16867 mptsas_dma_addr_destroy(ddi_dma_handle_t *dma_hdp, ddi_acc_handle_t *acc_hdp)
16868 {
16869 if (*dma_hdp == NULL)
16870 return;
16871
16872 (void) ddi_dma_unbind_handle(*dma_hdp);
16873 (void) ddi_dma_mem_free(acc_hdp);
16874 ddi_dma_free_handle(dma_hdp);
16875 *dma_hdp = NULL;
16876 }