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 2019 Joyent, Inc.
26 * Copyright 2014 OmniTI Computer Consulting, Inc. All rights reserved.
27 * Copyright (c) 2014, Tegile Systems Inc. All rights reserved.
28 * Copyright 2023 Oxide Computer Company
29 * Copyright 2023 Racktop Systems, Inc.
30 */
31
32 /*
33 * Copyright (c) 2000 to 2010, LSI Corporation.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms of all code within
37 * this file that is exclusively owned by LSI, with or without
38 * modification, is permitted provided that, in addition to the CDDL 1.0
39 * License requirements, the following conditions are met:
40 *
41 * Neither the name of the author nor the names of its contributors may be
42 * used to endorse or promote products derived from this software without
43 * specific prior written permission.
44 *
45 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
46 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
47 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
48 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
49 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
50 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
51 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
52 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
53 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
54 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
55 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
56 * DAMAGE.
57 */
58
59 /*
60 * mptsas - This is a driver based on LSI Logic's MPT2.0/2.5 interface.
61 *
62 */
63
64 #if defined(lint) || defined(DEBUG)
65 #define MPTSAS_DEBUG
66 #endif
67
68 /*
69 * standard header files.
70 */
71 #include <sys/note.h>
72 #include <sys/scsi/scsi.h>
73 #include <sys/pci.h>
74 #include <sys/file.h>
75 #include <sys/policy.h>
76 #include <sys/model.h>
77 #include <sys/refhash.h>
78 #include <sys/sysevent.h>
79 #include <sys/sysevent/eventdefs.h>
80 #include <sys/sysevent/dr.h>
81 #include <sys/sata/sata_defs.h>
82 #include <sys/sata/sata_hba.h>
83 #include <sys/scsi/generic/sas.h>
84 #include <sys/scsi/impl/scsi_sas.h>
85
86 #pragma pack(1)
87 #include <sys/scsi/adapters/mpi/mpi2_type.h>
88 #include <sys/scsi/adapters/mpi/mpi2.h>
89 #include <sys/scsi/adapters/mpi/mpi2_cnfg.h>
90 #include <sys/scsi/adapters/mpi/mpi2_init.h>
91 #include <sys/scsi/adapters/mpi/mpi2_ioc.h>
92 #include <sys/scsi/adapters/mpi/mpi2_sas.h>
93 #include <sys/scsi/adapters/mpi/mpi2_tool.h>
94 #include <sys/scsi/adapters/mpi/mpi2_raid.h>
95 #pragma pack()
96
97 /*
98 * private header files.
99 *
100 */
101 #include <sys/scsi/impl/scsi_reset_notify.h>
102 #include <sys/scsi/adapters/mpt_sas/mptsas_var.h>
103 #include <sys/scsi/adapters/mpt_sas/mptsas_ioctl.h>
104 #include <sys/scsi/adapters/mpt_sas/mptsas_smhba.h>
105 #include <sys/raidioctl.h>
106
107 #include <sys/fs/dv_node.h> /* devfs_clean */
108
109 /*
110 * FMA header files
111 */
112 #include <sys/ddifm.h>
113 #include <sys/fm/protocol.h>
114 #include <sys/fm/util.h>
115 #include <sys/fm/io/ddi.h>
116
117 /*
118 * autoconfiguration data and routines.
119 */
120 static int mptsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
121 static int mptsas_detach(dev_info_t *devi, ddi_detach_cmd_t cmd);
122 static int mptsas_power(dev_info_t *dip, int component, int level);
123
124 /*
125 * cb_ops function
126 */
127 static int mptsas_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
128 cred_t *credp, int *rval);
129 #ifdef __sparc
130 static int mptsas_reset(dev_info_t *devi, ddi_reset_cmd_t cmd);
131 #else /* __sparc */
132 static int mptsas_quiesce(dev_info_t *devi);
133 #endif /* __sparc */
134
135 /*
136 * ddi_ufm_ops
137 */
138 static int mptsas_ufm_fill_image(ddi_ufm_handle_t *ufmh, void *arg,
139 uint_t imgno, ddi_ufm_image_t *img);
140 static int mptsas_ufm_fill_slot(ddi_ufm_handle_t *ufmh, void *arg,
141 uint_t imgno, uint_t slotno, ddi_ufm_slot_t *slot);
142 static int mptsas_ufm_getcaps(ddi_ufm_handle_t *ufmh, void *arg,
143 ddi_ufm_cap_t *caps);
144
145 /*
146 * Resource initialization for hardware
147 */
148 static void mptsas_setup_cmd_reg(mptsas_t *mpt);
149 static void mptsas_disable_bus_master(mptsas_t *mpt);
150 static void mptsas_hba_fini(mptsas_t *mpt);
151 static void mptsas_cfg_fini(mptsas_t *mptsas_blkp);
152 static int mptsas_hba_setup(mptsas_t *mpt);
153 static void mptsas_hba_teardown(mptsas_t *mpt);
154 static int mptsas_config_space_init(mptsas_t *mpt);
155 static void mptsas_config_space_fini(mptsas_t *mpt);
156 static void mptsas_iport_register(mptsas_t *mpt);
157 static int mptsas_smp_setup(mptsas_t *mpt);
158 static void mptsas_smp_teardown(mptsas_t *mpt);
159 static int mptsas_enc_setup(mptsas_t *mpt);
160 static void mptsas_enc_teardown(mptsas_t *mpt);
161 static int mptsas_cache_create(mptsas_t *mpt);
162 static void mptsas_cache_destroy(mptsas_t *mpt);
163 static int mptsas_alloc_request_frames(mptsas_t *mpt);
164 static int mptsas_alloc_sense_bufs(mptsas_t *mpt);
165 static int mptsas_alloc_reply_frames(mptsas_t *mpt);
166 static int mptsas_alloc_free_queue(mptsas_t *mpt);
167 static int mptsas_alloc_post_queue(mptsas_t *mpt);
168 static void mptsas_alloc_reply_args(mptsas_t *mpt);
169 static int mptsas_alloc_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd);
170 static void mptsas_free_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd);
171 static int mptsas_init_chip(mptsas_t *mpt, int first_time);
172 static void mptsas_update_hashtab(mptsas_t *mpt);
173
174 /*
175 * SCSA function prototypes
176 */
177 static int mptsas_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt);
178 static int mptsas_scsi_reset(struct scsi_address *ap, int level);
179 static int mptsas_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt);
180 static int mptsas_scsi_getcap(struct scsi_address *ap, char *cap, int tgtonly);
181 static int mptsas_scsi_setcap(struct scsi_address *ap, char *cap, int value,
182 int tgtonly);
183 static void mptsas_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt);
184 static struct scsi_pkt *mptsas_scsi_init_pkt(struct scsi_address *ap,
185 struct scsi_pkt *pkt, struct buf *bp, int cmdlen, int statuslen,
186 int tgtlen, int flags, int (*callback)(), caddr_t arg);
187 static void mptsas_scsi_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt);
188 static void mptsas_scsi_destroy_pkt(struct scsi_address *ap,
189 struct scsi_pkt *pkt);
190 static int mptsas_scsi_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
191 scsi_hba_tran_t *hba_tran, struct scsi_device *sd);
192 static void mptsas_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip,
193 scsi_hba_tran_t *hba_tran, struct scsi_device *sd);
194 static int mptsas_scsi_reset_notify(struct scsi_address *ap, int flag,
195 void (*callback)(caddr_t), caddr_t arg);
196 static int mptsas_get_name(struct scsi_device *sd, char *name, int len);
197 static int mptsas_get_bus_addr(struct scsi_device *sd, char *name, int len);
198 static int mptsas_scsi_quiesce(dev_info_t *dip);
199 static int mptsas_scsi_unquiesce(dev_info_t *dip);
200 static int mptsas_bus_config(dev_info_t *pdip, uint_t flags,
201 ddi_bus_config_op_t op, void *arg, dev_info_t **childp);
202
203 /*
204 * SMP functions
205 */
206 static int mptsas_smp_start(struct smp_pkt *smp_pkt);
207
208 /*
209 * internal function prototypes.
210 */
211 static void mptsas_list_add(mptsas_t *mpt);
212 static void mptsas_list_del(mptsas_t *mpt);
213
214 static int mptsas_quiesce_bus(mptsas_t *mpt);
215 static int mptsas_unquiesce_bus(mptsas_t *mpt);
216
217 static int mptsas_alloc_handshake_msg(mptsas_t *mpt, size_t alloc_size);
218 static void mptsas_free_handshake_msg(mptsas_t *mpt);
219
220 static void mptsas_ncmds_checkdrain(void *arg);
221
222 static int mptsas_prepare_pkt(mptsas_cmd_t *cmd);
223 static int mptsas_accept_pkt(mptsas_t *mpt, mptsas_cmd_t *sp);
224 static int mptsas_accept_txwq_and_pkt(mptsas_t *mpt, mptsas_cmd_t *sp);
225 static void mptsas_accept_tx_waitq(mptsas_t *mpt);
226
227 static int mptsas_do_detach(dev_info_t *dev);
228 static int mptsas_do_scsi_reset(mptsas_t *mpt, uint16_t devhdl);
229 static int mptsas_do_scsi_abort(mptsas_t *mpt, int target, int lun,
230 struct scsi_pkt *pkt);
231 static int mptsas_scsi_capchk(char *cap, int tgtonly, int *cidxp);
232
233 static void mptsas_handle_qfull(mptsas_t *mpt, mptsas_cmd_t *cmd);
234 static void mptsas_handle_event(void *args);
235 static int mptsas_handle_event_sync(void *args);
236 static void mptsas_handle_dr(void *args);
237 static void mptsas_handle_topo_change(mptsas_topo_change_list_t *topo_node,
238 dev_info_t *pdip);
239
240 static void mptsas_restart_cmd(void *);
241
242 static void mptsas_flush_hba(mptsas_t *mpt);
243 static void mptsas_flush_target(mptsas_t *mpt, ushort_t target, int lun,
244 uint8_t tasktype);
245 static void mptsas_set_pkt_reason(mptsas_t *mpt, mptsas_cmd_t *cmd,
246 uchar_t reason, uint_t stat);
247
248 static uint_t mptsas_intr(caddr_t arg1, caddr_t arg2);
249 static void mptsas_process_intr(mptsas_t *mpt,
250 pMpi2ReplyDescriptorsUnion_t reply_desc_union);
251 static void mptsas_handle_scsi_io_success(mptsas_t *mpt,
252 pMpi2ReplyDescriptorsUnion_t reply_desc);
253 static void mptsas_handle_address_reply(mptsas_t *mpt,
254 pMpi2ReplyDescriptorsUnion_t reply_desc);
255 static int mptsas_wait_intr(mptsas_t *mpt, int polltime);
256 static void mptsas_sge_setup(mptsas_t *mpt, mptsas_cmd_t *cmd,
257 uint32_t *control, pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl);
258
259 static void mptsas_watch(void *arg);
260 static void mptsas_watchsubr(mptsas_t *mpt);
261 static void mptsas_cmd_timeout(mptsas_t *mpt, mptsas_target_t *ptgt);
262
263 static void mptsas_start_passthru(mptsas_t *mpt, mptsas_cmd_t *cmd);
264 static int mptsas_do_passthru(mptsas_t *mpt, uint8_t *request, uint8_t *reply,
265 uint8_t *data, uint32_t request_size, uint32_t reply_size,
266 uint32_t data_size, uint32_t direction, uint8_t *dataout,
267 uint32_t dataout_size, short timeout, int mode);
268 static int mptsas_free_devhdl(mptsas_t *mpt, uint16_t devhdl);
269
270 static uint8_t mptsas_get_fw_diag_buffer_number(mptsas_t *mpt,
271 uint32_t unique_id);
272 static void mptsas_start_diag(mptsas_t *mpt, mptsas_cmd_t *cmd);
273 static int mptsas_post_fw_diag_buffer(mptsas_t *mpt,
274 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code);
275 static int mptsas_release_fw_diag_buffer(mptsas_t *mpt,
276 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code,
277 uint32_t diag_type);
278 static int mptsas_diag_register(mptsas_t *mpt,
279 mptsas_fw_diag_register_t *diag_register, uint32_t *return_code);
280 static int mptsas_diag_unregister(mptsas_t *mpt,
281 mptsas_fw_diag_unregister_t *diag_unregister, uint32_t *return_code);
282 static int mptsas_diag_query(mptsas_t *mpt, mptsas_fw_diag_query_t *diag_query,
283 uint32_t *return_code);
284 static int mptsas_diag_read_buffer(mptsas_t *mpt,
285 mptsas_diag_read_buffer_t *diag_read_buffer, uint8_t *ioctl_buf,
286 uint32_t *return_code, int ioctl_mode);
287 static int mptsas_diag_release(mptsas_t *mpt,
288 mptsas_fw_diag_release_t *diag_release, uint32_t *return_code);
289 static int mptsas_do_diag_action(mptsas_t *mpt, uint32_t action,
290 uint8_t *diag_action, uint32_t length, uint32_t *return_code,
291 int ioctl_mode);
292 static int mptsas_diag_action(mptsas_t *mpt, mptsas_diag_action_t *data,
293 int mode);
294
295 static int mptsas_pkt_alloc_extern(mptsas_t *mpt, mptsas_cmd_t *cmd,
296 int cmdlen, int tgtlen, int statuslen, int kf);
297 static void mptsas_pkt_destroy_extern(mptsas_t *mpt, mptsas_cmd_t *cmd);
298
299 static int mptsas_kmem_cache_constructor(void *buf, void *cdrarg, int kmflags);
300 static void mptsas_kmem_cache_destructor(void *buf, void *cdrarg);
301
302 static int mptsas_cache_frames_constructor(void *buf, void *cdrarg,
303 int kmflags);
304 static void mptsas_cache_frames_destructor(void *buf, void *cdrarg);
305
306 static void mptsas_check_scsi_io_error(mptsas_t *mpt, pMpi2SCSIIOReply_t reply,
307 mptsas_cmd_t *cmd);
308 static void mptsas_check_task_mgt(mptsas_t *mpt,
309 pMpi2SCSIManagementReply_t reply, mptsas_cmd_t *cmd);
310 static int mptsas_send_scsi_cmd(mptsas_t *mpt, struct scsi_address *ap,
311 mptsas_target_t *ptgt, uchar_t *cdb, int cdblen, struct buf *data_bp,
312 int *resid);
313
314 static int mptsas_alloc_active_slots(mptsas_t *mpt, int flag);
315 static void mptsas_free_active_slots(mptsas_t *mpt);
316 static int mptsas_start_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd);
317
318 static void mptsas_restart_hba(mptsas_t *mpt);
319 static void mptsas_restart_waitq(mptsas_t *mpt);
320
321 static void mptsas_deliver_doneq_thread(mptsas_t *mpt);
322 static void mptsas_doneq_add(mptsas_t *mpt, mptsas_cmd_t *cmd);
323 static void mptsas_doneq_mv(mptsas_t *mpt, uint64_t t);
324
325 static mptsas_cmd_t *mptsas_doneq_thread_rm(mptsas_t *mpt, uint64_t t);
326 static void mptsas_doneq_empty(mptsas_t *mpt);
327 static void mptsas_doneq_thread(mptsas_doneq_thread_arg_t *arg);
328
329 static mptsas_cmd_t *mptsas_waitq_rm(mptsas_t *mpt);
330 static void mptsas_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd);
331 static mptsas_cmd_t *mptsas_tx_waitq_rm(mptsas_t *mpt);
332 static void mptsas_tx_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd);
333
334
335 static void mptsas_start_watch_reset_delay();
336 static void mptsas_setup_bus_reset_delay(mptsas_t *mpt);
337 static void mptsas_watch_reset_delay(void *arg);
338 static int mptsas_watch_reset_delay_subr(mptsas_t *mpt);
339
340 /*
341 * helper functions
342 */
343 static void mptsas_dump_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd);
344
345 static dev_info_t *mptsas_find_child(dev_info_t *pdip, char *name);
346 static dev_info_t *mptsas_find_child_phy(dev_info_t *pdip, uint8_t phy);
347 static dev_info_t *mptsas_find_child_addr(dev_info_t *pdip, uint64_t sasaddr,
348 int lun);
349 static mdi_pathinfo_t *mptsas_find_path_addr(dev_info_t *pdip, uint64_t sasaddr,
350 int lun);
351 static mdi_pathinfo_t *mptsas_find_path_phy(dev_info_t *pdip, uint8_t phy);
352 static dev_info_t *mptsas_find_smp_child(dev_info_t *pdip, char *str_wwn);
353
354 static int mptsas_parse_address(char *name, uint64_t *wwid, uint8_t *phy,
355 int *lun);
356 static int mptsas_parse_smp_name(char *name, uint64_t *wwn);
357
358 static mptsas_target_t *mptsas_phy_to_tgt(mptsas_t *mpt,
359 mptsas_phymask_t phymask, uint8_t phy);
360 static mptsas_target_t *mptsas_wwid_to_ptgt(mptsas_t *mpt,
361 mptsas_phymask_t phymask, uint64_t wwid);
362 static mptsas_smp_t *mptsas_wwid_to_psmp(mptsas_t *mpt,
363 mptsas_phymask_t phymask, uint64_t wwid);
364
365 static int mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun,
366 uchar_t page, unsigned char *buf, int len, int *rlen, uchar_t evpd);
367
368 static int mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address,
369 uint16_t *handle, mptsas_target_t **pptgt);
370 static void mptsas_update_phymask(mptsas_t *mpt);
371
372 static int mptsas_flush_led_status(mptsas_t *mpt, mptsas_enclosure_t *mep,
373 uint16_t idx);
374 static int mptsas_send_sep(mptsas_t *mpt, mptsas_enclosure_t *mep, uint16_t idx,
375 uint32_t *status, uint8_t cmd);
376 static dev_info_t *mptsas_get_dip_from_dev(dev_t dev,
377 mptsas_phymask_t *phymask);
378 static mptsas_target_t *mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr,
379 mptsas_phymask_t phymask);
380
381
382 /*
383 * Enumeration / DR functions
384 */
385 static void mptsas_config_all(dev_info_t *pdip);
386 static int mptsas_config_one_addr(dev_info_t *pdip, uint64_t sasaddr, int lun,
387 dev_info_t **lundip);
388 static int mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun,
389 dev_info_t **lundip);
390
391 static int mptsas_config_target(dev_info_t *pdip, mptsas_target_t *ptgt);
392 static int mptsas_offline_target(dev_info_t *pdip, char *name);
393
394 static int mptsas_config_raid(dev_info_t *pdip, uint16_t target,
395 dev_info_t **dip);
396
397 static int mptsas_config_luns(dev_info_t *pdip, mptsas_target_t *ptgt);
398 static int mptsas_probe_lun(dev_info_t *pdip, int lun,
399 dev_info_t **dip, mptsas_target_t *ptgt);
400
401 static int mptsas_create_lun(dev_info_t *pdip, struct scsi_inquiry *sd_inq,
402 dev_info_t **dip, mptsas_target_t *ptgt, int lun);
403
404 static int mptsas_create_phys_lun(dev_info_t *pdip, struct scsi_inquiry *sd,
405 char *guid, dev_info_t **dip, mptsas_target_t *ptgt, int lun);
406 static int mptsas_create_virt_lun(dev_info_t *pdip, struct scsi_inquiry *sd,
407 char *guid, dev_info_t **dip, mdi_pathinfo_t **pip, mptsas_target_t *ptgt,
408 int lun);
409
410 static void mptsas_offline_missed_luns(dev_info_t *pdip,
411 uint16_t *repluns, int lun_cnt, mptsas_target_t *ptgt);
412 static int mptsas_offline_lun(dev_info_t *pdip, dev_info_t *rdip,
413 mdi_pathinfo_t *rpip, uint_t flags);
414
415 static int mptsas_config_smp(dev_info_t *pdip, uint64_t sas_wwn,
416 dev_info_t **smp_dip);
417 static int mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node,
418 uint_t flags);
419
420 static int mptsas_event_query(mptsas_t *mpt, mptsas_event_query_t *data,
421 int mode, int *rval);
422 static int mptsas_event_enable(mptsas_t *mpt, mptsas_event_enable_t *data,
423 int mode, int *rval);
424 static int mptsas_event_report(mptsas_t *mpt, mptsas_event_report_t *data,
425 int mode, int *rval);
426 static void mptsas_record_event(void *args);
427 static int mptsas_reg_access(mptsas_t *mpt, mptsas_reg_access_t *data,
428 int mode);
429
430 mptsas_target_t *mptsas_tgt_alloc(refhash_t *, uint16_t, uint64_t,
431 uint32_t, mptsas_phymask_t, uint8_t);
432 static mptsas_smp_t *mptsas_smp_alloc(mptsas_t *, mptsas_smp_t *);
433 static int mptsas_online_smp(dev_info_t *pdip, mptsas_smp_t *smp_node,
434 dev_info_t **smp_dip);
435
436 /*
437 * Power management functions
438 */
439 static int mptsas_get_pci_cap(mptsas_t *mpt);
440 static int mptsas_init_pm(mptsas_t *mpt);
441
442 /*
443 * MPT MSI tunable:
444 *
445 * By default MSI is enabled on all supported platforms.
446 */
447 boolean_t mptsas_enable_msi = B_TRUE;
448 boolean_t mptsas_physical_bind_failed_page_83 = B_FALSE;
449
450 /*
451 * Global switch for use of MPI2.5 FAST PATH.
452 * We don't really know what FAST PATH actually does, so if it is suspected
453 * to cause problems it can be turned off by setting this variable to B_FALSE.
454 */
455 boolean_t mptsas_use_fastpath = B_TRUE;
456
457 static int mptsas_register_intrs(mptsas_t *);
458 static void mptsas_unregister_intrs(mptsas_t *);
459 static int mptsas_add_intrs(mptsas_t *, int);
460 static void mptsas_rem_intrs(mptsas_t *);
461
462 /*
463 * FMA Prototypes
464 */
465 static void mptsas_fm_init(mptsas_t *mpt);
466 static void mptsas_fm_fini(mptsas_t *mpt);
467 static int mptsas_fm_error_cb(dev_info_t *, ddi_fm_error_t *, const void *);
468
469 extern pri_t minclsyspri, maxclsyspri;
470
471 /*
472 * This device is created by the SCSI pseudo nexus driver (SCSI vHCI). It is
473 * under this device that the paths to a physical device are created when
474 * MPxIO is used.
475 */
476 extern dev_info_t *scsi_vhci_dip;
477
478 /*
479 * Tunable timeout value for Inquiry VPD page 0x83
480 * By default the value is 30 seconds.
481 */
482 int mptsas_inq83_retry_timeout = 30;
483
484 /*
485 * This is used to allocate memory for message frame storage, not for
486 * data I/O DMA. All message frames must be stored in the first 4G of
487 * physical memory.
488 */
489 ddi_dma_attr_t mptsas_dma_attrs = {
490 DMA_ATTR_V0, /* attribute layout version */
491 0x0ull, /* address low - should be 0 (longlong) */
492 0xffffffffull, /* address high - 32-bit max range */
493 0x00ffffffull, /* count max - max DMA object size */
494 4, /* allocation alignment requirements */
495 0x78, /* burstsizes - binary encoded values */
496 1, /* minxfer - gran. of DMA engine */
497 0x00ffffffull, /* maxxfer - gran. of DMA engine */
498 0xffffffffull, /* max segment size (DMA boundary) */
499 MPTSAS_MAX_DMA_SEGS, /* scatter/gather list length */
500 512, /* granularity - device transfer size */
501 0 /* flags, set to 0 */
502 };
503
504 /*
505 * This is used for data I/O DMA memory allocation. (full 64-bit DMA
506 * physical addresses are supported.)
507 */
508 ddi_dma_attr_t mptsas_dma_attrs64 = {
509 DMA_ATTR_V0, /* attribute layout version */
510 0x0ull, /* address low - should be 0 (longlong) */
511 0xffffffffffffffffull, /* address high - 64-bit max */
512 0x00ffffffull, /* count max - max DMA object size */
513 4, /* allocation alignment requirements */
514 0x78, /* burstsizes - binary encoded values */
515 1, /* minxfer - gran. of DMA engine */
516 0x00ffffffull, /* maxxfer - gran. of DMA engine */
517 0xffffffffull, /* max segment size (DMA boundary) */
518 MPTSAS_MAX_DMA_SEGS, /* scatter/gather list length */
519 512, /* granularity - device transfer size */
520 0 /* flags, set to 0 */
521 };
522
523 ddi_device_acc_attr_t mptsas_dev_attr = {
524 DDI_DEVICE_ATTR_V1,
525 DDI_STRUCTURE_LE_ACC,
526 DDI_STRICTORDER_ACC,
527 DDI_DEFAULT_ACC
528 };
529
530 static struct cb_ops mptsas_cb_ops = {
531 scsi_hba_open, /* open */
532 scsi_hba_close, /* close */
533 nodev, /* strategy */
534 nodev, /* print */
535 nodev, /* dump */
536 nodev, /* read */
537 nodev, /* write */
538 mptsas_ioctl, /* ioctl */
539 nodev, /* devmap */
540 nodev, /* mmap */
541 nodev, /* segmap */
542 nochpoll, /* chpoll */
543 ddi_prop_op, /* cb_prop_op */
544 NULL, /* streamtab */
545 D_MP, /* cb_flag */
546 CB_REV, /* rev */
547 nodev, /* aread */
548 nodev /* awrite */
549 };
550
551 static struct dev_ops mptsas_ops = {
552 DEVO_REV, /* devo_rev, */
553 0, /* refcnt */
554 ddi_no_info, /* info */
555 nulldev, /* identify */
556 nulldev, /* probe */
557 mptsas_attach, /* attach */
558 mptsas_detach, /* detach */
559 #ifdef __sparc
560 mptsas_reset,
561 #else
562 nodev, /* reset */
563 #endif /* __sparc */
564 &mptsas_cb_ops, /* driver operations */
565 NULL, /* bus operations */
566 mptsas_power, /* power management */
567 #ifdef __sparc
568 ddi_quiesce_not_needed
569 #else
570 mptsas_quiesce /* quiesce */
571 #endif /* __sparc */
572 };
573
574 static ddi_ufm_ops_t mptsas_ufm_ops = {
575 NULL,
576 mptsas_ufm_fill_image,
577 mptsas_ufm_fill_slot,
578 mptsas_ufm_getcaps
579 };
580
581 #define MPTSAS_MOD_STRING "MPTSAS HBA Driver 00.00.00.24"
582
583 static struct modldrv modldrv = {
584 &mod_driverops, /* Type of module. This one is a driver */
585 MPTSAS_MOD_STRING, /* Name of the module. */
586 &mptsas_ops, /* driver ops */
587 };
588
589 static struct modlinkage modlinkage = {
590 MODREV_1, &modldrv, NULL
591 };
592 #define TARGET_PROP "target"
593 #define LUN_PROP "lun"
594 #define LUN64_PROP "lun64"
595 #define SAS_PROP "sas-mpt"
596 #define MDI_GUID "wwn"
597 #define NDI_GUID "guid"
598 #define MPTSAS_DEV_GONE "mptsas_dev_gone"
599
600 /*
601 * Local static data
602 */
603 #if defined(MPTSAS_DEBUG)
604 /*
605 * Flags to indicate which debug messages are to be printed and which go to the
606 * debug log ring buffer. Default is to not print anything, and to log
607 * everything except the watchsubr() output which normally happens every second.
608 */
609 uint32_t mptsas_debugprt_flags = 0x0;
610 uint32_t mptsas_debuglog_flags = ~(1U << 30);
611 #endif /* defined(MPTSAS_DEBUG) */
612 uint32_t mptsas_debug_resets = 0;
613
614 static kmutex_t mptsas_global_mutex;
615 static void *mptsas_state; /* soft state ptr */
616 static krwlock_t mptsas_global_rwlock;
617
618 static kmutex_t mptsas_log_mutex;
619 static char mptsas_log_buf[256];
620 _NOTE(MUTEX_PROTECTS_DATA(mptsas_log_mutex, mptsas_log_buf))
621
622 static mptsas_t *mptsas_head, *mptsas_tail;
623 static clock_t mptsas_scsi_watchdog_tick;
624 static clock_t mptsas_tick;
625 static timeout_id_t mptsas_reset_watch;
626 static timeout_id_t mptsas_timeout_id;
627 static int mptsas_timeouts_enabled = 0;
628
629 /*
630 * Default length for extended auto request sense buffers.
631 * All sense buffers need to be under the same alloc because there
632 * is only one common top 32bits (of 64bits) address register.
633 * Most requests only require 32 bytes, but some request >256.
634 * We use rmalloc()/rmfree() on this additional memory to manage the
635 * "extended" requests.
636 */
637 int mptsas_extreq_sense_bufsize = 256*64;
638
639 /*
640 * We believe that all software resrictions of having to run with DMA
641 * attributes to limit allocation to the first 4G are removed.
642 * However, this flag remains to enable quick switchback should suspicious
643 * problems emerge.
644 * Note that scsi_alloc_consistent_buf() does still adhere to allocating
645 * 32 bit addressable memory, but we can cope if that is changed now.
646 */
647 int mptsas_use_64bit_msgaddr = 1;
648
649 /*
650 * warlock directives
651 */
652 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", scsi_pkt \
653 mptsas_cmd NcrTableIndirect buf scsi_cdb scsi_status))
654 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", smp_pkt))
655 _NOTE(SCHEME_PROTECTS_DATA("stable data", scsi_device scsi_address))
656 _NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", mptsas_tgt_private))
657 _NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", scsi_hba_tran::tran_tgt_private))
658
659 /*
660 * SM - HBA statics
661 */
662 char *mptsas_driver_rev = MPTSAS_MOD_STRING;
663
664 #ifdef MPTSAS_DEBUG
665 void debug_enter(char *);
666 #endif
667
668 /*
669 * Notes:
670 * - scsi_hba_init(9F) initializes SCSI HBA modules
671 * - must call scsi_hba_fini(9F) if modload() fails
672 */
673 int
_init(void)674 _init(void)
675 {
676 int status;
677 /* CONSTCOND */
678 ASSERT(NO_COMPETING_THREADS);
679
680 NDBG0(("_init"));
681
682 status = ddi_soft_state_init(&mptsas_state, MPTSAS_SIZE,
683 MPTSAS_INITIAL_SOFT_SPACE);
684 if (status != 0) {
685 return (status);
686 }
687
688 if ((status = scsi_hba_init(&modlinkage)) != 0) {
689 ddi_soft_state_fini(&mptsas_state);
690 return (status);
691 }
692
693 mutex_init(&mptsas_global_mutex, NULL, MUTEX_DRIVER, NULL);
694 rw_init(&mptsas_global_rwlock, NULL, RW_DRIVER, NULL);
695 mutex_init(&mptsas_log_mutex, NULL, MUTEX_DRIVER, NULL);
696
697 if ((status = mod_install(&modlinkage)) != 0) {
698 mutex_destroy(&mptsas_log_mutex);
699 rw_destroy(&mptsas_global_rwlock);
700 mutex_destroy(&mptsas_global_mutex);
701 ddi_soft_state_fini(&mptsas_state);
702 scsi_hba_fini(&modlinkage);
703 }
704
705 return (status);
706 }
707
708 /*
709 * Notes:
710 * - scsi_hba_fini(9F) uninitializes SCSI HBA modules
711 */
712 int
_fini(void)713 _fini(void)
714 {
715 int status;
716 /* CONSTCOND */
717 ASSERT(NO_COMPETING_THREADS);
718
719 NDBG0(("_fini"));
720
721 if ((status = mod_remove(&modlinkage)) == 0) {
722 ddi_soft_state_fini(&mptsas_state);
723 scsi_hba_fini(&modlinkage);
724 mutex_destroy(&mptsas_global_mutex);
725 rw_destroy(&mptsas_global_rwlock);
726 mutex_destroy(&mptsas_log_mutex);
727 }
728 return (status);
729 }
730
731 /*
732 * The loadable-module _info(9E) entry point
733 */
734 int
_info(struct modinfo * modinfop)735 _info(struct modinfo *modinfop)
736 {
737 /* CONSTCOND */
738 ASSERT(NO_COMPETING_THREADS);
739 NDBG0(("mptsas _info"));
740
741 return (mod_info(&modlinkage, modinfop));
742 }
743
744 static int
mptsas_target_eval_devhdl(const void * op,void * arg)745 mptsas_target_eval_devhdl(const void *op, void *arg)
746 {
747 uint16_t dh = *(uint16_t *)arg;
748 const mptsas_target_t *tp = op;
749
750 return ((int)tp->m_devhdl - (int)dh);
751 }
752
753 static int
mptsas_target_eval_nowwn(const void * op,void * arg)754 mptsas_target_eval_nowwn(const void *op, void *arg)
755 {
756 uint8_t phy = *(uint8_t *)arg;
757 const mptsas_target_t *tp = op;
758
759 if (tp->m_addr.mta_wwn != 0)
760 return (-1);
761
762 return ((int)tp->m_phynum - (int)phy);
763 }
764
765 static int
mptsas_smp_eval_devhdl(const void * op,void * arg)766 mptsas_smp_eval_devhdl(const void *op, void *arg)
767 {
768 uint16_t dh = *(uint16_t *)arg;
769 const mptsas_smp_t *sp = op;
770
771 return ((int)sp->m_devhdl - (int)dh);
772 }
773
774 static uint64_t
mptsas_target_addr_hash(const void * tp)775 mptsas_target_addr_hash(const void *tp)
776 {
777 const mptsas_target_addr_t *tap = tp;
778
779 return ((tap->mta_wwn & 0xffffffffffffULL) |
780 ((uint64_t)tap->mta_phymask << 48));
781 }
782
783 static int
mptsas_target_addr_cmp(const void * a,const void * b)784 mptsas_target_addr_cmp(const void *a, const void *b)
785 {
786 const mptsas_target_addr_t *aap = a;
787 const mptsas_target_addr_t *bap = b;
788
789 if (aap->mta_wwn < bap->mta_wwn)
790 return (-1);
791 if (aap->mta_wwn > bap->mta_wwn)
792 return (1);
793 return ((int)bap->mta_phymask - (int)aap->mta_phymask);
794 }
795
796 static uint64_t
mptsas_tmp_target_hash(const void * tp)797 mptsas_tmp_target_hash(const void *tp)
798 {
799 return ((uint64_t)(uintptr_t)tp);
800 }
801
802 static int
mptsas_tmp_target_cmp(const void * a,const void * b)803 mptsas_tmp_target_cmp(const void *a, const void *b)
804 {
805 if (a > b)
806 return (1);
807 if (b < a)
808 return (-1);
809
810 return (0);
811 }
812
813 static void
mptsas_target_free(void * op)814 mptsas_target_free(void *op)
815 {
816 kmem_free(op, sizeof (mptsas_target_t));
817 }
818
819 static void
mptsas_smp_free(void * op)820 mptsas_smp_free(void *op)
821 {
822 kmem_free(op, sizeof (mptsas_smp_t));
823 }
824
825 static void
mptsas_destroy_hashes(mptsas_t * mpt)826 mptsas_destroy_hashes(mptsas_t *mpt)
827 {
828 mptsas_target_t *tp;
829 mptsas_smp_t *sp;
830
831 for (tp = refhash_first(mpt->m_targets); tp != NULL;
832 tp = refhash_next(mpt->m_targets, tp)) {
833 refhash_remove(mpt->m_targets, tp);
834 }
835 for (sp = refhash_first(mpt->m_smp_targets); sp != NULL;
836 sp = refhash_next(mpt->m_smp_targets, sp)) {
837 refhash_remove(mpt->m_smp_targets, sp);
838 }
839 refhash_destroy(mpt->m_tmp_targets);
840 refhash_destroy(mpt->m_targets);
841 refhash_destroy(mpt->m_smp_targets);
842 mpt->m_targets = NULL;
843 mpt->m_smp_targets = NULL;
844 }
845
846 static int
mptsas_iport_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)847 mptsas_iport_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
848 {
849 dev_info_t *pdip;
850 mptsas_t *mpt;
851 scsi_hba_tran_t *hba_tran;
852 char *iport = NULL;
853 char phymask[MPTSAS_MAX_PHYS];
854 mptsas_phymask_t phy_mask = 0;
855 int dynamic_port = 0;
856 uint32_t page_address;
857 char initiator_wwnstr[MPTSAS_WWN_STRLEN];
858 int rval = DDI_FAILURE;
859 int i = 0;
860 uint8_t numphys = 0;
861 uint8_t phy_id;
862 uint8_t phy_port = 0;
863 uint16_t attached_devhdl = 0;
864 uint32_t dev_info;
865 uint64_t attached_sas_wwn;
866 uint16_t dev_hdl;
867 uint16_t pdev_hdl;
868 uint16_t bay_num, enclosure, io_flags;
869 char attached_wwnstr[MPTSAS_WWN_STRLEN];
870
871 /* CONSTCOND */
872 ASSERT(NO_COMPETING_THREADS);
873
874 switch (cmd) {
875 case DDI_ATTACH:
876 break;
877
878 case DDI_RESUME:
879 /*
880 * If this a scsi-iport node, nothing to do here.
881 */
882 return (DDI_SUCCESS);
883
884 default:
885 return (DDI_FAILURE);
886 }
887
888 pdip = ddi_get_parent(dip);
889
890 if ((hba_tran = ndi_flavorv_get(pdip, SCSA_FLAVOR_SCSI_DEVICE)) ==
891 NULL) {
892 cmn_err(CE_WARN, "Failed attach iport because fail to "
893 "get tran vector for the HBA node");
894 return (DDI_FAILURE);
895 }
896
897 mpt = TRAN2MPT(hba_tran);
898 ASSERT(mpt != NULL);
899 if (mpt == NULL)
900 return (DDI_FAILURE);
901
902 if ((hba_tran = ndi_flavorv_get(dip, SCSA_FLAVOR_SCSI_DEVICE)) ==
903 NULL) {
904 mptsas_log(mpt, CE_WARN, "Failed attach iport because fail to "
905 "get tran vector for the iport node");
906 return (DDI_FAILURE);
907 }
908
909 /*
910 * Overwrite parent's tran_hba_private to iport's tran vector
911 */
912 hba_tran->tran_hba_private = mpt;
913
914 ddi_report_dev(dip);
915
916 /*
917 * Get SAS address for initiator port according dev_handle
918 */
919 iport = ddi_get_name_addr(dip);
920 if (iport && strncmp(iport, "v0", 2) == 0) {
921 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip,
922 MPTSAS_VIRTUAL_PORT, 1) !=
923 DDI_PROP_SUCCESS) {
924 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip,
925 MPTSAS_VIRTUAL_PORT);
926 mptsas_log(mpt, CE_WARN, "mptsas virtual port "
927 "prop update failed");
928 return (DDI_FAILURE);
929 }
930 return (DDI_SUCCESS);
931 }
932
933 mutex_enter(&mpt->m_mutex);
934 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
935 bzero(phymask, sizeof (phymask));
936 (void) sprintf(phymask,
937 "%x", mpt->m_phy_info[i].phy_mask);
938 if (strcmp(phymask, iport) == 0) {
939 break;
940 }
941 }
942
943 if (i == MPTSAS_MAX_PHYS) {
944 mptsas_log(mpt, CE_WARN, "Failed attach port %s because port"
945 "seems not exist", iport);
946 mutex_exit(&mpt->m_mutex);
947 return (DDI_FAILURE);
948 }
949
950 phy_mask = mpt->m_phy_info[i].phy_mask;
951
952 if (mpt->m_phy_info[i].port_flags & AUTO_PORT_CONFIGURATION)
953 dynamic_port = 1;
954 else
955 dynamic_port = 0;
956
957 /*
958 * Update PHY info for smhba
959 */
960 if (mptsas_smhba_phy_init(mpt)) {
961 mutex_exit(&mpt->m_mutex);
962 mptsas_log(mpt, CE_WARN, "mptsas phy update "
963 "failed");
964 return (DDI_FAILURE);
965 }
966
967 mutex_exit(&mpt->m_mutex);
968
969 numphys = 0;
970 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
971 if ((phy_mask >> i) & 0x01) {
972 numphys++;
973 }
974 }
975
976 bzero(initiator_wwnstr, sizeof (initiator_wwnstr));
977 (void) sprintf(initiator_wwnstr, "w%016"PRIx64,
978 mpt->un.m_base_wwid);
979
980 if (ddi_prop_update_string(DDI_DEV_T_NONE, dip,
981 SCSI_ADDR_PROP_INITIATOR_PORT, initiator_wwnstr) !=
982 DDI_PROP_SUCCESS) {
983 (void) ddi_prop_remove(DDI_DEV_T_NONE,
984 dip, SCSI_ADDR_PROP_INITIATOR_PORT);
985 mptsas_log(mpt, CE_WARN, "mptsas Initiator port "
986 "prop update failed");
987 return (DDI_FAILURE);
988 }
989 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip,
990 MPTSAS_NUM_PHYS, numphys) !=
991 DDI_PROP_SUCCESS) {
992 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, MPTSAS_NUM_PHYS);
993 return (DDI_FAILURE);
994 }
995
996 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip,
997 "phymask", phy_mask) !=
998 DDI_PROP_SUCCESS) {
999 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "phymask");
1000 mptsas_log(mpt, CE_WARN, "mptsas phy mask "
1001 "prop update failed");
1002 return (DDI_FAILURE);
1003 }
1004
1005 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip,
1006 "dynamic-port", dynamic_port) !=
1007 DDI_PROP_SUCCESS) {
1008 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "dynamic-port");
1009 mptsas_log(mpt, CE_WARN, "mptsas dynamic port "
1010 "prop update failed");
1011 return (DDI_FAILURE);
1012 }
1013 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip,
1014 MPTSAS_VIRTUAL_PORT, 0) !=
1015 DDI_PROP_SUCCESS) {
1016 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip,
1017 MPTSAS_VIRTUAL_PORT);
1018 mptsas_log(mpt, CE_WARN, "mptsas virtual port "
1019 "prop update failed");
1020 return (DDI_FAILURE);
1021 }
1022 mptsas_smhba_set_all_phy_props(mpt, dip, numphys, phy_mask,
1023 &attached_devhdl);
1024
1025 mutex_enter(&mpt->m_mutex);
1026 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
1027 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)attached_devhdl;
1028 rval = mptsas_get_sas_device_page0(mpt, page_address, &dev_hdl,
1029 &attached_sas_wwn, &dev_info, &phy_port, &phy_id,
1030 &pdev_hdl, &bay_num, &enclosure, &io_flags);
1031 if (rval != DDI_SUCCESS) {
1032 mptsas_log(mpt, CE_WARN,
1033 "Failed to get device page0 for handle:%d",
1034 attached_devhdl);
1035 mutex_exit(&mpt->m_mutex);
1036 return (DDI_FAILURE);
1037 }
1038
1039 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
1040 bzero(phymask, sizeof (phymask));
1041 (void) sprintf(phymask, "%x", mpt->m_phy_info[i].phy_mask);
1042 if (strcmp(phymask, iport) == 0) {
1043 (void) sprintf(&mpt->m_phy_info[i].smhba_info.path[0],
1044 "%x",
1045 mpt->m_phy_info[i].phy_mask);
1046 }
1047 }
1048 mutex_exit(&mpt->m_mutex);
1049
1050 bzero(attached_wwnstr, sizeof (attached_wwnstr));
1051 (void) sprintf(attached_wwnstr, "w%016"PRIx64,
1052 attached_sas_wwn);
1053 if (ddi_prop_update_string(DDI_DEV_T_NONE, dip,
1054 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) !=
1055 DDI_PROP_SUCCESS) {
1056 (void) ddi_prop_remove(DDI_DEV_T_NONE,
1057 dip, SCSI_ADDR_PROP_ATTACHED_PORT);
1058 return (DDI_FAILURE);
1059 }
1060
1061 /* Create kstats for each phy on this iport */
1062
1063 mptsas_create_phy_stats(mpt, iport, dip);
1064
1065 /*
1066 * register sas hba iport with mdi (MPxIO/vhci)
1067 */
1068 if (mdi_phci_register(MDI_HCI_CLASS_SCSI,
1069 dip, 0) == MDI_SUCCESS) {
1070 mpt->m_mpxio_enable = TRUE;
1071 }
1072 return (DDI_SUCCESS);
1073 }
1074
1075 /*
1076 * Notes:
1077 * Set up all device state and allocate data structures,
1078 * mutexes, condition variables, etc. for device operation.
1079 * Add interrupts needed.
1080 * Return DDI_SUCCESS if device is ready, else return DDI_FAILURE.
1081 */
1082 static int
mptsas_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)1083 mptsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
1084 {
1085 mptsas_t *mpt = NULL;
1086 int instance, i, j;
1087 int doneq_thread_num;
1088 char intr_added = 0;
1089 char map_setup = 0;
1090 char config_setup = 0;
1091 char hba_attach_setup = 0;
1092 char smp_attach_setup = 0;
1093 char enc_attach_setup = 0;
1094 char mutex_init_done = 0;
1095 char event_taskq_create = 0;
1096 char dr_taskq_create = 0;
1097 char doneq_thread_create = 0;
1098 char added_watchdog = 0;
1099 scsi_hba_tran_t *hba_tran;
1100 uint_t mem_bar;
1101 int rval = DDI_FAILURE;
1102
1103 /* CONSTCOND */
1104 ASSERT(NO_COMPETING_THREADS);
1105
1106 if (scsi_hba_iport_unit_address(dip)) {
1107 return (mptsas_iport_attach(dip, cmd));
1108 }
1109
1110 switch (cmd) {
1111 case DDI_ATTACH:
1112 break;
1113
1114 case DDI_RESUME:
1115 if ((hba_tran = ddi_get_driver_private(dip)) == NULL)
1116 return (DDI_FAILURE);
1117
1118 mpt = TRAN2MPT(hba_tran);
1119
1120 if (!mpt) {
1121 return (DDI_FAILURE);
1122 }
1123
1124 /*
1125 * Reset hardware and softc to "no outstanding commands"
1126 * Note that a check condition can result on first command
1127 * to a target.
1128 */
1129 mutex_enter(&mpt->m_mutex);
1130
1131 /*
1132 * raise power.
1133 */
1134 if (mpt->m_options & MPTSAS_OPT_PM) {
1135 mutex_exit(&mpt->m_mutex);
1136 (void) pm_busy_component(dip, 0);
1137 rval = pm_power_has_changed(dip, 0, PM_LEVEL_D0);
1138 if (rval == DDI_SUCCESS) {
1139 mutex_enter(&mpt->m_mutex);
1140 } else {
1141 /*
1142 * The pm_raise_power() call above failed,
1143 * and that can only occur if we were unable
1144 * to reset the hardware. This is probably
1145 * due to unhealty hardware, and because
1146 * important filesystems(such as the root
1147 * filesystem) could be on the attached disks,
1148 * it would not be a good idea to continue,
1149 * as we won't be entirely certain we are
1150 * writing correct data. So we panic() here
1151 * to not only prevent possible data corruption,
1152 * but to give developers or end users a hope
1153 * of identifying and correcting any problems.
1154 */
1155 fm_panic("mptsas could not reset hardware "
1156 "during resume");
1157 }
1158 }
1159
1160 mpt->m_suspended = 0;
1161
1162 /*
1163 * Reinitialize ioc
1164 */
1165 mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET;
1166 if (mptsas_init_chip(mpt, FALSE) == DDI_FAILURE) {
1167 mutex_exit(&mpt->m_mutex);
1168 if (mpt->m_options & MPTSAS_OPT_PM) {
1169 (void) pm_idle_component(dip, 0);
1170 }
1171 fm_panic("mptsas init chip fail during resume");
1172 }
1173 /*
1174 * mptsas_update_driver_data needs interrupts so enable them
1175 * first.
1176 */
1177 MPTSAS_ENABLE_INTR(mpt);
1178 mptsas_update_driver_data(mpt);
1179
1180 /* start requests, if possible */
1181 mptsas_restart_hba(mpt);
1182
1183 mutex_exit(&mpt->m_mutex);
1184
1185 /*
1186 * Restart watch thread
1187 */
1188 mutex_enter(&mptsas_global_mutex);
1189 if (mptsas_timeout_id == 0) {
1190 mptsas_timeout_id = timeout(mptsas_watch, NULL,
1191 mptsas_tick);
1192 mptsas_timeouts_enabled = 1;
1193 }
1194 mutex_exit(&mptsas_global_mutex);
1195
1196 /* report idle status to pm framework */
1197 if (mpt->m_options & MPTSAS_OPT_PM) {
1198 (void) pm_idle_component(dip, 0);
1199 }
1200
1201 return (DDI_SUCCESS);
1202
1203 default:
1204 return (DDI_FAILURE);
1205
1206 }
1207
1208 instance = ddi_get_instance(dip);
1209
1210 /*
1211 * Allocate softc information.
1212 */
1213 if (ddi_soft_state_zalloc(mptsas_state, instance) != DDI_SUCCESS) {
1214 mptsas_log(NULL, CE_WARN,
1215 "mptsas%d: cannot allocate soft state", instance);
1216 goto fail;
1217 }
1218
1219 mpt = ddi_get_soft_state(mptsas_state, instance);
1220
1221 if (mpt == NULL) {
1222 mptsas_log(NULL, CE_WARN,
1223 "mptsas%d: cannot get soft state", instance);
1224 goto fail;
1225 }
1226
1227 /* Indicate that we are 'sizeof (scsi_*(9S))' clean. */
1228 scsi_size_clean(dip);
1229
1230 mpt->m_dip = dip;
1231 mpt->m_instance = instance;
1232
1233 /* Make a per-instance copy of the structures */
1234 mpt->m_io_dma_attr = mptsas_dma_attrs64;
1235 if (mptsas_use_64bit_msgaddr) {
1236 mpt->m_msg_dma_attr = mptsas_dma_attrs64;
1237 } else {
1238 mpt->m_msg_dma_attr = mptsas_dma_attrs;
1239 }
1240 mpt->m_reg_acc_attr = mptsas_dev_attr;
1241 mpt->m_dev_acc_attr = mptsas_dev_attr;
1242
1243 /*
1244 * Size of individual request sense buffer
1245 */
1246 mpt->m_req_sense_size = EXTCMDS_STATUS_SIZE;
1247
1248 /*
1249 * Initialize FMA
1250 */
1251 mpt->m_fm_capabilities = ddi_getprop(DDI_DEV_T_ANY, mpt->m_dip,
1252 DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "fm-capable",
1253 DDI_FM_EREPORT_CAPABLE | DDI_FM_ACCCHK_CAPABLE |
1254 DDI_FM_DMACHK_CAPABLE | DDI_FM_ERRCB_CAPABLE);
1255
1256 mptsas_fm_init(mpt);
1257
1258 /*
1259 * Initialize us with the UFM subsystem
1260 */
1261 if (ddi_ufm_init(dip, DDI_UFM_CURRENT_VERSION, &mptsas_ufm_ops,
1262 &mpt->m_ufmh, mpt) != 0) {
1263 mptsas_log(mpt, CE_WARN, "failed to initialize UFM subsystem");
1264 goto fail;
1265 }
1266
1267 if (mptsas_alloc_handshake_msg(mpt,
1268 sizeof (Mpi2SCSITaskManagementRequest_t)) == DDI_FAILURE) {
1269 mptsas_log(mpt, CE_WARN, "cannot initialize handshake msg.");
1270 goto fail;
1271 }
1272
1273 /*
1274 * Setup configuration space
1275 */
1276 if (mptsas_config_space_init(mpt) == FALSE) {
1277 mptsas_log(mpt, CE_WARN, "mptsas_config_space_init failed");
1278 goto fail;
1279 }
1280 config_setup++;
1281
1282 mem_bar = mpt->m_mem_bar;
1283 if (ddi_regs_map_setup(dip, mem_bar, (caddr_t *)&mpt->m_reg,
1284 0, 0, &mpt->m_reg_acc_attr, &mpt->m_datap) != DDI_SUCCESS) {
1285 mptsas_log(mpt, CE_WARN, "map setup failed");
1286 goto fail;
1287 }
1288 map_setup++;
1289
1290 /*
1291 * A taskq is created for dealing with the event handler
1292 */
1293 if ((mpt->m_event_taskq = ddi_taskq_create(dip, "mptsas_event_taskq",
1294 1, TASKQ_DEFAULTPRI, 0)) == NULL) {
1295 mptsas_log(mpt, CE_NOTE, "ddi_taskq_create failed");
1296 goto fail;
1297 }
1298 event_taskq_create++;
1299
1300 /*
1301 * A taskq is created for dealing with dr events
1302 */
1303 if ((mpt->m_dr_taskq = ddi_taskq_create(dip,
1304 "mptsas_dr_taskq",
1305 1, TASKQ_DEFAULTPRI, 0)) == NULL) {
1306 mptsas_log(mpt, CE_NOTE, "ddi_taskq_create for discovery "
1307 "failed");
1308 goto fail;
1309 }
1310 dr_taskq_create++;
1311
1312 mpt->m_doneq_thread_threshold = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
1313 0, "mptsas_doneq_thread_threshold_prop", 10);
1314 mpt->m_doneq_length_threshold = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
1315 0, "mptsas_doneq_length_threshold_prop", 8);
1316 mpt->m_doneq_thread_n = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
1317 0, "mptsas_doneq_thread_n_prop", 8);
1318
1319 if (mpt->m_doneq_thread_n) {
1320 cv_init(&mpt->m_doneq_thread_cv, NULL, CV_DRIVER, NULL);
1321 mutex_init(&mpt->m_doneq_mutex, NULL, MUTEX_DRIVER, NULL);
1322
1323 mutex_enter(&mpt->m_doneq_mutex);
1324 mpt->m_doneq_thread_id =
1325 kmem_zalloc(sizeof (mptsas_doneq_thread_list_t)
1326 * mpt->m_doneq_thread_n, KM_SLEEP);
1327
1328 for (j = 0; j < mpt->m_doneq_thread_n; j++) {
1329 cv_init(&mpt->m_doneq_thread_id[j].cv, NULL,
1330 CV_DRIVER, NULL);
1331 mutex_init(&mpt->m_doneq_thread_id[j].mutex, NULL,
1332 MUTEX_DRIVER, NULL);
1333 mutex_enter(&mpt->m_doneq_thread_id[j].mutex);
1334 mpt->m_doneq_thread_id[j].flag |=
1335 MPTSAS_DONEQ_THREAD_ACTIVE;
1336 mpt->m_doneq_thread_id[j].arg.mpt = mpt;
1337 mpt->m_doneq_thread_id[j].arg.t = j;
1338 mpt->m_doneq_thread_id[j].threadp =
1339 thread_create(NULL, 0, mptsas_doneq_thread,
1340 &mpt->m_doneq_thread_id[j].arg,
1341 0, &p0, TS_RUN, minclsyspri);
1342 mpt->m_doneq_thread_id[j].donetail =
1343 &mpt->m_doneq_thread_id[j].doneq;
1344 mutex_exit(&mpt->m_doneq_thread_id[j].mutex);
1345 }
1346 mutex_exit(&mpt->m_doneq_mutex);
1347 doneq_thread_create++;
1348 }
1349
1350 /*
1351 * Disable hardware interrupt since we're not ready to
1352 * handle it yet.
1353 */
1354 MPTSAS_DISABLE_INTR(mpt);
1355 if (mptsas_register_intrs(mpt) == FALSE)
1356 goto fail;
1357 intr_added++;
1358
1359 /* Initialize mutex used in interrupt handler */
1360 mutex_init(&mpt->m_mutex, NULL, MUTEX_DRIVER,
1361 DDI_INTR_PRI(mpt->m_intr_pri));
1362 mutex_init(&mpt->m_passthru_mutex, NULL, MUTEX_DRIVER, NULL);
1363 mutex_init(&mpt->m_tx_waitq_mutex, NULL, MUTEX_DRIVER,
1364 DDI_INTR_PRI(mpt->m_intr_pri));
1365 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
1366 mutex_init(&mpt->m_phy_info[i].smhba_info.phy_mutex,
1367 NULL, MUTEX_DRIVER,
1368 DDI_INTR_PRI(mpt->m_intr_pri));
1369 }
1370
1371 cv_init(&mpt->m_cv, NULL, CV_DRIVER, NULL);
1372 cv_init(&mpt->m_passthru_cv, NULL, CV_DRIVER, NULL);
1373 cv_init(&mpt->m_fw_cv, NULL, CV_DRIVER, NULL);
1374 cv_init(&mpt->m_config_cv, NULL, CV_DRIVER, NULL);
1375 cv_init(&mpt->m_fw_diag_cv, NULL, CV_DRIVER, NULL);
1376 cv_init(&mpt->m_extreq_sense_refcount_cv, NULL, CV_DRIVER, NULL);
1377 mutex_init_done++;
1378
1379 mutex_enter(&mpt->m_mutex);
1380 /*
1381 * Initialize power management component
1382 */
1383 if (mpt->m_options & MPTSAS_OPT_PM) {
1384 if (mptsas_init_pm(mpt)) {
1385 mutex_exit(&mpt->m_mutex);
1386 mptsas_log(mpt, CE_WARN, "mptsas pm initialization "
1387 "failed");
1388 goto fail;
1389 }
1390 }
1391
1392 /*
1393 * Initialize chip using Message Unit Reset, if allowed
1394 */
1395 mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET;
1396 if (mptsas_init_chip(mpt, TRUE) == DDI_FAILURE) {
1397 mutex_exit(&mpt->m_mutex);
1398 mptsas_log(mpt, CE_WARN, "mptsas chip initialization failed");
1399 goto fail;
1400 }
1401
1402 mpt->m_targets = refhash_create(MPTSAS_TARGET_BUCKET_COUNT,
1403 mptsas_target_addr_hash, mptsas_target_addr_cmp,
1404 mptsas_target_free, sizeof (mptsas_target_t),
1405 offsetof(mptsas_target_t, m_link),
1406 offsetof(mptsas_target_t, m_addr), KM_SLEEP);
1407
1408 /*
1409 * The refhash for temporary targets uses the address of the target
1410 * struct itself as tag, so the tag offset is 0. See the implementation
1411 * of mptsas_tmp_target_hash() and mptsas_tmp_target_cmp().
1412 */
1413 mpt->m_tmp_targets = refhash_create(MPTSAS_TMP_TARGET_BUCKET_COUNT,
1414 mptsas_tmp_target_hash, mptsas_tmp_target_cmp,
1415 mptsas_target_free, sizeof (mptsas_target_t),
1416 offsetof(mptsas_target_t, m_link), 0, KM_SLEEP);
1417
1418 /*
1419 * Fill in the phy_info structure and get the base WWID
1420 */
1421 if (mptsas_get_manufacture_page5(mpt) == DDI_FAILURE) {
1422 mptsas_log(mpt, CE_WARN,
1423 "mptsas_get_manufacture_page5 failed!");
1424 goto fail;
1425 }
1426
1427 if (mptsas_get_sas_io_unit_page_hndshk(mpt)) {
1428 mptsas_log(mpt, CE_WARN,
1429 "mptsas_get_sas_io_unit_page_hndshk failed!");
1430 goto fail;
1431 }
1432
1433 if (mptsas_get_manufacture_page0(mpt) == DDI_FAILURE) {
1434 mptsas_log(mpt, CE_WARN,
1435 "mptsas_get_manufacture_page0 failed!");
1436 goto fail;
1437 }
1438
1439 mutex_exit(&mpt->m_mutex);
1440
1441 /*
1442 * Register the iport for multiple port HBA
1443 */
1444 mptsas_iport_register(mpt);
1445
1446 /*
1447 * initialize SCSI HBA transport structure
1448 */
1449 if (mptsas_hba_setup(mpt) == FALSE)
1450 goto fail;
1451 hba_attach_setup++;
1452
1453 if (mptsas_smp_setup(mpt) == FALSE)
1454 goto fail;
1455 smp_attach_setup++;
1456
1457 if (mptsas_enc_setup(mpt) == FALSE)
1458 goto fail;
1459 enc_attach_setup++;
1460
1461 if (mptsas_cache_create(mpt) == FALSE)
1462 goto fail;
1463
1464 mpt->m_scsi_reset_delay = ddi_prop_get_int(DDI_DEV_T_ANY,
1465 dip, 0, "scsi-reset-delay", SCSI_DEFAULT_RESET_DELAY);
1466 if (mpt->m_scsi_reset_delay == 0) {
1467 mptsas_log(mpt, CE_NOTE,
1468 "scsi_reset_delay of 0 is not recommended,"
1469 " resetting to SCSI_DEFAULT_RESET_DELAY\n");
1470 mpt->m_scsi_reset_delay = SCSI_DEFAULT_RESET_DELAY;
1471 }
1472
1473 /*
1474 * Initialize the wait and done FIFO queue
1475 */
1476 mpt->m_donetail = &mpt->m_doneq;
1477 mpt->m_waitqtail = &mpt->m_waitq;
1478 mpt->m_tx_waitqtail = &mpt->m_tx_waitq;
1479 mpt->m_tx_draining = 0;
1480
1481 /*
1482 * ioc cmd queue initialize
1483 */
1484 mpt->m_ioc_event_cmdtail = &mpt->m_ioc_event_cmdq;
1485 mpt->m_dev_handle = 0xFFFF;
1486
1487 MPTSAS_ENABLE_INTR(mpt);
1488
1489 /*
1490 * enable event notification
1491 */
1492 mutex_enter(&mpt->m_mutex);
1493 if (mptsas_ioc_enable_event_notification(mpt)) {
1494 mutex_exit(&mpt->m_mutex);
1495 goto fail;
1496 }
1497 mutex_exit(&mpt->m_mutex);
1498
1499 /*
1500 * used for mptsas_watch
1501 */
1502 mptsas_list_add(mpt);
1503
1504 mutex_enter(&mptsas_global_mutex);
1505 if (mptsas_timeouts_enabled == 0) {
1506 mptsas_scsi_watchdog_tick = ddi_prop_get_int(DDI_DEV_T_ANY,
1507 dip, 0, "scsi-watchdog-tick", DEFAULT_WD_TICK);
1508
1509 mptsas_tick = mptsas_scsi_watchdog_tick *
1510 drv_usectohz((clock_t)1000000);
1511
1512 mptsas_timeout_id = timeout(mptsas_watch, NULL, mptsas_tick);
1513 mptsas_timeouts_enabled = 1;
1514 }
1515 mutex_exit(&mptsas_global_mutex);
1516 added_watchdog++;
1517
1518 /*
1519 * Initialize PHY info for smhba.
1520 * This requires watchdog to be enabled otherwise if interrupts
1521 * don't work the system will hang.
1522 */
1523 if (mptsas_smhba_setup(mpt)) {
1524 mptsas_log(mpt, CE_WARN, "mptsas phy initialization "
1525 "failed");
1526 goto fail;
1527 }
1528
1529 /* Check all dma handles allocated in attach */
1530 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl)
1531 != DDI_SUCCESS) ||
1532 (mptsas_check_dma_handle(mpt->m_dma_req_sense_hdl)
1533 != DDI_SUCCESS) ||
1534 (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl)
1535 != DDI_SUCCESS) ||
1536 (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl)
1537 != DDI_SUCCESS) ||
1538 (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl)
1539 != DDI_SUCCESS) ||
1540 (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl)
1541 != DDI_SUCCESS)) {
1542 goto fail;
1543 }
1544
1545 /* Check all acc handles allocated in attach */
1546 if ((mptsas_check_acc_handle(mpt->m_datap) != DDI_SUCCESS) ||
1547 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl)
1548 != DDI_SUCCESS) ||
1549 (mptsas_check_acc_handle(mpt->m_acc_req_sense_hdl)
1550 != DDI_SUCCESS) ||
1551 (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl)
1552 != DDI_SUCCESS) ||
1553 (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl)
1554 != DDI_SUCCESS) ||
1555 (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl)
1556 != DDI_SUCCESS) ||
1557 (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl)
1558 != DDI_SUCCESS) ||
1559 (mptsas_check_acc_handle(mpt->m_config_handle)
1560 != DDI_SUCCESS)) {
1561 goto fail;
1562 }
1563
1564 /*
1565 * After this point, we are not going to fail the attach.
1566 */
1567
1568 /* Let the UFM susbsystem know we're ready to receive callbacks */
1569 ddi_ufm_update(mpt->m_ufmh);
1570
1571 /* Print message of HBA present */
1572 ddi_report_dev(dip);
1573
1574 /* report idle status to pm framework */
1575 if (mpt->m_options & MPTSAS_OPT_PM) {
1576 (void) pm_idle_component(dip, 0);
1577 }
1578
1579 return (DDI_SUCCESS);
1580
1581 fail:
1582 mptsas_log(mpt, CE_WARN, "attach failed");
1583 mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE);
1584 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST);
1585 if (mpt) {
1586 /* deallocate in reverse order */
1587 if (added_watchdog) {
1588 mptsas_list_del(mpt);
1589 mutex_enter(&mptsas_global_mutex);
1590
1591 if (mptsas_timeout_id && (mptsas_head == NULL)) {
1592 timeout_id_t tid = mptsas_timeout_id;
1593 mptsas_timeouts_enabled = 0;
1594 mptsas_timeout_id = 0;
1595 mutex_exit(&mptsas_global_mutex);
1596 (void) untimeout(tid);
1597 mutex_enter(&mptsas_global_mutex);
1598 }
1599 mutex_exit(&mptsas_global_mutex);
1600 }
1601
1602 mptsas_cache_destroy(mpt);
1603
1604 if (smp_attach_setup) {
1605 mptsas_smp_teardown(mpt);
1606 }
1607 if (enc_attach_setup) {
1608 mptsas_enc_teardown(mpt);
1609 }
1610 if (hba_attach_setup) {
1611 mptsas_hba_teardown(mpt);
1612 }
1613
1614 if (mpt->m_tmp_targets)
1615 refhash_destroy(mpt->m_tmp_targets);
1616 if (mpt->m_targets)
1617 refhash_destroy(mpt->m_targets);
1618 if (mpt->m_smp_targets)
1619 refhash_destroy(mpt->m_smp_targets);
1620
1621 if (mpt->m_active) {
1622 mptsas_free_active_slots(mpt);
1623 }
1624 if (intr_added) {
1625 mptsas_unregister_intrs(mpt);
1626 }
1627
1628 if (doneq_thread_create) {
1629 mutex_enter(&mpt->m_doneq_mutex);
1630 doneq_thread_num = mpt->m_doneq_thread_n;
1631 for (j = 0; j < mpt->m_doneq_thread_n; j++) {
1632 mutex_enter(&mpt->m_doneq_thread_id[j].mutex);
1633 mpt->m_doneq_thread_id[j].flag &=
1634 (~MPTSAS_DONEQ_THREAD_ACTIVE);
1635 cv_signal(&mpt->m_doneq_thread_id[j].cv);
1636 mutex_exit(&mpt->m_doneq_thread_id[j].mutex);
1637 }
1638 while (mpt->m_doneq_thread_n) {
1639 cv_wait(&mpt->m_doneq_thread_cv,
1640 &mpt->m_doneq_mutex);
1641 }
1642 for (j = 0; j < doneq_thread_num; j++) {
1643 cv_destroy(&mpt->m_doneq_thread_id[j].cv);
1644 mutex_destroy(&mpt->m_doneq_thread_id[j].mutex);
1645 }
1646 kmem_free(mpt->m_doneq_thread_id,
1647 sizeof (mptsas_doneq_thread_list_t)
1648 * doneq_thread_num);
1649 mutex_exit(&mpt->m_doneq_mutex);
1650 cv_destroy(&mpt->m_doneq_thread_cv);
1651 mutex_destroy(&mpt->m_doneq_mutex);
1652 }
1653 if (event_taskq_create) {
1654 ddi_taskq_destroy(mpt->m_event_taskq);
1655 }
1656 if (dr_taskq_create) {
1657 ddi_taskq_destroy(mpt->m_dr_taskq);
1658 }
1659 if (mutex_init_done) {
1660 mutex_destroy(&mpt->m_tx_waitq_mutex);
1661 mutex_destroy(&mpt->m_passthru_mutex);
1662 mutex_destroy(&mpt->m_mutex);
1663 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
1664 mutex_destroy(
1665 &mpt->m_phy_info[i].smhba_info.phy_mutex);
1666 }
1667 cv_destroy(&mpt->m_cv);
1668 cv_destroy(&mpt->m_passthru_cv);
1669 cv_destroy(&mpt->m_fw_cv);
1670 cv_destroy(&mpt->m_config_cv);
1671 cv_destroy(&mpt->m_fw_diag_cv);
1672 cv_destroy(&mpt->m_extreq_sense_refcount_cv);
1673 }
1674
1675 if (map_setup) {
1676 mptsas_cfg_fini(mpt);
1677 }
1678 if (config_setup) {
1679 mptsas_config_space_fini(mpt);
1680 }
1681 mptsas_free_handshake_msg(mpt);
1682 mptsas_hba_fini(mpt);
1683
1684 mptsas_fm_fini(mpt);
1685 ddi_soft_state_free(mptsas_state, instance);
1686 ddi_prop_remove_all(dip);
1687 }
1688 return (DDI_FAILURE);
1689 }
1690
1691 static int
mptsas_suspend(dev_info_t * devi)1692 mptsas_suspend(dev_info_t *devi)
1693 {
1694 mptsas_t *mpt, *g;
1695 scsi_hba_tran_t *tran;
1696
1697 if (scsi_hba_iport_unit_address(devi)) {
1698 return (DDI_SUCCESS);
1699 }
1700
1701 if ((tran = ddi_get_driver_private(devi)) == NULL)
1702 return (DDI_SUCCESS);
1703
1704 mpt = TRAN2MPT(tran);
1705 if (!mpt) {
1706 return (DDI_SUCCESS);
1707 }
1708
1709 mutex_enter(&mpt->m_mutex);
1710
1711 if (mpt->m_suspended++) {
1712 mutex_exit(&mpt->m_mutex);
1713 return (DDI_SUCCESS);
1714 }
1715
1716 /*
1717 * Cancel timeout threads for this mpt
1718 */
1719 if (mpt->m_quiesce_timeid) {
1720 timeout_id_t tid = mpt->m_quiesce_timeid;
1721 mpt->m_quiesce_timeid = 0;
1722 mutex_exit(&mpt->m_mutex);
1723 (void) untimeout(tid);
1724 mutex_enter(&mpt->m_mutex);
1725 }
1726
1727 if (mpt->m_restart_cmd_timeid) {
1728 timeout_id_t tid = mpt->m_restart_cmd_timeid;
1729 mpt->m_restart_cmd_timeid = 0;
1730 mutex_exit(&mpt->m_mutex);
1731 (void) untimeout(tid);
1732 mutex_enter(&mpt->m_mutex);
1733 }
1734
1735 mutex_exit(&mpt->m_mutex);
1736
1737 (void) pm_idle_component(mpt->m_dip, 0);
1738
1739 /*
1740 * Cancel watch threads if all mpts suspended
1741 */
1742 rw_enter(&mptsas_global_rwlock, RW_WRITER);
1743 for (g = mptsas_head; g != NULL; g = g->m_next) {
1744 if (!g->m_suspended)
1745 break;
1746 }
1747 rw_exit(&mptsas_global_rwlock);
1748
1749 mutex_enter(&mptsas_global_mutex);
1750 if (g == NULL) {
1751 timeout_id_t tid;
1752
1753 mptsas_timeouts_enabled = 0;
1754 if (mptsas_timeout_id) {
1755 tid = mptsas_timeout_id;
1756 mptsas_timeout_id = 0;
1757 mutex_exit(&mptsas_global_mutex);
1758 (void) untimeout(tid);
1759 mutex_enter(&mptsas_global_mutex);
1760 }
1761 if (mptsas_reset_watch) {
1762 tid = mptsas_reset_watch;
1763 mptsas_reset_watch = 0;
1764 mutex_exit(&mptsas_global_mutex);
1765 (void) untimeout(tid);
1766 mutex_enter(&mptsas_global_mutex);
1767 }
1768 }
1769 mutex_exit(&mptsas_global_mutex);
1770
1771 mutex_enter(&mpt->m_mutex);
1772
1773 /*
1774 * If this mpt is not in full power(PM_LEVEL_D0), just return.
1775 */
1776 if ((mpt->m_options & MPTSAS_OPT_PM) &&
1777 (mpt->m_power_level != PM_LEVEL_D0)) {
1778 mutex_exit(&mpt->m_mutex);
1779 return (DDI_SUCCESS);
1780 }
1781
1782 /* Disable HBA interrupts in hardware */
1783 MPTSAS_DISABLE_INTR(mpt);
1784 /*
1785 * Send RAID action system shutdown to sync IR
1786 */
1787 mptsas_raid_action_system_shutdown(mpt);
1788
1789 mutex_exit(&mpt->m_mutex);
1790
1791 /* drain the taskq */
1792 ddi_taskq_wait(mpt->m_event_taskq);
1793 ddi_taskq_wait(mpt->m_dr_taskq);
1794
1795 return (DDI_SUCCESS);
1796 }
1797
1798 #ifdef __sparc
1799 /*ARGSUSED*/
1800 static int
mptsas_reset(dev_info_t * devi,ddi_reset_cmd_t cmd)1801 mptsas_reset(dev_info_t *devi, ddi_reset_cmd_t cmd)
1802 {
1803 mptsas_t *mpt;
1804 scsi_hba_tran_t *tran;
1805
1806 /*
1807 * If this call is for iport, just return.
1808 */
1809 if (scsi_hba_iport_unit_address(devi))
1810 return (DDI_SUCCESS);
1811
1812 if ((tran = ddi_get_driver_private(devi)) == NULL)
1813 return (DDI_SUCCESS);
1814
1815 if ((mpt = TRAN2MPT(tran)) == NULL)
1816 return (DDI_SUCCESS);
1817
1818 /*
1819 * Send RAID action system shutdown to sync IR. Disable HBA
1820 * interrupts in hardware first.
1821 */
1822 MPTSAS_DISABLE_INTR(mpt);
1823 mptsas_raid_action_system_shutdown(mpt);
1824
1825 return (DDI_SUCCESS);
1826 }
1827 #else /* __sparc */
1828 /*
1829 * quiesce(9E) entry point.
1830 *
1831 * This function is called when the system is single-threaded at high
1832 * PIL with preemption disabled. Therefore, this function must not be
1833 * blocked.
1834 *
1835 * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
1836 * DDI_FAILURE indicates an error condition and should almost never happen.
1837 */
1838 static int
mptsas_quiesce(dev_info_t * devi)1839 mptsas_quiesce(dev_info_t *devi)
1840 {
1841 mptsas_t *mpt;
1842 scsi_hba_tran_t *tran;
1843
1844 /*
1845 * If this call is for iport, just return.
1846 */
1847 if (scsi_hba_iport_unit_address(devi))
1848 return (DDI_SUCCESS);
1849
1850 if ((tran = ddi_get_driver_private(devi)) == NULL)
1851 return (DDI_SUCCESS);
1852
1853 if ((mpt = TRAN2MPT(tran)) == NULL)
1854 return (DDI_SUCCESS);
1855
1856 /* Disable HBA interrupts in hardware */
1857 MPTSAS_DISABLE_INTR(mpt);
1858 /* Send RAID action system shutdonw to sync IR */
1859 mptsas_raid_action_system_shutdown(mpt);
1860
1861 return (DDI_SUCCESS);
1862 }
1863 #endif /* __sparc */
1864
1865 /*
1866 * detach(9E). Remove all device allocations and system resources;
1867 * disable device interrupts.
1868 * Return DDI_SUCCESS if done; DDI_FAILURE if there's a problem.
1869 */
1870 static int
mptsas_detach(dev_info_t * devi,ddi_detach_cmd_t cmd)1871 mptsas_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
1872 {
1873 /* CONSTCOND */
1874 ASSERT(NO_COMPETING_THREADS);
1875 NDBG0(("mptsas_detach: dip=0x%p cmd=0x%p", (void *)devi, (void *)cmd));
1876
1877 switch (cmd) {
1878 case DDI_DETACH:
1879 return (mptsas_do_detach(devi));
1880
1881 case DDI_SUSPEND:
1882 return (mptsas_suspend(devi));
1883
1884 default:
1885 return (DDI_FAILURE);
1886 }
1887 /* NOTREACHED */
1888 }
1889
1890 static int
mptsas_do_detach(dev_info_t * dip)1891 mptsas_do_detach(dev_info_t *dip)
1892 {
1893 mptsas_t *mpt;
1894 scsi_hba_tran_t *tran;
1895 mdi_pathinfo_t *pip = NULL;
1896 int i;
1897 int doneq_thread_num = 0;
1898
1899 NDBG0(("mptsas_do_detach: dip=0x%p", (void *)dip));
1900
1901 if ((tran = ndi_flavorv_get(dip, SCSA_FLAVOR_SCSI_DEVICE)) == NULL)
1902 return (DDI_FAILURE);
1903
1904 mpt = TRAN2MPT(tran);
1905 if (!mpt) {
1906 return (DDI_FAILURE);
1907 }
1908
1909 ddi_ufm_fini(mpt->m_ufmh);
1910
1911 /*
1912 * Still have pathinfo child, should not detach mpt driver
1913 */
1914 if (scsi_hba_iport_unit_address(dip)) {
1915 if (mpt->m_mpxio_enable) {
1916 /*
1917 * MPxIO enabled for the iport
1918 */
1919 ndi_devi_enter(scsi_vhci_dip);
1920 ndi_devi_enter(dip);
1921 while ((pip = mdi_get_next_client_path(dip, NULL)) !=
1922 NULL) {
1923 if (mdi_pi_free(pip, 0) == MDI_SUCCESS) {
1924 continue;
1925 }
1926 ndi_devi_exit(dip);
1927 ndi_devi_exit(scsi_vhci_dip);
1928 NDBG12(("detach failed because of "
1929 "outstanding path info"));
1930 return (DDI_FAILURE);
1931 }
1932 ndi_devi_exit(dip);
1933 ndi_devi_exit(scsi_vhci_dip);
1934 (void) mdi_phci_unregister(dip, 0);
1935 }
1936
1937 ddi_prop_remove_all(dip);
1938
1939 return (DDI_SUCCESS);
1940 }
1941
1942 /* Make sure power level is D0 before accessing registers */
1943 if (mpt->m_options & MPTSAS_OPT_PM) {
1944 (void) pm_busy_component(dip, 0);
1945 if (mpt->m_power_level != PM_LEVEL_D0) {
1946 if (pm_raise_power(dip, 0, PM_LEVEL_D0) !=
1947 DDI_SUCCESS) {
1948 mptsas_log(mpt, CE_WARN,
1949 "mptsas%d: Raise power request failed.",
1950 mpt->m_instance);
1951 (void) pm_idle_component(dip, 0);
1952 return (DDI_FAILURE);
1953 }
1954 }
1955 }
1956
1957 /*
1958 * Send RAID action system shutdown to sync IR. After action, send a
1959 * Message Unit Reset. Since after that DMA resource will be freed,
1960 * set ioc to READY state will avoid HBA initiated DMA operation.
1961 */
1962 mutex_enter(&mpt->m_mutex);
1963 MPTSAS_DISABLE_INTR(mpt);
1964 mptsas_raid_action_system_shutdown(mpt);
1965 mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET;
1966 (void) mptsas_ioc_reset(mpt, FALSE);
1967 mutex_exit(&mpt->m_mutex);
1968 mptsas_rem_intrs(mpt);
1969 ddi_taskq_destroy(mpt->m_event_taskq);
1970 ddi_taskq_destroy(mpt->m_dr_taskq);
1971
1972 if (mpt->m_doneq_thread_n) {
1973 mutex_enter(&mpt->m_doneq_mutex);
1974 doneq_thread_num = mpt->m_doneq_thread_n;
1975 for (i = 0; i < mpt->m_doneq_thread_n; i++) {
1976 mutex_enter(&mpt->m_doneq_thread_id[i].mutex);
1977 mpt->m_doneq_thread_id[i].flag &=
1978 (~MPTSAS_DONEQ_THREAD_ACTIVE);
1979 cv_signal(&mpt->m_doneq_thread_id[i].cv);
1980 mutex_exit(&mpt->m_doneq_thread_id[i].mutex);
1981 }
1982 while (mpt->m_doneq_thread_n) {
1983 cv_wait(&mpt->m_doneq_thread_cv,
1984 &mpt->m_doneq_mutex);
1985 }
1986 for (i = 0; i < doneq_thread_num; i++) {
1987 cv_destroy(&mpt->m_doneq_thread_id[i].cv);
1988 mutex_destroy(&mpt->m_doneq_thread_id[i].mutex);
1989 }
1990 kmem_free(mpt->m_doneq_thread_id,
1991 sizeof (mptsas_doneq_thread_list_t)
1992 * doneq_thread_num);
1993 mutex_exit(&mpt->m_doneq_mutex);
1994 cv_destroy(&mpt->m_doneq_thread_cv);
1995 mutex_destroy(&mpt->m_doneq_mutex);
1996 }
1997
1998 scsi_hba_reset_notify_tear_down(mpt->m_reset_notify_listf);
1999
2000 mptsas_list_del(mpt);
2001
2002 /*
2003 * Cancel timeout threads for this mpt
2004 */
2005 mutex_enter(&mpt->m_mutex);
2006 if (mpt->m_quiesce_timeid) {
2007 timeout_id_t tid = mpt->m_quiesce_timeid;
2008 mpt->m_quiesce_timeid = 0;
2009 mutex_exit(&mpt->m_mutex);
2010 (void) untimeout(tid);
2011 mutex_enter(&mpt->m_mutex);
2012 }
2013
2014 if (mpt->m_restart_cmd_timeid) {
2015 timeout_id_t tid = mpt->m_restart_cmd_timeid;
2016 mpt->m_restart_cmd_timeid = 0;
2017 mutex_exit(&mpt->m_mutex);
2018 (void) untimeout(tid);
2019 mutex_enter(&mpt->m_mutex);
2020 }
2021
2022 mutex_exit(&mpt->m_mutex);
2023
2024 /*
2025 * last mpt? ... if active, CANCEL watch threads.
2026 */
2027 mutex_enter(&mptsas_global_mutex);
2028 if (mptsas_head == NULL) {
2029 timeout_id_t tid;
2030 /*
2031 * Clear mptsas_timeouts_enable so that the watch thread
2032 * gets restarted on DDI_ATTACH
2033 */
2034 mptsas_timeouts_enabled = 0;
2035 if (mptsas_timeout_id) {
2036 tid = mptsas_timeout_id;
2037 mptsas_timeout_id = 0;
2038 mutex_exit(&mptsas_global_mutex);
2039 (void) untimeout(tid);
2040 mutex_enter(&mptsas_global_mutex);
2041 }
2042 if (mptsas_reset_watch) {
2043 tid = mptsas_reset_watch;
2044 mptsas_reset_watch = 0;
2045 mutex_exit(&mptsas_global_mutex);
2046 (void) untimeout(tid);
2047 mutex_enter(&mptsas_global_mutex);
2048 }
2049 }
2050 mutex_exit(&mptsas_global_mutex);
2051
2052 /*
2053 * Delete Phy stats
2054 */
2055 mptsas_destroy_phy_stats(mpt);
2056
2057 mptsas_destroy_hashes(mpt);
2058
2059 /*
2060 * Delete nt_active.
2061 */
2062 mutex_enter(&mpt->m_mutex);
2063 mptsas_free_active_slots(mpt);
2064 mutex_exit(&mpt->m_mutex);
2065
2066 /* deallocate everything that was allocated in mptsas_attach */
2067 mptsas_cache_destroy(mpt);
2068
2069 mptsas_hba_fini(mpt);
2070 mptsas_cfg_fini(mpt);
2071
2072 /* Lower the power informing PM Framework */
2073 if (mpt->m_options & MPTSAS_OPT_PM) {
2074 if (pm_lower_power(dip, 0, PM_LEVEL_D3) != DDI_SUCCESS)
2075 mptsas_log(mpt, CE_WARN,
2076 "!mptsas%d: Lower power request failed "
2077 "during detach, ignoring.",
2078 mpt->m_instance);
2079 }
2080
2081 mutex_destroy(&mpt->m_tx_waitq_mutex);
2082 mutex_destroy(&mpt->m_passthru_mutex);
2083 mutex_destroy(&mpt->m_mutex);
2084 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
2085 mutex_destroy(&mpt->m_phy_info[i].smhba_info.phy_mutex);
2086 }
2087 cv_destroy(&mpt->m_cv);
2088 cv_destroy(&mpt->m_passthru_cv);
2089 cv_destroy(&mpt->m_fw_cv);
2090 cv_destroy(&mpt->m_config_cv);
2091 cv_destroy(&mpt->m_fw_diag_cv);
2092 cv_destroy(&mpt->m_extreq_sense_refcount_cv);
2093
2094 mptsas_smp_teardown(mpt);
2095 mptsas_enc_teardown(mpt);
2096 mptsas_hba_teardown(mpt);
2097
2098 mptsas_config_space_fini(mpt);
2099
2100 mptsas_free_handshake_msg(mpt);
2101
2102 mptsas_fm_fini(mpt);
2103 ddi_soft_state_free(mptsas_state, ddi_get_instance(dip));
2104 ddi_prop_remove_all(dip);
2105
2106 return (DDI_SUCCESS);
2107 }
2108
2109 static void
mptsas_list_add(mptsas_t * mpt)2110 mptsas_list_add(mptsas_t *mpt)
2111 {
2112 rw_enter(&mptsas_global_rwlock, RW_WRITER);
2113
2114 if (mptsas_head == NULL) {
2115 mptsas_head = mpt;
2116 } else {
2117 mptsas_tail->m_next = mpt;
2118 }
2119 mptsas_tail = mpt;
2120 rw_exit(&mptsas_global_rwlock);
2121 }
2122
2123 static void
mptsas_list_del(mptsas_t * mpt)2124 mptsas_list_del(mptsas_t *mpt)
2125 {
2126 mptsas_t *m;
2127 /*
2128 * Remove device instance from the global linked list
2129 */
2130 rw_enter(&mptsas_global_rwlock, RW_WRITER);
2131 if (mptsas_head == mpt) {
2132 m = mptsas_head = mpt->m_next;
2133 } else {
2134 for (m = mptsas_head; m != NULL; m = m->m_next) {
2135 if (m->m_next == mpt) {
2136 m->m_next = mpt->m_next;
2137 break;
2138 }
2139 }
2140 if (m == NULL) {
2141 mptsas_log(mpt, CE_PANIC, "Not in softc list!");
2142 }
2143 }
2144
2145 if (mptsas_tail == mpt) {
2146 mptsas_tail = m;
2147 }
2148 rw_exit(&mptsas_global_rwlock);
2149 }
2150
2151 static int
mptsas_alloc_handshake_msg(mptsas_t * mpt,size_t alloc_size)2152 mptsas_alloc_handshake_msg(mptsas_t *mpt, size_t alloc_size)
2153 {
2154 ddi_dma_attr_t task_dma_attrs;
2155
2156 mpt->m_hshk_dma_size = 0;
2157 task_dma_attrs = mpt->m_msg_dma_attr;
2158 task_dma_attrs.dma_attr_sgllen = 1;
2159 task_dma_attrs.dma_attr_granular = (uint32_t)(alloc_size);
2160
2161 /* allocate Task Management ddi_dma resources */
2162 if (mptsas_dma_addr_create(mpt, task_dma_attrs,
2163 &mpt->m_hshk_dma_hdl, &mpt->m_hshk_acc_hdl, &mpt->m_hshk_memp,
2164 alloc_size, NULL) == FALSE) {
2165 return (DDI_FAILURE);
2166 }
2167 mpt->m_hshk_dma_size = alloc_size;
2168
2169 return (DDI_SUCCESS);
2170 }
2171
2172 static void
mptsas_free_handshake_msg(mptsas_t * mpt)2173 mptsas_free_handshake_msg(mptsas_t *mpt)
2174 {
2175 if (mpt->m_hshk_dma_size == 0)
2176 return;
2177 mptsas_dma_addr_destroy(&mpt->m_hshk_dma_hdl, &mpt->m_hshk_acc_hdl);
2178 mpt->m_hshk_dma_size = 0;
2179 }
2180
2181 static int
mptsas_hba_setup(mptsas_t * mpt)2182 mptsas_hba_setup(mptsas_t *mpt)
2183 {
2184 scsi_hba_tran_t *hba_tran;
2185 int tran_flags;
2186
2187 /* Allocate a transport structure */
2188 hba_tran = mpt->m_tran = scsi_hba_tran_alloc(mpt->m_dip,
2189 SCSI_HBA_CANSLEEP);
2190 ASSERT(mpt->m_tran != NULL);
2191
2192 hba_tran->tran_hba_private = mpt;
2193 hba_tran->tran_tgt_private = NULL;
2194
2195 hba_tran->tran_tgt_init = mptsas_scsi_tgt_init;
2196 hba_tran->tran_tgt_free = mptsas_scsi_tgt_free;
2197
2198 hba_tran->tran_start = mptsas_scsi_start;
2199 hba_tran->tran_reset = mptsas_scsi_reset;
2200 hba_tran->tran_abort = mptsas_scsi_abort;
2201 hba_tran->tran_getcap = mptsas_scsi_getcap;
2202 hba_tran->tran_setcap = mptsas_scsi_setcap;
2203 hba_tran->tran_init_pkt = mptsas_scsi_init_pkt;
2204 hba_tran->tran_destroy_pkt = mptsas_scsi_destroy_pkt;
2205
2206 hba_tran->tran_dmafree = mptsas_scsi_dmafree;
2207 hba_tran->tran_sync_pkt = mptsas_scsi_sync_pkt;
2208 hba_tran->tran_reset_notify = mptsas_scsi_reset_notify;
2209
2210 hba_tran->tran_get_bus_addr = mptsas_get_bus_addr;
2211 hba_tran->tran_get_name = mptsas_get_name;
2212
2213 hba_tran->tran_quiesce = mptsas_scsi_quiesce;
2214 hba_tran->tran_unquiesce = mptsas_scsi_unquiesce;
2215 hba_tran->tran_bus_reset = NULL;
2216
2217 hba_tran->tran_add_eventcall = NULL;
2218 hba_tran->tran_get_eventcookie = NULL;
2219 hba_tran->tran_post_event = NULL;
2220 hba_tran->tran_remove_eventcall = NULL;
2221
2222 hba_tran->tran_bus_config = mptsas_bus_config;
2223
2224 hba_tran->tran_interconnect_type = INTERCONNECT_SAS;
2225
2226 /*
2227 * All children of the HBA are iports. We need tran was cloned.
2228 * So we pass the flags to SCSA. SCSI_HBA_TRAN_CLONE will be
2229 * inherited to iport's tran vector.
2230 */
2231 tran_flags = (SCSI_HBA_HBA | SCSI_HBA_TRAN_CLONE);
2232
2233 if (scsi_hba_attach_setup(mpt->m_dip, &mpt->m_msg_dma_attr,
2234 hba_tran, tran_flags) != DDI_SUCCESS) {
2235 mptsas_log(mpt, CE_WARN, "hba attach setup failed");
2236 scsi_hba_tran_free(hba_tran);
2237 mpt->m_tran = NULL;
2238 return (FALSE);
2239 }
2240 return (TRUE);
2241 }
2242
2243 static void
mptsas_hba_teardown(mptsas_t * mpt)2244 mptsas_hba_teardown(mptsas_t *mpt)
2245 {
2246 (void) scsi_hba_detach(mpt->m_dip);
2247 if (mpt->m_tran != NULL) {
2248 scsi_hba_tran_free(mpt->m_tran);
2249 mpt->m_tran = NULL;
2250 }
2251 }
2252
2253 static void
mptsas_iport_register(mptsas_t * mpt)2254 mptsas_iport_register(mptsas_t *mpt)
2255 {
2256 int i, j;
2257 mptsas_phymask_t mask = 0x0;
2258 /*
2259 * initial value of mask is 0
2260 */
2261 mutex_enter(&mpt->m_mutex);
2262 for (i = 0; i < mpt->m_num_phys; i++) {
2263 mptsas_phymask_t phy_mask = 0x0;
2264 char phy_mask_name[MPTSAS_MAX_PHYS];
2265 uint8_t current_port;
2266
2267 if (mpt->m_phy_info[i].attached_devhdl == 0)
2268 continue;
2269
2270 bzero(phy_mask_name, sizeof (phy_mask_name));
2271
2272 current_port = mpt->m_phy_info[i].port_num;
2273
2274 if ((mask & (1 << i)) != 0)
2275 continue;
2276
2277 for (j = 0; j < mpt->m_num_phys; j++) {
2278 if (mpt->m_phy_info[j].attached_devhdl &&
2279 (mpt->m_phy_info[j].port_num == current_port)) {
2280 phy_mask |= (1 << j);
2281 }
2282 }
2283 mask = mask | phy_mask;
2284
2285 for (j = 0; j < mpt->m_num_phys; j++) {
2286 if ((phy_mask >> j) & 0x01) {
2287 mpt->m_phy_info[j].phy_mask = phy_mask;
2288 }
2289 }
2290
2291 (void) sprintf(phy_mask_name, "%x", phy_mask);
2292
2293 mutex_exit(&mpt->m_mutex);
2294 /*
2295 * register a iport
2296 */
2297 (void) scsi_hba_iport_register(mpt->m_dip, phy_mask_name);
2298 mutex_enter(&mpt->m_mutex);
2299 }
2300 mutex_exit(&mpt->m_mutex);
2301 /*
2302 * register a virtual port for RAID volume always
2303 */
2304 (void) scsi_hba_iport_register(mpt->m_dip, "v0");
2305
2306 }
2307
2308 static int
mptsas_smp_setup(mptsas_t * mpt)2309 mptsas_smp_setup(mptsas_t *mpt)
2310 {
2311 mpt->m_smptran = smp_hba_tran_alloc(mpt->m_dip);
2312 ASSERT(mpt->m_smptran != NULL);
2313 mpt->m_smptran->smp_tran_hba_private = mpt;
2314 mpt->m_smptran->smp_tran_start = mptsas_smp_start;
2315 if (smp_hba_attach_setup(mpt->m_dip, mpt->m_smptran) != DDI_SUCCESS) {
2316 mptsas_log(mpt, CE_WARN, "smp attach setup failed");
2317 smp_hba_tran_free(mpt->m_smptran);
2318 mpt->m_smptran = NULL;
2319 return (FALSE);
2320 }
2321 /*
2322 * Initialize smp hash table
2323 */
2324 mpt->m_smp_targets = refhash_create(MPTSAS_SMP_BUCKET_COUNT,
2325 mptsas_target_addr_hash, mptsas_target_addr_cmp,
2326 mptsas_smp_free, sizeof (mptsas_smp_t),
2327 offsetof(mptsas_smp_t, m_link), offsetof(mptsas_smp_t, m_addr),
2328 KM_SLEEP);
2329 mpt->m_smp_devhdl = 0xFFFF;
2330
2331 return (TRUE);
2332 }
2333
2334 static void
mptsas_smp_teardown(mptsas_t * mpt)2335 mptsas_smp_teardown(mptsas_t *mpt)
2336 {
2337 (void) smp_hba_detach(mpt->m_dip);
2338 if (mpt->m_smptran != NULL) {
2339 smp_hba_tran_free(mpt->m_smptran);
2340 mpt->m_smptran = NULL;
2341 }
2342 mpt->m_smp_devhdl = 0;
2343 }
2344
2345 static int
mptsas_enc_setup(mptsas_t * mpt)2346 mptsas_enc_setup(mptsas_t *mpt)
2347 {
2348 list_create(&mpt->m_enclosures, sizeof (mptsas_enclosure_t),
2349 offsetof(mptsas_enclosure_t, me_link));
2350 return (TRUE);
2351 }
2352
2353 static void
mptsas_enc_free(mptsas_enclosure_t * mep)2354 mptsas_enc_free(mptsas_enclosure_t *mep)
2355 {
2356 if (mep == NULL)
2357 return;
2358 if (mep->me_slotleds != NULL) {
2359 VERIFY3U(mep->me_nslots, >, 0);
2360 kmem_free(mep->me_slotleds, sizeof (uint8_t) * mep->me_nslots);
2361 }
2362 kmem_free(mep, sizeof (mptsas_enclosure_t));
2363 }
2364
2365 static void
mptsas_enc_teardown(mptsas_t * mpt)2366 mptsas_enc_teardown(mptsas_t *mpt)
2367 {
2368 mptsas_enclosure_t *mep;
2369
2370 while ((mep = list_remove_head(&mpt->m_enclosures)) != NULL) {
2371 mptsas_enc_free(mep);
2372 }
2373 list_destroy(&mpt->m_enclosures);
2374 }
2375
2376 static mptsas_enclosure_t *
mptsas_enc_lookup(mptsas_t * mpt,uint16_t hdl)2377 mptsas_enc_lookup(mptsas_t *mpt, uint16_t hdl)
2378 {
2379 mptsas_enclosure_t *mep;
2380
2381 ASSERT(MUTEX_HELD(&mpt->m_mutex));
2382
2383 for (mep = list_head(&mpt->m_enclosures); mep != NULL;
2384 mep = list_next(&mpt->m_enclosures, mep)) {
2385 if (hdl == mep->me_enchdl) {
2386 return (mep);
2387 }
2388 }
2389
2390 return (NULL);
2391 }
2392
2393 static int
mptsas_cache_create(mptsas_t * mpt)2394 mptsas_cache_create(mptsas_t *mpt)
2395 {
2396 int instance = mpt->m_instance;
2397 char buf[64];
2398
2399 /*
2400 * create kmem cache for packets
2401 */
2402 (void) sprintf(buf, "mptsas%d_cache", instance);
2403 mpt->m_kmem_cache = kmem_cache_create(buf,
2404 sizeof (struct mptsas_cmd) + scsi_pkt_size(), 8,
2405 mptsas_kmem_cache_constructor, mptsas_kmem_cache_destructor,
2406 NULL, (void *)mpt, NULL, 0);
2407
2408 if (mpt->m_kmem_cache == NULL) {
2409 mptsas_log(mpt, CE_WARN, "creating kmem cache failed");
2410 return (FALSE);
2411 }
2412
2413 /*
2414 * create kmem cache for extra SGL frames if SGL cannot
2415 * be accomodated into main request frame.
2416 */
2417 (void) sprintf(buf, "mptsas%d_cache_frames", instance);
2418 mpt->m_cache_frames = kmem_cache_create(buf,
2419 sizeof (mptsas_cache_frames_t), 8,
2420 mptsas_cache_frames_constructor, mptsas_cache_frames_destructor,
2421 NULL, (void *)mpt, NULL, 0);
2422
2423 if (mpt->m_cache_frames == NULL) {
2424 mptsas_log(mpt, CE_WARN, "creating cache for frames failed");
2425 return (FALSE);
2426 }
2427
2428 return (TRUE);
2429 }
2430
2431 static void
mptsas_cache_destroy(mptsas_t * mpt)2432 mptsas_cache_destroy(mptsas_t *mpt)
2433 {
2434 /* deallocate in reverse order */
2435 if (mpt->m_cache_frames) {
2436 kmem_cache_destroy(mpt->m_cache_frames);
2437 mpt->m_cache_frames = NULL;
2438 }
2439 if (mpt->m_kmem_cache) {
2440 kmem_cache_destroy(mpt->m_kmem_cache);
2441 mpt->m_kmem_cache = NULL;
2442 }
2443 }
2444
2445 static int
mptsas_power(dev_info_t * dip,int component,int level)2446 mptsas_power(dev_info_t *dip, int component, int level)
2447 {
2448 #ifndef __lock_lint
2449 _NOTE(ARGUNUSED(component))
2450 #endif
2451 mptsas_t *mpt;
2452 int rval = DDI_SUCCESS;
2453 int polls = 0;
2454 uint32_t ioc_status;
2455
2456 if (scsi_hba_iport_unit_address(dip) != 0)
2457 return (DDI_SUCCESS);
2458
2459 mpt = ddi_get_soft_state(mptsas_state, ddi_get_instance(dip));
2460 if (mpt == NULL) {
2461 return (DDI_FAILURE);
2462 }
2463
2464 mutex_enter(&mpt->m_mutex);
2465
2466 /*
2467 * If the device is busy, don't lower its power level
2468 */
2469 if (mpt->m_busy && (mpt->m_power_level > level)) {
2470 mutex_exit(&mpt->m_mutex);
2471 return (DDI_FAILURE);
2472 }
2473 switch (level) {
2474 case PM_LEVEL_D0:
2475 NDBG11(("mptsas%d: turning power ON.", mpt->m_instance));
2476 MPTSAS_POWER_ON(mpt);
2477 /*
2478 * Wait up to 30 seconds for IOC to come out of reset.
2479 */
2480 while (((ioc_status = mptsas_hirrd(mpt,
2481 &mpt->m_reg->Doorbell)) &
2482 MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_RESET) {
2483 if (polls++ > 3000) {
2484 break;
2485 }
2486 delay(drv_usectohz(10000));
2487 }
2488 /*
2489 * If IOC is not in operational state, try to hard reset it.
2490 */
2491 if ((ioc_status & MPI2_IOC_STATE_MASK) !=
2492 MPI2_IOC_STATE_OPERATIONAL) {
2493 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET;
2494 if (mptsas_restart_ioc(mpt) == DDI_FAILURE) {
2495 mptsas_log(mpt, CE_WARN,
2496 "mptsas_power: hard reset failed");
2497 mutex_exit(&mpt->m_mutex);
2498 return (DDI_FAILURE);
2499 }
2500 }
2501 mpt->m_power_level = PM_LEVEL_D0;
2502 break;
2503 case PM_LEVEL_D3:
2504 NDBG11(("mptsas%d: turning power OFF.", mpt->m_instance));
2505 MPTSAS_POWER_OFF(mpt);
2506 break;
2507 default:
2508 mptsas_log(mpt, CE_WARN, "mptsas%d: unknown power level <%x>.",
2509 mpt->m_instance, level);
2510 rval = DDI_FAILURE;
2511 break;
2512 }
2513 mutex_exit(&mpt->m_mutex);
2514 return (rval);
2515 }
2516
2517 /*
2518 * Check for newer v2.6 SAS chips.
2519 */
2520 static void
mptsas_ioc_check_rev(mptsas_t * mpt)2521 mptsas_ioc_check_rev(mptsas_t *mpt)
2522 {
2523 switch (mpt->m_devid) {
2524 case MPI26_MFGPAGE_DEVID_SAS3816:
2525 case MPI26_MFGPAGE_DEVID_SAS3816_1:
2526 mpt->m_is_sea_ioc = 1;
2527 mptsas_log(mpt, CE_NOTE, "!mptsas3%d: SAS3816 IOC Detected",
2528 mpt->m_instance);
2529 /* fallthrough */
2530 case MPI26_MFGPAGE_DEVID_SAS3616:
2531 case MPI26_MFGPAGE_DEVID_SAS3708:
2532 case MPI26_MFGPAGE_DEVID_SAS3716:
2533 mptsas_log(mpt, CE_NOTE, "!mptsas3%d: gen3.5 IOC Detected",
2534 mpt->m_instance);
2535 mpt->m_is_gen35_ioc = 1;
2536 break;
2537 default:
2538 break;
2539 }
2540 }
2541
2542 /*
2543 * Search through the reg property for the first memory BAR.
2544 */
2545 static void
mptsas_find_mem_bar(mptsas_t * mpt)2546 mptsas_find_mem_bar(mptsas_t *mpt)
2547 {
2548 int i, rcount;
2549 pci_regspec_t *reg_data;
2550 int reglen;
2551
2552 mpt->m_mem_bar = MEM_SPACE; /* old default */
2553 /*
2554 * Lookup the 'reg' property.
2555 */
2556 if (ddi_getlongprop(DDI_DEV_T_ANY, mpt->m_dip,
2557 DDI_PROP_DONTPASS, "reg", (caddr_t)®_data, ®len) ==
2558 DDI_PROP_SUCCESS) {
2559 rcount = reglen / sizeof (pci_regspec_t);
2560 for (i = 0; i < rcount; i++) {
2561 if (PCI_REG_ADDR_G(reg_data[i].pci_phys_hi) ==
2562 PCI_REG_ADDR_G(PCI_ADDR_MEM64)) {
2563 mpt->m_mem_bar = i;
2564 break;
2565 }
2566 }
2567 }
2568 }
2569
2570
2571 /*
2572 * Initialize configuration space and figure out which
2573 * chip and revison of the chip the mpt driver is using.
2574 */
2575 static int
mptsas_config_space_init(mptsas_t * mpt)2576 mptsas_config_space_init(mptsas_t *mpt)
2577 {
2578 NDBG0(("mptsas_config_space_init"));
2579
2580 if (mpt->m_config_handle != NULL)
2581 return (TRUE);
2582
2583 if (pci_config_setup(mpt->m_dip,
2584 &mpt->m_config_handle) != DDI_SUCCESS) {
2585 mptsas_log(mpt, CE_WARN, "cannot map configuration space.");
2586 return (FALSE);
2587 }
2588
2589 /*
2590 * This is a workaround for a XMITS ASIC bug which does not
2591 * drive the CBE upper bits.
2592 */
2593 if (pci_config_get16(mpt->m_config_handle, PCI_CONF_STAT) &
2594 PCI_STAT_PERROR) {
2595 pci_config_put16(mpt->m_config_handle, PCI_CONF_STAT,
2596 PCI_STAT_PERROR);
2597 }
2598
2599 mptsas_setup_cmd_reg(mpt);
2600
2601 /*
2602 * Get the chip device id:
2603 */
2604 mpt->m_devid = pci_config_get16(mpt->m_config_handle, PCI_CONF_DEVID);
2605
2606 /*
2607 * Save the revision.
2608 */
2609 mpt->m_revid = pci_config_get8(mpt->m_config_handle, PCI_CONF_REVID);
2610
2611 /*
2612 * Save the SubSystem Vendor and Device IDs
2613 */
2614 mpt->m_svid = pci_config_get16(mpt->m_config_handle, PCI_CONF_SUBVENID);
2615 mpt->m_ssid = pci_config_get16(mpt->m_config_handle, PCI_CONF_SUBSYSID);
2616
2617 /*
2618 * Set the latency timer to 0x40 as specified by the upa -> pci
2619 * bridge chip design team. This may be done by the sparc pci
2620 * bus nexus driver, but the driver should make sure the latency
2621 * timer is correct for performance reasons.
2622 */
2623 pci_config_put8(mpt->m_config_handle, PCI_CONF_LATENCY_TIMER,
2624 MPTSAS_LATENCY_TIMER);
2625
2626 mptsas_ioc_check_rev(mpt);
2627 mptsas_find_mem_bar(mpt);
2628 (void) mptsas_get_pci_cap(mpt);
2629 return (TRUE);
2630 }
2631
2632 static void
mptsas_config_space_fini(mptsas_t * mpt)2633 mptsas_config_space_fini(mptsas_t *mpt)
2634 {
2635 if (mpt->m_config_handle != NULL) {
2636 mptsas_disable_bus_master(mpt);
2637 pci_config_teardown(&mpt->m_config_handle);
2638 mpt->m_config_handle = NULL;
2639 }
2640 }
2641
2642 static void
mptsas_setup_cmd_reg(mptsas_t * mpt)2643 mptsas_setup_cmd_reg(mptsas_t *mpt)
2644 {
2645 ushort_t cmdreg;
2646
2647 /*
2648 * Set the command register to the needed values.
2649 */
2650 cmdreg = pci_config_get16(mpt->m_config_handle, PCI_CONF_COMM);
2651 cmdreg |= (PCI_COMM_ME | PCI_COMM_SERR_ENABLE |
2652 PCI_COMM_PARITY_DETECT | PCI_COMM_MAE);
2653 cmdreg &= ~PCI_COMM_IO;
2654 pci_config_put16(mpt->m_config_handle, PCI_CONF_COMM, cmdreg);
2655 }
2656
2657 static void
mptsas_disable_bus_master(mptsas_t * mpt)2658 mptsas_disable_bus_master(mptsas_t *mpt)
2659 {
2660 ushort_t cmdreg;
2661
2662 /*
2663 * Clear the master enable bit in the PCI command register.
2664 * This prevents any bus mastering activity like DMA.
2665 */
2666 cmdreg = pci_config_get16(mpt->m_config_handle, PCI_CONF_COMM);
2667 cmdreg &= ~PCI_COMM_ME;
2668 pci_config_put16(mpt->m_config_handle, PCI_CONF_COMM, cmdreg);
2669 }
2670
2671 int
mptsas_dma_alloc(mptsas_t * mpt,mptsas_dma_alloc_state_t * dma_statep)2672 mptsas_dma_alloc(mptsas_t *mpt, mptsas_dma_alloc_state_t *dma_statep)
2673 {
2674 ddi_dma_attr_t attrs;
2675
2676 attrs = mpt->m_io_dma_attr;
2677 attrs.dma_attr_sgllen = 1;
2678
2679 ASSERT(dma_statep != NULL);
2680
2681 if (mptsas_dma_addr_create(mpt, attrs, &dma_statep->handle,
2682 &dma_statep->accessp, &dma_statep->memp, dma_statep->size,
2683 &dma_statep->cookie) == FALSE) {
2684 return (DDI_FAILURE);
2685 }
2686
2687 return (DDI_SUCCESS);
2688 }
2689
2690 void
mptsas_dma_free(mptsas_dma_alloc_state_t * dma_statep)2691 mptsas_dma_free(mptsas_dma_alloc_state_t *dma_statep)
2692 {
2693 ASSERT(dma_statep != NULL);
2694 mptsas_dma_addr_destroy(&dma_statep->handle, &dma_statep->accessp);
2695 dma_statep->size = 0;
2696 }
2697
2698 int
mptsas_do_dma(mptsas_t * mpt,uint32_t size,int var,int (* callback)())2699 mptsas_do_dma(mptsas_t *mpt, uint32_t size, int var, int (*callback)())
2700 {
2701 ddi_dma_attr_t attrs;
2702 ddi_dma_handle_t dma_handle;
2703 caddr_t memp;
2704 ddi_acc_handle_t accessp;
2705 int rval;
2706
2707 ASSERT(mutex_owned(&mpt->m_mutex));
2708
2709 attrs = mpt->m_msg_dma_attr;
2710 attrs.dma_attr_sgllen = 1;
2711 attrs.dma_attr_granular = size;
2712
2713 if (mptsas_dma_addr_create(mpt, attrs, &dma_handle,
2714 &accessp, &memp, size, NULL) == FALSE) {
2715 return (DDI_FAILURE);
2716 }
2717
2718 rval = (*callback) (mpt, memp, var, accessp);
2719
2720 if ((mptsas_check_dma_handle(dma_handle) != DDI_SUCCESS) ||
2721 (mptsas_check_acc_handle(accessp) != DDI_SUCCESS)) {
2722 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
2723 rval = DDI_FAILURE;
2724 }
2725
2726 mptsas_dma_addr_destroy(&dma_handle, &accessp);
2727 return (rval);
2728
2729 }
2730
2731 static int
mptsas_alloc_request_frames(mptsas_t * mpt)2732 mptsas_alloc_request_frames(mptsas_t *mpt)
2733 {
2734 ddi_dma_attr_t frame_dma_attrs;
2735 caddr_t memp;
2736 ddi_dma_cookie_t cookie;
2737 size_t mem_size;
2738
2739 /*
2740 * re-alloc when it has already alloced
2741 */
2742 if (mpt->m_dma_req_frame_hdl)
2743 mptsas_dma_addr_destroy(&mpt->m_dma_req_frame_hdl,
2744 &mpt->m_acc_req_frame_hdl);
2745
2746 /*
2747 * The size of the request frame pool is:
2748 * Number of Request Frames * Request Frame Size
2749 */
2750 mem_size = mpt->m_max_requests * mpt->m_req_frame_size;
2751
2752 /*
2753 * set the DMA attributes. System Request Message Frames must be
2754 * aligned on a 16-byte boundry.
2755 */
2756 frame_dma_attrs = mpt->m_msg_dma_attr;
2757 frame_dma_attrs.dma_attr_align = 16;
2758 frame_dma_attrs.dma_attr_sgllen = 1;
2759
2760 /*
2761 * allocate the request frame pool.
2762 */
2763 if (mptsas_dma_addr_create(mpt, frame_dma_attrs,
2764 &mpt->m_dma_req_frame_hdl, &mpt->m_acc_req_frame_hdl, &memp,
2765 mem_size, &cookie) == FALSE) {
2766 return (DDI_FAILURE);
2767 }
2768
2769 /*
2770 * Store the request frame memory address. This chip uses this
2771 * address to dma to and from the driver's frame. The second
2772 * address is the address mpt uses to fill in the frame.
2773 */
2774 mpt->m_req_frame_dma_addr = cookie.dmac_laddress;
2775 mpt->m_req_frame = memp;
2776
2777 /*
2778 * Clear the request frame pool.
2779 */
2780 bzero(mpt->m_req_frame, mem_size);
2781
2782 return (DDI_SUCCESS);
2783 }
2784
2785 static int
mptsas_alloc_sense_bufs(mptsas_t * mpt)2786 mptsas_alloc_sense_bufs(mptsas_t *mpt)
2787 {
2788 ddi_dma_attr_t sense_dma_attrs;
2789 caddr_t memp;
2790 ddi_dma_cookie_t cookie;
2791 size_t mem_size;
2792 int num_extrqsense_bufs;
2793
2794 ASSERT(mpt->m_extreq_sense_refcount == 0);
2795
2796 /*
2797 * re-alloc when it has already alloced
2798 */
2799 if (mpt->m_dma_req_sense_hdl) {
2800 rmfreemap(mpt->m_erqsense_map);
2801 mptsas_dma_addr_destroy(&mpt->m_dma_req_sense_hdl,
2802 &mpt->m_acc_req_sense_hdl);
2803 }
2804
2805 /*
2806 * The size of the request sense pool is:
2807 * (Number of Request Frames - 2 ) * Request Sense Size +
2808 * extra memory for extended sense requests.
2809 */
2810 mem_size = ((mpt->m_max_requests - 2) * mpt->m_req_sense_size) +
2811 mptsas_extreq_sense_bufsize;
2812
2813 /*
2814 * set the DMA attributes. ARQ buffers
2815 * aligned on a 16-byte boundry.
2816 */
2817 sense_dma_attrs = mpt->m_msg_dma_attr;
2818 sense_dma_attrs.dma_attr_align = 16;
2819 sense_dma_attrs.dma_attr_sgllen = 1;
2820
2821 /*
2822 * allocate the request sense buffer pool.
2823 */
2824 if (mptsas_dma_addr_create(mpt, sense_dma_attrs,
2825 &mpt->m_dma_req_sense_hdl, &mpt->m_acc_req_sense_hdl, &memp,
2826 mem_size, &cookie) == FALSE) {
2827 return (DDI_FAILURE);
2828 }
2829
2830 /*
2831 * Store the request sense base memory address. This chip uses this
2832 * address to dma the request sense data. The second
2833 * address is the address mpt uses to access the data.
2834 * The third is the base for the extended rqsense buffers.
2835 */
2836 mpt->m_req_sense_dma_addr = cookie.dmac_laddress;
2837 mpt->m_req_sense = memp;
2838 memp += (mpt->m_max_requests - 2) * mpt->m_req_sense_size;
2839 mpt->m_extreq_sense = memp;
2840
2841 /*
2842 * The extra memory is divided up into multiples of the base
2843 * buffer size in order to allocate via rmalloc().
2844 * Note that the rmallocmap cannot start at zero!
2845 */
2846 num_extrqsense_bufs = mptsas_extreq_sense_bufsize /
2847 mpt->m_req_sense_size;
2848 mpt->m_erqsense_map = rmallocmap_wait(num_extrqsense_bufs);
2849 rmfree(mpt->m_erqsense_map, num_extrqsense_bufs, 1);
2850
2851 /*
2852 * Clear the pool.
2853 */
2854 bzero(mpt->m_req_sense, mem_size);
2855
2856 return (DDI_SUCCESS);
2857 }
2858
2859 static int
mptsas_alloc_reply_frames(mptsas_t * mpt)2860 mptsas_alloc_reply_frames(mptsas_t *mpt)
2861 {
2862 ddi_dma_attr_t frame_dma_attrs;
2863 caddr_t memp;
2864 ddi_dma_cookie_t cookie;
2865 size_t mem_size;
2866
2867 /*
2868 * re-alloc when it has already alloced
2869 */
2870 if (mpt->m_dma_reply_frame_hdl) {
2871 mptsas_dma_addr_destroy(&mpt->m_dma_reply_frame_hdl,
2872 &mpt->m_acc_reply_frame_hdl);
2873 }
2874
2875 /*
2876 * The size of the reply frame pool is:
2877 * Number of Reply Frames * Reply Frame Size
2878 */
2879 mem_size = mpt->m_max_replies * mpt->m_reply_frame_size;
2880
2881 /*
2882 * set the DMA attributes. System Reply Message Frames must be
2883 * aligned on a 4-byte boundry. This is the default.
2884 */
2885 frame_dma_attrs = mpt->m_msg_dma_attr;
2886 frame_dma_attrs.dma_attr_sgllen = 1;
2887
2888 /*
2889 * allocate the reply frame pool
2890 */
2891 if (mptsas_dma_addr_create(mpt, frame_dma_attrs,
2892 &mpt->m_dma_reply_frame_hdl, &mpt->m_acc_reply_frame_hdl, &memp,
2893 mem_size, &cookie) == FALSE) {
2894 return (DDI_FAILURE);
2895 }
2896
2897 /*
2898 * Store the reply frame memory address. This chip uses this
2899 * address to dma to and from the driver's frame. The second
2900 * address is the address mpt uses to process the frame.
2901 */
2902 mpt->m_reply_frame_dma_addr = cookie.dmac_laddress;
2903 mpt->m_reply_frame = memp;
2904
2905 /*
2906 * Clear the reply frame pool.
2907 */
2908 bzero(mpt->m_reply_frame, mem_size);
2909
2910 return (DDI_SUCCESS);
2911 }
2912
2913 static int
mptsas_alloc_free_queue(mptsas_t * mpt)2914 mptsas_alloc_free_queue(mptsas_t *mpt)
2915 {
2916 ddi_dma_attr_t frame_dma_attrs;
2917 caddr_t memp;
2918 ddi_dma_cookie_t cookie;
2919 size_t mem_size;
2920
2921 /*
2922 * re-alloc when it has already alloced
2923 */
2924 if (mpt->m_dma_free_queue_hdl) {
2925 mptsas_dma_addr_destroy(&mpt->m_dma_free_queue_hdl,
2926 &mpt->m_acc_free_queue_hdl);
2927 }
2928
2929 /*
2930 * The reply free queue size is:
2931 * Reply Free Queue Depth * 4
2932 * The "4" is the size of one 32 bit address (low part of 64-bit
2933 * address)
2934 */
2935 mem_size = mpt->m_free_queue_depth * 4;
2936
2937 /*
2938 * set the DMA attributes The Reply Free Queue must be aligned on a
2939 * 16-byte boundry.
2940 */
2941 frame_dma_attrs = mpt->m_msg_dma_attr;
2942 frame_dma_attrs.dma_attr_align = 16;
2943 frame_dma_attrs.dma_attr_sgllen = 1;
2944
2945 /*
2946 * allocate the reply free queue
2947 */
2948 if (mptsas_dma_addr_create(mpt, frame_dma_attrs,
2949 &mpt->m_dma_free_queue_hdl, &mpt->m_acc_free_queue_hdl, &memp,
2950 mem_size, &cookie) == FALSE) {
2951 return (DDI_FAILURE);
2952 }
2953
2954 /*
2955 * Store the reply free queue memory address. This chip uses this
2956 * address to read from the reply free queue. The second address
2957 * is the address mpt uses to manage the queue.
2958 */
2959 mpt->m_free_queue_dma_addr = cookie.dmac_laddress;
2960 mpt->m_free_queue = memp;
2961
2962 /*
2963 * Clear the reply free queue memory.
2964 */
2965 bzero(mpt->m_free_queue, mem_size);
2966
2967 return (DDI_SUCCESS);
2968 }
2969
2970 static int
mptsas_alloc_post_queue(mptsas_t * mpt)2971 mptsas_alloc_post_queue(mptsas_t *mpt)
2972 {
2973 ddi_dma_attr_t frame_dma_attrs;
2974 caddr_t memp;
2975 ddi_dma_cookie_t cookie;
2976 size_t mem_size;
2977
2978 /*
2979 * re-alloc when it has already alloced
2980 */
2981 if (mpt->m_dma_post_queue_hdl) {
2982 mptsas_dma_addr_destroy(&mpt->m_dma_post_queue_hdl,
2983 &mpt->m_acc_post_queue_hdl);
2984 }
2985
2986 /*
2987 * The reply descriptor post queue size is:
2988 * Reply Descriptor Post Queue Depth * 8
2989 * The "8" is the size of each descriptor (8 bytes or 64 bits).
2990 */
2991 mem_size = mpt->m_post_queue_depth * 8;
2992
2993 /*
2994 * set the DMA attributes. The Reply Descriptor Post Queue must be
2995 * aligned on a 16-byte boundry.
2996 */
2997 frame_dma_attrs = mpt->m_msg_dma_attr;
2998 frame_dma_attrs.dma_attr_align = 16;
2999 frame_dma_attrs.dma_attr_sgllen = 1;
3000
3001 /*
3002 * allocate the reply post queue
3003 */
3004 if (mptsas_dma_addr_create(mpt, frame_dma_attrs,
3005 &mpt->m_dma_post_queue_hdl, &mpt->m_acc_post_queue_hdl, &memp,
3006 mem_size, &cookie) == FALSE) {
3007 return (DDI_FAILURE);
3008 }
3009
3010 /*
3011 * Store the reply descriptor post queue memory address. This chip
3012 * uses this address to write to the reply descriptor post queue. The
3013 * second address is the address mpt uses to manage the queue.
3014 */
3015 mpt->m_post_queue_dma_addr = cookie.dmac_laddress;
3016 mpt->m_post_queue = memp;
3017
3018 /*
3019 * Clear the reply post queue memory.
3020 */
3021 bzero(mpt->m_post_queue, mem_size);
3022
3023 return (DDI_SUCCESS);
3024 }
3025
3026 static void
mptsas_alloc_reply_args(mptsas_t * mpt)3027 mptsas_alloc_reply_args(mptsas_t *mpt)
3028 {
3029 if (mpt->m_replyh_args == NULL) {
3030 mpt->m_replyh_args = kmem_zalloc(sizeof (m_replyh_arg_t) *
3031 mpt->m_max_replies, KM_SLEEP);
3032 }
3033 }
3034
3035 static int
mptsas_alloc_extra_sgl_frame(mptsas_t * mpt,mptsas_cmd_t * cmd)3036 mptsas_alloc_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd)
3037 {
3038 mptsas_cache_frames_t *frames = NULL;
3039 if (cmd->cmd_extra_frames == NULL) {
3040 frames = kmem_cache_alloc(mpt->m_cache_frames, KM_NOSLEEP);
3041 if (frames == NULL) {
3042 return (DDI_FAILURE);
3043 }
3044 cmd->cmd_extra_frames = frames;
3045 }
3046 return (DDI_SUCCESS);
3047 }
3048
3049 static void
mptsas_free_extra_sgl_frame(mptsas_t * mpt,mptsas_cmd_t * cmd)3050 mptsas_free_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd)
3051 {
3052 if (cmd->cmd_extra_frames) {
3053 kmem_cache_free(mpt->m_cache_frames,
3054 (void *)cmd->cmd_extra_frames);
3055 cmd->cmd_extra_frames = NULL;
3056 }
3057 }
3058
3059 static void
mptsas_cfg_fini(mptsas_t * mpt)3060 mptsas_cfg_fini(mptsas_t *mpt)
3061 {
3062 NDBG0(("mptsas_cfg_fini"));
3063 ddi_regs_map_free(&mpt->m_datap);
3064 }
3065
3066 static void
mptsas_hba_fini(mptsas_t * mpt)3067 mptsas_hba_fini(mptsas_t *mpt)
3068 {
3069 NDBG0(("mptsas_hba_fini"));
3070
3071 /*
3072 * Free up any allocated memory
3073 */
3074 if (mpt->m_dma_req_frame_hdl) {
3075 mptsas_dma_addr_destroy(&mpt->m_dma_req_frame_hdl,
3076 &mpt->m_acc_req_frame_hdl);
3077 }
3078
3079 if (mpt->m_dma_req_sense_hdl) {
3080 rmfreemap(mpt->m_erqsense_map);
3081 mptsas_dma_addr_destroy(&mpt->m_dma_req_sense_hdl,
3082 &mpt->m_acc_req_sense_hdl);
3083 }
3084
3085 if (mpt->m_dma_reply_frame_hdl) {
3086 mptsas_dma_addr_destroy(&mpt->m_dma_reply_frame_hdl,
3087 &mpt->m_acc_reply_frame_hdl);
3088 }
3089
3090 if (mpt->m_dma_free_queue_hdl) {
3091 mptsas_dma_addr_destroy(&mpt->m_dma_free_queue_hdl,
3092 &mpt->m_acc_free_queue_hdl);
3093 }
3094
3095 if (mpt->m_dma_post_queue_hdl) {
3096 mptsas_dma_addr_destroy(&mpt->m_dma_post_queue_hdl,
3097 &mpt->m_acc_post_queue_hdl);
3098 }
3099
3100 if (mpt->m_replyh_args != NULL) {
3101 kmem_free(mpt->m_replyh_args, sizeof (m_replyh_arg_t)
3102 * mpt->m_max_replies);
3103 }
3104 }
3105
3106 static int
mptsas_name_child(dev_info_t * lun_dip,char * name,int len)3107 mptsas_name_child(dev_info_t *lun_dip, char *name, int len)
3108 {
3109 int lun = 0;
3110 char *sas_wwn = NULL;
3111 int phynum = -1;
3112 int reallen = 0;
3113
3114 /* Get the target num */
3115 lun = ddi_prop_get_int(DDI_DEV_T_ANY, lun_dip, DDI_PROP_DONTPASS,
3116 LUN_PROP, 0);
3117
3118 if ((phynum = ddi_prop_get_int(DDI_DEV_T_ANY, lun_dip,
3119 DDI_PROP_DONTPASS, "sata-phy", -1)) != -1) {
3120 /*
3121 * Stick in the address of form "pPHY,LUN"
3122 */
3123 reallen = snprintf(name, len, "p%x,%x", phynum, lun);
3124 } else if (ddi_prop_lookup_string(DDI_DEV_T_ANY, lun_dip,
3125 DDI_PROP_DONTPASS, SCSI_ADDR_PROP_TARGET_PORT, &sas_wwn)
3126 == DDI_PROP_SUCCESS) {
3127 /*
3128 * Stick in the address of the form "wWWN,LUN"
3129 */
3130 reallen = snprintf(name, len, "%s,%x", sas_wwn, lun);
3131 ddi_prop_free(sas_wwn);
3132 } else {
3133 return (DDI_FAILURE);
3134 }
3135
3136 ASSERT(reallen < len);
3137 if (reallen >= len) {
3138 mptsas_log(0, CE_WARN, "!mptsas_get_name: name parameter "
3139 "length too small, it needs to be %d bytes", reallen + 1);
3140 }
3141 return (DDI_SUCCESS);
3142 }
3143
3144 /*
3145 * tran_tgt_init(9E) - target device instance initialization
3146 */
3147 static int
mptsas_scsi_tgt_init(dev_info_t * hba_dip,dev_info_t * tgt_dip,scsi_hba_tran_t * hba_tran,struct scsi_device * sd)3148 mptsas_scsi_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
3149 scsi_hba_tran_t *hba_tran, struct scsi_device *sd)
3150 {
3151 #ifndef __lock_lint
3152 _NOTE(ARGUNUSED(hba_tran))
3153 #endif
3154
3155 /*
3156 * At this point, the scsi_device structure already exists
3157 * and has been initialized.
3158 *
3159 * Use this function to allocate target-private data structures,
3160 * if needed by this HBA. Add revised flow-control and queue
3161 * properties for child here, if desired and if you can tell they
3162 * support tagged queueing by now.
3163 */
3164 mptsas_t *mpt;
3165 int lun = sd->sd_address.a_lun;
3166 mdi_pathinfo_t *pip = NULL;
3167 mptsas_tgt_private_t *tgt_private = NULL;
3168 mptsas_target_t *ptgt = NULL;
3169 char *psas_wwn = NULL;
3170 mptsas_phymask_t phymask = 0;
3171 uint64_t sas_wwn = 0;
3172 mptsas_target_addr_t addr;
3173 mpt = SDEV2MPT(sd);
3174
3175 ASSERT(scsi_hba_iport_unit_address(hba_dip) != 0);
3176
3177 NDBG0(("mptsas_scsi_tgt_init: hbadip=0x%p tgtdip=0x%p lun=%d",
3178 (void *)hba_dip, (void *)tgt_dip, lun));
3179
3180 if (ndi_dev_is_persistent_node(tgt_dip) == 0) {
3181 (void) ndi_merge_node(tgt_dip, mptsas_name_child);
3182 ddi_set_name_addr(tgt_dip, NULL);
3183 return (DDI_FAILURE);
3184 }
3185 /*
3186 * phymask is 0 means the virtual port for RAID
3187 */
3188 phymask = (mptsas_phymask_t)ddi_prop_get_int(DDI_DEV_T_ANY, hba_dip, 0,
3189 "phymask", 0);
3190 if (mdi_component_is_client(tgt_dip, NULL) == MDI_SUCCESS) {
3191 if ((pip = (void *)(sd->sd_private)) == NULL) {
3192 /*
3193 * Very bad news if this occurs. Somehow scsi_vhci has
3194 * lost the pathinfo node for this target.
3195 */
3196 return (DDI_NOT_WELL_FORMED);
3197 }
3198
3199 if (mdi_prop_lookup_int(pip, LUN_PROP, &lun) !=
3200 DDI_PROP_SUCCESS) {
3201 mptsas_log(mpt, CE_WARN, "Get lun property failed\n");
3202 return (DDI_FAILURE);
3203 }
3204
3205 if (mdi_prop_lookup_string(pip, SCSI_ADDR_PROP_TARGET_PORT,
3206 &psas_wwn) == MDI_SUCCESS) {
3207 if (scsi_wwnstr_to_wwn(psas_wwn, &sas_wwn)) {
3208 sas_wwn = 0;
3209 }
3210 (void) mdi_prop_free(psas_wwn);
3211 }
3212 } else {
3213 lun = ddi_prop_get_int(DDI_DEV_T_ANY, tgt_dip,
3214 DDI_PROP_DONTPASS, LUN_PROP, 0);
3215 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, tgt_dip,
3216 DDI_PROP_DONTPASS, SCSI_ADDR_PROP_TARGET_PORT, &psas_wwn) ==
3217 DDI_PROP_SUCCESS) {
3218 if (scsi_wwnstr_to_wwn(psas_wwn, &sas_wwn)) {
3219 sas_wwn = 0;
3220 }
3221 ddi_prop_free(psas_wwn);
3222 } else {
3223 sas_wwn = 0;
3224 }
3225 }
3226
3227 ASSERT((sas_wwn != 0) || (phymask != 0));
3228 addr.mta_wwn = sas_wwn;
3229 addr.mta_phymask = phymask;
3230 mutex_enter(&mpt->m_mutex);
3231 ptgt = refhash_lookup(mpt->m_targets, &addr);
3232 mutex_exit(&mpt->m_mutex);
3233 if (ptgt == NULL) {
3234 mptsas_log(mpt, CE_WARN, "!tgt_init: target doesn't exist or "
3235 "gone already! phymask:%x, saswwn %"PRIx64, phymask,
3236 sas_wwn);
3237 return (DDI_FAILURE);
3238 }
3239 if (hba_tran->tran_tgt_private == NULL) {
3240 tgt_private = kmem_zalloc(sizeof (mptsas_tgt_private_t),
3241 KM_SLEEP);
3242 tgt_private->t_lun = lun;
3243 tgt_private->t_private = ptgt;
3244 hba_tran->tran_tgt_private = tgt_private;
3245 }
3246
3247 if (mdi_component_is_client(tgt_dip, NULL) == MDI_SUCCESS) {
3248 return (DDI_SUCCESS);
3249 }
3250 mutex_enter(&mpt->m_mutex);
3251
3252 if (ptgt->m_deviceinfo &
3253 (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
3254 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
3255 uchar_t *inq89 = NULL;
3256 int inq89_len = 0x238;
3257 int reallen = 0;
3258 int rval = 0;
3259 struct sata_id *sid = NULL;
3260 char model[SATA_ID_MODEL_LEN + 1];
3261 char fw[SATA_ID_FW_LEN + 1];
3262 char *vid, *pid;
3263
3264 mutex_exit(&mpt->m_mutex);
3265 /*
3266 * According SCSI/ATA Translation -2 (SAT-2) revision 01a
3267 * chapter 12.4.2 VPD page 89h includes 512 bytes ATA IDENTIFY
3268 * DEVICE data or ATA IDENTIFY PACKET DEVICE data.
3269 */
3270 inq89 = kmem_zalloc(inq89_len, KM_SLEEP);
3271 rval = mptsas_inquiry(mpt, ptgt, 0, 0x89,
3272 inq89, inq89_len, &reallen, 1);
3273
3274 if (rval != 0) {
3275 if (inq89 != NULL) {
3276 kmem_free(inq89, inq89_len);
3277 }
3278
3279 mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page "
3280 "0x89 for SATA target:%x failed!", ptgt->m_devhdl);
3281 return (DDI_SUCCESS);
3282 }
3283 sid = (void *)(&inq89[60]);
3284
3285 swab(sid->ai_model, model, SATA_ID_MODEL_LEN);
3286 swab(sid->ai_fw, fw, SATA_ID_FW_LEN);
3287
3288 model[SATA_ID_MODEL_LEN] = 0;
3289 fw[SATA_ID_FW_LEN] = 0;
3290
3291 sata_split_model(model, &vid, &pid);
3292
3293 /*
3294 * override SCSA "inquiry-*" properties
3295 */
3296 if (vid)
3297 (void) scsi_device_prop_update_inqstring(sd,
3298 INQUIRY_VENDOR_ID, vid, strlen(vid));
3299 if (pid)
3300 (void) scsi_device_prop_update_inqstring(sd,
3301 INQUIRY_PRODUCT_ID, pid, strlen(pid));
3302 (void) scsi_device_prop_update_inqstring(sd,
3303 INQUIRY_REVISION_ID, fw, strlen(fw));
3304
3305 if (inq89 != NULL) {
3306 kmem_free(inq89, inq89_len);
3307 }
3308 } else {
3309 mutex_exit(&mpt->m_mutex);
3310 }
3311
3312 return (DDI_SUCCESS);
3313 }
3314 /*
3315 * tran_tgt_free(9E) - target device instance deallocation
3316 */
3317 static void
mptsas_scsi_tgt_free(dev_info_t * hba_dip,dev_info_t * tgt_dip,scsi_hba_tran_t * hba_tran,struct scsi_device * sd)3318 mptsas_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip,
3319 scsi_hba_tran_t *hba_tran, struct scsi_device *sd)
3320 {
3321 #ifndef __lock_lint
3322 _NOTE(ARGUNUSED(hba_dip, tgt_dip, hba_tran, sd))
3323 #endif
3324
3325 mptsas_tgt_private_t *tgt_private = hba_tran->tran_tgt_private;
3326
3327 if (tgt_private != NULL) {
3328 kmem_free(tgt_private, sizeof (mptsas_tgt_private_t));
3329 hba_tran->tran_tgt_private = NULL;
3330 }
3331 }
3332
3333 /*
3334 * scsi_pkt handling
3335 *
3336 * Visible to the external world via the transport structure.
3337 */
3338
3339 /*
3340 * Notes:
3341 * - transport the command to the addressed SCSI target/lun device
3342 * - normal operation is to schedule the command to be transported,
3343 * and return TRAN_ACCEPT if this is successful.
3344 * - if NO_INTR, tran_start must poll device for command completion
3345 */
3346 static int
mptsas_scsi_start(struct scsi_address * ap,struct scsi_pkt * pkt)3347 mptsas_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt)
3348 {
3349 #ifndef __lock_lint
3350 _NOTE(ARGUNUSED(ap))
3351 #endif
3352 mptsas_t *mpt = PKT2MPT(pkt);
3353 mptsas_cmd_t *cmd = PKT2CMD(pkt);
3354 int rval;
3355 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
3356
3357 NDBG1(("mptsas_scsi_start: pkt=0x%p", (void *)pkt));
3358 ASSERT(ptgt);
3359 if (ptgt == NULL)
3360 return (TRAN_FATAL_ERROR);
3361
3362 /*
3363 * prepare the pkt before taking mutex.
3364 */
3365 rval = mptsas_prepare_pkt(cmd);
3366 if (rval != TRAN_ACCEPT) {
3367 return (rval);
3368 }
3369
3370 /*
3371 * Send the command to target/lun, however your HBA requires it.
3372 * If busy, return TRAN_BUSY; if there's some other formatting error
3373 * in the packet, return TRAN_BADPKT; otherwise, fall through to the
3374 * return of TRAN_ACCEPT.
3375 *
3376 * Remember that access to shared resources, including the mptsas_t
3377 * data structure and the HBA hardware registers, must be protected
3378 * with mutexes, here and everywhere.
3379 *
3380 * Also remember that at interrupt time, you'll get an argument
3381 * to the interrupt handler which is a pointer to your mptsas_t
3382 * structure; you'll have to remember which commands are outstanding
3383 * and which scsi_pkt is the currently-running command so the
3384 * interrupt handler can refer to the pkt to set completion
3385 * status, call the target driver back through pkt_comp, etc.
3386 *
3387 * If the instance lock is held by other thread, don't spin to wait
3388 * for it. Instead, queue the cmd and next time when the instance lock
3389 * is not held, accept all the queued cmd. A extra tx_waitq is
3390 * introduced to protect the queue.
3391 *
3392 * The polled cmd will not be queud and accepted as usual.
3393 *
3394 * Under the tx_waitq mutex, record whether a thread is draining
3395 * the tx_waitq. An IO requesting thread that finds the instance
3396 * mutex contended appends to the tx_waitq and while holding the
3397 * tx_wait mutex, if the draining flag is not set, sets it and then
3398 * proceeds to spin for the instance mutex. This scheme ensures that
3399 * the last cmd in a burst be processed.
3400 *
3401 * we enable this feature only when the helper threads are enabled,
3402 * at which we think the loads are heavy.
3403 *
3404 * per instance mutex m_tx_waitq_mutex is introduced to protect the
3405 * m_tx_waitqtail, m_tx_waitq, m_tx_draining.
3406 */
3407
3408 if (mpt->m_doneq_thread_n) {
3409 if (mutex_tryenter(&mpt->m_mutex) != 0) {
3410 rval = mptsas_accept_txwq_and_pkt(mpt, cmd);
3411 mutex_exit(&mpt->m_mutex);
3412 } else if (cmd->cmd_pkt_flags & FLAG_NOINTR) {
3413 mutex_enter(&mpt->m_mutex);
3414 rval = mptsas_accept_txwq_and_pkt(mpt, cmd);
3415 mutex_exit(&mpt->m_mutex);
3416 } else {
3417 mutex_enter(&mpt->m_tx_waitq_mutex);
3418 /*
3419 * ptgt->m_dr_flag is protected by m_mutex or
3420 * m_tx_waitq_mutex. In this case, m_tx_waitq_mutex
3421 * is acquired.
3422 */
3423 if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) {
3424 if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) {
3425 /*
3426 * The command should be allowed to
3427 * retry by returning TRAN_BUSY to
3428 * to stall the I/O's which come from
3429 * scsi_vhci since the device/path is
3430 * in unstable state now.
3431 */
3432 mutex_exit(&mpt->m_tx_waitq_mutex);
3433 return (TRAN_BUSY);
3434 } else {
3435 /*
3436 * The device is offline, just fail the
3437 * command by returning
3438 * TRAN_FATAL_ERROR.
3439 */
3440 mutex_exit(&mpt->m_tx_waitq_mutex);
3441 return (TRAN_FATAL_ERROR);
3442 }
3443 }
3444 if (mpt->m_tx_draining) {
3445 cmd->cmd_flags |= CFLAG_TXQ;
3446 *mpt->m_tx_waitqtail = cmd;
3447 mpt->m_tx_waitqtail = &cmd->cmd_linkp;
3448 mutex_exit(&mpt->m_tx_waitq_mutex);
3449 } else { /* drain the queue */
3450 mpt->m_tx_draining = 1;
3451 mutex_exit(&mpt->m_tx_waitq_mutex);
3452 mutex_enter(&mpt->m_mutex);
3453 rval = mptsas_accept_txwq_and_pkt(mpt, cmd);
3454 mutex_exit(&mpt->m_mutex);
3455 }
3456 }
3457 } else {
3458 mutex_enter(&mpt->m_mutex);
3459 /*
3460 * ptgt->m_dr_flag is protected by m_mutex or m_tx_waitq_mutex
3461 * in this case, m_mutex is acquired.
3462 */
3463 if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) {
3464 if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) {
3465 /*
3466 * commands should be allowed to retry by
3467 * returning TRAN_BUSY to stall the I/O's
3468 * which come from scsi_vhci since the device/
3469 * path is in unstable state now.
3470 */
3471 mutex_exit(&mpt->m_mutex);
3472 return (TRAN_BUSY);
3473 } else {
3474 /*
3475 * The device is offline, just fail the
3476 * command by returning TRAN_FATAL_ERROR.
3477 */
3478 mutex_exit(&mpt->m_mutex);
3479 return (TRAN_FATAL_ERROR);
3480 }
3481 }
3482 rval = mptsas_accept_pkt(mpt, cmd);
3483 mutex_exit(&mpt->m_mutex);
3484 }
3485
3486 return (rval);
3487 }
3488
3489 /*
3490 * Accept all the queued cmds(if any) before accept the current one.
3491 */
3492 static int
mptsas_accept_txwq_and_pkt(mptsas_t * mpt,mptsas_cmd_t * cmd)3493 mptsas_accept_txwq_and_pkt(mptsas_t *mpt, mptsas_cmd_t *cmd)
3494 {
3495 int rval;
3496 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
3497
3498 ASSERT(mutex_owned(&mpt->m_mutex));
3499 /*
3500 * The call to mptsas_accept_tx_waitq() must always be performed
3501 * because that is where mpt->m_tx_draining is cleared.
3502 */
3503 mutex_enter(&mpt->m_tx_waitq_mutex);
3504 mptsas_accept_tx_waitq(mpt);
3505 mutex_exit(&mpt->m_tx_waitq_mutex);
3506 /*
3507 * ptgt->m_dr_flag is protected by m_mutex or m_tx_waitq_mutex
3508 * in this case, m_mutex is acquired.
3509 */
3510 if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) {
3511 if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) {
3512 /*
3513 * The command should be allowed to retry by returning
3514 * TRAN_BUSY to stall the I/O's which come from
3515 * scsi_vhci since the device/path is in unstable state
3516 * now.
3517 */
3518 return (TRAN_BUSY);
3519 } else {
3520 /*
3521 * The device is offline, just fail the command by
3522 * return TRAN_FATAL_ERROR.
3523 */
3524 return (TRAN_FATAL_ERROR);
3525 }
3526 }
3527 rval = mptsas_accept_pkt(mpt, cmd);
3528
3529 return (rval);
3530 }
3531
3532 static int
mptsas_accept_pkt(mptsas_t * mpt,mptsas_cmd_t * cmd)3533 mptsas_accept_pkt(mptsas_t *mpt, mptsas_cmd_t *cmd)
3534 {
3535 int rval = TRAN_ACCEPT;
3536 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
3537
3538 NDBG1(("mptsas_accept_pkt: cmd=0x%p", (void *)cmd));
3539
3540 ASSERT(mutex_owned(&mpt->m_mutex));
3541
3542 if ((cmd->cmd_flags & CFLAG_PREPARED) == 0) {
3543 rval = mptsas_prepare_pkt(cmd);
3544 if (rval != TRAN_ACCEPT) {
3545 cmd->cmd_flags &= ~CFLAG_TRANFLAG;
3546 return (rval);
3547 }
3548 }
3549
3550 /*
3551 * reset the throttle if we were draining
3552 */
3553 if ((ptgt->m_t_ncmds == 0) &&
3554 (ptgt->m_t_throttle == DRAIN_THROTTLE)) {
3555 NDBG23(("reset throttle"));
3556 ASSERT(ptgt->m_reset_delay == 0);
3557 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
3558 }
3559
3560 /*
3561 * If HBA is being reset, the DevHandles are being re-initialized,
3562 * which means that they could be invalid even if the target is still
3563 * attached. Check if being reset and if DevHandle is being
3564 * re-initialized. If this is the case, return BUSY so the I/O can be
3565 * retried later.
3566 */
3567 if ((ptgt->m_devhdl == MPTSAS_INVALID_DEVHDL) && mpt->m_in_reset) {
3568 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET);
3569 if (cmd->cmd_flags & CFLAG_TXQ) {
3570 mptsas_doneq_add(mpt, cmd);
3571 mptsas_doneq_empty(mpt);
3572 return (rval);
3573 } else {
3574 return (TRAN_BUSY);
3575 }
3576 }
3577
3578 /*
3579 * If device handle has already been invalidated, just
3580 * fail the command. In theory, command from scsi_vhci
3581 * client is impossible send down command with invalid
3582 * devhdl since devhdl is set after path offline, target
3583 * driver is not suppose to select a offlined path.
3584 */
3585 if (ptgt->m_devhdl == MPTSAS_INVALID_DEVHDL) {
3586 NDBG3(("rejecting command, it might because invalid devhdl "
3587 "request."));
3588 mptsas_set_pkt_reason(mpt, cmd, CMD_DEV_GONE, STAT_TERMINATED);
3589 if (cmd->cmd_flags & CFLAG_TXQ) {
3590 mptsas_doneq_add(mpt, cmd);
3591 mptsas_doneq_empty(mpt);
3592 return (rval);
3593 } else {
3594 return (TRAN_FATAL_ERROR);
3595 }
3596 }
3597 /*
3598 * The first case is the normal case. mpt gets a command from the
3599 * target driver and starts it.
3600 * Since SMID 0 is reserved and the TM slot is reserved, the actual max
3601 * commands is m_max_requests - 2.
3602 */
3603 if ((mpt->m_ncmds <= (mpt->m_max_requests - 2)) &&
3604 (ptgt->m_t_throttle > HOLD_THROTTLE) &&
3605 (ptgt->m_t_ncmds < ptgt->m_t_throttle) &&
3606 (ptgt->m_reset_delay == 0) &&
3607 (ptgt->m_t_nwait == 0) &&
3608 ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0)) {
3609 if (mptsas_save_cmd(mpt, cmd) == TRUE) {
3610 (void) mptsas_start_cmd(mpt, cmd);
3611 } else {
3612 mptsas_waitq_add(mpt, cmd);
3613 }
3614 } else {
3615 /*
3616 * Add this pkt to the work queue
3617 */
3618 mptsas_waitq_add(mpt, cmd);
3619
3620 if (cmd->cmd_pkt_flags & FLAG_NOINTR) {
3621 (void) mptsas_poll(mpt, cmd, MPTSAS_POLL_TIME);
3622
3623 /*
3624 * Only flush the doneq if this is not a TM
3625 * cmd. For TM cmds the flushing of the
3626 * doneq will be done in those routines.
3627 */
3628 if ((cmd->cmd_flags & CFLAG_TM_CMD) == 0) {
3629 mptsas_doneq_empty(mpt);
3630 }
3631 }
3632 }
3633 return (rval);
3634 }
3635
3636 int
mptsas_save_cmd(mptsas_t * mpt,mptsas_cmd_t * cmd)3637 mptsas_save_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
3638 {
3639 mptsas_slots_t *slots = mpt->m_active;
3640 uint_t slot, start_rotor;
3641 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
3642
3643 ASSERT(MUTEX_HELD(&mpt->m_mutex));
3644
3645 /*
3646 * Account for reserved TM request slot and reserved SMID of 0.
3647 */
3648 ASSERT(slots->m_n_normal == (mpt->m_max_requests - 2));
3649
3650 /*
3651 * Find the next available slot, beginning at m_rotor. If no slot is
3652 * available, we'll return FALSE to indicate that. This mechanism
3653 * considers only the normal slots, not the reserved slot 0 nor the
3654 * task management slot m_n_normal + 1. The rotor is left to point to
3655 * the normal slot after the one we select, unless we select the last
3656 * normal slot in which case it returns to slot 1.
3657 */
3658 start_rotor = slots->m_rotor;
3659 do {
3660 slot = slots->m_rotor++;
3661 if (slots->m_rotor > slots->m_n_normal)
3662 slots->m_rotor = 1;
3663
3664 if (slots->m_rotor == start_rotor)
3665 break;
3666 } while (slots->m_slot[slot] != NULL);
3667
3668 if (slots->m_slot[slot] != NULL)
3669 return (FALSE);
3670
3671 ASSERT(slot != 0 && slot <= slots->m_n_normal);
3672
3673 cmd->cmd_slot = slot;
3674 slots->m_slot[slot] = cmd;
3675 mpt->m_ncmds++;
3676
3677 /*
3678 * only increment per target ncmds if this is not a
3679 * command that has no target associated with it (i.e. a
3680 * event acknoledgment)
3681 */
3682 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) {
3683 /*
3684 * Expiration time is set in mptsas_start_cmd
3685 */
3686 ptgt->m_t_ncmds++;
3687 cmd->cmd_active_expiration = 0;
3688 } else {
3689 /*
3690 * Initialize expiration time for passthrough commands,
3691 */
3692 cmd->cmd_active_expiration = gethrtime() +
3693 (hrtime_t)cmd->cmd_pkt->pkt_time * NANOSEC;
3694 }
3695 return (TRUE);
3696 }
3697
3698 /*
3699 * prepare the pkt:
3700 * the pkt may have been resubmitted or just reused so
3701 * initialize some fields and do some checks.
3702 */
3703 static int
mptsas_prepare_pkt(mptsas_cmd_t * cmd)3704 mptsas_prepare_pkt(mptsas_cmd_t *cmd)
3705 {
3706 struct scsi_pkt *pkt = CMD2PKT(cmd);
3707
3708 NDBG1(("mptsas_prepare_pkt: cmd=0x%p", (void *)cmd));
3709
3710 /*
3711 * Reinitialize some fields that need it; the packet may
3712 * have been resubmitted
3713 */
3714 pkt->pkt_reason = CMD_CMPLT;
3715 pkt->pkt_state = 0;
3716 pkt->pkt_statistics = 0;
3717 pkt->pkt_resid = 0;
3718 cmd->cmd_age = 0;
3719 cmd->cmd_pkt_flags = pkt->pkt_flags;
3720
3721 /*
3722 * zero status byte.
3723 */
3724 *(pkt->pkt_scbp) = 0;
3725
3726 if (cmd->cmd_flags & CFLAG_DMAVALID) {
3727 pkt->pkt_resid = cmd->cmd_dmacount;
3728
3729 /*
3730 * consistent packets need to be sync'ed first
3731 * (only for data going out)
3732 */
3733 if ((cmd->cmd_flags & CFLAG_CMDIOPB) &&
3734 (cmd->cmd_flags & CFLAG_DMASEND)) {
3735 (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0,
3736 DDI_DMA_SYNC_FORDEV);
3737 }
3738 }
3739
3740 cmd->cmd_flags =
3741 (cmd->cmd_flags & ~(CFLAG_TRANFLAG)) |
3742 CFLAG_PREPARED | CFLAG_IN_TRANSPORT;
3743
3744 return (TRAN_ACCEPT);
3745 }
3746
3747 /*
3748 * tran_init_pkt(9E) - allocate scsi_pkt(9S) for command
3749 *
3750 * One of three possibilities:
3751 * - allocate scsi_pkt
3752 * - allocate scsi_pkt and DMA resources
3753 * - allocate DMA resources to an already-allocated pkt
3754 */
3755 static struct scsi_pkt *
mptsas_scsi_init_pkt(struct scsi_address * ap,struct scsi_pkt * pkt,struct buf * bp,int cmdlen,int statuslen,int tgtlen,int flags,int (* callback)(),caddr_t arg)3756 mptsas_scsi_init_pkt(struct scsi_address *ap, struct scsi_pkt *pkt,
3757 struct buf *bp, int cmdlen, int statuslen, int tgtlen, int flags,
3758 int (*callback)(), caddr_t arg)
3759 {
3760 mptsas_cmd_t *cmd, *new_cmd;
3761 mptsas_t *mpt = ADDR2MPT(ap);
3762 uint_t oldcookiec;
3763 mptsas_target_t *ptgt = NULL;
3764 int rval;
3765 mptsas_tgt_private_t *tgt_private;
3766 int kf;
3767
3768 kf = (callback == SLEEP_FUNC)? KM_SLEEP: KM_NOSLEEP;
3769
3770 tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran->
3771 tran_tgt_private;
3772 ASSERT(tgt_private != NULL);
3773 if (tgt_private == NULL) {
3774 return (NULL);
3775 }
3776 ptgt = tgt_private->t_private;
3777 ASSERT(ptgt != NULL);
3778 if (ptgt == NULL)
3779 return (NULL);
3780 ap->a_target = ptgt->m_devhdl;
3781 ap->a_lun = tgt_private->t_lun;
3782
3783 ASSERT(callback == NULL_FUNC || callback == SLEEP_FUNC);
3784 #ifdef MPTSAS_TEST_EXTRN_ALLOC
3785 statuslen *= 100; tgtlen *= 4;
3786 #endif
3787 NDBG3(("mptsas_scsi_init_pkt:\n"
3788 "\ttgt=%d in=0x%p bp=0x%p clen=%d slen=%d tlen=%d flags=%x",
3789 ap->a_target, (void *)pkt, (void *)bp,
3790 cmdlen, statuslen, tgtlen, flags));
3791
3792 /*
3793 * Allocate the new packet.
3794 */
3795 if (pkt == NULL) {
3796 ddi_dma_handle_t save_dma_handle;
3797
3798 cmd = kmem_cache_alloc(mpt->m_kmem_cache, kf);
3799 if (cmd == NULL)
3800 return (NULL);
3801
3802 save_dma_handle = cmd->cmd_dmahandle;
3803 bzero(cmd, sizeof (*cmd) + scsi_pkt_size());
3804 cmd->cmd_dmahandle = save_dma_handle;
3805
3806 pkt = (void *)((uchar_t *)cmd +
3807 sizeof (struct mptsas_cmd));
3808 pkt->pkt_ha_private = (opaque_t)cmd;
3809 pkt->pkt_address = *ap;
3810 pkt->pkt_private = (opaque_t)cmd->cmd_pkt_private;
3811 pkt->pkt_scbp = (opaque_t)&cmd->cmd_scb;
3812 pkt->pkt_cdbp = (opaque_t)&cmd->cmd_cdb;
3813 cmd->cmd_pkt = (struct scsi_pkt *)pkt;
3814 cmd->cmd_cdblen = (uchar_t)cmdlen;
3815 cmd->cmd_scblen = statuslen;
3816 cmd->cmd_rqslen = SENSE_LENGTH;
3817 cmd->cmd_tgt_addr = ptgt;
3818
3819 if ((cmdlen > sizeof (cmd->cmd_cdb)) ||
3820 (tgtlen > PKT_PRIV_LEN) ||
3821 (statuslen > EXTCMDS_STATUS_SIZE)) {
3822 int failure;
3823
3824 /*
3825 * We are going to allocate external packet space which
3826 * might include the sense data buffer for DMA so we
3827 * need to increase the reference counter here. In a
3828 * case the HBA is in reset we just simply free the
3829 * allocated packet and bail out.
3830 */
3831 mutex_enter(&mpt->m_mutex);
3832 if (mpt->m_in_reset) {
3833 mutex_exit(&mpt->m_mutex);
3834
3835 cmd->cmd_flags = CFLAG_FREE;
3836 kmem_cache_free(mpt->m_kmem_cache, cmd);
3837 return (NULL);
3838 }
3839 mpt->m_extreq_sense_refcount++;
3840 ASSERT(mpt->m_extreq_sense_refcount > 0);
3841 mutex_exit(&mpt->m_mutex);
3842
3843 /*
3844 * if extern alloc fails, all will be
3845 * deallocated, including cmd
3846 */
3847 failure = mptsas_pkt_alloc_extern(mpt, cmd,
3848 cmdlen, tgtlen, statuslen, kf);
3849
3850 if (failure != 0 || cmd->cmd_extrqslen == 0) {
3851 /*
3852 * If the external packet space allocation
3853 * failed, or we didn't allocate the sense
3854 * data buffer for DMA we need to decrease the
3855 * reference counter.
3856 */
3857 mutex_enter(&mpt->m_mutex);
3858 ASSERT(mpt->m_extreq_sense_refcount > 0);
3859 mpt->m_extreq_sense_refcount--;
3860 if (mpt->m_extreq_sense_refcount == 0)
3861 cv_broadcast(
3862 &mpt->m_extreq_sense_refcount_cv);
3863 mutex_exit(&mpt->m_mutex);
3864
3865 if (failure != 0) {
3866 /*
3867 * if extern allocation fails, it will
3868 * deallocate the new pkt as well
3869 */
3870 return (NULL);
3871 }
3872 }
3873 }
3874 new_cmd = cmd;
3875
3876 } else {
3877 cmd = PKT2CMD(pkt);
3878 new_cmd = NULL;
3879 }
3880
3881
3882 /* grab cmd->cmd_cookiec here as oldcookiec */
3883
3884 oldcookiec = cmd->cmd_cookiec;
3885
3886 /*
3887 * If the dma was broken up into PARTIAL transfers cmd_nwin will be
3888 * greater than 0 and we'll need to grab the next dma window
3889 */
3890 /*
3891 * SLM-not doing extra command frame right now; may add later
3892 */
3893
3894 if (cmd->cmd_nwin > 0) {
3895
3896 /*
3897 * Make sure we havn't gone past the the total number
3898 * of windows
3899 */
3900 if (++cmd->cmd_winindex >= cmd->cmd_nwin) {
3901 return (NULL);
3902 }
3903 if (ddi_dma_getwin(cmd->cmd_dmahandle, cmd->cmd_winindex,
3904 &cmd->cmd_dma_offset, &cmd->cmd_dma_len,
3905 &cmd->cmd_cookie, &cmd->cmd_cookiec) == DDI_FAILURE) {
3906 return (NULL);
3907 }
3908 goto get_dma_cookies;
3909 }
3910
3911
3912 if (flags & PKT_XARQ) {
3913 cmd->cmd_flags |= CFLAG_XARQ;
3914 }
3915
3916 /*
3917 * DMA resource allocation. This version assumes your
3918 * HBA has some sort of bus-mastering or onboard DMA capability, with a
3919 * scatter-gather list of length MPTSAS_MAX_DMA_SEGS, as given in the
3920 * ddi_dma_attr_t structure and passed to scsi_impl_dmaget.
3921 */
3922 if (bp && (bp->b_bcount != 0) &&
3923 (cmd->cmd_flags & CFLAG_DMAVALID) == 0) {
3924
3925 int cnt, dma_flags;
3926 mptti_t *dmap; /* ptr to the S/G list */
3927
3928 /*
3929 * Set up DMA memory and position to the next DMA segment.
3930 */
3931 ASSERT(cmd->cmd_dmahandle != NULL);
3932
3933 if (bp->b_flags & B_READ) {
3934 dma_flags = DDI_DMA_READ;
3935 cmd->cmd_flags &= ~CFLAG_DMASEND;
3936 } else {
3937 dma_flags = DDI_DMA_WRITE;
3938 cmd->cmd_flags |= CFLAG_DMASEND;
3939 }
3940 if (flags & PKT_CONSISTENT) {
3941 cmd->cmd_flags |= CFLAG_CMDIOPB;
3942 dma_flags |= DDI_DMA_CONSISTENT;
3943 }
3944
3945 if (flags & PKT_DMA_PARTIAL) {
3946 dma_flags |= DDI_DMA_PARTIAL;
3947 }
3948
3949 /*
3950 * workaround for byte hole issue on psycho and
3951 * schizo pre 2.1
3952 */
3953 if ((bp->b_flags & B_READ) && ((bp->b_flags &
3954 (B_PAGEIO|B_REMAPPED)) != B_PAGEIO) &&
3955 ((uintptr_t)bp->b_un.b_addr & 0x7)) {
3956 dma_flags |= DDI_DMA_CONSISTENT;
3957 }
3958
3959 rval = ddi_dma_buf_bind_handle(cmd->cmd_dmahandle, bp,
3960 dma_flags, callback, arg,
3961 &cmd->cmd_cookie, &cmd->cmd_cookiec);
3962 if (rval == DDI_DMA_PARTIAL_MAP) {
3963 (void) ddi_dma_numwin(cmd->cmd_dmahandle,
3964 &cmd->cmd_nwin);
3965 cmd->cmd_winindex = 0;
3966 (void) ddi_dma_getwin(cmd->cmd_dmahandle,
3967 cmd->cmd_winindex, &cmd->cmd_dma_offset,
3968 &cmd->cmd_dma_len, &cmd->cmd_cookie,
3969 &cmd->cmd_cookiec);
3970 } else if (rval && (rval != DDI_DMA_MAPPED)) {
3971 switch (rval) {
3972 case DDI_DMA_NORESOURCES:
3973 bioerror(bp, 0);
3974 break;
3975 case DDI_DMA_BADATTR:
3976 case DDI_DMA_NOMAPPING:
3977 bioerror(bp, EFAULT);
3978 break;
3979 case DDI_DMA_TOOBIG:
3980 default:
3981 bioerror(bp, EINVAL);
3982 break;
3983 }
3984 cmd->cmd_flags &= ~CFLAG_DMAVALID;
3985 if (new_cmd) {
3986 mptsas_scsi_destroy_pkt(ap, pkt);
3987 }
3988 return ((struct scsi_pkt *)NULL);
3989 }
3990
3991 get_dma_cookies:
3992 cmd->cmd_flags |= CFLAG_DMAVALID;
3993 ASSERT(cmd->cmd_cookiec > 0);
3994
3995 if (cmd->cmd_cookiec > MPTSAS_MAX_CMD_SEGS) {
3996 mptsas_log(mpt, CE_NOTE, "large cookiec received %d\n",
3997 cmd->cmd_cookiec);
3998 bioerror(bp, EINVAL);
3999 if (new_cmd) {
4000 mptsas_scsi_destroy_pkt(ap, pkt);
4001 }
4002 return ((struct scsi_pkt *)NULL);
4003 }
4004
4005 /*
4006 * Allocate extra SGL buffer if needed.
4007 */
4008 if ((cmd->cmd_cookiec > MPTSAS_MAX_FRAME_SGES64(mpt)) &&
4009 (cmd->cmd_extra_frames == NULL)) {
4010 if (mptsas_alloc_extra_sgl_frame(mpt, cmd) ==
4011 DDI_FAILURE) {
4012 mptsas_log(mpt, CE_WARN, "MPT SGL mem alloc "
4013 "failed");
4014 bioerror(bp, ENOMEM);
4015 if (new_cmd) {
4016 mptsas_scsi_destroy_pkt(ap, pkt);
4017 }
4018 return ((struct scsi_pkt *)NULL);
4019 }
4020 }
4021
4022 /*
4023 * Always use scatter-gather transfer
4024 * Use the loop below to store physical addresses of
4025 * DMA segments, from the DMA cookies, into your HBA's
4026 * scatter-gather list.
4027 * We need to ensure we have enough kmem alloc'd
4028 * for the sg entries since we are no longer using an
4029 * array inside mptsas_cmd_t.
4030 *
4031 * We check cmd->cmd_cookiec against oldcookiec so
4032 * the scatter-gather list is correctly allocated
4033 */
4034
4035 if (oldcookiec != cmd->cmd_cookiec) {
4036 if (cmd->cmd_sg != (mptti_t *)NULL) {
4037 kmem_free(cmd->cmd_sg, sizeof (mptti_t) *
4038 oldcookiec);
4039 cmd->cmd_sg = NULL;
4040 }
4041 }
4042
4043 if (cmd->cmd_sg == (mptti_t *)NULL) {
4044 cmd->cmd_sg = kmem_alloc((size_t)(sizeof (mptti_t)*
4045 cmd->cmd_cookiec), kf);
4046
4047 if (cmd->cmd_sg == (mptti_t *)NULL) {
4048 mptsas_log(mpt, CE_WARN,
4049 "unable to kmem_alloc enough memory "
4050 "for scatter/gather list");
4051 /*
4052 * if we have an ENOMEM condition we need to behave
4053 * the same way as the rest of this routine
4054 */
4055
4056 bioerror(bp, ENOMEM);
4057 if (new_cmd) {
4058 mptsas_scsi_destroy_pkt(ap, pkt);
4059 }
4060 return ((struct scsi_pkt *)NULL);
4061 }
4062 }
4063
4064 dmap = cmd->cmd_sg;
4065
4066 ASSERT(cmd->cmd_cookie.dmac_size != 0);
4067
4068 /*
4069 * store the first segment into the S/G list
4070 */
4071 dmap->count = cmd->cmd_cookie.dmac_size;
4072 dmap->addr.address64.Low = (uint32_t)
4073 (cmd->cmd_cookie.dmac_laddress & 0xffffffffull);
4074 dmap->addr.address64.High = (uint32_t)
4075 (cmd->cmd_cookie.dmac_laddress >> 32);
4076
4077 /*
4078 * dmacount counts the size of the dma for this window
4079 * (if partial dma is being used). totaldmacount
4080 * keeps track of the total amount of dma we have
4081 * transferred for all the windows (needed to calculate
4082 * the resid value below).
4083 */
4084 cmd->cmd_dmacount = cmd->cmd_cookie.dmac_size;
4085 cmd->cmd_totaldmacount += cmd->cmd_cookie.dmac_size;
4086
4087 /*
4088 * We already stored the first DMA scatter gather segment,
4089 * start at 1 if we need to store more.
4090 */
4091 for (cnt = 1; cnt < cmd->cmd_cookiec; cnt++) {
4092 /*
4093 * Get next DMA cookie
4094 */
4095 ddi_dma_nextcookie(cmd->cmd_dmahandle,
4096 &cmd->cmd_cookie);
4097 dmap++;
4098
4099 cmd->cmd_dmacount += cmd->cmd_cookie.dmac_size;
4100 cmd->cmd_totaldmacount += cmd->cmd_cookie.dmac_size;
4101
4102 /*
4103 * store the segment parms into the S/G list
4104 */
4105 dmap->count = cmd->cmd_cookie.dmac_size;
4106 dmap->addr.address64.Low = (uint32_t)
4107 (cmd->cmd_cookie.dmac_laddress & 0xffffffffull);
4108 dmap->addr.address64.High = (uint32_t)
4109 (cmd->cmd_cookie.dmac_laddress >> 32);
4110 }
4111
4112 /*
4113 * If this was partially allocated we set the resid
4114 * the amount of data NOT transferred in this window
4115 * If there is only one window, the resid will be 0
4116 */
4117 pkt->pkt_resid = (bp->b_bcount - cmd->cmd_totaldmacount);
4118 NDBG3(("mptsas_scsi_init_pkt: cmd_dmacount=%d.",
4119 cmd->cmd_dmacount));
4120 }
4121 return (pkt);
4122 }
4123
4124 /*
4125 * tran_destroy_pkt(9E) - scsi_pkt(9s) deallocation
4126 *
4127 * Notes:
4128 * - also frees DMA resources if allocated
4129 * - implicit DMA synchonization
4130 */
4131 static void
mptsas_scsi_destroy_pkt(struct scsi_address * ap,struct scsi_pkt * pkt)4132 mptsas_scsi_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
4133 {
4134 mptsas_cmd_t *cmd = PKT2CMD(pkt);
4135 mptsas_t *mpt = ADDR2MPT(ap);
4136
4137 NDBG3(("mptsas_scsi_destroy_pkt: target=%d pkt=0x%p",
4138 ap->a_target, (void *)pkt));
4139
4140 if (cmd->cmd_flags & CFLAG_DMAVALID) {
4141 (void) ddi_dma_unbind_handle(cmd->cmd_dmahandle);
4142 cmd->cmd_flags &= ~CFLAG_DMAVALID;
4143 }
4144
4145 if (cmd->cmd_sg) {
4146 kmem_free(cmd->cmd_sg, sizeof (mptti_t) * cmd->cmd_cookiec);
4147 cmd->cmd_sg = NULL;
4148 }
4149
4150 mptsas_free_extra_sgl_frame(mpt, cmd);
4151
4152 if ((cmd->cmd_flags &
4153 (CFLAG_FREE | CFLAG_CDBEXTERN | CFLAG_PRIVEXTERN |
4154 CFLAG_SCBEXTERN)) == 0) {
4155 cmd->cmd_flags = CFLAG_FREE;
4156 kmem_cache_free(mpt->m_kmem_cache, (void *)cmd);
4157 } else {
4158 boolean_t extrqslen = cmd->cmd_extrqslen != 0;
4159
4160 mptsas_pkt_destroy_extern(mpt, cmd);
4161
4162 /*
4163 * If the packet had the sense data buffer for DMA allocated we
4164 * need to decrease the reference counter.
4165 */
4166 if (extrqslen) {
4167 mutex_enter(&mpt->m_mutex);
4168 ASSERT(mpt->m_extreq_sense_refcount > 0);
4169 mpt->m_extreq_sense_refcount--;
4170 if (mpt->m_extreq_sense_refcount == 0)
4171 cv_broadcast(&mpt->m_extreq_sense_refcount_cv);
4172 mutex_exit(&mpt->m_mutex);
4173 }
4174 }
4175 }
4176
4177 /*
4178 * kmem cache constructor and destructor:
4179 * When constructing, we bzero the cmd and allocate the dma handle
4180 * When destructing, just free the dma handle
4181 */
4182 static int
mptsas_kmem_cache_constructor(void * buf,void * cdrarg,int kmflags)4183 mptsas_kmem_cache_constructor(void *buf, void *cdrarg, int kmflags)
4184 {
4185 mptsas_cmd_t *cmd = buf;
4186 mptsas_t *mpt = cdrarg;
4187 int (*callback)(caddr_t);
4188
4189 callback = (kmflags == KM_SLEEP)? DDI_DMA_SLEEP: DDI_DMA_DONTWAIT;
4190
4191 NDBG4(("mptsas_kmem_cache_constructor"));
4192
4193 /*
4194 * allocate a dma handle
4195 */
4196 if ((ddi_dma_alloc_handle(mpt->m_dip, &mpt->m_io_dma_attr, callback,
4197 NULL, &cmd->cmd_dmahandle)) != DDI_SUCCESS) {
4198 cmd->cmd_dmahandle = NULL;
4199 return (-1);
4200 }
4201 return (0);
4202 }
4203
4204 static void
mptsas_kmem_cache_destructor(void * buf,void * cdrarg)4205 mptsas_kmem_cache_destructor(void *buf, void *cdrarg)
4206 {
4207 #ifndef __lock_lint
4208 _NOTE(ARGUNUSED(cdrarg))
4209 #endif
4210 mptsas_cmd_t *cmd = buf;
4211
4212 NDBG4(("mptsas_kmem_cache_destructor"));
4213
4214 if (cmd->cmd_dmahandle) {
4215 ddi_dma_free_handle(&cmd->cmd_dmahandle);
4216 cmd->cmd_dmahandle = NULL;
4217 }
4218 }
4219
4220 static int
mptsas_cache_frames_constructor(void * buf,void * cdrarg,int kmflags)4221 mptsas_cache_frames_constructor(void *buf, void *cdrarg, int kmflags)
4222 {
4223 mptsas_cache_frames_t *p = buf;
4224 mptsas_t *mpt = cdrarg;
4225 ddi_dma_attr_t frame_dma_attr;
4226 size_t mem_size, alloc_len;
4227 ddi_dma_cookie_t cookie;
4228 uint_t ncookie;
4229 int (*callback)(caddr_t) = (kmflags == KM_SLEEP)
4230 ? DDI_DMA_SLEEP: DDI_DMA_DONTWAIT;
4231
4232 frame_dma_attr = mpt->m_msg_dma_attr;
4233 frame_dma_attr.dma_attr_align = 0x10;
4234 frame_dma_attr.dma_attr_sgllen = 1;
4235
4236 if (ddi_dma_alloc_handle(mpt->m_dip, &frame_dma_attr, callback, NULL,
4237 &p->m_dma_hdl) != DDI_SUCCESS) {
4238 mptsas_log(mpt, CE_WARN, "Unable to allocate dma handle for"
4239 " extra SGL.");
4240 return (DDI_FAILURE);
4241 }
4242
4243 mem_size = (mpt->m_max_request_frames - 1) * mpt->m_req_frame_size;
4244
4245 if (ddi_dma_mem_alloc(p->m_dma_hdl, mem_size, &mpt->m_dev_acc_attr,
4246 DDI_DMA_CONSISTENT, callback, NULL, (caddr_t *)&p->m_frames_addr,
4247 &alloc_len, &p->m_acc_hdl) != DDI_SUCCESS) {
4248 ddi_dma_free_handle(&p->m_dma_hdl);
4249 p->m_dma_hdl = NULL;
4250 mptsas_log(mpt, CE_WARN, "Unable to allocate dma memory for"
4251 " extra SGL.");
4252 return (DDI_FAILURE);
4253 }
4254
4255 if (ddi_dma_addr_bind_handle(p->m_dma_hdl, NULL, p->m_frames_addr,
4256 alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, callback, NULL,
4257 &cookie, &ncookie) != DDI_DMA_MAPPED) {
4258 (void) ddi_dma_mem_free(&p->m_acc_hdl);
4259 ddi_dma_free_handle(&p->m_dma_hdl);
4260 p->m_dma_hdl = NULL;
4261 mptsas_log(mpt, CE_WARN, "Unable to bind DMA resources for"
4262 " extra SGL");
4263 return (DDI_FAILURE);
4264 }
4265
4266 /*
4267 * Store the SGL memory address. This chip uses this
4268 * address to dma to and from the driver. The second
4269 * address is the address mpt uses to fill in the SGL.
4270 */
4271 p->m_phys_addr = cookie.dmac_laddress;
4272
4273 return (DDI_SUCCESS);
4274 }
4275
4276 static void
mptsas_cache_frames_destructor(void * buf,void * cdrarg)4277 mptsas_cache_frames_destructor(void *buf, void *cdrarg)
4278 {
4279 #ifndef __lock_lint
4280 _NOTE(ARGUNUSED(cdrarg))
4281 #endif
4282 mptsas_cache_frames_t *p = buf;
4283 if (p->m_dma_hdl != NULL) {
4284 (void) ddi_dma_unbind_handle(p->m_dma_hdl);
4285 (void) ddi_dma_mem_free(&p->m_acc_hdl);
4286 ddi_dma_free_handle(&p->m_dma_hdl);
4287 p->m_phys_addr = 0;
4288 p->m_frames_addr = NULL;
4289 p->m_dma_hdl = NULL;
4290 p->m_acc_hdl = NULL;
4291 }
4292
4293 }
4294
4295 /*
4296 * Figure out if we need to use a different method for the request
4297 * sense buffer and allocate from the map if necessary.
4298 */
4299 static boolean_t
mptsas_cmdarqsize(mptsas_t * mpt,mptsas_cmd_t * cmd,size_t senselength,int kf)4300 mptsas_cmdarqsize(mptsas_t *mpt, mptsas_cmd_t *cmd, size_t senselength, int kf)
4301 {
4302 if (senselength > mpt->m_req_sense_size) {
4303 unsigned long i;
4304
4305 /* Sense length is limited to an 8 bit value in MPI Spec. */
4306 if (senselength > 255)
4307 senselength = 255;
4308 cmd->cmd_extrqschunks = (senselength +
4309 (mpt->m_req_sense_size - 1))/mpt->m_req_sense_size;
4310 i = (kf == KM_SLEEP ? rmalloc_wait : rmalloc)
4311 (mpt->m_erqsense_map, cmd->cmd_extrqschunks);
4312
4313 if (i == 0)
4314 return (B_FALSE);
4315
4316 cmd->cmd_extrqslen = (uint16_t)senselength;
4317 cmd->cmd_extrqsidx = i - 1;
4318 cmd->cmd_arq_buf = mpt->m_extreq_sense +
4319 (cmd->cmd_extrqsidx * mpt->m_req_sense_size);
4320 } else {
4321 cmd->cmd_rqslen = (uchar_t)senselength;
4322 }
4323
4324 return (B_TRUE);
4325 }
4326
4327 /*
4328 * allocate and deallocate external pkt space (ie. not part of mptsas_cmd)
4329 * for non-standard length cdb, pkt_private, status areas
4330 * if allocation fails, then deallocate all external space and the pkt
4331 */
4332 /* ARGSUSED */
4333 static int
mptsas_pkt_alloc_extern(mptsas_t * mpt,mptsas_cmd_t * cmd,int cmdlen,int tgtlen,int statuslen,int kf)4334 mptsas_pkt_alloc_extern(mptsas_t *mpt, mptsas_cmd_t *cmd,
4335 int cmdlen, int tgtlen, int statuslen, int kf)
4336 {
4337 caddr_t cdbp, scbp, tgt;
4338
4339 NDBG3(("mptsas_pkt_alloc_extern: "
4340 "cmd=0x%p cmdlen=%d tgtlen=%d statuslen=%d kf=%x",
4341 (void *)cmd, cmdlen, tgtlen, statuslen, kf));
4342
4343 tgt = cdbp = scbp = NULL;
4344 cmd->cmd_scblen = statuslen;
4345 cmd->cmd_privlen = (uchar_t)tgtlen;
4346
4347 if (cmdlen > sizeof (cmd->cmd_cdb)) {
4348 if ((cdbp = kmem_zalloc((size_t)cmdlen, kf)) == NULL) {
4349 goto fail;
4350 }
4351 cmd->cmd_pkt->pkt_cdbp = (opaque_t)cdbp;
4352 cmd->cmd_flags |= CFLAG_CDBEXTERN;
4353 }
4354 if (tgtlen > PKT_PRIV_LEN) {
4355 if ((tgt = kmem_zalloc((size_t)tgtlen, kf)) == NULL) {
4356 goto fail;
4357 }
4358 cmd->cmd_flags |= CFLAG_PRIVEXTERN;
4359 cmd->cmd_pkt->pkt_private = tgt;
4360 }
4361 if (statuslen > EXTCMDS_STATUS_SIZE) {
4362 if ((scbp = kmem_zalloc((size_t)statuslen, kf)) == NULL) {
4363 goto fail;
4364 }
4365 cmd->cmd_flags |= CFLAG_SCBEXTERN;
4366 cmd->cmd_pkt->pkt_scbp = (opaque_t)scbp;
4367
4368 /* allocate sense data buf for DMA */
4369 if (mptsas_cmdarqsize(mpt, cmd, statuslen -
4370 MPTSAS_GET_ITEM_OFF(struct scsi_arq_status, sts_sensedata),
4371 kf) == B_FALSE)
4372 goto fail;
4373 }
4374 return (0);
4375 fail:
4376 mptsas_pkt_destroy_extern(mpt, cmd);
4377 return (1);
4378 }
4379
4380 /*
4381 * deallocate external pkt space and deallocate the pkt
4382 */
4383 static void
mptsas_pkt_destroy_extern(mptsas_t * mpt,mptsas_cmd_t * cmd)4384 mptsas_pkt_destroy_extern(mptsas_t *mpt, mptsas_cmd_t *cmd)
4385 {
4386 NDBG3(("mptsas_pkt_destroy_extern: cmd=0x%p", (void *)cmd));
4387
4388 if (cmd->cmd_flags & CFLAG_FREE) {
4389 mptsas_log(mpt, CE_PANIC,
4390 "mptsas_pkt_destroy_extern: freeing free packet");
4391 _NOTE(NOT_REACHED)
4392 /* NOTREACHED */
4393 }
4394 if (cmd->cmd_extrqslen != 0) {
4395 rmfree(mpt->m_erqsense_map, cmd->cmd_extrqschunks,
4396 cmd->cmd_extrqsidx + 1);
4397 }
4398 if (cmd->cmd_flags & CFLAG_CDBEXTERN) {
4399 kmem_free(cmd->cmd_pkt->pkt_cdbp, (size_t)cmd->cmd_cdblen);
4400 }
4401 if (cmd->cmd_flags & CFLAG_SCBEXTERN) {
4402 kmem_free(cmd->cmd_pkt->pkt_scbp, (size_t)cmd->cmd_scblen);
4403 }
4404 if (cmd->cmd_flags & CFLAG_PRIVEXTERN) {
4405 kmem_free(cmd->cmd_pkt->pkt_private, (size_t)cmd->cmd_privlen);
4406 }
4407 cmd->cmd_flags = CFLAG_FREE;
4408 kmem_cache_free(mpt->m_kmem_cache, (void *)cmd);
4409 }
4410
4411 /*
4412 * tran_sync_pkt(9E) - explicit DMA synchronization
4413 */
4414 /*ARGSUSED*/
4415 static void
mptsas_scsi_sync_pkt(struct scsi_address * ap,struct scsi_pkt * pkt)4416 mptsas_scsi_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
4417 {
4418 mptsas_cmd_t *cmd = PKT2CMD(pkt);
4419
4420 NDBG3(("mptsas_scsi_sync_pkt: target=%d, pkt=0x%p",
4421 ap->a_target, (void *)pkt));
4422
4423 if (cmd->cmd_dmahandle) {
4424 (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0,
4425 (cmd->cmd_flags & CFLAG_DMASEND) ?
4426 DDI_DMA_SYNC_FORDEV : DDI_DMA_SYNC_FORCPU);
4427 }
4428 }
4429
4430 /*
4431 * tran_dmafree(9E) - deallocate DMA resources allocated for command
4432 */
4433 /*ARGSUSED*/
4434 static void
mptsas_scsi_dmafree(struct scsi_address * ap,struct scsi_pkt * pkt)4435 mptsas_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt)
4436 {
4437 mptsas_cmd_t *cmd = PKT2CMD(pkt);
4438 mptsas_t *mpt = ADDR2MPT(ap);
4439
4440 NDBG3(("mptsas_scsi_dmafree: target=%d pkt=0x%p",
4441 ap->a_target, (void *)pkt));
4442
4443 if (cmd->cmd_flags & CFLAG_DMAVALID) {
4444 (void) ddi_dma_unbind_handle(cmd->cmd_dmahandle);
4445 cmd->cmd_flags &= ~CFLAG_DMAVALID;
4446 }
4447
4448 mptsas_free_extra_sgl_frame(mpt, cmd);
4449 }
4450
4451 static void
mptsas_pkt_comp(struct scsi_pkt * pkt,mptsas_cmd_t * cmd)4452 mptsas_pkt_comp(struct scsi_pkt *pkt, mptsas_cmd_t *cmd)
4453 {
4454 if ((cmd->cmd_flags & CFLAG_CMDIOPB) &&
4455 (!(cmd->cmd_flags & CFLAG_DMASEND))) {
4456 (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0,
4457 DDI_DMA_SYNC_FORCPU);
4458 }
4459 (*pkt->pkt_comp)(pkt);
4460 }
4461
4462 static void
mptsas_sge_mainframe(mptsas_cmd_t * cmd,pMpi2SCSIIORequest_t frame,ddi_acc_handle_t acc_hdl,uint_t cookiec,uint32_t end_flags)4463 mptsas_sge_mainframe(mptsas_cmd_t *cmd, pMpi2SCSIIORequest_t frame,
4464 ddi_acc_handle_t acc_hdl, uint_t cookiec, uint32_t end_flags)
4465 {
4466 pMpi2SGESimple64_t sge;
4467 mptti_t *dmap;
4468 uint32_t flags;
4469
4470 dmap = cmd->cmd_sg;
4471
4472 sge = (pMpi2SGESimple64_t)(&frame->SGL);
4473 while (cookiec--) {
4474 ddi_put32(acc_hdl,
4475 &sge->Address.Low, dmap->addr.address64.Low);
4476 ddi_put32(acc_hdl,
4477 &sge->Address.High, dmap->addr.address64.High);
4478 ddi_put32(acc_hdl, &sge->FlagsLength,
4479 dmap->count);
4480 flags = ddi_get32(acc_hdl, &sge->FlagsLength);
4481 flags |= ((uint32_t)
4482 (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
4483 MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
4484 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
4485 MPI2_SGE_FLAGS_SHIFT);
4486
4487 /*
4488 * If this is the last cookie, we set the flags
4489 * to indicate so
4490 */
4491 if (cookiec == 0) {
4492 flags |= end_flags;
4493 }
4494 if (cmd->cmd_flags & CFLAG_DMASEND) {
4495 flags |= (MPI2_SGE_FLAGS_HOST_TO_IOC <<
4496 MPI2_SGE_FLAGS_SHIFT);
4497 } else {
4498 flags |= (MPI2_SGE_FLAGS_IOC_TO_HOST <<
4499 MPI2_SGE_FLAGS_SHIFT);
4500 }
4501 ddi_put32(acc_hdl, &sge->FlagsLength, flags);
4502 dmap++;
4503 sge++;
4504 }
4505 }
4506
4507 static void
mptsas_sge_chain(mptsas_t * mpt,mptsas_cmd_t * cmd,pMpi2SCSIIORequest_t frame,ddi_acc_handle_t acc_hdl)4508 mptsas_sge_chain(mptsas_t *mpt, mptsas_cmd_t *cmd,
4509 pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl)
4510 {
4511 pMpi2SGESimple64_t sge;
4512 pMpi2SGEChain64_t sgechain;
4513 uint64_t nframe_phys_addr;
4514 uint_t cookiec;
4515 mptti_t *dmap;
4516 uint32_t flags;
4517
4518 /*
4519 * Save the number of entries in the DMA
4520 * Scatter/Gather list
4521 */
4522 cookiec = cmd->cmd_cookiec;
4523
4524 /*
4525 * Hereby we start to deal with multiple frames.
4526 * The process is as follows:
4527 * 1. Determine how many frames are needed for SGL element
4528 * storage; Note that all frames are stored in contiguous
4529 * memory space and in 64-bit DMA mode each element is
4530 * 3 double-words (12 bytes) long.
4531 * 2. Fill up the main frame. We need to do this separately
4532 * since it contains the SCSI IO request header and needs
4533 * dedicated processing. Note that the last 4 double-words
4534 * of the SCSI IO header is for SGL element storage
4535 * (MPI2_SGE_IO_UNION).
4536 * 3. Fill the chain element in the main frame, so the DMA
4537 * engine can use the following frames.
4538 * 4. Enter a loop to fill the remaining frames. Note that the
4539 * last frame contains no chain element. The remaining
4540 * frames go into the mpt SGL buffer allocated on the fly,
4541 * not immediately following the main message frame, as in
4542 * Gen1.
4543 * Some restrictions:
4544 * 1. For 64-bit DMA, the simple element and chain element
4545 * are both of 3 double-words (12 bytes) in size, even
4546 * though all frames are stored in the first 4G of mem
4547 * range and the higher 32-bits of the address are always 0.
4548 * 2. On some controllers (like the 1064/1068), a frame can
4549 * hold SGL elements with the last 1 or 2 double-words
4550 * (4 or 8 bytes) un-used. On these controllers, we should
4551 * recognize that there's not enough room for another SGL
4552 * element and move the sge pointer to the next frame.
4553 */
4554 int i, j, k, l, frames, sgemax;
4555 int temp;
4556 uint8_t chainflags;
4557 uint16_t chainlength;
4558 mptsas_cache_frames_t *p;
4559
4560 /*
4561 * Sgemax is the number of SGE's that will fit
4562 * each extra frame and frames is total
4563 * number of frames we'll need. 1 sge entry per
4564 * frame is reseverd for the chain element thus the -1 below.
4565 */
4566 sgemax = ((mpt->m_req_frame_size / sizeof (MPI2_SGE_SIMPLE64))
4567 - 1);
4568 temp = (cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) / sgemax;
4569
4570 /*
4571 * A little check to see if we need to round up the number
4572 * of frames we need
4573 */
4574 if ((cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) - (temp *
4575 sgemax) > 1) {
4576 frames = (temp + 1);
4577 } else {
4578 frames = temp;
4579 }
4580 dmap = cmd->cmd_sg;
4581 sge = (pMpi2SGESimple64_t)(&frame->SGL);
4582
4583 /*
4584 * First fill in the main frame
4585 */
4586 j = MPTSAS_MAX_FRAME_SGES64(mpt) - 1;
4587 mptsas_sge_mainframe(cmd, frame, acc_hdl, j,
4588 ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT) <<
4589 MPI2_SGE_FLAGS_SHIFT));
4590 dmap += j;
4591 sge += j;
4592 j++;
4593
4594 /*
4595 * Fill in the chain element in the main frame.
4596 * About calculation on ChainOffset:
4597 * 1. Struct msg_scsi_io_request has 4 double-words (16 bytes)
4598 * in the end reserved for SGL element storage
4599 * (MPI2_SGE_IO_UNION); we should count it in our
4600 * calculation. See its definition in the header file.
4601 * 2. Constant j is the counter of the current SGL element
4602 * that will be processed, and (j - 1) is the number of
4603 * SGL elements that have been processed (stored in the
4604 * main frame).
4605 * 3. ChainOffset value should be in units of double-words (4
4606 * bytes) so the last value should be divided by 4.
4607 */
4608 ddi_put8(acc_hdl, &frame->ChainOffset,
4609 (sizeof (MPI2_SCSI_IO_REQUEST) -
4610 sizeof (MPI2_SGE_IO_UNION) +
4611 (j - 1) * sizeof (MPI2_SGE_SIMPLE64)) >> 2);
4612 sgechain = (pMpi2SGEChain64_t)sge;
4613 chainflags = (MPI2_SGE_FLAGS_CHAIN_ELEMENT |
4614 MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
4615 MPI2_SGE_FLAGS_64_BIT_ADDRESSING);
4616 ddi_put8(acc_hdl, &sgechain->Flags, chainflags);
4617
4618 /*
4619 * The size of the next frame is the accurate size of space
4620 * (in bytes) used to store the SGL elements. j is the counter
4621 * of SGL elements. (j - 1) is the number of SGL elements that
4622 * have been processed (stored in frames).
4623 */
4624 if (frames >= 2) {
4625 ASSERT(mpt->m_req_frame_size >= sizeof (MPI2_SGE_SIMPLE64));
4626 chainlength = mpt->m_req_frame_size /
4627 sizeof (MPI2_SGE_SIMPLE64) *
4628 sizeof (MPI2_SGE_SIMPLE64);
4629 } else {
4630 chainlength = ((cookiec - (j - 1)) *
4631 sizeof (MPI2_SGE_SIMPLE64));
4632 }
4633
4634 p = cmd->cmd_extra_frames;
4635
4636 ddi_put16(acc_hdl, &sgechain->Length, chainlength);
4637 ddi_put32(acc_hdl, &sgechain->Address.Low, p->m_phys_addr);
4638 ddi_put32(acc_hdl, &sgechain->Address.High, p->m_phys_addr >> 32);
4639
4640 /*
4641 * If there are more than 2 frames left we have to
4642 * fill in the next chain offset to the location of
4643 * the chain element in the next frame.
4644 * sgemax is the number of simple elements in an extra
4645 * frame. Note that the value NextChainOffset should be
4646 * in double-words (4 bytes).
4647 */
4648 if (frames >= 2) {
4649 ddi_put8(acc_hdl, &sgechain->NextChainOffset,
4650 (sgemax * sizeof (MPI2_SGE_SIMPLE64)) >> 2);
4651 } else {
4652 ddi_put8(acc_hdl, &sgechain->NextChainOffset, 0);
4653 }
4654
4655 /*
4656 * Jump to next frame;
4657 * Starting here, chain buffers go into the per command SGL.
4658 * This buffer is allocated when chain buffers are needed.
4659 */
4660 sge = (pMpi2SGESimple64_t)p->m_frames_addr;
4661 i = cookiec;
4662
4663 /*
4664 * Start filling in frames with SGE's. If we
4665 * reach the end of frame and still have SGE's
4666 * to fill we need to add a chain element and
4667 * use another frame. j will be our counter
4668 * for what cookie we are at and i will be
4669 * the total cookiec. k is the current frame
4670 */
4671 for (k = 1; k <= frames; k++) {
4672 for (l = 1; (l <= (sgemax + 1)) && (j <= i); j++, l++) {
4673
4674 /*
4675 * If we have reached the end of frame
4676 * and we have more SGE's to fill in
4677 * we have to fill the final entry
4678 * with a chain element and then
4679 * continue to the next frame
4680 */
4681 if ((l == (sgemax + 1)) && (k != frames)) {
4682 sgechain = (pMpi2SGEChain64_t)sge;
4683 j--;
4684 chainflags = (
4685 MPI2_SGE_FLAGS_CHAIN_ELEMENT |
4686 MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
4687 MPI2_SGE_FLAGS_64_BIT_ADDRESSING);
4688 ddi_put8(p->m_acc_hdl,
4689 &sgechain->Flags, chainflags);
4690 /*
4691 * k is the frame counter and (k + 1)
4692 * is the number of the next frame.
4693 * Note that frames are in contiguous
4694 * memory space.
4695 */
4696 nframe_phys_addr = p->m_phys_addr +
4697 (mpt->m_req_frame_size * k);
4698 ddi_put32(p->m_acc_hdl,
4699 &sgechain->Address.Low,
4700 nframe_phys_addr);
4701 ddi_put32(p->m_acc_hdl,
4702 &sgechain->Address.High,
4703 nframe_phys_addr >> 32);
4704
4705 /*
4706 * If there are more than 2 frames left
4707 * we have to next chain offset to
4708 * the location of the chain element
4709 * in the next frame and fill in the
4710 * length of the next chain
4711 */
4712 if ((frames - k) >= 2) {
4713 ddi_put8(p->m_acc_hdl,
4714 &sgechain->NextChainOffset,
4715 (sgemax *
4716 sizeof (MPI2_SGE_SIMPLE64))
4717 >> 2);
4718 ddi_put16(p->m_acc_hdl,
4719 &sgechain->Length,
4720 mpt->m_req_frame_size /
4721 sizeof (MPI2_SGE_SIMPLE64) *
4722 sizeof (MPI2_SGE_SIMPLE64));
4723 } else {
4724 /*
4725 * This is the last frame. Set
4726 * the NextChainOffset to 0 and
4727 * Length is the total size of
4728 * all remaining simple elements
4729 */
4730 ddi_put8(p->m_acc_hdl,
4731 &sgechain->NextChainOffset,
4732 0);
4733 ddi_put16(p->m_acc_hdl,
4734 &sgechain->Length,
4735 (cookiec - j) *
4736 sizeof (MPI2_SGE_SIMPLE64));
4737 }
4738
4739 /* Jump to the next frame */
4740 sge = (pMpi2SGESimple64_t)
4741 ((char *)p->m_frames_addr +
4742 (int)mpt->m_req_frame_size * k);
4743
4744 continue;
4745 }
4746
4747 ddi_put32(p->m_acc_hdl,
4748 &sge->Address.Low,
4749 dmap->addr.address64.Low);
4750 ddi_put32(p->m_acc_hdl,
4751 &sge->Address.High,
4752 dmap->addr.address64.High);
4753 ddi_put32(p->m_acc_hdl,
4754 &sge->FlagsLength, dmap->count);
4755 flags = ddi_get32(p->m_acc_hdl,
4756 &sge->FlagsLength);
4757 flags |= ((uint32_t)(
4758 MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
4759 MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
4760 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
4761 MPI2_SGE_FLAGS_SHIFT);
4762
4763 /*
4764 * If we are at the end of the frame and
4765 * there is another frame to fill in
4766 * we set the last simple element as last
4767 * element
4768 */
4769 if ((l == sgemax) && (k != frames)) {
4770 flags |= ((uint32_t)
4771 (MPI2_SGE_FLAGS_LAST_ELEMENT) <<
4772 MPI2_SGE_FLAGS_SHIFT);
4773 }
4774
4775 /*
4776 * If this is the final cookie we
4777 * indicate it by setting the flags
4778 */
4779 if (j == i) {
4780 flags |= ((uint32_t)
4781 (MPI2_SGE_FLAGS_LAST_ELEMENT |
4782 MPI2_SGE_FLAGS_END_OF_BUFFER |
4783 MPI2_SGE_FLAGS_END_OF_LIST) <<
4784 MPI2_SGE_FLAGS_SHIFT);
4785 }
4786 if (cmd->cmd_flags & CFLAG_DMASEND) {
4787 flags |=
4788 (MPI2_SGE_FLAGS_HOST_TO_IOC <<
4789 MPI2_SGE_FLAGS_SHIFT);
4790 } else {
4791 flags |=
4792 (MPI2_SGE_FLAGS_IOC_TO_HOST <<
4793 MPI2_SGE_FLAGS_SHIFT);
4794 }
4795 ddi_put32(p->m_acc_hdl,
4796 &sge->FlagsLength, flags);
4797 dmap++;
4798 sge++;
4799 }
4800 }
4801
4802 /*
4803 * Sync DMA with the chain buffers that were just created
4804 */
4805 (void) ddi_dma_sync(p->m_dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
4806 }
4807
4808 static void
mptsas_ieee_sge_mainframe(mptsas_cmd_t * cmd,pMpi2SCSIIORequest_t frame,ddi_acc_handle_t acc_hdl,uint_t cookiec,uint8_t end_flag)4809 mptsas_ieee_sge_mainframe(mptsas_cmd_t *cmd, pMpi2SCSIIORequest_t frame,
4810 ddi_acc_handle_t acc_hdl, uint_t cookiec, uint8_t end_flag)
4811 {
4812 pMpi2IeeeSgeSimple64_t ieeesge;
4813 mptti_t *dmap;
4814 uint8_t flags;
4815
4816 dmap = cmd->cmd_sg;
4817
4818 NDBG1(("mptsas_ieee_sge_mainframe: cookiec=%d, %s", cookiec,
4819 cmd->cmd_flags & CFLAG_DMASEND?"Out":"In"));
4820
4821 ieeesge = (pMpi2IeeeSgeSimple64_t)(&frame->SGL);
4822 while (cookiec--) {
4823 ddi_put32(acc_hdl,
4824 &ieeesge->Address.Low, dmap->addr.address64.Low);
4825 ddi_put32(acc_hdl,
4826 &ieeesge->Address.High, dmap->addr.address64.High);
4827 ddi_put32(acc_hdl, &ieeesge->Length,
4828 dmap->count);
4829 NDBG1(("mptsas_ieee_sge_mainframe: len=%d", dmap->count));
4830 flags = (MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT |
4831 MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR);
4832
4833 /*
4834 * If this is the last cookie, we set the flags
4835 * to indicate so
4836 */
4837 if (cookiec == 0) {
4838 flags |= end_flag;
4839 }
4840
4841 ddi_put8(acc_hdl, &ieeesge->Flags, flags);
4842 dmap++;
4843 ieeesge++;
4844 }
4845 }
4846
4847 static void
mptsas_ieee_sge_chain(mptsas_t * mpt,mptsas_cmd_t * cmd,pMpi2SCSIIORequest_t frame,ddi_acc_handle_t acc_hdl)4848 mptsas_ieee_sge_chain(mptsas_t *mpt, mptsas_cmd_t *cmd,
4849 pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl)
4850 {
4851 pMpi2IeeeSgeSimple64_t ieeesge;
4852 pMpi25IeeeSgeChain64_t ieeesgechain;
4853 uint64_t nframe_phys_addr;
4854 uint_t cookiec;
4855 mptti_t *dmap;
4856 uint8_t flags;
4857
4858 /*
4859 * Save the number of entries in the DMA
4860 * Scatter/Gather list
4861 */
4862 cookiec = cmd->cmd_cookiec;
4863
4864 NDBG1(("mptsas_ieee_sge_chain: cookiec=%d", cookiec));
4865
4866 /*
4867 * Hereby we start to deal with multiple frames.
4868 * The process is as follows:
4869 * 1. Determine how many frames are needed for SGL element
4870 * storage; Note that all frames are stored in contiguous
4871 * memory space and in 64-bit DMA mode each element is
4872 * 4 double-words (16 bytes) long.
4873 * 2. Fill up the main frame. We need to do this separately
4874 * since it contains the SCSI IO request header and needs
4875 * dedicated processing. Note that the last 4 double-words
4876 * of the SCSI IO header is for SGL element storage
4877 * (MPI2_SGE_IO_UNION).
4878 * 3. Fill the chain element in the main frame, so the DMA
4879 * engine can use the following frames.
4880 * 4. Enter a loop to fill the remaining frames. Note that the
4881 * last frame contains no chain element. The remaining
4882 * frames go into the mpt SGL buffer allocated on the fly,
4883 * not immediately following the main message frame, as in
4884 * Gen1.
4885 * Restrictions:
4886 * For 64-bit DMA, the simple element and chain element
4887 * are both of 4 double-words (16 bytes) in size, even
4888 * though all frames are stored in the first 4G of mem
4889 * range and the higher 32-bits of the address are always 0.
4890 */
4891 int i, j, k, l, frames, sgemax;
4892 int temp;
4893 uint8_t chainflags;
4894 uint32_t chainlength;
4895 mptsas_cache_frames_t *p;
4896
4897 /*
4898 * Sgemax is the number of SGE's that will fit
4899 * each extra frame and frames is total
4900 * number of frames we'll need. 1 sge entry per
4901 * frame is reseverd for the chain element thus the -1 below.
4902 */
4903 sgemax = ((mpt->m_req_frame_size / sizeof (MPI2_IEEE_SGE_SIMPLE64))
4904 - 1);
4905 temp = (cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) / sgemax;
4906
4907 /*
4908 * A little check to see if we need to round up the number
4909 * of frames we need
4910 */
4911 if ((cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) - (temp *
4912 sgemax) > 1) {
4913 frames = (temp + 1);
4914 } else {
4915 frames = temp;
4916 }
4917 NDBG1(("mptsas_ieee_sge_chain: temp=%d, frames=%d", temp, frames));
4918 dmap = cmd->cmd_sg;
4919 ieeesge = (pMpi2IeeeSgeSimple64_t)(&frame->SGL);
4920
4921 /*
4922 * First fill in the main frame
4923 */
4924 j = MPTSAS_MAX_FRAME_SGES64(mpt) - 1;
4925 mptsas_ieee_sge_mainframe(cmd, frame, acc_hdl, j, 0);
4926 dmap += j;
4927 ieeesge += j;
4928 j++;
4929
4930 /*
4931 * Fill in the chain element in the main frame.
4932 * About calculation on ChainOffset:
4933 * 1. Struct msg_scsi_io_request has 4 double-words (16 bytes)
4934 * in the end reserved for SGL element storage
4935 * (MPI2_SGE_IO_UNION); we should count it in our
4936 * calculation. See its definition in the header file.
4937 * 2. Constant j is the counter of the current SGL element
4938 * that will be processed, and (j - 1) is the number of
4939 * SGL elements that have been processed (stored in the
4940 * main frame).
4941 * 3. ChainOffset value should be in units of quad-words (16
4942 * bytes) so the last value should be divided by 16.
4943 */
4944 ddi_put8(acc_hdl, &frame->ChainOffset,
4945 (sizeof (MPI2_SCSI_IO_REQUEST) -
4946 sizeof (MPI2_SGE_IO_UNION) +
4947 (j - 1) * sizeof (MPI2_IEEE_SGE_SIMPLE64)) >> 4);
4948 ieeesgechain = (pMpi25IeeeSgeChain64_t)ieeesge;
4949 chainflags = (MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT |
4950 MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR);
4951 ddi_put8(acc_hdl, &ieeesgechain->Flags, chainflags);
4952
4953 /*
4954 * The size of the next frame is the accurate size of space
4955 * (in bytes) used to store the SGL elements. j is the counter
4956 * of SGL elements. (j - 1) is the number of SGL elements that
4957 * have been processed (stored in frames).
4958 */
4959 if (frames >= 2) {
4960 ASSERT(mpt->m_req_frame_size >=
4961 sizeof (MPI2_IEEE_SGE_SIMPLE64));
4962 chainlength = mpt->m_req_frame_size /
4963 sizeof (MPI2_IEEE_SGE_SIMPLE64) *
4964 sizeof (MPI2_IEEE_SGE_SIMPLE64);
4965 } else {
4966 chainlength = ((cookiec - (j - 1)) *
4967 sizeof (MPI2_IEEE_SGE_SIMPLE64));
4968 }
4969
4970 p = cmd->cmd_extra_frames;
4971
4972 ddi_put32(acc_hdl, &ieeesgechain->Length, chainlength);
4973 ddi_put32(acc_hdl, &ieeesgechain->Address.Low, p->m_phys_addr);
4974 ddi_put32(acc_hdl, &ieeesgechain->Address.High, p->m_phys_addr >> 32);
4975
4976 /*
4977 * If there are more than 2 frames left we have to
4978 * fill in the next chain offset to the location of
4979 * the chain element in the next frame.
4980 * sgemax is the number of simple elements in an extra
4981 * frame. Note that the value NextChainOffset should be
4982 * in double-words (4 bytes).
4983 */
4984 if (frames >= 2) {
4985 ddi_put8(acc_hdl, &ieeesgechain->NextChainOffset,
4986 (sgemax * sizeof (MPI2_IEEE_SGE_SIMPLE64)) >> 4);
4987 } else {
4988 ddi_put8(acc_hdl, &ieeesgechain->NextChainOffset, 0);
4989 }
4990
4991 /*
4992 * Jump to next frame;
4993 * Starting here, chain buffers go into the per command SGL.
4994 * This buffer is allocated when chain buffers are needed.
4995 */
4996 ieeesge = (pMpi2IeeeSgeSimple64_t)p->m_frames_addr;
4997 i = cookiec;
4998
4999 /*
5000 * Start filling in frames with SGE's. If we
5001 * reach the end of frame and still have SGE's
5002 * to fill we need to add a chain element and
5003 * use another frame. j will be our counter
5004 * for what cookie we are at and i will be
5005 * the total cookiec. k is the current frame
5006 */
5007 for (k = 1; k <= frames; k++) {
5008 for (l = 1; (l <= (sgemax + 1)) && (j <= i); j++, l++) {
5009
5010 /*
5011 * If we have reached the end of frame
5012 * and we have more SGE's to fill in
5013 * we have to fill the final entry
5014 * with a chain element and then
5015 * continue to the next frame
5016 */
5017 if ((l == (sgemax + 1)) && (k != frames)) {
5018 ieeesgechain = (pMpi25IeeeSgeChain64_t)ieeesge;
5019 j--;
5020 chainflags =
5021 MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT |
5022 MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR;
5023 ddi_put8(p->m_acc_hdl,
5024 &ieeesgechain->Flags, chainflags);
5025 /*
5026 * k is the frame counter and (k + 1)
5027 * is the number of the next frame.
5028 * Note that frames are in contiguous
5029 * memory space.
5030 */
5031 nframe_phys_addr = p->m_phys_addr +
5032 (mpt->m_req_frame_size * k);
5033 ddi_put32(p->m_acc_hdl,
5034 &ieeesgechain->Address.Low,
5035 nframe_phys_addr);
5036 ddi_put32(p->m_acc_hdl,
5037 &ieeesgechain->Address.High,
5038 nframe_phys_addr >> 32);
5039
5040 /*
5041 * If there are more than 2 frames left
5042 * we have to next chain offset to
5043 * the location of the chain element
5044 * in the next frame and fill in the
5045 * length of the next chain
5046 */
5047 if ((frames - k) >= 2) {
5048 ddi_put8(p->m_acc_hdl,
5049 &ieeesgechain->NextChainOffset,
5050 (sgemax *
5051 sizeof (MPI2_IEEE_SGE_SIMPLE64))
5052 >> 4);
5053 ASSERT(mpt->m_req_frame_size >=
5054 sizeof (MPI2_IEEE_SGE_SIMPLE64));
5055 ddi_put32(p->m_acc_hdl,
5056 &ieeesgechain->Length,
5057 mpt->m_req_frame_size /
5058 sizeof (MPI2_IEEE_SGE_SIMPLE64) *
5059 sizeof (MPI2_IEEE_SGE_SIMPLE64));
5060 } else {
5061 /*
5062 * This is the last frame. Set
5063 * the NextChainOffset to 0 and
5064 * Length is the total size of
5065 * all remaining simple elements
5066 */
5067 ddi_put8(p->m_acc_hdl,
5068 &ieeesgechain->NextChainOffset,
5069 0);
5070 ddi_put32(p->m_acc_hdl,
5071 &ieeesgechain->Length,
5072 (cookiec - j) *
5073 sizeof (MPI2_IEEE_SGE_SIMPLE64));
5074 }
5075
5076 /* Jump to the next frame */
5077 ieeesge = (pMpi2IeeeSgeSimple64_t)
5078 ((char *)p->m_frames_addr +
5079 (int)mpt->m_req_frame_size * k);
5080
5081 continue;
5082 }
5083
5084 ddi_put32(p->m_acc_hdl,
5085 &ieeesge->Address.Low,
5086 dmap->addr.address64.Low);
5087 ddi_put32(p->m_acc_hdl,
5088 &ieeesge->Address.High,
5089 dmap->addr.address64.High);
5090 ddi_put32(p->m_acc_hdl,
5091 &ieeesge->Length, dmap->count);
5092 flags = (MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT |
5093 MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR);
5094
5095 /*
5096 * If we are at the end of the frame and
5097 * there is another frame to fill in
5098 * do we need to do anything?
5099 * if ((l == sgemax) && (k != frames)) {
5100 * }
5101 */
5102
5103 /*
5104 * If this is the final cookie set end of list.
5105 */
5106 if (j == i) {
5107 flags |= MPI25_IEEE_SGE_FLAGS_END_OF_LIST;
5108 }
5109
5110 ddi_put8(p->m_acc_hdl, &ieeesge->Flags, flags);
5111 dmap++;
5112 ieeesge++;
5113 }
5114 }
5115
5116 /*
5117 * Sync DMA with the chain buffers that were just created
5118 */
5119 (void) ddi_dma_sync(p->m_dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
5120 }
5121
5122 static void
mptsas_sge_setup(mptsas_t * mpt,mptsas_cmd_t * cmd,uint32_t * control,pMpi2SCSIIORequest_t frame,ddi_acc_handle_t acc_hdl)5123 mptsas_sge_setup(mptsas_t *mpt, mptsas_cmd_t *cmd, uint32_t *control,
5124 pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl)
5125 {
5126 ASSERT(cmd->cmd_flags & CFLAG_DMAVALID);
5127
5128 NDBG1(("mptsas_sge_setup: cookiec=%d", cmd->cmd_cookiec));
5129
5130 /*
5131 * Set read/write bit in control.
5132 */
5133 if (cmd->cmd_flags & CFLAG_DMASEND) {
5134 *control |= MPI2_SCSIIO_CONTROL_WRITE;
5135 } else {
5136 *control |= MPI2_SCSIIO_CONTROL_READ;
5137 }
5138
5139 ddi_put32(acc_hdl, &frame->DataLength, cmd->cmd_dmacount);
5140
5141 /*
5142 * We have 4 cases here. First where we can fit all the
5143 * SG elements into the main frame, and the case
5144 * where we can't. The SG element is also different when using
5145 * MPI2.5 interface.
5146 * If we have more cookies than we can attach to a frame
5147 * we will need to use a chain element to point
5148 * a location of memory where the rest of the S/G
5149 * elements reside.
5150 */
5151 if (cmd->cmd_cookiec <= MPTSAS_MAX_FRAME_SGES64(mpt)) {
5152 if (mpt->m_MPI25) {
5153 mptsas_ieee_sge_mainframe(cmd, frame, acc_hdl,
5154 cmd->cmd_cookiec,
5155 MPI25_IEEE_SGE_FLAGS_END_OF_LIST);
5156 } else {
5157 mptsas_sge_mainframe(cmd, frame, acc_hdl,
5158 cmd->cmd_cookiec,
5159 ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT
5160 | MPI2_SGE_FLAGS_END_OF_BUFFER
5161 | MPI2_SGE_FLAGS_END_OF_LIST) <<
5162 MPI2_SGE_FLAGS_SHIFT));
5163 }
5164 } else {
5165 if (mpt->m_MPI25) {
5166 mptsas_ieee_sge_chain(mpt, cmd, frame, acc_hdl);
5167 } else {
5168 mptsas_sge_chain(mpt, cmd, frame, acc_hdl);
5169 }
5170 }
5171 }
5172
5173 /*
5174 * Interrupt handling
5175 * Utility routine. Poll for status of a command sent to HBA
5176 * without interrupts (a FLAG_NOINTR command).
5177 */
5178 int
mptsas_poll(mptsas_t * mpt,mptsas_cmd_t * poll_cmd,int polltime)5179 mptsas_poll(mptsas_t *mpt, mptsas_cmd_t *poll_cmd, int polltime)
5180 {
5181 int rval = TRUE;
5182
5183 NDBG5(("mptsas_poll: cmd=0x%p", (void *)poll_cmd));
5184
5185 if ((poll_cmd->cmd_flags & CFLAG_TM_CMD) == 0) {
5186 mptsas_restart_hba(mpt);
5187 }
5188
5189 /*
5190 * Wait, using drv_usecwait(), long enough for the command to
5191 * reasonably return from the target if the target isn't
5192 * "dead". A polled command may well be sent from scsi_poll, and
5193 * there are retries built in to scsi_poll if the transport
5194 * accepted the packet (TRAN_ACCEPT). scsi_poll waits 1 second
5195 * and retries the transport up to scsi_poll_busycnt times
5196 * (currently 60) if
5197 * 1. pkt_reason is CMD_INCOMPLETE and pkt_state is 0, or
5198 * 2. pkt_reason is CMD_CMPLT and *pkt_scbp has STATUS_BUSY
5199 *
5200 * limit the waiting to avoid a hang in the event that the
5201 * cmd never gets started but we are still receiving interrupts
5202 */
5203 while (!(poll_cmd->cmd_flags & CFLAG_FINISHED)) {
5204 if (mptsas_wait_intr(mpt, polltime) == FALSE) {
5205 NDBG5(("mptsas_poll: command incomplete"));
5206 rval = FALSE;
5207 break;
5208 }
5209 }
5210
5211 if (rval == FALSE) {
5212
5213 /*
5214 * this isn't supposed to happen, the hba must be wedged
5215 * Mark this cmd as a timeout.
5216 */
5217 mptsas_set_pkt_reason(mpt, poll_cmd, CMD_TIMEOUT,
5218 (STAT_TIMEOUT|STAT_ABORTED));
5219
5220 if (poll_cmd->cmd_queued == FALSE) {
5221
5222 NDBG5(("mptsas_poll: not on waitq"));
5223
5224 poll_cmd->cmd_pkt->pkt_state |=
5225 (STATE_GOT_BUS|STATE_GOT_TARGET|STATE_SENT_CMD);
5226 } else {
5227
5228 /* find and remove it from the waitq */
5229 NDBG5(("mptsas_poll: delete from waitq"));
5230 mptsas_waitq_delete(mpt, poll_cmd);
5231 }
5232
5233 }
5234 mptsas_fma_check(mpt, poll_cmd);
5235 NDBG5(("mptsas_poll: done"));
5236 return (rval);
5237 }
5238
5239 /*
5240 * Used for polling cmds and TM function
5241 */
5242 static int
mptsas_wait_intr(mptsas_t * mpt,int polltime)5243 mptsas_wait_intr(mptsas_t *mpt, int polltime)
5244 {
5245 int cnt;
5246 pMpi2ReplyDescriptorsUnion_t reply_desc_union;
5247 uint32_t int_mask;
5248
5249 NDBG5(("mptsas_wait_intr"));
5250
5251 mpt->m_polled_intr = 1;
5252
5253 /*
5254 * Get the current interrupt mask and disable interrupts. When
5255 * re-enabling ints, set mask to saved value.
5256 */
5257 int_mask = mptsas_hirrd(mpt, &mpt->m_reg->HostInterruptMask);
5258 MPTSAS_DISABLE_INTR(mpt);
5259
5260 /*
5261 * Keep polling for at least (polltime * 1000) seconds
5262 */
5263 for (cnt = 0; cnt < polltime; cnt++) {
5264 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0,
5265 DDI_DMA_SYNC_FORCPU);
5266
5267 reply_desc_union = (pMpi2ReplyDescriptorsUnion_t)
5268 MPTSAS_GET_NEXT_REPLY(mpt, mpt->m_post_index);
5269
5270 if (ddi_get32(mpt->m_acc_post_queue_hdl,
5271 &reply_desc_union->Words.Low) == 0xFFFFFFFF ||
5272 ddi_get32(mpt->m_acc_post_queue_hdl,
5273 &reply_desc_union->Words.High) == 0xFFFFFFFF) {
5274 drv_usecwait(1000);
5275 continue;
5276 }
5277
5278 /*
5279 * The reply is valid, process it according to its
5280 * type.
5281 */
5282 mptsas_process_intr(mpt, reply_desc_union);
5283
5284 if (++mpt->m_post_index == mpt->m_post_queue_depth) {
5285 mpt->m_post_index = 0;
5286 }
5287
5288 /*
5289 * Update the global reply index
5290 */
5291 ddi_put32(mpt->m_datap,
5292 &mpt->m_reg->ReplyPostHostIndex, mpt->m_post_index);
5293 mpt->m_polled_intr = 0;
5294
5295 /*
5296 * Re-enable interrupts and quit.
5297 */
5298 ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptMask,
5299 int_mask);
5300 return (TRUE);
5301
5302 }
5303
5304 /*
5305 * Clear polling flag, re-enable interrupts and quit.
5306 */
5307 mpt->m_polled_intr = 0;
5308 ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptMask, int_mask);
5309 return (FALSE);
5310 }
5311
5312 static void
mptsas_handle_scsi_io_success(mptsas_t * mpt,pMpi2ReplyDescriptorsUnion_t reply_desc)5313 mptsas_handle_scsi_io_success(mptsas_t *mpt,
5314 pMpi2ReplyDescriptorsUnion_t reply_desc)
5315 {
5316 pMpi2SCSIIOSuccessReplyDescriptor_t scsi_io_success;
5317 uint16_t SMID;
5318 mptsas_slots_t *slots = mpt->m_active;
5319 mptsas_cmd_t *cmd = NULL;
5320 struct scsi_pkt *pkt;
5321
5322 ASSERT(mutex_owned(&mpt->m_mutex));
5323
5324 scsi_io_success = (pMpi2SCSIIOSuccessReplyDescriptor_t)reply_desc;
5325 SMID = ddi_get16(mpt->m_acc_post_queue_hdl, &scsi_io_success->SMID);
5326
5327 /*
5328 * This is a success reply so just complete the IO. First, do a sanity
5329 * check on the SMID. The final slot is used for TM requests, which
5330 * would not come into this reply handler.
5331 */
5332 if ((SMID == 0) || (SMID > slots->m_n_normal)) {
5333 mptsas_log(mpt, CE_WARN, "?Received invalid SMID of %d\n",
5334 SMID);
5335 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
5336 return;
5337 }
5338
5339 cmd = slots->m_slot[SMID];
5340
5341 /*
5342 * print warning and return if the slot is empty
5343 */
5344 if (cmd == NULL) {
5345 mptsas_log(mpt, CE_WARN, "?NULL command for successful SCSI IO "
5346 "in slot %d", SMID);
5347 return;
5348 }
5349
5350 pkt = CMD2PKT(cmd);
5351 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD |
5352 STATE_GOT_STATUS);
5353 if (cmd->cmd_flags & CFLAG_DMAVALID) {
5354 pkt->pkt_state |= STATE_XFERRED_DATA;
5355 }
5356 pkt->pkt_resid = 0;
5357
5358 if (cmd->cmd_flags & CFLAG_PASSTHRU) {
5359 cmd->cmd_flags |= CFLAG_FINISHED;
5360 cv_broadcast(&mpt->m_passthru_cv);
5361 return;
5362 } else {
5363 mptsas_remove_cmd(mpt, cmd);
5364 }
5365
5366 if (cmd->cmd_flags & CFLAG_RETRY) {
5367 /*
5368 * The target returned QFULL or busy, do not add tihs
5369 * pkt to the doneq since the hba will retry
5370 * this cmd.
5371 *
5372 * The pkt has already been resubmitted in
5373 * mptsas_handle_qfull() or in mptsas_check_scsi_io_error().
5374 * Remove this cmd_flag here.
5375 */
5376 cmd->cmd_flags &= ~CFLAG_RETRY;
5377 } else {
5378 mptsas_doneq_add(mpt, cmd);
5379 }
5380 }
5381
5382 static void
mptsas_handle_address_reply(mptsas_t * mpt,pMpi2ReplyDescriptorsUnion_t reply_desc)5383 mptsas_handle_address_reply(mptsas_t *mpt,
5384 pMpi2ReplyDescriptorsUnion_t reply_desc)
5385 {
5386 pMpi2AddressReplyDescriptor_t address_reply;
5387 pMPI2DefaultReply_t reply;
5388 mptsas_fw_diagnostic_buffer_t *pBuffer;
5389 uint32_t reply_addr, reply_frame_dma_baseaddr;
5390 uint16_t SMID, iocstatus;
5391 mptsas_slots_t *slots = mpt->m_active;
5392 mptsas_cmd_t *cmd = NULL;
5393 uint8_t function, buffer_type;
5394 m_replyh_arg_t *args;
5395 int reply_frame_no;
5396
5397 ASSERT(mutex_owned(&mpt->m_mutex));
5398
5399 address_reply = (pMpi2AddressReplyDescriptor_t)reply_desc;
5400 reply_addr = ddi_get32(mpt->m_acc_post_queue_hdl,
5401 &address_reply->ReplyFrameAddress);
5402 SMID = ddi_get16(mpt->m_acc_post_queue_hdl, &address_reply->SMID);
5403
5404 /*
5405 * If reply frame is not in the proper range we should ignore this
5406 * message and exit the interrupt handler.
5407 */
5408 reply_frame_dma_baseaddr = mpt->m_reply_frame_dma_addr & 0xffffffffu;
5409 if ((reply_addr < reply_frame_dma_baseaddr) ||
5410 (reply_addr >= (reply_frame_dma_baseaddr +
5411 (mpt->m_reply_frame_size * mpt->m_max_replies))) ||
5412 ((reply_addr - reply_frame_dma_baseaddr) %
5413 mpt->m_reply_frame_size != 0)) {
5414 mptsas_log(mpt, CE_WARN, "?Received invalid reply frame "
5415 "address 0x%x\n", reply_addr);
5416 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
5417 return;
5418 }
5419
5420 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
5421 DDI_DMA_SYNC_FORCPU);
5422 reply = (pMPI2DefaultReply_t)(mpt->m_reply_frame + (reply_addr -
5423 reply_frame_dma_baseaddr));
5424 function = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->Function);
5425
5426 NDBG31(("mptsas_handle_address_reply: function 0x%x, reply_addr=0x%x",
5427 function, reply_addr));
5428
5429 /*
5430 * don't get slot information and command for events since these values
5431 * don't exist
5432 */
5433 if ((function != MPI2_FUNCTION_EVENT_NOTIFICATION) &&
5434 (function != MPI2_FUNCTION_DIAG_BUFFER_POST)) {
5435 /*
5436 * This could be a TM reply, which use the last allocated SMID,
5437 * so allow for that.
5438 */
5439 if ((SMID == 0) || (SMID > (slots->m_n_normal + 1))) {
5440 mptsas_log(mpt, CE_WARN, "?Received invalid SMID of "
5441 "%d\n", SMID);
5442 ddi_fm_service_impact(mpt->m_dip,
5443 DDI_SERVICE_UNAFFECTED);
5444 return;
5445 }
5446
5447 cmd = slots->m_slot[SMID];
5448
5449 /*
5450 * print warning and return if the slot is empty
5451 */
5452 if (cmd == NULL) {
5453 mptsas_log(mpt, CE_WARN, "?NULL command for address "
5454 "reply in slot %d", SMID);
5455 return;
5456 }
5457 if ((cmd->cmd_flags &
5458 (CFLAG_PASSTHRU | CFLAG_CONFIG | CFLAG_FW_DIAG))) {
5459 cmd->cmd_rfm = reply_addr;
5460 cmd->cmd_flags |= CFLAG_FINISHED;
5461 cv_broadcast(&mpt->m_passthru_cv);
5462 cv_broadcast(&mpt->m_config_cv);
5463 cv_broadcast(&mpt->m_fw_diag_cv);
5464 return;
5465 } else if (!(cmd->cmd_flags & CFLAG_FW_CMD)) {
5466 mptsas_remove_cmd(mpt, cmd);
5467 }
5468 NDBG31(("\t\tmptsas_process_intr: slot=%d", SMID));
5469 }
5470 /*
5471 * Depending on the function, we need to handle
5472 * the reply frame (and cmd) differently.
5473 */
5474 switch (function) {
5475 case MPI2_FUNCTION_SCSI_IO_REQUEST:
5476 mptsas_check_scsi_io_error(mpt, (pMpi2SCSIIOReply_t)reply, cmd);
5477 break;
5478 case MPI2_FUNCTION_SCSI_TASK_MGMT:
5479 cmd->cmd_rfm = reply_addr;
5480 mptsas_check_task_mgt(mpt, (pMpi2SCSIManagementReply_t)reply,
5481 cmd);
5482 break;
5483 case MPI2_FUNCTION_FW_DOWNLOAD:
5484 cmd->cmd_flags |= CFLAG_FINISHED;
5485 cv_signal(&mpt->m_fw_cv);
5486 break;
5487 case MPI2_FUNCTION_EVENT_NOTIFICATION:
5488 reply_frame_no = (reply_addr - reply_frame_dma_baseaddr) /
5489 mpt->m_reply_frame_size;
5490 args = &mpt->m_replyh_args[reply_frame_no];
5491 args->mpt = (void *)mpt;
5492 args->rfm = reply_addr;
5493
5494 /*
5495 * Record the event if its type is enabled in
5496 * this mpt instance by ioctl.
5497 */
5498 mptsas_record_event(args);
5499
5500 /*
5501 * Handle time critical events
5502 * NOT_RESPONDING/ADDED only now
5503 */
5504 if (mptsas_handle_event_sync(args) == DDI_SUCCESS) {
5505 /*
5506 * Would not return main process,
5507 * just let taskq resolve ack action
5508 * and ack would be sent in taskq thread
5509 */
5510 NDBG20(("send mptsas_handle_event_sync success"));
5511 }
5512
5513 if (mpt->m_in_reset) {
5514 NDBG20(("dropping event received during reset"));
5515 return;
5516 }
5517
5518 if ((ddi_taskq_dispatch(mpt->m_event_taskq, mptsas_handle_event,
5519 (void *)args, DDI_NOSLEEP)) != DDI_SUCCESS) {
5520 mptsas_log(mpt, CE_WARN, "No memory available"
5521 "for dispatch taskq");
5522 /*
5523 * Return the reply frame to the free queue.
5524 */
5525 ddi_put32(mpt->m_acc_free_queue_hdl,
5526 &((uint32_t *)(void *)
5527 mpt->m_free_queue)[mpt->m_free_index], reply_addr);
5528 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
5529 DDI_DMA_SYNC_FORDEV);
5530 if (++mpt->m_free_index == mpt->m_free_queue_depth) {
5531 mpt->m_free_index = 0;
5532 }
5533
5534 ddi_put32(mpt->m_datap,
5535 &mpt->m_reg->ReplyFreeHostIndex, mpt->m_free_index);
5536 }
5537 return;
5538 case MPI2_FUNCTION_DIAG_BUFFER_POST:
5539 /*
5540 * If SMID is 0, this implies that the reply is due to a
5541 * release function with a status that the buffer has been
5542 * released. Set the buffer flags accordingly.
5543 */
5544 if (SMID == 0) {
5545 iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
5546 &reply->IOCStatus);
5547 buffer_type = ddi_get8(mpt->m_acc_reply_frame_hdl,
5548 &(((pMpi2DiagBufferPostReply_t)reply)->BufferType));
5549 if (iocstatus == MPI2_IOCSTATUS_DIAGNOSTIC_RELEASED) {
5550 pBuffer =
5551 &mpt->m_fw_diag_buffer_list[buffer_type];
5552 pBuffer->valid_data = TRUE;
5553 pBuffer->owned_by_firmware = FALSE;
5554 pBuffer->immediate = FALSE;
5555 }
5556 } else {
5557 /*
5558 * Normal handling of diag post reply with SMID.
5559 */
5560 cmd = slots->m_slot[SMID];
5561
5562 /*
5563 * print warning and return if the slot is empty
5564 */
5565 if (cmd == NULL) {
5566 mptsas_log(mpt, CE_WARN, "?NULL command for "
5567 "address reply in slot %d", SMID);
5568 return;
5569 }
5570 cmd->cmd_rfm = reply_addr;
5571 cmd->cmd_flags |= CFLAG_FINISHED;
5572 cv_broadcast(&mpt->m_fw_diag_cv);
5573 }
5574 return;
5575 default:
5576 mptsas_log(mpt, CE_WARN, "Unknown function 0x%x ", function);
5577 break;
5578 }
5579
5580 /*
5581 * Return the reply frame to the free queue.
5582 */
5583 ddi_put32(mpt->m_acc_free_queue_hdl,
5584 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index],
5585 reply_addr);
5586 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
5587 DDI_DMA_SYNC_FORDEV);
5588 if (++mpt->m_free_index == mpt->m_free_queue_depth) {
5589 mpt->m_free_index = 0;
5590 }
5591 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
5592 mpt->m_free_index);
5593
5594 if (cmd->cmd_flags & CFLAG_FW_CMD)
5595 return;
5596
5597 if (cmd->cmd_flags & CFLAG_RETRY) {
5598 /*
5599 * The target returned QFULL or busy, do not add this
5600 * pkt to the doneq since the hba will retry
5601 * this cmd.
5602 *
5603 * The pkt has already been resubmitted in
5604 * mptsas_handle_qfull() or in mptsas_check_scsi_io_error().
5605 * Remove this cmd_flag here.
5606 */
5607 cmd->cmd_flags &= ~CFLAG_RETRY;
5608 } else {
5609 mptsas_doneq_add(mpt, cmd);
5610 }
5611 }
5612
5613 #ifdef MPTSAS_DEBUG
5614 static uint8_t mptsas_last_sense[256];
5615 #endif
5616
5617 static void
mptsas_check_scsi_io_error(mptsas_t * mpt,pMpi2SCSIIOReply_t reply,mptsas_cmd_t * cmd)5618 mptsas_check_scsi_io_error(mptsas_t *mpt, pMpi2SCSIIOReply_t reply,
5619 mptsas_cmd_t *cmd)
5620 {
5621 uint8_t scsi_status, scsi_state;
5622 uint16_t ioc_status, cmd_rqs_len;
5623 uint32_t xferred, sensecount, responsedata, loginfo = 0;
5624 struct scsi_pkt *pkt;
5625 struct scsi_arq_status *arqstat;
5626 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
5627 uint8_t *sensedata = NULL;
5628 uint64_t sas_wwn;
5629 uint8_t phy;
5630 char wwn_str[MPTSAS_WWN_STRLEN];
5631
5632 scsi_status = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->SCSIStatus);
5633 ioc_status = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->IOCStatus);
5634 scsi_state = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->SCSIState);
5635 xferred = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->TransferCount);
5636 sensecount = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->SenseCount);
5637 responsedata = ddi_get32(mpt->m_acc_reply_frame_hdl,
5638 &reply->ResponseInfo);
5639
5640 if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
5641 sas_wwn = ptgt->m_addr.mta_wwn;
5642 phy = ptgt->m_phynum;
5643 if (sas_wwn == 0) {
5644 (void) sprintf(wwn_str, "p%x", phy);
5645 } else {
5646 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn);
5647 }
5648 loginfo = ddi_get32(mpt->m_acc_reply_frame_hdl,
5649 &reply->IOCLogInfo);
5650 mptsas_log(mpt, CE_NOTE,
5651 "?Log info 0x%x received for target %d %s.\n"
5652 "\tscsi_status=0x%x, ioc_status=0x%x, scsi_state=0x%x",
5653 loginfo, Tgt(cmd), wwn_str, scsi_status, ioc_status,
5654 scsi_state);
5655 }
5656
5657 NDBG31(("\t\tscsi_status=0x%x, ioc_status=0x%x, scsi_state=0x%x",
5658 scsi_status, ioc_status, scsi_state));
5659
5660 pkt = CMD2PKT(cmd);
5661 *(pkt->pkt_scbp) = scsi_status;
5662
5663 if (loginfo == 0x31170000) {
5664 /*
5665 * if loginfo PL_LOGINFO_CODE_IO_DEVICE_MISSING_DELAY_RETRY
5666 * 0x31170000 comes, that means the device missing delay
5667 * is in progressing, the command need retry later.
5668 */
5669 *(pkt->pkt_scbp) = STATUS_BUSY;
5670 return;
5671 }
5672
5673 if ((scsi_state & MPI2_SCSI_STATE_NO_SCSI_STATUS) &&
5674 ((ioc_status & MPI2_IOCSTATUS_MASK) ==
5675 MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE)) {
5676 pkt->pkt_reason = CMD_INCOMPLETE;
5677 pkt->pkt_state |= STATE_GOT_BUS;
5678 if (ptgt->m_reset_delay == 0) {
5679 mptsas_set_throttle(mpt, ptgt,
5680 DRAIN_THROTTLE);
5681 }
5682 return;
5683 }
5684
5685 if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) {
5686 responsedata &= 0x000000FF;
5687 if (responsedata & MPTSAS_SCSI_RESPONSE_CODE_TLR_OFF) {
5688 mptsas_log(mpt, CE_NOTE, "Do not support the TLR\n");
5689 pkt->pkt_reason = CMD_TLR_OFF;
5690 return;
5691 }
5692 }
5693
5694
5695 switch (scsi_status) {
5696 case MPI2_SCSI_STATUS_CHECK_CONDITION:
5697 pkt->pkt_resid = (cmd->cmd_dmacount - xferred);
5698 arqstat = (void*)(pkt->pkt_scbp);
5699 arqstat->sts_rqpkt_status = *((struct scsi_status *)
5700 (pkt->pkt_scbp));
5701 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET |
5702 STATE_SENT_CMD | STATE_GOT_STATUS | STATE_ARQ_DONE);
5703 if (cmd->cmd_flags & CFLAG_XARQ) {
5704 pkt->pkt_state |= STATE_XARQ_DONE;
5705 }
5706 if (pkt->pkt_resid != cmd->cmd_dmacount) {
5707 pkt->pkt_state |= STATE_XFERRED_DATA;
5708 }
5709 arqstat->sts_rqpkt_reason = pkt->pkt_reason;
5710 arqstat->sts_rqpkt_state = pkt->pkt_state;
5711 arqstat->sts_rqpkt_state |= STATE_XFERRED_DATA;
5712 arqstat->sts_rqpkt_statistics = pkt->pkt_statistics;
5713 sensedata = (uint8_t *)&arqstat->sts_sensedata;
5714 cmd_rqs_len = cmd->cmd_extrqslen ?
5715 cmd->cmd_extrqslen : cmd->cmd_rqslen;
5716 (void) ddi_dma_sync(mpt->m_dma_req_sense_hdl, 0, 0,
5717 DDI_DMA_SYNC_FORKERNEL);
5718 #ifdef MPTSAS_DEBUG
5719 bcopy(cmd->cmd_arq_buf, mptsas_last_sense,
5720 ((cmd_rqs_len >= sizeof (mptsas_last_sense)) ?
5721 sizeof (mptsas_last_sense):cmd_rqs_len));
5722 #endif
5723 bcopy((uchar_t *)cmd->cmd_arq_buf, sensedata,
5724 ((cmd_rqs_len >= sensecount) ? sensecount :
5725 cmd_rqs_len));
5726 arqstat->sts_rqpkt_resid = (cmd_rqs_len - sensecount);
5727 cmd->cmd_flags |= CFLAG_CMDARQ;
5728 /*
5729 * Set proper status for pkt if autosense was valid
5730 */
5731 if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) {
5732 struct scsi_status zero_status = { 0 };
5733 arqstat->sts_rqpkt_status = zero_status;
5734 }
5735
5736 /*
5737 * ASC=0x47 is parity error
5738 * ASC=0x48 is initiator detected error received
5739 */
5740 if ((scsi_sense_key(sensedata) == KEY_ABORTED_COMMAND) &&
5741 ((scsi_sense_asc(sensedata) == 0x47) ||
5742 (scsi_sense_asc(sensedata) == 0x48))) {
5743 mptsas_log(mpt, CE_NOTE, "Aborted_command!");
5744 }
5745
5746 /*
5747 * ASC/ASCQ=0x3F/0x0E means report_luns data changed
5748 * ASC/ASCQ=0x25/0x00 means invalid lun
5749 */
5750 if (((scsi_sense_key(sensedata) == KEY_UNIT_ATTENTION) &&
5751 (scsi_sense_asc(sensedata) == 0x3F) &&
5752 (scsi_sense_ascq(sensedata) == 0x0E)) ||
5753 ((scsi_sense_key(sensedata) == KEY_ILLEGAL_REQUEST) &&
5754 (scsi_sense_asc(sensedata) == 0x25) &&
5755 (scsi_sense_ascq(sensedata) == 0x00))) {
5756 mptsas_topo_change_list_t *topo_node = NULL;
5757
5758 topo_node = kmem_zalloc(
5759 sizeof (mptsas_topo_change_list_t),
5760 KM_NOSLEEP);
5761 if (topo_node == NULL) {
5762 mptsas_log(mpt, CE_NOTE, "No memory"
5763 "resource for handle SAS dynamic"
5764 "reconfigure.\n");
5765 break;
5766 }
5767 topo_node->mpt = mpt;
5768 topo_node->event = MPTSAS_DR_EVENT_RECONFIG_TARGET;
5769 topo_node->un.phymask = ptgt->m_addr.mta_phymask;
5770 topo_node->devhdl = ptgt->m_devhdl;
5771 topo_node->object = (void *)ptgt;
5772 topo_node->flags = MPTSAS_TOPO_FLAG_LUN_ASSOCIATED;
5773
5774 if ((ddi_taskq_dispatch(mpt->m_dr_taskq,
5775 mptsas_handle_dr,
5776 (void *)topo_node,
5777 DDI_NOSLEEP)) != DDI_SUCCESS) {
5778 kmem_free(topo_node,
5779 sizeof (mptsas_topo_change_list_t));
5780 mptsas_log(mpt, CE_NOTE, "mptsas start taskq"
5781 "for handle SAS dynamic reconfigure"
5782 "failed. \n");
5783 }
5784 }
5785 break;
5786 case MPI2_SCSI_STATUS_GOOD:
5787 switch (ioc_status & MPI2_IOCSTATUS_MASK) {
5788 case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
5789 pkt->pkt_reason = CMD_DEV_GONE;
5790 pkt->pkt_state |= STATE_GOT_BUS;
5791 if (ptgt->m_reset_delay == 0) {
5792 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
5793 }
5794 NDBG31(("lost disk for target%d, command:%x",
5795 Tgt(cmd), pkt->pkt_cdbp[0]));
5796 break;
5797 case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN:
5798 NDBG31(("data overrun: xferred=%d", xferred));
5799 NDBG31(("dmacount=%d", cmd->cmd_dmacount));
5800 pkt->pkt_reason = CMD_DATA_OVR;
5801 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET
5802 | STATE_SENT_CMD | STATE_GOT_STATUS
5803 | STATE_XFERRED_DATA);
5804 pkt->pkt_resid = 0;
5805 break;
5806 case MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:
5807 case MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN:
5808 NDBG31(("data underrun: xferred=%d", xferred));
5809 NDBG31(("dmacount=%d", cmd->cmd_dmacount));
5810 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET
5811 | STATE_SENT_CMD | STATE_GOT_STATUS);
5812 pkt->pkt_resid = (cmd->cmd_dmacount - xferred);
5813 if (pkt->pkt_resid != cmd->cmd_dmacount) {
5814 pkt->pkt_state |= STATE_XFERRED_DATA;
5815 }
5816 break;
5817 case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED:
5818 if (cmd->cmd_active_expiration <= gethrtime()) {
5819 /*
5820 * When timeout requested, propagate
5821 * proper reason and statistics to
5822 * target drivers.
5823 */
5824 mptsas_set_pkt_reason(mpt, cmd, CMD_TIMEOUT,
5825 STAT_BUS_RESET | STAT_TIMEOUT);
5826 } else {
5827 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET,
5828 STAT_BUS_RESET);
5829 }
5830 break;
5831 case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED:
5832 case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED:
5833 mptsas_set_pkt_reason(mpt,
5834 cmd, CMD_RESET, STAT_DEV_RESET);
5835 break;
5836 case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR:
5837 case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR:
5838 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET);
5839 mptsas_set_pkt_reason(mpt,
5840 cmd, CMD_TERMINATED, STAT_TERMINATED);
5841 break;
5842 case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES:
5843 case MPI2_IOCSTATUS_BUSY:
5844 /*
5845 * set throttles to drain
5846 */
5847 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
5848 ptgt = refhash_next(mpt->m_targets, ptgt)) {
5849 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
5850 }
5851
5852 /*
5853 * retry command
5854 */
5855 cmd->cmd_flags |= CFLAG_RETRY;
5856 cmd->cmd_pkt_flags |= FLAG_HEAD;
5857
5858 (void) mptsas_accept_pkt(mpt, cmd);
5859 break;
5860 default:
5861 mptsas_log(mpt, CE_WARN,
5862 "unknown ioc_status = %x\n", ioc_status);
5863 mptsas_log(mpt, CE_CONT, "scsi_state = %x, transfer "
5864 "count = %x, scsi_status = %x", scsi_state,
5865 xferred, scsi_status);
5866 break;
5867 }
5868 break;
5869 case MPI2_SCSI_STATUS_TASK_SET_FULL:
5870 mptsas_handle_qfull(mpt, cmd);
5871 break;
5872 case MPI2_SCSI_STATUS_BUSY:
5873 NDBG31(("scsi_status busy received"));
5874 break;
5875 case MPI2_SCSI_STATUS_RESERVATION_CONFLICT:
5876 NDBG31(("scsi_status reservation conflict received"));
5877 break;
5878 default:
5879 mptsas_log(mpt, CE_WARN, "scsi_status=%x, ioc_status=%x\n",
5880 scsi_status, ioc_status);
5881 mptsas_log(mpt, CE_WARN,
5882 "mptsas_process_intr: invalid scsi status\n");
5883 break;
5884 }
5885 }
5886
5887 static void
mptsas_check_task_mgt(mptsas_t * mpt,pMpi2SCSIManagementReply_t reply,mptsas_cmd_t * cmd)5888 mptsas_check_task_mgt(mptsas_t *mpt, pMpi2SCSIManagementReply_t reply,
5889 mptsas_cmd_t *cmd)
5890 {
5891 uint8_t task_type;
5892 uint16_t ioc_status;
5893 uint32_t log_info;
5894 uint16_t dev_handle;
5895 struct scsi_pkt *pkt = CMD2PKT(cmd);
5896
5897 task_type = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->TaskType);
5898 ioc_status = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->IOCStatus);
5899 log_info = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->IOCLogInfo);
5900 dev_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->DevHandle);
5901
5902 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
5903 mptsas_log(mpt, CE_WARN, "mptsas_check_task_mgt: Task 0x%x "
5904 "failed. IOCStatus=0x%x IOCLogInfo=0x%x target=%d\n",
5905 task_type, ioc_status, log_info, dev_handle);
5906 pkt->pkt_reason = CMD_INCOMPLETE;
5907 return;
5908 }
5909
5910 switch (task_type) {
5911 case MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK:
5912 case MPI2_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET:
5913 case MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK:
5914 case MPI2_SCSITASKMGMT_TASKTYPE_CLR_ACA:
5915 case MPI2_SCSITASKMGMT_TASKTYPE_QRY_TASK_SET:
5916 case MPI2_SCSITASKMGMT_TASKTYPE_QRY_UNIT_ATTENTION:
5917 break;
5918 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
5919 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
5920 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
5921 /*
5922 * Check for invalid DevHandle of 0 in case application
5923 * sends bad command. DevHandle of 0 could cause problems.
5924 */
5925 if (dev_handle == 0) {
5926 mptsas_log(mpt, CE_WARN, "!Can't flush target with"
5927 " DevHandle of 0.");
5928 } else {
5929 mptsas_flush_target(mpt, dev_handle, Lun(cmd),
5930 task_type);
5931 }
5932 break;
5933 default:
5934 mptsas_log(mpt, CE_WARN, "Unknown task management type %d.",
5935 task_type);
5936 mptsas_log(mpt, CE_WARN, "ioc status = %x", ioc_status);
5937 break;
5938 }
5939 }
5940
5941 static void
mptsas_doneq_thread(mptsas_doneq_thread_arg_t * arg)5942 mptsas_doneq_thread(mptsas_doneq_thread_arg_t *arg)
5943 {
5944 mptsas_t *mpt = arg->mpt;
5945 uint64_t t = arg->t;
5946 mptsas_cmd_t *cmd;
5947 struct scsi_pkt *pkt;
5948 mptsas_doneq_thread_list_t *item = &mpt->m_doneq_thread_id[t];
5949
5950 mutex_enter(&item->mutex);
5951 while (item->flag & MPTSAS_DONEQ_THREAD_ACTIVE) {
5952 if (!item->doneq) {
5953 cv_wait(&item->cv, &item->mutex);
5954 }
5955 pkt = NULL;
5956 if ((cmd = mptsas_doneq_thread_rm(mpt, t)) != NULL) {
5957 cmd->cmd_flags |= CFLAG_COMPLETED;
5958 pkt = CMD2PKT(cmd);
5959 }
5960 mutex_exit(&item->mutex);
5961 if (pkt) {
5962 mptsas_pkt_comp(pkt, cmd);
5963 }
5964 mutex_enter(&item->mutex);
5965 }
5966 mutex_exit(&item->mutex);
5967 mutex_enter(&mpt->m_doneq_mutex);
5968 mpt->m_doneq_thread_n--;
5969 cv_broadcast(&mpt->m_doneq_thread_cv);
5970 mutex_exit(&mpt->m_doneq_mutex);
5971 }
5972
5973
5974 /*
5975 * mpt interrupt handler.
5976 */
5977 static uint_t
mptsas_intr(caddr_t arg1,caddr_t arg2)5978 mptsas_intr(caddr_t arg1, caddr_t arg2)
5979 {
5980 mptsas_t *mpt = (void *)arg1;
5981 pMpi2ReplyDescriptorsUnion_t reply_desc_union;
5982 uchar_t did_reply = FALSE;
5983
5984 NDBG1(("mptsas_intr: arg1 0x%p arg2 0x%p", (void *)arg1, (void *)arg2));
5985
5986 mutex_enter(&mpt->m_mutex);
5987
5988 /*
5989 * If interrupts are shared by two channels then check whether this
5990 * interrupt is genuinely for this channel by making sure first the
5991 * chip is in high power state.
5992 */
5993 if ((mpt->m_options & MPTSAS_OPT_PM) &&
5994 (mpt->m_power_level != PM_LEVEL_D0)) {
5995 mutex_exit(&mpt->m_mutex);
5996 return (DDI_INTR_UNCLAIMED);
5997 }
5998
5999 /*
6000 * If polling, interrupt was triggered by some shared interrupt because
6001 * IOC interrupts are disabled during polling, so polling routine will
6002 * handle any replies. Considering this, if polling is happening,
6003 * return with interrupt unclaimed.
6004 */
6005 if (mpt->m_polled_intr) {
6006 mutex_exit(&mpt->m_mutex);
6007 mptsas_log(mpt, CE_WARN, "mpt_sas: Unclaimed interrupt");
6008 return (DDI_INTR_UNCLAIMED);
6009 }
6010
6011 /*
6012 * Read the istat register.
6013 */
6014 if ((INTPENDING(mpt)) != 0) {
6015 /*
6016 * read fifo until empty.
6017 */
6018 #ifndef __lock_lint
6019 _NOTE(CONSTCOND)
6020 #endif
6021 while (TRUE) {
6022 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0,
6023 DDI_DMA_SYNC_FORCPU);
6024 reply_desc_union = (pMpi2ReplyDescriptorsUnion_t)
6025 MPTSAS_GET_NEXT_REPLY(mpt, mpt->m_post_index);
6026
6027 if (ddi_get32(mpt->m_acc_post_queue_hdl,
6028 &reply_desc_union->Words.Low) == 0xFFFFFFFF ||
6029 ddi_get32(mpt->m_acc_post_queue_hdl,
6030 &reply_desc_union->Words.High) == 0xFFFFFFFF) {
6031 break;
6032 }
6033
6034 /*
6035 * The reply is valid, process it according to its
6036 * type. Also, set a flag for updating the reply index
6037 * after they've all been processed.
6038 */
6039 did_reply = TRUE;
6040
6041 mptsas_process_intr(mpt, reply_desc_union);
6042
6043 /*
6044 * Increment post index and roll over if needed.
6045 */
6046 if (++mpt->m_post_index == mpt->m_post_queue_depth) {
6047 mpt->m_post_index = 0;
6048 }
6049 }
6050
6051 /*
6052 * Update the global reply index if at least one reply was
6053 * processed.
6054 */
6055 if (did_reply) {
6056 ddi_put32(mpt->m_datap,
6057 &mpt->m_reg->ReplyPostHostIndex, mpt->m_post_index);
6058 }
6059 } else {
6060 mutex_exit(&mpt->m_mutex);
6061 return (DDI_INTR_UNCLAIMED);
6062 }
6063 NDBG1(("mptsas_intr complete"));
6064
6065 /*
6066 * If no helper threads are created, process the doneq in ISR. If
6067 * helpers are created, use the doneq length as a metric to measure the
6068 * load on the interrupt CPU. If it is long enough, which indicates the
6069 * load is heavy, then we deliver the IO completions to the helpers.
6070 * This measurement has some limitations, although it is simple and
6071 * straightforward and works well for most of the cases at present.
6072 */
6073 if (!mpt->m_doneq_thread_n ||
6074 (mpt->m_doneq_len <= mpt->m_doneq_length_threshold)) {
6075 mptsas_doneq_empty(mpt);
6076 } else {
6077 mptsas_deliver_doneq_thread(mpt);
6078 }
6079
6080 /*
6081 * If there are queued cmd, start them now.
6082 */
6083 if (mpt->m_waitq != NULL) {
6084 mptsas_restart_waitq(mpt);
6085 }
6086
6087 mutex_exit(&mpt->m_mutex);
6088 return (DDI_INTR_CLAIMED);
6089 }
6090
6091 static void
mptsas_process_intr(mptsas_t * mpt,pMpi2ReplyDescriptorsUnion_t reply_desc_union)6092 mptsas_process_intr(mptsas_t *mpt,
6093 pMpi2ReplyDescriptorsUnion_t reply_desc_union)
6094 {
6095 uint8_t reply_type;
6096
6097 ASSERT(mutex_owned(&mpt->m_mutex));
6098
6099 /*
6100 * The reply is valid, process it according to its
6101 * type. Also, set a flag for updated the reply index
6102 * after they've all been processed.
6103 */
6104 reply_type = ddi_get8(mpt->m_acc_post_queue_hdl,
6105 &reply_desc_union->Default.ReplyFlags);
6106 reply_type &= MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
6107 if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS ||
6108 reply_type == MPI25_RPY_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO_SUCCESS) {
6109 mptsas_handle_scsi_io_success(mpt, reply_desc_union);
6110 } else if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) {
6111 mptsas_handle_address_reply(mpt, reply_desc_union);
6112 } else {
6113 mptsas_log(mpt, CE_WARN, "?Bad reply type %x", reply_type);
6114 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
6115 }
6116
6117 /*
6118 * Clear the reply descriptor for re-use and increment
6119 * index.
6120 */
6121 ddi_put64(mpt->m_acc_post_queue_hdl,
6122 &((uint64_t *)(void *)mpt->m_post_queue)[mpt->m_post_index],
6123 0xFFFFFFFFFFFFFFFF);
6124 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0,
6125 DDI_DMA_SYNC_FORDEV);
6126 }
6127
6128 /*
6129 * handle qfull condition
6130 */
6131 static void
mptsas_handle_qfull(mptsas_t * mpt,mptsas_cmd_t * cmd)6132 mptsas_handle_qfull(mptsas_t *mpt, mptsas_cmd_t *cmd)
6133 {
6134 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
6135
6136 if ((++cmd->cmd_qfull_retries > ptgt->m_qfull_retries) ||
6137 (ptgt->m_qfull_retries == 0)) {
6138 /*
6139 * We have exhausted the retries on QFULL, or,
6140 * the target driver has indicated that it
6141 * wants to handle QFULL itself by setting
6142 * qfull-retries capability to 0. In either case
6143 * we want the target driver's QFULL handling
6144 * to kick in. We do this by having pkt_reason
6145 * as CMD_CMPLT and pkt_scbp as STATUS_QFULL.
6146 */
6147 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
6148 } else {
6149 if (ptgt->m_reset_delay == 0) {
6150 ptgt->m_t_throttle =
6151 max((ptgt->m_t_ncmds - 2), 0);
6152 }
6153
6154 cmd->cmd_pkt_flags |= FLAG_HEAD;
6155 cmd->cmd_flags &= ~(CFLAG_TRANFLAG);
6156 cmd->cmd_flags |= CFLAG_RETRY;
6157
6158 (void) mptsas_accept_pkt(mpt, cmd);
6159
6160 /*
6161 * when target gives queue full status with no commands
6162 * outstanding (m_t_ncmds == 0), throttle is set to 0
6163 * (HOLD_THROTTLE), and the queue full handling start
6164 * (see psarc/1994/313); if there are commands outstanding,
6165 * throttle is set to (m_t_ncmds - 2)
6166 */
6167 if (ptgt->m_t_throttle == HOLD_THROTTLE) {
6168 /*
6169 * By setting throttle to QFULL_THROTTLE, we
6170 * avoid submitting new commands and in
6171 * mptsas_restart_cmd find out slots which need
6172 * their throttles to be cleared.
6173 */
6174 mptsas_set_throttle(mpt, ptgt, QFULL_THROTTLE);
6175 if (mpt->m_restart_cmd_timeid == 0) {
6176 mpt->m_restart_cmd_timeid =
6177 timeout(mptsas_restart_cmd, mpt,
6178 ptgt->m_qfull_retry_interval);
6179 }
6180 }
6181 }
6182 }
6183
6184 mptsas_phymask_t
mptsas_physport_to_phymask(mptsas_t * mpt,uint8_t physport)6185 mptsas_physport_to_phymask(mptsas_t *mpt, uint8_t physport)
6186 {
6187 mptsas_phymask_t phy_mask = 0;
6188 uint8_t i = 0;
6189
6190 NDBG20(("mptsas%d physport_to_phymask enter", mpt->m_instance));
6191
6192 ASSERT(mutex_owned(&mpt->m_mutex));
6193
6194 /*
6195 * If physport is 0xFF, this is a RAID volume. Use phymask of 0.
6196 */
6197 if (physport == 0xFF) {
6198 return (0);
6199 }
6200
6201 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
6202 if (mpt->m_phy_info[i].attached_devhdl &&
6203 (mpt->m_phy_info[i].phy_mask != 0) &&
6204 (mpt->m_phy_info[i].port_num == physport)) {
6205 phy_mask = mpt->m_phy_info[i].phy_mask;
6206 break;
6207 }
6208 }
6209 NDBG20(("mptsas%d physport_to_phymask:physport :%x phymask :%x, ",
6210 mpt->m_instance, physport, phy_mask));
6211 return (phy_mask);
6212 }
6213
6214 /*
6215 * mpt free device handle after device gone, by use of passthrough
6216 */
6217 static int
mptsas_free_devhdl(mptsas_t * mpt,uint16_t devhdl)6218 mptsas_free_devhdl(mptsas_t *mpt, uint16_t devhdl)
6219 {
6220 Mpi2SasIoUnitControlRequest_t req;
6221 Mpi2SasIoUnitControlReply_t rep;
6222 int ret;
6223
6224 ASSERT(mutex_owned(&mpt->m_mutex));
6225
6226 /*
6227 * Need to compose a SAS IO Unit Control request message
6228 * and call mptsas_do_passthru() function
6229 */
6230 bzero(&req, sizeof (req));
6231 bzero(&rep, sizeof (rep));
6232
6233 req.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
6234 req.Operation = MPI2_SAS_OP_REMOVE_DEVICE;
6235 req.DevHandle = LE_16(devhdl);
6236
6237 ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, NULL,
6238 sizeof (req), sizeof (rep), 0, MPTSAS_PASS_THRU_DIRECTION_NONE,
6239 NULL, 0, 60, FKIOCTL);
6240 if (ret != 0) {
6241 cmn_err(CE_WARN, "mptsas_free_devhdl: passthru SAS IO Unit "
6242 "Control error %d", ret);
6243 return (DDI_FAILURE);
6244 }
6245
6246 /* do passthrough success, check the ioc status */
6247 if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) {
6248 cmn_err(CE_WARN, "mptsas_free_devhdl: passthru SAS IO Unit "
6249 "Control IOCStatus %d", LE_16(rep.IOCStatus));
6250 return (DDI_FAILURE);
6251 }
6252
6253 return (DDI_SUCCESS);
6254 }
6255
6256 /*
6257 * We have a SATA target that has changed, which means the "bridge-port"
6258 * property must be updated to reflect the SAS WWN of the new attachment point.
6259 * This may change if a SATA device changes which bay, and therefore phy, it is
6260 * plugged into. This SATA device may be a multipath virtual device or may be a
6261 * physical device. We have to handle both cases.
6262 */
6263 static boolean_t
mptsas_update_sata_bridge(mptsas_t * mpt,dev_info_t * parent,mptsas_target_t * ptgt)6264 mptsas_update_sata_bridge(mptsas_t *mpt, dev_info_t *parent,
6265 mptsas_target_t *ptgt)
6266 {
6267 int rval;
6268 uint16_t dev_hdl;
6269 uint16_t pdev_hdl;
6270 uint64_t dev_sas_wwn;
6271 uint8_t physport;
6272 uint8_t phy_id;
6273 uint32_t page_address;
6274 uint16_t bay_num, enclosure, io_flags;
6275 uint32_t dev_info;
6276 char uabuf[SCSI_WWN_BUFLEN];
6277 dev_info_t *dip;
6278 mdi_pathinfo_t *pip;
6279
6280 mutex_enter(&mpt->m_mutex);
6281 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
6282 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)ptgt->m_devhdl;
6283 rval = mptsas_get_sas_device_page0(mpt, page_address, &dev_hdl,
6284 &dev_sas_wwn, &dev_info, &physport, &phy_id, &pdev_hdl, &bay_num,
6285 &enclosure, &io_flags);
6286 mutex_exit(&mpt->m_mutex);
6287 if (rval != DDI_SUCCESS) {
6288 mptsas_log(mpt, CE_WARN, "unable to get SAS page 0 for "
6289 "handle %d", page_address);
6290 return (B_FALSE);
6291 }
6292
6293 if (scsi_wwn_to_wwnstr(dev_sas_wwn, 1, uabuf) == NULL) {
6294 mptsas_log(mpt, CE_WARN,
6295 "mptsas unable to format SATA bridge WWN");
6296 return (B_FALSE);
6297 }
6298
6299 if (mpt->m_mpxio_enable == TRUE && (pip = mptsas_find_path_addr(parent,
6300 ptgt->m_addr.mta_wwn, 0)) != NULL) {
6301 if (mdi_prop_update_string(pip, SCSI_ADDR_PROP_BRIDGE_PORT,
6302 uabuf) != DDI_SUCCESS) {
6303 mptsas_log(mpt, CE_WARN,
6304 "mptsas unable to create SCSI bridge port "
6305 "property for SATA device");
6306 return (B_FALSE);
6307 }
6308 return (B_TRUE);
6309 }
6310
6311 if ((dip = mptsas_find_child_addr(parent, ptgt->m_addr.mta_wwn,
6312 0)) != NULL) {
6313 if (ndi_prop_update_string(DDI_DEV_T_NONE, dip,
6314 SCSI_ADDR_PROP_BRIDGE_PORT, uabuf) != DDI_PROP_SUCCESS) {
6315 mptsas_log(mpt, CE_WARN,
6316 "mptsas unable to create SCSI bridge port "
6317 "property for SATA device");
6318 return (B_FALSE);
6319 }
6320 return (B_TRUE);
6321 }
6322
6323 mptsas_log(mpt, CE_WARN, "mptsas failed to find dev_info_t or "
6324 "mdi_pathinfo_t for target with WWN %016" PRIx64,
6325 ptgt->m_addr.mta_wwn);
6326
6327 return (B_FALSE);
6328 }
6329
6330 static void
mptsas_update_phymask(mptsas_t * mpt)6331 mptsas_update_phymask(mptsas_t *mpt)
6332 {
6333 mptsas_phymask_t mask = 0, phy_mask;
6334 char *phy_mask_name;
6335 uint8_t current_port;
6336 int i, j;
6337
6338 NDBG20(("mptsas%d update phymask ", mpt->m_instance));
6339
6340 ASSERT(mutex_owned(&mpt->m_mutex));
6341
6342 (void) mptsas_get_sas_io_unit_page(mpt);
6343
6344 phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP);
6345
6346 for (i = 0; i < mpt->m_num_phys; i++) {
6347 phy_mask = 0x00;
6348
6349 if (mpt->m_phy_info[i].attached_devhdl == 0)
6350 continue;
6351
6352 bzero(phy_mask_name, sizeof (phy_mask_name));
6353
6354 current_port = mpt->m_phy_info[i].port_num;
6355
6356 if ((mask & (1 << i)) != 0)
6357 continue;
6358
6359 for (j = 0; j < mpt->m_num_phys; j++) {
6360 if (mpt->m_phy_info[j].attached_devhdl &&
6361 (mpt->m_phy_info[j].port_num == current_port)) {
6362 phy_mask |= (1 << j);
6363 }
6364 }
6365 mask = mask | phy_mask;
6366
6367 for (j = 0; j < mpt->m_num_phys; j++) {
6368 if ((phy_mask >> j) & 0x01) {
6369 mpt->m_phy_info[j].phy_mask = phy_mask;
6370 }
6371 }
6372
6373 (void) sprintf(phy_mask_name, "%x", phy_mask);
6374
6375 mutex_exit(&mpt->m_mutex);
6376 /*
6377 * register a iport, if the port has already been existed
6378 * SCSA will do nothing and just return.
6379 */
6380 (void) scsi_hba_iport_register(mpt->m_dip, phy_mask_name);
6381 mutex_enter(&mpt->m_mutex);
6382 }
6383 kmem_free(phy_mask_name, MPTSAS_MAX_PHYS);
6384 NDBG20(("mptsas%d update phymask return", mpt->m_instance));
6385 }
6386
6387 /*
6388 * mptsas_handle_dr is a task handler for DR, the DR action includes:
6389 * 1. Directly attched Device Added/Removed.
6390 * 2. Expander Device Added/Removed.
6391 * 3. Indirectly Attached Device Added/Expander.
6392 * 4. LUNs of a existing device status change.
6393 * 5. RAID volume created/deleted.
6394 * 6. Member of RAID volume is released because of RAID deletion.
6395 * 7. Physical disks are removed because of RAID creation.
6396 */
6397 static void
mptsas_handle_dr(void * args)6398 mptsas_handle_dr(void *args)
6399 {
6400 mptsas_topo_change_list_t *topo_node = NULL;
6401 mptsas_topo_change_list_t *save_node = NULL;
6402 mptsas_t *mpt;
6403 dev_info_t *parent = NULL;
6404 mptsas_phymask_t phymask = 0;
6405 char *phy_mask_name;
6406 uint8_t flags = 0, physport = 0xff;
6407 uint8_t port_update = 0;
6408 uint_t event;
6409
6410 topo_node = (mptsas_topo_change_list_t *)args;
6411
6412 mpt = topo_node->mpt;
6413 event = topo_node->event;
6414 flags = topo_node->flags;
6415
6416 phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP);
6417
6418 NDBG20(("mptsas%d handle_dr enter", mpt->m_instance));
6419
6420 switch (event) {
6421 case MPTSAS_DR_EVENT_RECONFIG_TARGET:
6422 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) ||
6423 (flags == MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE) ||
6424 (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED)) {
6425 /*
6426 * Direct attached or expander attached device added
6427 * into system or a Phys Disk that is being unhidden.
6428 */
6429 port_update = 1;
6430 }
6431 break;
6432 case MPTSAS_DR_EVENT_RECONFIG_SMP:
6433 /*
6434 * New expander added into system, it must be the head
6435 * of topo_change_list_t
6436 */
6437 port_update = 1;
6438 break;
6439 default:
6440 port_update = 0;
6441 break;
6442 }
6443 /*
6444 * All cases port_update == 1 may cause initiator port form change
6445 */
6446 mutex_enter(&mpt->m_mutex);
6447 if (mpt->m_port_chng && port_update) {
6448 /*
6449 * mpt->m_port_chng flag indicates some PHYs of initiator
6450 * port have changed to online. So when expander added or
6451 * directly attached device online event come, we force to
6452 * update port information by issueing SAS IO Unit Page and
6453 * update PHYMASKs.
6454 */
6455 (void) mptsas_update_phymask(mpt);
6456 mpt->m_port_chng = 0;
6457
6458 }
6459 mutex_exit(&mpt->m_mutex);
6460 while (topo_node) {
6461 phymask = 0;
6462 if (parent == NULL) {
6463 physport = topo_node->un.physport;
6464 event = topo_node->event;
6465 flags = topo_node->flags;
6466 if (event & (MPTSAS_DR_EVENT_OFFLINE_TARGET |
6467 MPTSAS_DR_EVENT_OFFLINE_SMP)) {
6468 /*
6469 * For all offline events, phymask is known
6470 */
6471 phymask = topo_node->un.phymask;
6472 goto find_parent;
6473 }
6474 if (event & MPTSAS_TOPO_FLAG_REMOVE_HANDLE) {
6475 goto handle_topo_change;
6476 }
6477 if (flags & MPTSAS_TOPO_FLAG_LUN_ASSOCIATED) {
6478 phymask = topo_node->un.phymask;
6479 goto find_parent;
6480 }
6481
6482 if ((flags ==
6483 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) &&
6484 (event == MPTSAS_DR_EVENT_RECONFIG_TARGET)) {
6485 /*
6486 * There is no any field in IR_CONFIG_CHANGE
6487 * event indicate physport/phynum, let's get
6488 * parent after SAS Device Page0 request.
6489 */
6490 goto handle_topo_change;
6491 }
6492
6493 mutex_enter(&mpt->m_mutex);
6494 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) {
6495 /*
6496 * If the direct attached device added or a
6497 * phys disk is being unhidden, argument
6498 * physport actually is PHY#, so we have to get
6499 * phymask according PHY#.
6500 */
6501 physport = mpt->m_phy_info[physport].port_num;
6502 }
6503
6504 /*
6505 * Translate physport to phymask so that we can search
6506 * parent dip.
6507 */
6508 phymask = mptsas_physport_to_phymask(mpt,
6509 physport);
6510 mutex_exit(&mpt->m_mutex);
6511
6512 find_parent:
6513 bzero(phy_mask_name, MPTSAS_MAX_PHYS);
6514 /*
6515 * For RAID topology change node, write the iport name
6516 * as v0.
6517 */
6518 if (flags & MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) {
6519 (void) sprintf(phy_mask_name, "v0");
6520 } else {
6521 /*
6522 * phymask can bo 0 if the drive has been
6523 * pulled by the time an add event is
6524 * processed. If phymask is 0, just skip this
6525 * event and continue.
6526 */
6527 if (phymask == 0) {
6528 mutex_enter(&mpt->m_mutex);
6529 save_node = topo_node;
6530 topo_node = topo_node->next;
6531 ASSERT(save_node);
6532 kmem_free(save_node,
6533 sizeof (mptsas_topo_change_list_t));
6534 mutex_exit(&mpt->m_mutex);
6535
6536 parent = NULL;
6537 continue;
6538 }
6539 (void) sprintf(phy_mask_name, "%x", phymask);
6540 }
6541 parent = scsi_hba_iport_find(mpt->m_dip,
6542 phy_mask_name);
6543 if (parent == NULL) {
6544 mptsas_log(mpt, CE_WARN, "Failed to find an "
6545 "iport, should not happen!");
6546 goto out;
6547 }
6548
6549 }
6550 ASSERT(parent);
6551 handle_topo_change:
6552
6553 mutex_enter(&mpt->m_mutex);
6554 /*
6555 * If HBA is being reset, don't perform operations depending
6556 * on the IOC. We must free the topo list, however.
6557 */
6558 if (!mpt->m_in_reset) {
6559 mptsas_handle_topo_change(topo_node, parent);
6560 } else {
6561 NDBG20(("skipping topo change received during reset"));
6562 }
6563 save_node = topo_node;
6564 topo_node = topo_node->next;
6565 ASSERT(save_node);
6566 kmem_free(save_node, sizeof (mptsas_topo_change_list_t));
6567 mutex_exit(&mpt->m_mutex);
6568
6569 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) ||
6570 (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) ||
6571 (flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED)) {
6572 /*
6573 * If direct attached device associated, make sure
6574 * reset the parent before start the next one. But
6575 * all devices associated with expander shares the
6576 * parent. Also, reset parent if this is for RAID.
6577 */
6578 parent = NULL;
6579 }
6580 }
6581 out:
6582 kmem_free(phy_mask_name, MPTSAS_MAX_PHYS);
6583 }
6584
6585 static void
mptsas_handle_topo_change(mptsas_topo_change_list_t * topo_node,dev_info_t * parent)6586 mptsas_handle_topo_change(mptsas_topo_change_list_t *topo_node,
6587 dev_info_t *parent)
6588 {
6589 mptsas_target_t *ptgt = NULL;
6590 mptsas_smp_t *psmp = NULL;
6591 mptsas_t *mpt = (void *)topo_node->mpt;
6592 uint16_t devhdl;
6593 uint16_t attached_devhdl;
6594 uint64_t sas_wwn = 0;
6595 int rval = 0;
6596 uint32_t page_address;
6597 uint8_t phy, flags;
6598 char *addr = NULL;
6599 dev_info_t *lundip;
6600 char attached_wwnstr[MPTSAS_WWN_STRLEN];
6601
6602 NDBG20(("mptsas%d handle_topo_change enter, devhdl 0x%x,"
6603 "event 0x%x, flags 0x%x", mpt->m_instance, topo_node->devhdl,
6604 topo_node->event, topo_node->flags));
6605
6606 ASSERT(mutex_owned(&mpt->m_mutex));
6607
6608 switch (topo_node->event) {
6609 case MPTSAS_DR_EVENT_RECONFIG_TARGET:
6610 {
6611 char *phy_mask_name;
6612 mptsas_phymask_t phymask = 0;
6613
6614 if (topo_node->flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) {
6615 /*
6616 * Get latest RAID info.
6617 */
6618 (void) mptsas_get_raid_info(mpt);
6619 ptgt = refhash_linear_search(mpt->m_targets,
6620 mptsas_target_eval_devhdl, &topo_node->devhdl);
6621 if (ptgt == NULL)
6622 break;
6623 } else {
6624 ptgt = (void *)topo_node->object;
6625 }
6626
6627 if (ptgt == NULL) {
6628 /*
6629 * If a Phys Disk was deleted, RAID info needs to be
6630 * updated to reflect the new topology.
6631 */
6632 (void) mptsas_get_raid_info(mpt);
6633
6634 /*
6635 * Get sas device page 0 by DevHandle to make sure if
6636 * SSP/SATA end device exist.
6637 */
6638 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
6639 MPI2_SAS_DEVICE_PGAD_FORM_MASK) |
6640 topo_node->devhdl;
6641
6642 rval = mptsas_get_target_device_info(mpt, page_address,
6643 &devhdl, &ptgt);
6644 if (rval == DEV_INFO_WRONG_DEVICE_TYPE) {
6645 mptsas_log(mpt, CE_NOTE,
6646 "mptsas_handle_topo_change: target %d is "
6647 "not a SAS/SATA device. \n",
6648 topo_node->devhdl);
6649 } else if (rval == DEV_INFO_FAIL_ALLOC) {
6650 mptsas_log(mpt, CE_NOTE,
6651 "mptsas_handle_topo_change: could not "
6652 "allocate memory. \n");
6653 } else if (rval == DEV_INFO_FAIL_GUID) {
6654 mptsas_log(mpt, CE_NOTE,
6655 "mptsas_handle_topo_change: could not "
6656 "get SATA GUID for target %d. \n",
6657 topo_node->devhdl);
6658 }
6659 /*
6660 * If rval is DEV_INFO_PHYS_DISK or indicates failure
6661 * then there is nothing else to do, just leave.
6662 */
6663 if (rval != DEV_INFO_SUCCESS) {
6664 return;
6665 }
6666 }
6667
6668 ASSERT(ptgt->m_devhdl == topo_node->devhdl);
6669
6670 mutex_exit(&mpt->m_mutex);
6671 flags = topo_node->flags;
6672
6673 if (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) {
6674 phymask = ptgt->m_addr.mta_phymask;
6675 phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP);
6676 (void) sprintf(phy_mask_name, "%x", phymask);
6677 parent = scsi_hba_iport_find(mpt->m_dip,
6678 phy_mask_name);
6679 kmem_free(phy_mask_name, MPTSAS_MAX_PHYS);
6680 if (parent == NULL) {
6681 mptsas_log(mpt, CE_WARN, "Failed to find a "
6682 "iport for PD, should not happen!");
6683 mutex_enter(&mpt->m_mutex);
6684 break;
6685 }
6686 }
6687
6688 if (flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) {
6689 ndi_devi_enter(parent);
6690 (void) mptsas_config_raid(parent, topo_node->devhdl,
6691 &lundip);
6692 ndi_devi_exit(parent);
6693 } else {
6694 /*
6695 * hold nexus for bus configure
6696 */
6697 ndi_devi_enter(scsi_vhci_dip);
6698 ndi_devi_enter(parent);
6699 rval = mptsas_config_target(parent, ptgt);
6700 /*
6701 * release nexus for bus configure
6702 */
6703 ndi_devi_exit(parent);
6704 ndi_devi_exit(scsi_vhci_dip);
6705
6706 /*
6707 * If this is a SATA device, make sure that the
6708 * bridge-port (the SAS WWN that the SATA device is
6709 * plugged into) is updated. This may change if a SATA
6710 * device changes which bay, and therefore phy, it is
6711 * plugged into.
6712 */
6713 if (IS_SATA_DEVICE(ptgt->m_deviceinfo)) {
6714 if (!mptsas_update_sata_bridge(mpt, parent,
6715 ptgt)) {
6716 mutex_enter(&mpt->m_mutex);
6717 return;
6718 }
6719 }
6720
6721 /*
6722 * Add parent's props for SMHBA support
6723 */
6724 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) {
6725 bzero(attached_wwnstr,
6726 sizeof (attached_wwnstr));
6727 (void) sprintf(attached_wwnstr, "w%016"PRIx64,
6728 ptgt->m_addr.mta_wwn);
6729 if (ddi_prop_update_string(DDI_DEV_T_NONE,
6730 parent,
6731 SCSI_ADDR_PROP_ATTACHED_PORT,
6732 attached_wwnstr)
6733 != DDI_PROP_SUCCESS) {
6734 (void) ddi_prop_remove(DDI_DEV_T_NONE,
6735 parent,
6736 SCSI_ADDR_PROP_ATTACHED_PORT);
6737 mptsas_log(mpt, CE_WARN, "Failed to"
6738 "attached-port props");
6739 mutex_enter(&mpt->m_mutex);
6740 return;
6741 }
6742 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6743 MPTSAS_NUM_PHYS, 1) !=
6744 DDI_PROP_SUCCESS) {
6745 (void) ddi_prop_remove(DDI_DEV_T_NONE,
6746 parent, MPTSAS_NUM_PHYS);
6747 mptsas_log(mpt, CE_WARN, "Failed to"
6748 " create num-phys props");
6749 mutex_enter(&mpt->m_mutex);
6750 return;
6751 }
6752
6753 /*
6754 * Update PHY info for smhba
6755 */
6756 mutex_enter(&mpt->m_mutex);
6757 if (mptsas_smhba_phy_init(mpt)) {
6758 mptsas_log(mpt, CE_WARN, "mptsas phy"
6759 " update failed");
6760 return;
6761 }
6762 mutex_exit(&mpt->m_mutex);
6763
6764 /*
6765 * topo_node->un.physport is really the PHY#
6766 * for direct attached devices
6767 */
6768 mptsas_smhba_set_one_phy_props(mpt, parent,
6769 topo_node->un.physport, &attached_devhdl);
6770
6771 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6772 MPTSAS_VIRTUAL_PORT, 0) !=
6773 DDI_PROP_SUCCESS) {
6774 (void) ddi_prop_remove(DDI_DEV_T_NONE,
6775 parent, MPTSAS_VIRTUAL_PORT);
6776 mptsas_log(mpt, CE_WARN,
6777 "mptsas virtual-port"
6778 "port prop update failed");
6779 mutex_enter(&mpt->m_mutex);
6780 return;
6781 }
6782 }
6783 }
6784 mutex_enter(&mpt->m_mutex);
6785
6786 NDBG20(("mptsas%d handle_topo_change to online devhdl:%x, "
6787 "phymask:%x.", mpt->m_instance, ptgt->m_devhdl,
6788 ptgt->m_addr.mta_phymask));
6789 break;
6790 }
6791 case MPTSAS_DR_EVENT_OFFLINE_TARGET:
6792 {
6793 devhdl = topo_node->devhdl;
6794 ptgt = refhash_linear_search(mpt->m_targets,
6795 mptsas_target_eval_devhdl, &devhdl);
6796 if (ptgt == NULL)
6797 break;
6798
6799 sas_wwn = ptgt->m_addr.mta_wwn;
6800 phy = ptgt->m_phynum;
6801
6802 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
6803
6804 if (sas_wwn) {
6805 (void) sprintf(addr, "w%016"PRIx64, sas_wwn);
6806 } else {
6807 (void) sprintf(addr, "p%x", phy);
6808 }
6809 ASSERT(ptgt->m_devhdl == devhdl);
6810
6811 if ((topo_node->flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) ||
6812 (topo_node->flags ==
6813 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED)) {
6814 /*
6815 * Get latest RAID info if RAID volume status changes
6816 * or Phys Disk status changes
6817 */
6818 (void) mptsas_get_raid_info(mpt);
6819 }
6820 /*
6821 * Abort all outstanding command on the device
6822 */
6823 rval = mptsas_do_scsi_reset(mpt, devhdl);
6824 if (rval) {
6825 NDBG20(("mptsas%d handle_topo_change to reset target "
6826 "before offline devhdl:%x, phymask:%x, rval:%x",
6827 mpt->m_instance, ptgt->m_devhdl,
6828 ptgt->m_addr.mta_phymask, rval));
6829 }
6830
6831 mutex_exit(&mpt->m_mutex);
6832
6833 ndi_devi_enter(scsi_vhci_dip);
6834 ndi_devi_enter(parent);
6835 rval = mptsas_offline_target(parent, addr);
6836 ndi_devi_exit(parent);
6837 ndi_devi_exit(scsi_vhci_dip);
6838 NDBG20(("mptsas%d handle_topo_change to offline devhdl:%x, "
6839 "phymask:%x, rval:%x", mpt->m_instance,
6840 ptgt->m_devhdl, ptgt->m_addr.mta_phymask, rval));
6841
6842 kmem_free(addr, SCSI_MAXNAMELEN);
6843
6844 /*
6845 * Clear parent's props for SMHBA support
6846 */
6847 flags = topo_node->flags;
6848 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) {
6849 bzero(attached_wwnstr, sizeof (attached_wwnstr));
6850 if (ddi_prop_update_string(DDI_DEV_T_NONE, parent,
6851 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) !=
6852 DDI_PROP_SUCCESS) {
6853 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6854 SCSI_ADDR_PROP_ATTACHED_PORT);
6855 mptsas_log(mpt, CE_WARN, "mptsas attached port "
6856 "prop update failed");
6857 mutex_enter(&mpt->m_mutex);
6858 break;
6859 }
6860 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6861 MPTSAS_NUM_PHYS, 0) !=
6862 DDI_PROP_SUCCESS) {
6863 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6864 MPTSAS_NUM_PHYS);
6865 mptsas_log(mpt, CE_WARN, "mptsas num phys "
6866 "prop update failed");
6867 mutex_enter(&mpt->m_mutex);
6868 break;
6869 }
6870 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6871 MPTSAS_VIRTUAL_PORT, 1) !=
6872 DDI_PROP_SUCCESS) {
6873 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6874 MPTSAS_VIRTUAL_PORT);
6875 mptsas_log(mpt, CE_WARN, "mptsas virtual port "
6876 "prop update failed");
6877 mutex_enter(&mpt->m_mutex);
6878 break;
6879 }
6880 }
6881
6882 mutex_enter(&mpt->m_mutex);
6883 if (rval == DDI_SUCCESS) {
6884 refhash_remove(mpt->m_targets, ptgt);
6885 ptgt = NULL;
6886 } else {
6887 /*
6888 * clean DR_INTRANSITION flag to allow I/O down to
6889 * PHCI driver since failover finished.
6890 * Invalidate the devhdl
6891 */
6892 ptgt->m_devhdl = MPTSAS_INVALID_DEVHDL;
6893 ptgt->m_tgt_unconfigured = 0;
6894 mutex_enter(&mpt->m_tx_waitq_mutex);
6895 ptgt->m_dr_flag = MPTSAS_DR_INACTIVE;
6896 mutex_exit(&mpt->m_tx_waitq_mutex);
6897 }
6898
6899 /*
6900 * Send SAS IO Unit Control to free the dev handle
6901 */
6902 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) ||
6903 (flags == MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE)) {
6904 rval = mptsas_free_devhdl(mpt, devhdl);
6905
6906 NDBG20(("mptsas%d handle_topo_change to remove "
6907 "devhdl:%x, rval:%x", mpt->m_instance, devhdl,
6908 rval));
6909 }
6910
6911 break;
6912 }
6913 case MPTSAS_TOPO_FLAG_REMOVE_HANDLE:
6914 {
6915 devhdl = topo_node->devhdl;
6916 /*
6917 * If this is the remove handle event, do a reset first.
6918 */
6919 if (topo_node->event == MPTSAS_TOPO_FLAG_REMOVE_HANDLE) {
6920 rval = mptsas_do_scsi_reset(mpt, devhdl);
6921 if (rval) {
6922 NDBG20(("mpt%d reset target before remove "
6923 "devhdl:%x, rval:%x", mpt->m_instance,
6924 devhdl, rval));
6925 }
6926 }
6927
6928 /*
6929 * Send SAS IO Unit Control to free the dev handle
6930 */
6931 rval = mptsas_free_devhdl(mpt, devhdl);
6932 NDBG20(("mptsas%d handle_topo_change to remove "
6933 "devhdl:%x, rval:%x", mpt->m_instance, devhdl,
6934 rval));
6935 break;
6936 }
6937 case MPTSAS_DR_EVENT_RECONFIG_SMP:
6938 {
6939 mptsas_smp_t smp;
6940 dev_info_t *smpdip;
6941
6942 devhdl = topo_node->devhdl;
6943
6944 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_HNDL &
6945 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)devhdl;
6946 rval = mptsas_get_sas_expander_page0(mpt, page_address, &smp);
6947 if (rval != DDI_SUCCESS) {
6948 mptsas_log(mpt, CE_WARN, "failed to online smp, "
6949 "handle %x", devhdl);
6950 return;
6951 }
6952
6953 psmp = mptsas_smp_alloc(mpt, &smp);
6954 if (psmp == NULL) {
6955 return;
6956 }
6957
6958 mutex_exit(&mpt->m_mutex);
6959 ndi_devi_enter(parent);
6960 (void) mptsas_online_smp(parent, psmp, &smpdip);
6961 ndi_devi_exit(parent);
6962
6963 mutex_enter(&mpt->m_mutex);
6964 break;
6965 }
6966 case MPTSAS_DR_EVENT_OFFLINE_SMP:
6967 {
6968 devhdl = topo_node->devhdl;
6969 uint32_t dev_info;
6970
6971 psmp = refhash_linear_search(mpt->m_smp_targets,
6972 mptsas_smp_eval_devhdl, &devhdl);
6973 if (psmp == NULL)
6974 break;
6975 /*
6976 * The mptsas_smp_t data is released only if the dip is offlined
6977 * successfully.
6978 */
6979 mutex_exit(&mpt->m_mutex);
6980
6981 ndi_devi_enter(parent);
6982 rval = mptsas_offline_smp(parent, psmp, NDI_DEVI_REMOVE);
6983 ndi_devi_exit(parent);
6984
6985 dev_info = psmp->m_deviceinfo;
6986 if ((dev_info & DEVINFO_DIRECT_ATTACHED) ==
6987 DEVINFO_DIRECT_ATTACHED) {
6988 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6989 MPTSAS_VIRTUAL_PORT, 1) !=
6990 DDI_PROP_SUCCESS) {
6991 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6992 MPTSAS_VIRTUAL_PORT);
6993 mptsas_log(mpt, CE_WARN, "mptsas virtual port "
6994 "prop update failed");
6995 mutex_enter(&mpt->m_mutex);
6996 return;
6997 }
6998 /*
6999 * Check whether the smp connected to the iport,
7000 */
7001 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
7002 MPTSAS_NUM_PHYS, 0) !=
7003 DDI_PROP_SUCCESS) {
7004 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
7005 MPTSAS_NUM_PHYS);
7006 mptsas_log(mpt, CE_WARN, "mptsas num phys"
7007 "prop update failed");
7008 mutex_enter(&mpt->m_mutex);
7009 return;
7010 }
7011 /*
7012 * Clear parent's attached-port props
7013 */
7014 bzero(attached_wwnstr, sizeof (attached_wwnstr));
7015 if (ddi_prop_update_string(DDI_DEV_T_NONE, parent,
7016 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) !=
7017 DDI_PROP_SUCCESS) {
7018 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
7019 SCSI_ADDR_PROP_ATTACHED_PORT);
7020 mptsas_log(mpt, CE_WARN, "mptsas attached port "
7021 "prop update failed");
7022 mutex_enter(&mpt->m_mutex);
7023 return;
7024 }
7025 }
7026
7027 mutex_enter(&mpt->m_mutex);
7028 NDBG20(("mptsas%d handle_topo_change to remove devhdl:%x, "
7029 "rval:%x", mpt->m_instance, psmp->m_devhdl, rval));
7030 if (rval == DDI_SUCCESS) {
7031 refhash_remove(mpt->m_smp_targets, psmp);
7032 } else {
7033 psmp->m_devhdl = MPTSAS_INVALID_DEVHDL;
7034 }
7035
7036 bzero(attached_wwnstr, sizeof (attached_wwnstr));
7037
7038 break;
7039 }
7040 default:
7041 return;
7042 }
7043 }
7044
7045 /*
7046 * Record the event if its type is enabled in mpt instance by ioctl.
7047 */
7048 static void
mptsas_record_event(void * args)7049 mptsas_record_event(void *args)
7050 {
7051 m_replyh_arg_t *replyh_arg;
7052 pMpi2EventNotificationReply_t eventreply;
7053 uint32_t event, rfm;
7054 mptsas_t *mpt;
7055 int i, j;
7056 uint16_t event_data_len;
7057 boolean_t sendAEN = FALSE;
7058
7059 replyh_arg = (m_replyh_arg_t *)args;
7060 rfm = replyh_arg->rfm;
7061 mpt = replyh_arg->mpt;
7062
7063 eventreply = (pMpi2EventNotificationReply_t)
7064 (mpt->m_reply_frame + (rfm -
7065 (mpt->m_reply_frame_dma_addr & 0xffffffffu)));
7066 event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event);
7067
7068
7069 /*
7070 * Generate a system event to let anyone who cares know that a
7071 * LOG_ENTRY_ADDED event has occurred. This is sent no matter what the
7072 * event mask is set to.
7073 */
7074 if (event == MPI2_EVENT_LOG_ENTRY_ADDED) {
7075 sendAEN = TRUE;
7076 }
7077
7078 /*
7079 * Record the event only if it is not masked. Determine which dword
7080 * and bit of event mask to test.
7081 */
7082 i = (uint8_t)(event / 32);
7083 j = (uint8_t)(event % 32);
7084 if ((i < 4) && ((1 << j) & mpt->m_event_mask[i])) {
7085 i = mpt->m_event_index;
7086 mpt->m_events[i].Type = event;
7087 mpt->m_events[i].Number = ++mpt->m_event_number;
7088 bzero(mpt->m_events[i].Data, MPTSAS_MAX_EVENT_DATA_LENGTH * 4);
7089 event_data_len = ddi_get16(mpt->m_acc_reply_frame_hdl,
7090 &eventreply->EventDataLength);
7091
7092 if (event_data_len > 0) {
7093 /*
7094 * Limit data to size in m_event entry
7095 */
7096 if (event_data_len > MPTSAS_MAX_EVENT_DATA_LENGTH) {
7097 event_data_len = MPTSAS_MAX_EVENT_DATA_LENGTH;
7098 }
7099 for (j = 0; j < event_data_len; j++) {
7100 mpt->m_events[i].Data[j] =
7101 ddi_get32(mpt->m_acc_reply_frame_hdl,
7102 &(eventreply->EventData[j]));
7103 }
7104
7105 /*
7106 * check for index wrap-around
7107 */
7108 if (++i == MPTSAS_EVENT_QUEUE_SIZE) {
7109 i = 0;
7110 }
7111 mpt->m_event_index = (uint8_t)i;
7112
7113 /*
7114 * Set flag to send the event.
7115 */
7116 sendAEN = TRUE;
7117 }
7118 }
7119
7120 /*
7121 * Generate a system event if flag is set to let anyone who cares know
7122 * that an event has occurred.
7123 */
7124 if (sendAEN) {
7125 (void) ddi_log_sysevent(mpt->m_dip, DDI_VENDOR_LSI, "MPT_SAS",
7126 "SAS", NULL, NULL, DDI_NOSLEEP);
7127 }
7128 }
7129
7130 #define SMP_RESET_IN_PROGRESS MPI2_EVENT_SAS_TOPO_LR_SMP_RESET_IN_PROGRESS
7131 /*
7132 * handle sync events from ioc in interrupt
7133 * return value:
7134 * DDI_SUCCESS: The event is handled by this func
7135 * DDI_FAILURE: Event is not handled
7136 */
7137 static int
mptsas_handle_event_sync(void * args)7138 mptsas_handle_event_sync(void *args)
7139 {
7140 m_replyh_arg_t *replyh_arg;
7141 pMpi2EventNotificationReply_t eventreply;
7142 uint32_t event, rfm;
7143 mptsas_t *mpt;
7144 uint_t iocstatus;
7145
7146 replyh_arg = (m_replyh_arg_t *)args;
7147 rfm = replyh_arg->rfm;
7148 mpt = replyh_arg->mpt;
7149
7150 ASSERT(mutex_owned(&mpt->m_mutex));
7151
7152 eventreply = (pMpi2EventNotificationReply_t)
7153 (mpt->m_reply_frame + (rfm -
7154 (mpt->m_reply_frame_dma_addr & 0xffffffffu)));
7155 event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event);
7156
7157 if ((iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
7158 &eventreply->IOCStatus)) != 0) {
7159 if (iocstatus == MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
7160 mptsas_log(mpt, CE_WARN,
7161 "!mptsas_handle_event_sync: event 0x%x, "
7162 "IOCStatus=0x%x, "
7163 "IOCLogInfo=0x%x", event, iocstatus,
7164 ddi_get32(mpt->m_acc_reply_frame_hdl,
7165 &eventreply->IOCLogInfo));
7166 } else {
7167 mptsas_log(mpt, CE_WARN,
7168 "mptsas_handle_event_sync: event 0x%x, "
7169 "IOCStatus=0x%x, "
7170 "(IOCLogInfo=0x%x)", event, iocstatus,
7171 ddi_get32(mpt->m_acc_reply_frame_hdl,
7172 &eventreply->IOCLogInfo));
7173 }
7174 }
7175
7176 /*
7177 * figure out what kind of event we got and handle accordingly
7178 */
7179 switch (event) {
7180 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
7181 {
7182 pMpi2EventDataSasTopologyChangeList_t sas_topo_change_list;
7183 uint8_t num_entries, expstatus, phy;
7184 uint8_t phystatus, physport, state, i;
7185 uint8_t start_phy_num, link_rate;
7186 uint16_t dev_handle, reason_code;
7187 uint16_t enc_handle, expd_handle;
7188 char string[80], curr[80], prev[80];
7189 mptsas_topo_change_list_t *topo_head = NULL;
7190 mptsas_topo_change_list_t *topo_tail = NULL;
7191 mptsas_topo_change_list_t *topo_node = NULL;
7192 mptsas_target_t *ptgt;
7193 mptsas_smp_t *psmp;
7194 uint8_t flags = 0, exp_flag;
7195 smhba_info_t *pSmhba = NULL;
7196
7197 NDBG20(("mptsas_handle_event_sync: SAS topology change"));
7198
7199 sas_topo_change_list = (pMpi2EventDataSasTopologyChangeList_t)
7200 eventreply->EventData;
7201
7202 enc_handle = ddi_get16(mpt->m_acc_reply_frame_hdl,
7203 &sas_topo_change_list->EnclosureHandle);
7204 expd_handle = ddi_get16(mpt->m_acc_reply_frame_hdl,
7205 &sas_topo_change_list->ExpanderDevHandle);
7206 num_entries = ddi_get8(mpt->m_acc_reply_frame_hdl,
7207 &sas_topo_change_list->NumEntries);
7208 start_phy_num = ddi_get8(mpt->m_acc_reply_frame_hdl,
7209 &sas_topo_change_list->StartPhyNum);
7210 expstatus = ddi_get8(mpt->m_acc_reply_frame_hdl,
7211 &sas_topo_change_list->ExpStatus);
7212 physport = ddi_get8(mpt->m_acc_reply_frame_hdl,
7213 &sas_topo_change_list->PhysicalPort);
7214
7215 string[0] = 0;
7216 if (expd_handle) {
7217 flags = MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED;
7218 switch (expstatus) {
7219 case MPI2_EVENT_SAS_TOPO_ES_ADDED:
7220 (void) sprintf(string, " added");
7221 /*
7222 * New expander device added
7223 */
7224 mpt->m_port_chng = 1;
7225 topo_node = kmem_zalloc(
7226 sizeof (mptsas_topo_change_list_t),
7227 KM_SLEEP);
7228 topo_node->mpt = mpt;
7229 topo_node->event = MPTSAS_DR_EVENT_RECONFIG_SMP;
7230 topo_node->un.physport = physport;
7231 topo_node->devhdl = expd_handle;
7232 topo_node->flags = flags;
7233 topo_node->object = NULL;
7234 if (topo_head == NULL) {
7235 topo_head = topo_tail = topo_node;
7236 } else {
7237 topo_tail->next = topo_node;
7238 topo_tail = topo_node;
7239 }
7240 break;
7241 case MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING:
7242 (void) sprintf(string, " not responding, "
7243 "removed");
7244 psmp = refhash_linear_search(mpt->m_smp_targets,
7245 mptsas_smp_eval_devhdl, &expd_handle);
7246 if (psmp == NULL)
7247 break;
7248
7249 topo_node = kmem_zalloc(
7250 sizeof (mptsas_topo_change_list_t),
7251 KM_SLEEP);
7252 topo_node->mpt = mpt;
7253 topo_node->un.phymask =
7254 psmp->m_addr.mta_phymask;
7255 topo_node->event = MPTSAS_DR_EVENT_OFFLINE_SMP;
7256 topo_node->devhdl = expd_handle;
7257 topo_node->flags = flags;
7258 topo_node->object = NULL;
7259 if (topo_head == NULL) {
7260 topo_head = topo_tail = topo_node;
7261 } else {
7262 topo_tail->next = topo_node;
7263 topo_tail = topo_node;
7264 }
7265 break;
7266 case MPI2_EVENT_SAS_TOPO_ES_RESPONDING:
7267 break;
7268 case MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING:
7269 (void) sprintf(string, " not responding, "
7270 "delaying removal");
7271 break;
7272 default:
7273 break;
7274 }
7275 } else {
7276 flags = MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE;
7277 }
7278
7279 NDBG20(("SAS TOPOLOGY CHANGE for enclosure %x expander %x%s\n",
7280 enc_handle, expd_handle, string));
7281 for (i = 0; i < num_entries; i++) {
7282 phy = i + start_phy_num;
7283 phystatus = ddi_get8(mpt->m_acc_reply_frame_hdl,
7284 &sas_topo_change_list->PHY[i].PhyStatus);
7285 dev_handle = ddi_get16(mpt->m_acc_reply_frame_hdl,
7286 &sas_topo_change_list->PHY[i].AttachedDevHandle);
7287 reason_code = phystatus & MPI2_EVENT_SAS_TOPO_RC_MASK;
7288 /*
7289 * Filter out processing of Phy Vacant Status unless
7290 * the reason code is "Not Responding". Process all
7291 * other combinations of Phy Status and Reason Codes.
7292 */
7293 if ((phystatus &
7294 MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT) &&
7295 (reason_code !=
7296 MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING)) {
7297 continue;
7298 }
7299 curr[0] = 0;
7300 prev[0] = 0;
7301 string[0] = 0;
7302 switch (reason_code) {
7303 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
7304 {
7305 NDBG20(("mptsas%d phy %d physical_port %d "
7306 "dev_handle %d added", mpt->m_instance, phy,
7307 physport, dev_handle));
7308 link_rate = ddi_get8(mpt->m_acc_reply_frame_hdl,
7309 &sas_topo_change_list->PHY[i].LinkRate);
7310 state = (link_rate &
7311 MPI2_EVENT_SAS_TOPO_LR_CURRENT_MASK) >>
7312 MPI2_EVENT_SAS_TOPO_LR_CURRENT_SHIFT;
7313 switch (state) {
7314 case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED:
7315 (void) sprintf(curr, "is disabled");
7316 break;
7317 case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED:
7318 (void) sprintf(curr, "is offline, "
7319 "failed speed negotiation");
7320 break;
7321 case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE:
7322 (void) sprintf(curr, "SATA OOB "
7323 "complete");
7324 break;
7325 case SMP_RESET_IN_PROGRESS:
7326 (void) sprintf(curr, "SMP reset in "
7327 "progress");
7328 break;
7329 case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5:
7330 (void) sprintf(curr, "is online at "
7331 "1.5 Gbps");
7332 break;
7333 case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0:
7334 (void) sprintf(curr, "is online at 3.0 "
7335 "Gbps");
7336 break;
7337 case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0:
7338 (void) sprintf(curr, "is online at 6.0 "
7339 "Gbps");
7340 break;
7341 case MPI25_EVENT_SAS_TOPO_LR_RATE_12_0:
7342 (void) sprintf(curr,
7343 "is online at 12.0 Gbps");
7344 break;
7345 default:
7346 (void) sprintf(curr, "state is "
7347 "unknown");
7348 break;
7349 }
7350 /*
7351 * New target device added into the system.
7352 * Set association flag according to if an
7353 * expander is used or not.
7354 */
7355 exp_flag =
7356 MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE;
7357 if (flags ==
7358 MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED) {
7359 flags = exp_flag;
7360 }
7361 topo_node = kmem_zalloc(
7362 sizeof (mptsas_topo_change_list_t),
7363 KM_SLEEP);
7364 topo_node->mpt = mpt;
7365 topo_node->event =
7366 MPTSAS_DR_EVENT_RECONFIG_TARGET;
7367 if (expd_handle == 0) {
7368 /*
7369 * Per MPI 2, if expander dev handle
7370 * is 0, it's a directly attached
7371 * device. So driver use PHY to decide
7372 * which iport is associated
7373 */
7374 physport = phy;
7375 mpt->m_port_chng = 1;
7376 }
7377 topo_node->un.physport = physport;
7378 topo_node->devhdl = dev_handle;
7379 topo_node->flags = flags;
7380 topo_node->object = NULL;
7381 if (topo_head == NULL) {
7382 topo_head = topo_tail = topo_node;
7383 } else {
7384 topo_tail->next = topo_node;
7385 topo_tail = topo_node;
7386 }
7387 break;
7388 }
7389 case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING:
7390 {
7391 NDBG20(("mptsas%d phy %d physical_port %d "
7392 "dev_handle %d removed", mpt->m_instance,
7393 phy, physport, dev_handle));
7394 /*
7395 * Set association flag according to if an
7396 * expander is used or not.
7397 */
7398 exp_flag =
7399 MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE;
7400 if (flags ==
7401 MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED) {
7402 flags = exp_flag;
7403 }
7404 /*
7405 * Target device is removed from the system
7406 * Before the device is really offline from
7407 * from system.
7408 */
7409 ptgt = refhash_linear_search(mpt->m_targets,
7410 mptsas_target_eval_devhdl, &dev_handle);
7411 /*
7412 * If ptgt is NULL here, it means that the
7413 * DevHandle is not in the hash table. This is
7414 * reasonable sometimes. For example, if a
7415 * disk was pulled, then added, then pulled
7416 * again, the disk will not have been put into
7417 * the hash table because the add event will
7418 * have an invalid phymask. BUT, this does not
7419 * mean that the DevHandle is invalid. The
7420 * controller will still have a valid DevHandle
7421 * that must be removed. To do this, use the
7422 * MPTSAS_TOPO_FLAG_REMOVE_HANDLE event.
7423 */
7424 if (ptgt == NULL) {
7425 topo_node = kmem_zalloc(
7426 sizeof (mptsas_topo_change_list_t),
7427 KM_SLEEP);
7428 topo_node->mpt = mpt;
7429 topo_node->un.phymask = 0;
7430 topo_node->event =
7431 MPTSAS_TOPO_FLAG_REMOVE_HANDLE;
7432 topo_node->devhdl = dev_handle;
7433 topo_node->flags = flags;
7434 topo_node->object = NULL;
7435 if (topo_head == NULL) {
7436 topo_head = topo_tail =
7437 topo_node;
7438 } else {
7439 topo_tail->next = topo_node;
7440 topo_tail = topo_node;
7441 }
7442 break;
7443 }
7444
7445 /*
7446 * Update DR flag immediately avoid I/O failure
7447 * before failover finish. Pay attention to the
7448 * mutex protect, we need grab m_tx_waitq_mutex
7449 * during set m_dr_flag because we won't add
7450 * the following command into waitq, instead,
7451 * we need return TRAN_BUSY in the tran_start
7452 * context.
7453 */
7454 mutex_enter(&mpt->m_tx_waitq_mutex);
7455 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION;
7456 mutex_exit(&mpt->m_tx_waitq_mutex);
7457
7458 topo_node = kmem_zalloc(
7459 sizeof (mptsas_topo_change_list_t),
7460 KM_SLEEP);
7461 topo_node->mpt = mpt;
7462 topo_node->un.phymask =
7463 ptgt->m_addr.mta_phymask;
7464 topo_node->event =
7465 MPTSAS_DR_EVENT_OFFLINE_TARGET;
7466 topo_node->devhdl = dev_handle;
7467 topo_node->flags = flags;
7468 topo_node->object = NULL;
7469 if (topo_head == NULL) {
7470 topo_head = topo_tail = topo_node;
7471 } else {
7472 topo_tail->next = topo_node;
7473 topo_tail = topo_node;
7474 }
7475 break;
7476 }
7477 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
7478 link_rate = ddi_get8(mpt->m_acc_reply_frame_hdl,
7479 &sas_topo_change_list->PHY[i].LinkRate);
7480 state = (link_rate &
7481 MPI2_EVENT_SAS_TOPO_LR_CURRENT_MASK) >>
7482 MPI2_EVENT_SAS_TOPO_LR_CURRENT_SHIFT;
7483 pSmhba = &mpt->m_phy_info[i].smhba_info;
7484 pSmhba->negotiated_link_rate = state;
7485 switch (state) {
7486 case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED:
7487 (void) sprintf(curr, "is disabled");
7488 mptsas_smhba_log_sysevent(mpt,
7489 ESC_SAS_PHY_EVENT,
7490 SAS_PHY_REMOVE,
7491 &mpt->m_phy_info[i].smhba_info);
7492 mpt->m_phy_info[i].smhba_info.
7493 negotiated_link_rate
7494 = 0x1;
7495 break;
7496 case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED:
7497 (void) sprintf(curr, "is offline, "
7498 "failed speed negotiation");
7499 mptsas_smhba_log_sysevent(mpt,
7500 ESC_SAS_PHY_EVENT,
7501 SAS_PHY_OFFLINE,
7502 &mpt->m_phy_info[i].smhba_info);
7503 break;
7504 case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE:
7505 (void) sprintf(curr, "SATA OOB "
7506 "complete");
7507 break;
7508 case SMP_RESET_IN_PROGRESS:
7509 (void) sprintf(curr, "SMP reset in "
7510 "progress");
7511 break;
7512 case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5:
7513 (void) sprintf(curr, "is online at "
7514 "1.5 Gbps");
7515 if ((expd_handle == 0) &&
7516 (enc_handle == 1)) {
7517 mpt->m_port_chng = 1;
7518 }
7519 mptsas_smhba_log_sysevent(mpt,
7520 ESC_SAS_PHY_EVENT,
7521 SAS_PHY_ONLINE,
7522 &mpt->m_phy_info[i].smhba_info);
7523 break;
7524 case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0:
7525 (void) sprintf(curr, "is online at 3.0 "
7526 "Gbps");
7527 if ((expd_handle == 0) &&
7528 (enc_handle == 1)) {
7529 mpt->m_port_chng = 1;
7530 }
7531 mptsas_smhba_log_sysevent(mpt,
7532 ESC_SAS_PHY_EVENT,
7533 SAS_PHY_ONLINE,
7534 &mpt->m_phy_info[i].smhba_info);
7535 break;
7536 case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0:
7537 (void) sprintf(curr, "is online at "
7538 "6.0 Gbps");
7539 if ((expd_handle == 0) &&
7540 (enc_handle == 1)) {
7541 mpt->m_port_chng = 1;
7542 }
7543 mptsas_smhba_log_sysevent(mpt,
7544 ESC_SAS_PHY_EVENT,
7545 SAS_PHY_ONLINE,
7546 &mpt->m_phy_info[i].smhba_info);
7547 break;
7548 case MPI25_EVENT_SAS_TOPO_LR_RATE_12_0:
7549 (void) sprintf(curr, "is online at "
7550 "12.0 Gbps");
7551 if ((expd_handle == 0) &&
7552 (enc_handle == 1)) {
7553 mpt->m_port_chng = 1;
7554 }
7555 mptsas_smhba_log_sysevent(mpt,
7556 ESC_SAS_PHY_EVENT,
7557 SAS_PHY_ONLINE,
7558 &mpt->m_phy_info[i].smhba_info);
7559 break;
7560 default:
7561 (void) sprintf(curr, "state is "
7562 "unknown");
7563 break;
7564 }
7565
7566 state = (link_rate &
7567 MPI2_EVENT_SAS_TOPO_LR_PREV_MASK) >>
7568 MPI2_EVENT_SAS_TOPO_LR_PREV_SHIFT;
7569 switch (state) {
7570 case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED:
7571 (void) sprintf(prev, ", was disabled");
7572 break;
7573 case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED:
7574 (void) sprintf(prev, ", was offline, "
7575 "failed speed negotiation");
7576 break;
7577 case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE:
7578 (void) sprintf(prev, ", was SATA OOB "
7579 "complete");
7580 break;
7581 case SMP_RESET_IN_PROGRESS:
7582 (void) sprintf(prev, ", was SMP reset "
7583 "in progress");
7584 break;
7585 case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5:
7586 (void) sprintf(prev, ", was online at "
7587 "1.5 Gbps");
7588 break;
7589 case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0:
7590 (void) sprintf(prev, ", was online at "
7591 "3.0 Gbps");
7592 break;
7593 case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0:
7594 (void) sprintf(prev, ", was online at "
7595 "6.0 Gbps");
7596 break;
7597 case MPI25_EVENT_SAS_TOPO_LR_RATE_12_0:
7598 (void) sprintf(prev, ", was online at "
7599 "12.0 Gbps");
7600 break;
7601 default:
7602 break;
7603 }
7604 (void) sprintf(&string[strlen(string)], "link "
7605 "changed, ");
7606 break;
7607 case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE:
7608 continue;
7609 case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING:
7610 (void) sprintf(&string[strlen(string)],
7611 "target not responding, delaying "
7612 "removal");
7613 break;
7614 }
7615 NDBG20(("mptsas%d phy %d DevHandle %x, %s%s%s\n",
7616 mpt->m_instance, phy, dev_handle, string, curr,
7617 prev));
7618 }
7619 if (topo_head != NULL) {
7620 /*
7621 * Launch DR taskq to handle topology change
7622 */
7623 if ((ddi_taskq_dispatch(mpt->m_dr_taskq,
7624 mptsas_handle_dr, (void *)topo_head,
7625 DDI_NOSLEEP)) != DDI_SUCCESS) {
7626 while (topo_head != NULL) {
7627 topo_node = topo_head;
7628 topo_head = topo_head->next;
7629 kmem_free(topo_node,
7630 sizeof (mptsas_topo_change_list_t));
7631 }
7632 mptsas_log(mpt, CE_NOTE, "mptsas start taskq "
7633 "for handle SAS DR event failed. \n");
7634 }
7635 }
7636 break;
7637 }
7638 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
7639 {
7640 Mpi2EventDataIrConfigChangeList_t *irChangeList;
7641 mptsas_topo_change_list_t *topo_head = NULL;
7642 mptsas_topo_change_list_t *topo_tail = NULL;
7643 mptsas_topo_change_list_t *topo_node = NULL;
7644 mptsas_target_t *ptgt;
7645 uint8_t num_entries, i, reason;
7646 uint16_t volhandle, diskhandle;
7647
7648 irChangeList = (pMpi2EventDataIrConfigChangeList_t)
7649 eventreply->EventData;
7650 num_entries = ddi_get8(mpt->m_acc_reply_frame_hdl,
7651 &irChangeList->NumElements);
7652
7653 NDBG20(("mptsas%d IR_CONFIGURATION_CHANGE_LIST event received",
7654 mpt->m_instance));
7655
7656 for (i = 0; i < num_entries; i++) {
7657 reason = ddi_get8(mpt->m_acc_reply_frame_hdl,
7658 &irChangeList->ConfigElement[i].ReasonCode);
7659 volhandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
7660 &irChangeList->ConfigElement[i].VolDevHandle);
7661 diskhandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
7662 &irChangeList->ConfigElement[i].PhysDiskDevHandle);
7663
7664 switch (reason) {
7665 case MPI2_EVENT_IR_CHANGE_RC_ADDED:
7666 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED:
7667 {
7668 NDBG20(("mptsas %d volume added\n",
7669 mpt->m_instance));
7670
7671 topo_node = kmem_zalloc(
7672 sizeof (mptsas_topo_change_list_t),
7673 KM_SLEEP);
7674
7675 topo_node->mpt = mpt;
7676 topo_node->event =
7677 MPTSAS_DR_EVENT_RECONFIG_TARGET;
7678 topo_node->un.physport = 0xff;
7679 topo_node->devhdl = volhandle;
7680 topo_node->flags =
7681 MPTSAS_TOPO_FLAG_RAID_ASSOCIATED;
7682 topo_node->object = NULL;
7683 if (topo_head == NULL) {
7684 topo_head = topo_tail = topo_node;
7685 } else {
7686 topo_tail->next = topo_node;
7687 topo_tail = topo_node;
7688 }
7689 break;
7690 }
7691 case MPI2_EVENT_IR_CHANGE_RC_REMOVED:
7692 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED:
7693 {
7694 NDBG20(("mptsas %d volume deleted\n",
7695 mpt->m_instance));
7696 ptgt = refhash_linear_search(mpt->m_targets,
7697 mptsas_target_eval_devhdl, &volhandle);
7698 if (ptgt == NULL)
7699 break;
7700
7701 /*
7702 * Clear any flags related to volume
7703 */
7704 (void) mptsas_delete_volume(mpt, volhandle);
7705
7706 /*
7707 * Update DR flag immediately avoid I/O failure
7708 */
7709 mutex_enter(&mpt->m_tx_waitq_mutex);
7710 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION;
7711 mutex_exit(&mpt->m_tx_waitq_mutex);
7712
7713 topo_node = kmem_zalloc(
7714 sizeof (mptsas_topo_change_list_t),
7715 KM_SLEEP);
7716 topo_node->mpt = mpt;
7717 topo_node->un.phymask =
7718 ptgt->m_addr.mta_phymask;
7719 topo_node->event =
7720 MPTSAS_DR_EVENT_OFFLINE_TARGET;
7721 topo_node->devhdl = volhandle;
7722 topo_node->flags =
7723 MPTSAS_TOPO_FLAG_RAID_ASSOCIATED;
7724 topo_node->object = (void *)ptgt;
7725 if (topo_head == NULL) {
7726 topo_head = topo_tail = topo_node;
7727 } else {
7728 topo_tail->next = topo_node;
7729 topo_tail = topo_node;
7730 }
7731 break;
7732 }
7733 case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED:
7734 case MPI2_EVENT_IR_CHANGE_RC_HIDE:
7735 {
7736 ptgt = refhash_linear_search(mpt->m_targets,
7737 mptsas_target_eval_devhdl, &diskhandle);
7738 if (ptgt == NULL)
7739 break;
7740
7741 /*
7742 * Update DR flag immediately avoid I/O failure
7743 */
7744 mutex_enter(&mpt->m_tx_waitq_mutex);
7745 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION;
7746 mutex_exit(&mpt->m_tx_waitq_mutex);
7747
7748 topo_node = kmem_zalloc(
7749 sizeof (mptsas_topo_change_list_t),
7750 KM_SLEEP);
7751 topo_node->mpt = mpt;
7752 topo_node->un.phymask =
7753 ptgt->m_addr.mta_phymask;
7754 topo_node->event =
7755 MPTSAS_DR_EVENT_OFFLINE_TARGET;
7756 topo_node->devhdl = diskhandle;
7757 topo_node->flags =
7758 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED;
7759 topo_node->object = (void *)ptgt;
7760 if (topo_head == NULL) {
7761 topo_head = topo_tail = topo_node;
7762 } else {
7763 topo_tail->next = topo_node;
7764 topo_tail = topo_node;
7765 }
7766 break;
7767 }
7768 case MPI2_EVENT_IR_CHANGE_RC_UNHIDE:
7769 case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED:
7770 {
7771 /*
7772 * The physical drive is released by a IR
7773 * volume. But we cannot get the the physport
7774 * or phynum from the event data, so we only
7775 * can get the physport/phynum after SAS
7776 * Device Page0 request for the devhdl.
7777 */
7778 topo_node = kmem_zalloc(
7779 sizeof (mptsas_topo_change_list_t),
7780 KM_SLEEP);
7781 topo_node->mpt = mpt;
7782 topo_node->un.phymask = 0;
7783 topo_node->event =
7784 MPTSAS_DR_EVENT_RECONFIG_TARGET;
7785 topo_node->devhdl = diskhandle;
7786 topo_node->flags =
7787 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED;
7788 topo_node->object = NULL;
7789 mpt->m_port_chng = 1;
7790 if (topo_head == NULL) {
7791 topo_head = topo_tail = topo_node;
7792 } else {
7793 topo_tail->next = topo_node;
7794 topo_tail = topo_node;
7795 }
7796 break;
7797 }
7798 default:
7799 break;
7800 }
7801 }
7802
7803 if (topo_head != NULL) {
7804 /*
7805 * Launch DR taskq to handle topology change
7806 */
7807 if ((ddi_taskq_dispatch(mpt->m_dr_taskq,
7808 mptsas_handle_dr, (void *)topo_head,
7809 DDI_NOSLEEP)) != DDI_SUCCESS) {
7810 while (topo_head != NULL) {
7811 topo_node = topo_head;
7812 topo_head = topo_head->next;
7813 kmem_free(topo_node,
7814 sizeof (mptsas_topo_change_list_t));
7815 }
7816 mptsas_log(mpt, CE_NOTE, "mptsas start taskq "
7817 "for handle SAS DR event failed. \n");
7818 }
7819 }
7820 break;
7821 }
7822 default:
7823 return (DDI_FAILURE);
7824 }
7825
7826 return (DDI_SUCCESS);
7827 }
7828
7829 /*
7830 * handle events from ioc
7831 */
7832 static void
mptsas_handle_event(void * args)7833 mptsas_handle_event(void *args)
7834 {
7835 m_replyh_arg_t *replyh_arg;
7836 pMpi2EventNotificationReply_t eventreply;
7837 uint32_t event, iocloginfo, rfm;
7838 uint32_t status;
7839 uint8_t port;
7840 mptsas_t *mpt;
7841 uint_t iocstatus;
7842
7843 replyh_arg = (m_replyh_arg_t *)args;
7844 rfm = replyh_arg->rfm;
7845 mpt = replyh_arg->mpt;
7846
7847 mutex_enter(&mpt->m_mutex);
7848 /*
7849 * If HBA is being reset, drop incoming event.
7850 */
7851 if (mpt->m_in_reset) {
7852 NDBG20(("dropping event received prior to reset"));
7853 mutex_exit(&mpt->m_mutex);
7854 return;
7855 }
7856
7857 eventreply = (pMpi2EventNotificationReply_t)
7858 (mpt->m_reply_frame + (rfm -
7859 (mpt->m_reply_frame_dma_addr & 0xffffffffu)));
7860 event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event);
7861
7862 if ((iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
7863 &eventreply->IOCStatus)) != 0) {
7864 if (iocstatus == MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
7865 mptsas_log(mpt, CE_WARN,
7866 "!mptsas_handle_event: IOCStatus=0x%x, "
7867 "IOCLogInfo=0x%x", iocstatus,
7868 ddi_get32(mpt->m_acc_reply_frame_hdl,
7869 &eventreply->IOCLogInfo));
7870 } else {
7871 mptsas_log(mpt, CE_WARN,
7872 "mptsas_handle_event: IOCStatus=0x%x, "
7873 "IOCLogInfo=0x%x", iocstatus,
7874 ddi_get32(mpt->m_acc_reply_frame_hdl,
7875 &eventreply->IOCLogInfo));
7876 }
7877 }
7878
7879 /*
7880 * figure out what kind of event we got and handle accordingly
7881 */
7882 switch (event) {
7883 case MPI2_EVENT_LOG_ENTRY_ADDED:
7884 break;
7885 case MPI2_EVENT_LOG_DATA:
7886 iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl,
7887 &eventreply->IOCLogInfo);
7888 NDBG20(("mptsas %d log info %x received.\n", mpt->m_instance,
7889 iocloginfo));
7890 break;
7891 case MPI2_EVENT_STATE_CHANGE:
7892 NDBG20(("mptsas%d state change.", mpt->m_instance));
7893 break;
7894 case MPI2_EVENT_HARD_RESET_RECEIVED:
7895 NDBG20(("mptsas%d event change.", mpt->m_instance));
7896 break;
7897 case MPI2_EVENT_SAS_DISCOVERY:
7898 {
7899 MPI2_EVENT_DATA_SAS_DISCOVERY *sasdiscovery;
7900 char string[80];
7901 uint8_t rc;
7902
7903 sasdiscovery =
7904 (pMpi2EventDataSasDiscovery_t)eventreply->EventData;
7905
7906 rc = ddi_get8(mpt->m_acc_reply_frame_hdl,
7907 &sasdiscovery->ReasonCode);
7908 port = ddi_get8(mpt->m_acc_reply_frame_hdl,
7909 &sasdiscovery->PhysicalPort);
7910 status = ddi_get32(mpt->m_acc_reply_frame_hdl,
7911 &sasdiscovery->DiscoveryStatus);
7912
7913 string[0] = 0;
7914 switch (rc) {
7915 case MPI2_EVENT_SAS_DISC_RC_STARTED:
7916 (void) sprintf(string, "STARTING");
7917 break;
7918 case MPI2_EVENT_SAS_DISC_RC_COMPLETED:
7919 (void) sprintf(string, "COMPLETED");
7920 break;
7921 default:
7922 (void) sprintf(string, "UNKNOWN");
7923 break;
7924 }
7925
7926 NDBG20(("SAS DISCOVERY is %s for port %d, status %x", string,
7927 port, status));
7928
7929 break;
7930 }
7931 case MPI2_EVENT_EVENT_CHANGE:
7932 NDBG20(("mptsas%d event change.", mpt->m_instance));
7933 break;
7934 case MPI2_EVENT_TASK_SET_FULL:
7935 {
7936 pMpi2EventDataTaskSetFull_t taskfull;
7937
7938 taskfull = (pMpi2EventDataTaskSetFull_t)eventreply->EventData;
7939
7940 NDBG20(("TASK_SET_FULL received for mptsas%d, depth %d\n",
7941 mpt->m_instance, ddi_get16(mpt->m_acc_reply_frame_hdl,
7942 &taskfull->CurrentDepth)));
7943 break;
7944 }
7945 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
7946 {
7947 /*
7948 * SAS TOPOLOGY CHANGE LIST Event has already been handled
7949 * in mptsas_handle_event_sync() of interrupt context
7950 */
7951 break;
7952 }
7953 case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
7954 {
7955 pMpi2EventDataSasEnclDevStatusChange_t encstatus;
7956 uint8_t rc;
7957 uint16_t enchdl;
7958 char string[80];
7959 mptsas_enclosure_t *mep;
7960
7961 encstatus = (pMpi2EventDataSasEnclDevStatusChange_t)
7962 eventreply->EventData;
7963
7964 rc = ddi_get8(mpt->m_acc_reply_frame_hdl,
7965 &encstatus->ReasonCode);
7966 enchdl = ddi_get16(mpt->m_acc_reply_frame_hdl,
7967 &encstatus->EnclosureHandle);
7968
7969 switch (rc) {
7970 case MPI2_EVENT_SAS_ENCL_RC_ADDED:
7971 (void) sprintf(string, "added");
7972 break;
7973 case MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING:
7974 mep = mptsas_enc_lookup(mpt, enchdl);
7975 if (mep != NULL) {
7976 list_remove(&mpt->m_enclosures, mep);
7977 mptsas_enc_free(mep);
7978 mep = NULL;
7979 }
7980 (void) sprintf(string, ", not responding");
7981 break;
7982 default:
7983 break;
7984 }
7985 NDBG20(("mptsas%d ENCLOSURE STATUS CHANGE for enclosure "
7986 "%x%s\n", mpt->m_instance,
7987 ddi_get16(mpt->m_acc_reply_frame_hdl,
7988 &encstatus->EnclosureHandle), string));
7989
7990 /*
7991 * No matter what has happened, update all of our device state
7992 * for enclosures, by retriggering an evaluation.
7993 */
7994 mpt->m_done_traverse_enc = 0;
7995 mptsas_update_hashtab(mpt);
7996 break;
7997 }
7998
7999 /*
8000 * MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE is handled by
8001 * mptsas_handle_event_sync,in here just send ack message.
8002 */
8003 case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
8004 {
8005 pMpi2EventDataSasDeviceStatusChange_t statuschange;
8006 uint8_t rc;
8007 uint16_t devhdl;
8008 uint64_t wwn = 0;
8009 uint32_t wwn_lo, wwn_hi;
8010
8011 statuschange = (pMpi2EventDataSasDeviceStatusChange_t)
8012 eventreply->EventData;
8013 rc = ddi_get8(mpt->m_acc_reply_frame_hdl,
8014 &statuschange->ReasonCode);
8015 wwn_lo = ddi_get32(mpt->m_acc_reply_frame_hdl,
8016 (uint32_t *)(void *)&statuschange->SASAddress);
8017 wwn_hi = ddi_get32(mpt->m_acc_reply_frame_hdl,
8018 (uint32_t *)(void *)&statuschange->SASAddress + 1);
8019 wwn = ((uint64_t)wwn_hi << 32) | wwn_lo;
8020 devhdl = ddi_get16(mpt->m_acc_reply_frame_hdl,
8021 &statuschange->DevHandle);
8022
8023 NDBG13(("MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE wwn is %"PRIx64,
8024 wwn));
8025
8026 switch (rc) {
8027 case MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
8028 NDBG20(("SMART data received, ASC/ASCQ = %02x/%02x",
8029 ddi_get8(mpt->m_acc_reply_frame_hdl,
8030 &statuschange->ASC),
8031 ddi_get8(mpt->m_acc_reply_frame_hdl,
8032 &statuschange->ASCQ)));
8033 break;
8034
8035 case MPI2_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
8036 NDBG20(("Device not supported"));
8037 break;
8038
8039 case MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
8040 NDBG20(("IOC internally generated the Target Reset "
8041 "for devhdl:%x", devhdl));
8042 break;
8043
8044 case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET:
8045 NDBG20(("IOC's internally generated Target Reset "
8046 "completed for devhdl:%x", devhdl));
8047 break;
8048
8049 case MPI2_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
8050 NDBG20(("IOC internally generated Abort Task"));
8051 break;
8052
8053 case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_TASK_ABORT_INTERNAL:
8054 NDBG20(("IOC's internally generated Abort Task "
8055 "completed"));
8056 break;
8057
8058 case MPI2_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
8059 NDBG20(("IOC internally generated Abort Task Set"));
8060 break;
8061
8062 case MPI2_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
8063 NDBG20(("IOC internally generated Clear Task Set"));
8064 break;
8065
8066 case MPI2_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
8067 NDBG20(("IOC internally generated Query Task"));
8068 break;
8069
8070 case MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION:
8071 NDBG20(("Device sent an Asynchronous Notification"));
8072 break;
8073
8074 default:
8075 break;
8076 }
8077 break;
8078 }
8079 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
8080 {
8081 /*
8082 * IR TOPOLOGY CHANGE LIST Event has already been handled
8083 * in mpt_handle_event_sync() of interrupt context
8084 */
8085 break;
8086 }
8087 case MPI2_EVENT_IR_OPERATION_STATUS:
8088 {
8089 Mpi2EventDataIrOperationStatus_t *irOpStatus;
8090 char reason_str[80];
8091 uint8_t rc, percent;
8092 uint16_t handle;
8093
8094 irOpStatus = (pMpi2EventDataIrOperationStatus_t)
8095 eventreply->EventData;
8096 rc = ddi_get8(mpt->m_acc_reply_frame_hdl,
8097 &irOpStatus->RAIDOperation);
8098 percent = ddi_get8(mpt->m_acc_reply_frame_hdl,
8099 &irOpStatus->PercentComplete);
8100 handle = ddi_get16(mpt->m_acc_reply_frame_hdl,
8101 &irOpStatus->VolDevHandle);
8102
8103 switch (rc) {
8104 case MPI2_EVENT_IR_RAIDOP_RESYNC:
8105 (void) sprintf(reason_str, "resync");
8106 break;
8107 case MPI2_EVENT_IR_RAIDOP_ONLINE_CAP_EXPANSION:
8108 (void) sprintf(reason_str, "online capacity "
8109 "expansion");
8110 break;
8111 case MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK:
8112 (void) sprintf(reason_str, "consistency check");
8113 break;
8114 default:
8115 (void) sprintf(reason_str, "unknown reason %x",
8116 rc);
8117 }
8118
8119 NDBG20(("mptsas%d raid operational status: (%s)"
8120 "\thandle(0x%04x), percent complete(%d)\n",
8121 mpt->m_instance, reason_str, handle, percent));
8122 break;
8123 }
8124 case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE:
8125 {
8126 pMpi2EventDataSasBroadcastPrimitive_t sas_broadcast;
8127 uint8_t phy_num;
8128 uint8_t primitive;
8129
8130 sas_broadcast = (pMpi2EventDataSasBroadcastPrimitive_t)
8131 eventreply->EventData;
8132
8133 phy_num = ddi_get8(mpt->m_acc_reply_frame_hdl,
8134 &sas_broadcast->PhyNum);
8135 primitive = ddi_get8(mpt->m_acc_reply_frame_hdl,
8136 &sas_broadcast->Primitive);
8137
8138 switch (primitive) {
8139 case MPI2_EVENT_PRIMITIVE_CHANGE:
8140 mptsas_smhba_log_sysevent(mpt,
8141 ESC_SAS_HBA_PORT_BROADCAST,
8142 SAS_PORT_BROADCAST_CHANGE,
8143 &mpt->m_phy_info[phy_num].smhba_info);
8144 break;
8145 case MPI2_EVENT_PRIMITIVE_SES:
8146 mptsas_smhba_log_sysevent(mpt,
8147 ESC_SAS_HBA_PORT_BROADCAST,
8148 SAS_PORT_BROADCAST_SES,
8149 &mpt->m_phy_info[phy_num].smhba_info);
8150 break;
8151 case MPI2_EVENT_PRIMITIVE_EXPANDER:
8152 mptsas_smhba_log_sysevent(mpt,
8153 ESC_SAS_HBA_PORT_BROADCAST,
8154 SAS_PORT_BROADCAST_D01_4,
8155 &mpt->m_phy_info[phy_num].smhba_info);
8156 break;
8157 case MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT:
8158 mptsas_smhba_log_sysevent(mpt,
8159 ESC_SAS_HBA_PORT_BROADCAST,
8160 SAS_PORT_BROADCAST_D04_7,
8161 &mpt->m_phy_info[phy_num].smhba_info);
8162 break;
8163 case MPI2_EVENT_PRIMITIVE_RESERVED3:
8164 mptsas_smhba_log_sysevent(mpt,
8165 ESC_SAS_HBA_PORT_BROADCAST,
8166 SAS_PORT_BROADCAST_D16_7,
8167 &mpt->m_phy_info[phy_num].smhba_info);
8168 break;
8169 case MPI2_EVENT_PRIMITIVE_RESERVED4:
8170 mptsas_smhba_log_sysevent(mpt,
8171 ESC_SAS_HBA_PORT_BROADCAST,
8172 SAS_PORT_BROADCAST_D29_7,
8173 &mpt->m_phy_info[phy_num].smhba_info);
8174 break;
8175 case MPI2_EVENT_PRIMITIVE_CHANGE0_RESERVED:
8176 mptsas_smhba_log_sysevent(mpt,
8177 ESC_SAS_HBA_PORT_BROADCAST,
8178 SAS_PORT_BROADCAST_D24_0,
8179 &mpt->m_phy_info[phy_num].smhba_info);
8180 break;
8181 case MPI2_EVENT_PRIMITIVE_CHANGE1_RESERVED:
8182 mptsas_smhba_log_sysevent(mpt,
8183 ESC_SAS_HBA_PORT_BROADCAST,
8184 SAS_PORT_BROADCAST_D27_4,
8185 &mpt->m_phy_info[phy_num].smhba_info);
8186 break;
8187 default:
8188 NDBG16(("mptsas%d: unknown BROADCAST PRIMITIVE"
8189 " %x received",
8190 mpt->m_instance, primitive));
8191 break;
8192 }
8193 NDBG16(("mptsas%d sas broadcast primitive: "
8194 "\tprimitive(0x%04x), phy(%d) complete\n",
8195 mpt->m_instance, primitive, phy_num));
8196 break;
8197 }
8198 case MPI2_EVENT_IR_VOLUME:
8199 {
8200 Mpi2EventDataIrVolume_t *irVolume;
8201 uint16_t devhandle;
8202 uint32_t state;
8203 int config, vol;
8204 uint8_t found = FALSE;
8205
8206 irVolume = (pMpi2EventDataIrVolume_t)eventreply->EventData;
8207 state = ddi_get32(mpt->m_acc_reply_frame_hdl,
8208 &irVolume->NewValue);
8209 devhandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
8210 &irVolume->VolDevHandle);
8211
8212 NDBG20(("EVENT_IR_VOLUME event is received"));
8213
8214 /*
8215 * Get latest RAID info and then find the DevHandle for this
8216 * event in the configuration. If the DevHandle is not found
8217 * just exit the event.
8218 */
8219 (void) mptsas_get_raid_info(mpt);
8220 for (config = 0; (config < mpt->m_num_raid_configs) &&
8221 (!found); config++) {
8222 for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) {
8223 if (mpt->m_raidconfig[config].m_raidvol[vol].
8224 m_raidhandle == devhandle) {
8225 found = TRUE;
8226 break;
8227 }
8228 }
8229 }
8230 if (!found) {
8231 break;
8232 }
8233
8234 switch (irVolume->ReasonCode) {
8235 case MPI2_EVENT_IR_VOLUME_RC_SETTINGS_CHANGED:
8236 {
8237 uint32_t i;
8238 mpt->m_raidconfig[config].m_raidvol[vol].m_settings =
8239 state;
8240
8241 i = state & MPI2_RAIDVOL0_SETTING_MASK_WRITE_CACHING;
8242 mptsas_log(mpt, CE_NOTE, " Volume %d settings changed"
8243 ", auto-config of hot-swap drives is %s"
8244 ", write caching is %s"
8245 ", hot-spare pool mask is %02x\n",
8246 vol, state &
8247 MPI2_RAIDVOL0_SETTING_AUTO_CONFIG_HSWAP_DISABLE
8248 ? "disabled" : "enabled",
8249 i == MPI2_RAIDVOL0_SETTING_UNCHANGED
8250 ? "controlled by member disks" :
8251 i == MPI2_RAIDVOL0_SETTING_DISABLE_WRITE_CACHING
8252 ? "disabled" :
8253 i == MPI2_RAIDVOL0_SETTING_ENABLE_WRITE_CACHING
8254 ? "enabled" :
8255 "incorrectly set",
8256 (state >> 16) & 0xff);
8257 break;
8258 }
8259 case MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED:
8260 {
8261 mpt->m_raidconfig[config].m_raidvol[vol].m_state =
8262 (uint8_t)state;
8263
8264 mptsas_log(mpt, CE_NOTE,
8265 "Volume %d is now %s\n", vol,
8266 state == MPI2_RAID_VOL_STATE_OPTIMAL
8267 ? "optimal" :
8268 state == MPI2_RAID_VOL_STATE_DEGRADED
8269 ? "degraded" :
8270 state == MPI2_RAID_VOL_STATE_ONLINE
8271 ? "online" :
8272 state == MPI2_RAID_VOL_STATE_INITIALIZING
8273 ? "initializing" :
8274 state == MPI2_RAID_VOL_STATE_FAILED
8275 ? "failed" :
8276 state == MPI2_RAID_VOL_STATE_MISSING
8277 ? "missing" :
8278 "state unknown");
8279 break;
8280 }
8281 case MPI2_EVENT_IR_VOLUME_RC_STATUS_FLAGS_CHANGED:
8282 {
8283 mpt->m_raidconfig[config].m_raidvol[vol].
8284 m_statusflags = state;
8285
8286 mptsas_log(mpt, CE_NOTE,
8287 " Volume %d is now %s%s%s%s%s%s%s%s%s\n",
8288 vol,
8289 state & MPI2_RAIDVOL0_STATUS_FLAG_ENABLED
8290 ? ", enabled" : ", disabled",
8291 state & MPI2_RAIDVOL0_STATUS_FLAG_QUIESCED
8292 ? ", quiesced" : "",
8293 state & MPI2_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE
8294 ? ", inactive" : ", active",
8295 state &
8296 MPI2_RAIDVOL0_STATUS_FLAG_BAD_BLOCK_TABLE_FULL
8297 ? ", bad block table is full" : "",
8298 state &
8299 MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
8300 ? ", resync in progress" : "",
8301 state & MPI2_RAIDVOL0_STATUS_FLAG_BACKGROUND_INIT
8302 ? ", background initialization in progress" : "",
8303 state &
8304 MPI2_RAIDVOL0_STATUS_FLAG_CAPACITY_EXPANSION
8305 ? ", capacity expansion in progress" : "",
8306 state &
8307 MPI2_RAIDVOL0_STATUS_FLAG_CONSISTENCY_CHECK
8308 ? ", consistency check in progress" : "",
8309 state & MPI2_RAIDVOL0_STATUS_FLAG_DATA_SCRUB
8310 ? ", data scrub in progress" : "");
8311 break;
8312 }
8313 default:
8314 break;
8315 }
8316 break;
8317 }
8318 case MPI2_EVENT_IR_PHYSICAL_DISK:
8319 {
8320 Mpi2EventDataIrPhysicalDisk_t *irPhysDisk;
8321 uint16_t devhandle, enchandle, slot;
8322 uint32_t status, state;
8323 uint8_t physdisknum, reason;
8324
8325 irPhysDisk = (Mpi2EventDataIrPhysicalDisk_t *)
8326 eventreply->EventData;
8327 physdisknum = ddi_get8(mpt->m_acc_reply_frame_hdl,
8328 &irPhysDisk->PhysDiskNum);
8329 devhandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
8330 &irPhysDisk->PhysDiskDevHandle);
8331 enchandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
8332 &irPhysDisk->EnclosureHandle);
8333 slot = ddi_get16(mpt->m_acc_reply_frame_hdl,
8334 &irPhysDisk->Slot);
8335 state = ddi_get32(mpt->m_acc_reply_frame_hdl,
8336 &irPhysDisk->NewValue);
8337 reason = ddi_get8(mpt->m_acc_reply_frame_hdl,
8338 &irPhysDisk->ReasonCode);
8339
8340 NDBG20(("EVENT_IR_PHYSICAL_DISK event is received"));
8341
8342 switch (reason) {
8343 case MPI2_EVENT_IR_PHYSDISK_RC_SETTINGS_CHANGED:
8344 mptsas_log(mpt, CE_NOTE,
8345 " PhysDiskNum %d with DevHandle 0x%x in slot %d "
8346 "for enclosure with handle 0x%x is now in hot "
8347 "spare pool %d",
8348 physdisknum, devhandle, slot, enchandle,
8349 (state >> 16) & 0xff);
8350 break;
8351
8352 case MPI2_EVENT_IR_PHYSDISK_RC_STATUS_FLAGS_CHANGED:
8353 status = state;
8354 mptsas_log(mpt, CE_NOTE,
8355 " PhysDiskNum %d with DevHandle 0x%x in slot %d "
8356 "for enclosure with handle 0x%x is now "
8357 "%s%s%s%s%s\n", physdisknum, devhandle, slot,
8358 enchandle,
8359 status & MPI2_PHYSDISK0_STATUS_FLAG_INACTIVE_VOLUME
8360 ? ", inactive" : ", active",
8361 status & MPI2_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
8362 ? ", out of sync" : "",
8363 status & MPI2_PHYSDISK0_STATUS_FLAG_QUIESCED
8364 ? ", quiesced" : "",
8365 status &
8366 MPI2_PHYSDISK0_STATUS_FLAG_WRITE_CACHE_ENABLED
8367 ? ", write cache enabled" : "",
8368 status & MPI2_PHYSDISK0_STATUS_FLAG_OCE_TARGET
8369 ? ", capacity expansion target" : "");
8370 break;
8371
8372 case MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED:
8373 mptsas_log(mpt, CE_NOTE,
8374 " PhysDiskNum %d with DevHandle 0x%x in slot %d "
8375 "for enclosure with handle 0x%x is now %s\n",
8376 physdisknum, devhandle, slot, enchandle,
8377 state == MPI2_RAID_PD_STATE_OPTIMAL
8378 ? "optimal" :
8379 state == MPI2_RAID_PD_STATE_REBUILDING
8380 ? "rebuilding" :
8381 state == MPI2_RAID_PD_STATE_DEGRADED
8382 ? "degraded" :
8383 state == MPI2_RAID_PD_STATE_HOT_SPARE
8384 ? "a hot spare" :
8385 state == MPI2_RAID_PD_STATE_ONLINE
8386 ? "online" :
8387 state == MPI2_RAID_PD_STATE_OFFLINE
8388 ? "offline" :
8389 state == MPI2_RAID_PD_STATE_NOT_COMPATIBLE
8390 ? "not compatible" :
8391 state == MPI2_RAID_PD_STATE_NOT_CONFIGURED
8392 ? "not configured" :
8393 "state unknown");
8394 break;
8395 }
8396 break;
8397 }
8398 case MPI2_EVENT_ACTIVE_CABLE_EXCEPTION:
8399 {
8400 pMpi26EventDataActiveCableExcept_t actcable;
8401 uint32_t power;
8402 uint8_t reason, id;
8403
8404 actcable = (pMpi26EventDataActiveCableExcept_t)
8405 eventreply->EventData;
8406 power = ddi_get32(mpt->m_acc_reply_frame_hdl,
8407 &actcable->ActiveCablePowerRequirement);
8408 reason = ddi_get8(mpt->m_acc_reply_frame_hdl,
8409 &actcable->ReasonCode);
8410 id = ddi_get8(mpt->m_acc_reply_frame_hdl,
8411 &actcable->ReceptacleID);
8412
8413 /*
8414 * It'd be nice if this weren't just logging to the system but
8415 * were telling FMA about the active cable problem and FMA was
8416 * aware of the cable topology and state.
8417 */
8418 switch (reason) {
8419 case MPI26_EVENT_ACTIVE_CABLE_PRESENT:
8420 /* Don't log anything if it's fine */
8421 break;
8422 case MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER:
8423 mptsas_log(mpt, CE_WARN, "An active cable (id %u) does "
8424 "not have sufficient power to be enabled. "
8425 "Devices connected to this cable will not be "
8426 "visible to the system.", id);
8427 if (power == UINT32_MAX) {
8428 mptsas_log(mpt, CE_CONT, "The cable's power "
8429 "requirements are unknown.\n");
8430 } else {
8431 mptsas_log(mpt, CE_CONT, "The cable requires "
8432 "%u mW of power to function.\n", power);
8433 }
8434 break;
8435 case MPI26_EVENT_ACTIVE_CABLE_DEGRADED:
8436 mptsas_log(mpt, CE_WARN, "An active cable (id %u) is "
8437 "degraded and not running at its full speed. "
8438 "Some devices might not appear.", id);
8439 break;
8440 default:
8441 break;
8442 }
8443 break;
8444 }
8445 case MPI2_EVENT_PCIE_DEVICE_STATUS_CHANGE:
8446 case MPI2_EVENT_PCIE_ENUMERATION:
8447 case MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST:
8448 case MPI2_EVENT_PCIE_LINK_COUNTER:
8449 mptsas_log(mpt, CE_NOTE, "Unhandled mpt_sas PCIe device "
8450 "event received (0x%x)", event);
8451 break;
8452 default:
8453 NDBG20(("mptsas%d: unknown event %x received",
8454 mpt->m_instance, event));
8455 break;
8456 }
8457
8458 /*
8459 * Return the reply frame to the free queue.
8460 */
8461 ddi_put32(mpt->m_acc_free_queue_hdl,
8462 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], rfm);
8463 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
8464 DDI_DMA_SYNC_FORDEV);
8465 if (++mpt->m_free_index == mpt->m_free_queue_depth) {
8466 mpt->m_free_index = 0;
8467 }
8468 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
8469 mpt->m_free_index);
8470 mutex_exit(&mpt->m_mutex);
8471 }
8472
8473 /*
8474 * invoked from timeout() to restart qfull cmds with throttle == 0
8475 */
8476 static void
mptsas_restart_cmd(void * arg)8477 mptsas_restart_cmd(void *arg)
8478 {
8479 mptsas_t *mpt = arg;
8480 mptsas_target_t *ptgt = NULL;
8481
8482 mutex_enter(&mpt->m_mutex);
8483
8484 mpt->m_restart_cmd_timeid = 0;
8485
8486 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
8487 ptgt = refhash_next(mpt->m_targets, ptgt)) {
8488 if (ptgt->m_reset_delay == 0) {
8489 if (ptgt->m_t_throttle == QFULL_THROTTLE) {
8490 mptsas_set_throttle(mpt, ptgt,
8491 MAX_THROTTLE);
8492 }
8493 }
8494 }
8495 mptsas_restart_hba(mpt);
8496 mutex_exit(&mpt->m_mutex);
8497 }
8498
8499 void
mptsas_remove_cmd(mptsas_t * mpt,mptsas_cmd_t * cmd)8500 mptsas_remove_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
8501 {
8502 int slot;
8503 mptsas_slots_t *slots = mpt->m_active;
8504 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
8505
8506 ASSERT(cmd != NULL);
8507 ASSERT(cmd->cmd_queued == FALSE);
8508
8509 /*
8510 * Task Management cmds are removed in their own routines. Also,
8511 * we don't want to modify timeout based on TM cmds.
8512 */
8513 if (cmd->cmd_flags & CFLAG_TM_CMD) {
8514 return;
8515 }
8516
8517 slot = cmd->cmd_slot;
8518
8519 /*
8520 * remove the cmd.
8521 */
8522 if (cmd == slots->m_slot[slot]) {
8523 NDBG31(("mptsas_remove_cmd: removing cmd=0x%p, flags "
8524 "0x%x", (void *)cmd, cmd->cmd_flags));
8525 slots->m_slot[slot] = NULL;
8526 mpt->m_ncmds--;
8527
8528 /*
8529 * only decrement per target ncmds if command
8530 * has a target associated with it.
8531 */
8532 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) {
8533 ptgt->m_t_ncmds--;
8534 /*
8535 * reset throttle if we just ran an untagged command
8536 * to a tagged target
8537 */
8538 if ((ptgt->m_t_ncmds == 0) &&
8539 ((cmd->cmd_pkt_flags & FLAG_TAGMASK) == 0)) {
8540 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
8541 }
8542
8543 /*
8544 * Remove this command from the active queue.
8545 */
8546 if (cmd->cmd_active_expiration != 0) {
8547 TAILQ_REMOVE(&ptgt->m_active_cmdq, cmd,
8548 cmd_active_link);
8549 cmd->cmd_active_expiration = 0;
8550 }
8551 }
8552 }
8553
8554 /*
8555 * This is all we need to do for ioc commands.
8556 */
8557 if (cmd->cmd_flags & CFLAG_CMDIOC) {
8558 mptsas_return_to_pool(mpt, cmd);
8559 return;
8560 }
8561
8562 ASSERT(cmd != slots->m_slot[cmd->cmd_slot]);
8563 }
8564
8565 /*
8566 * accept all cmds on the tx_waitq if any and then
8567 * start a fresh request from the top of the device queue.
8568 *
8569 * since there are always cmds queued on the tx_waitq, and rare cmds on
8570 * the instance waitq, so this function should not be invoked in the ISR,
8571 * the mptsas_restart_waitq() is invoked in the ISR instead. otherwise, the
8572 * burden belongs to the IO dispatch CPUs is moved the interrupt CPU.
8573 */
8574 static void
mptsas_restart_hba(mptsas_t * mpt)8575 mptsas_restart_hba(mptsas_t *mpt)
8576 {
8577 ASSERT(mutex_owned(&mpt->m_mutex));
8578
8579 mutex_enter(&mpt->m_tx_waitq_mutex);
8580 if (mpt->m_tx_waitq) {
8581 mptsas_accept_tx_waitq(mpt);
8582 }
8583 mutex_exit(&mpt->m_tx_waitq_mutex);
8584 mptsas_restart_waitq(mpt);
8585 }
8586
8587 /*
8588 * start a fresh request from the top of the device queue
8589 */
8590 static void
mptsas_restart_waitq(mptsas_t * mpt)8591 mptsas_restart_waitq(mptsas_t *mpt)
8592 {
8593 mptsas_cmd_t *cmd, *next_cmd;
8594 mptsas_target_t *ptgt = NULL;
8595
8596 NDBG1(("mptsas_restart_waitq: mpt=0x%p", (void *)mpt));
8597
8598 ASSERT(mutex_owned(&mpt->m_mutex));
8599
8600 /*
8601 * If there is a reset delay, don't start any cmds. Otherwise, start
8602 * as many cmds as possible.
8603 * Since SMID 0 is reserved and the TM slot is reserved, the actual max
8604 * commands is m_max_requests - 2.
8605 */
8606 cmd = mpt->m_waitq;
8607
8608 while (cmd != NULL) {
8609 next_cmd = cmd->cmd_linkp;
8610 if (cmd->cmd_flags & CFLAG_PASSTHRU) {
8611 if (mptsas_save_cmd(mpt, cmd) == TRUE) {
8612 /*
8613 * passthru command get slot need
8614 * set CFLAG_PREPARED.
8615 */
8616 cmd->cmd_flags |= CFLAG_PREPARED;
8617 mptsas_waitq_delete(mpt, cmd);
8618 mptsas_start_passthru(mpt, cmd);
8619 }
8620 cmd = next_cmd;
8621 continue;
8622 }
8623 if (cmd->cmd_flags & CFLAG_CONFIG) {
8624 if (mptsas_save_cmd(mpt, cmd) == TRUE) {
8625 /*
8626 * Send the config page request and delete it
8627 * from the waitq.
8628 */
8629 cmd->cmd_flags |= CFLAG_PREPARED;
8630 mptsas_waitq_delete(mpt, cmd);
8631 mptsas_start_config_page_access(mpt, cmd);
8632 }
8633 cmd = next_cmd;
8634 continue;
8635 }
8636 if (cmd->cmd_flags & CFLAG_FW_DIAG) {
8637 if (mptsas_save_cmd(mpt, cmd) == TRUE) {
8638 /*
8639 * Send the FW Diag request and delete if from
8640 * the waitq.
8641 */
8642 cmd->cmd_flags |= CFLAG_PREPARED;
8643 mptsas_waitq_delete(mpt, cmd);
8644 mptsas_start_diag(mpt, cmd);
8645 }
8646 cmd = next_cmd;
8647 continue;
8648 }
8649
8650 ptgt = cmd->cmd_tgt_addr;
8651 if (ptgt && (ptgt->m_t_throttle == DRAIN_THROTTLE) &&
8652 (ptgt->m_t_ncmds == 0)) {
8653 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
8654 }
8655 if ((mpt->m_ncmds <= (mpt->m_max_requests - 2)) &&
8656 (ptgt && (ptgt->m_reset_delay == 0)) &&
8657 (ptgt && (ptgt->m_t_ncmds <
8658 ptgt->m_t_throttle))) {
8659 if (mptsas_save_cmd(mpt, cmd) == TRUE) {
8660 mptsas_waitq_delete(mpt, cmd);
8661 (void) mptsas_start_cmd(mpt, cmd);
8662 }
8663 }
8664 cmd = next_cmd;
8665 }
8666 }
8667 /*
8668 * Cmds are queued if tran_start() doesn't get the m_mutexlock(no wait).
8669 * Accept all those queued cmds before new cmd is accept so that the
8670 * cmds are sent in order.
8671 */
8672 static void
mptsas_accept_tx_waitq(mptsas_t * mpt)8673 mptsas_accept_tx_waitq(mptsas_t *mpt)
8674 {
8675 mptsas_cmd_t *cmd;
8676
8677 ASSERT(mutex_owned(&mpt->m_mutex));
8678 ASSERT(mutex_owned(&mpt->m_tx_waitq_mutex));
8679
8680 /*
8681 * A Bus Reset could occur at any time and flush the tx_waitq,
8682 * so we cannot count on the tx_waitq to contain even one cmd.
8683 * And when the m_tx_waitq_mutex is released and run
8684 * mptsas_accept_pkt(), the tx_waitq may be flushed.
8685 */
8686 cmd = mpt->m_tx_waitq;
8687 for (;;) {
8688 if ((cmd = mpt->m_tx_waitq) == NULL) {
8689 mpt->m_tx_draining = 0;
8690 break;
8691 }
8692 if ((mpt->m_tx_waitq = cmd->cmd_linkp) == NULL) {
8693 mpt->m_tx_waitqtail = &mpt->m_tx_waitq;
8694 }
8695 cmd->cmd_linkp = NULL;
8696 mutex_exit(&mpt->m_tx_waitq_mutex);
8697 if (mptsas_accept_pkt(mpt, cmd) != TRAN_ACCEPT)
8698 cmn_err(CE_WARN, "mpt: mptsas_accept_tx_waitq: failed "
8699 "to accept cmd on queue\n");
8700 mutex_enter(&mpt->m_tx_waitq_mutex);
8701 }
8702 }
8703
8704
8705 /*
8706 * mpt tag type lookup
8707 */
8708 static char mptsas_tag_lookup[] =
8709 {0, MSG_HEAD_QTAG, MSG_ORDERED_QTAG, 0, MSG_SIMPLE_QTAG};
8710
8711 static int
mptsas_start_cmd(mptsas_t * mpt,mptsas_cmd_t * cmd)8712 mptsas_start_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
8713 {
8714 struct scsi_pkt *pkt = CMD2PKT(cmd);
8715 uint32_t control = 0;
8716 caddr_t mem, arsbuf;
8717 pMpi2SCSIIORequest_t io_request;
8718 ddi_dma_handle_t dma_hdl = mpt->m_dma_req_frame_hdl;
8719 ddi_acc_handle_t acc_hdl = mpt->m_acc_req_frame_hdl;
8720 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
8721 uint16_t SMID, io_flags = 0;
8722 uint8_t ars_size;
8723 uint64_t request_desc;
8724 uint32_t ars_dmaaddrlow;
8725 mptsas_cmd_t *c;
8726
8727 NDBG1(("mptsas_start_cmd: cmd=0x%p, flags 0x%x", (void *)cmd,
8728 cmd->cmd_flags));
8729
8730 /*
8731 * Set SMID and increment index. Rollover to 1 instead of 0 if index
8732 * is at the max. 0 is an invalid SMID, so we call the first index 1.
8733 */
8734 SMID = cmd->cmd_slot;
8735
8736 /*
8737 * It is possible for back to back device reset to
8738 * happen before the reset delay has expired. That's
8739 * ok, just let the device reset go out on the bus.
8740 */
8741 if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) {
8742 ASSERT(ptgt->m_reset_delay == 0);
8743 }
8744
8745 /*
8746 * if a non-tagged cmd is submitted to an active tagged target
8747 * then drain before submitting this cmd; SCSI-2 allows RQSENSE
8748 * to be untagged
8749 */
8750 if (((cmd->cmd_pkt_flags & FLAG_TAGMASK) == 0) &&
8751 (ptgt->m_t_ncmds > 1) &&
8752 ((cmd->cmd_flags & CFLAG_TM_CMD) == 0) &&
8753 (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE)) {
8754 if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) {
8755 NDBG23(("target=%d, untagged cmd, start draining\n",
8756 ptgt->m_devhdl));
8757
8758 if (ptgt->m_reset_delay == 0) {
8759 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
8760 }
8761
8762 mptsas_remove_cmd(mpt, cmd);
8763 cmd->cmd_pkt_flags |= FLAG_HEAD;
8764 mptsas_waitq_add(mpt, cmd);
8765 }
8766 return (DDI_FAILURE);
8767 }
8768
8769 /*
8770 * Set correct tag bits.
8771 */
8772 if (cmd->cmd_pkt_flags & FLAG_TAGMASK) {
8773 switch (mptsas_tag_lookup[((cmd->cmd_pkt_flags &
8774 FLAG_TAGMASK) >> 12)]) {
8775 case MSG_SIMPLE_QTAG:
8776 control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
8777 break;
8778 case MSG_HEAD_QTAG:
8779 control |= MPI2_SCSIIO_CONTROL_HEADOFQ;
8780 break;
8781 case MSG_ORDERED_QTAG:
8782 control |= MPI2_SCSIIO_CONTROL_ORDEREDQ;
8783 break;
8784 default:
8785 mptsas_log(mpt, CE_WARN, "mpt: Invalid tag type\n");
8786 break;
8787 }
8788 } else {
8789 if (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE) {
8790 ptgt->m_t_throttle = 1;
8791 }
8792 control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
8793 }
8794
8795 if (cmd->cmd_pkt_flags & FLAG_TLR) {
8796 control |= MPI2_SCSIIO_CONTROL_TLR_ON;
8797 }
8798
8799 mem = mpt->m_req_frame + (mpt->m_req_frame_size * SMID);
8800 io_request = (pMpi2SCSIIORequest_t)mem;
8801 if (cmd->cmd_extrqslen != 0) {
8802 /*
8803 * Mapping of the buffer was done in mptsas_pkt_alloc_extern().
8804 * Calculate the DMA address with the same offset.
8805 */
8806 arsbuf = cmd->cmd_arq_buf;
8807 ars_size = cmd->cmd_extrqslen;
8808 ars_dmaaddrlow = (mpt->m_req_sense_dma_addr +
8809 ((uintptr_t)arsbuf - (uintptr_t)mpt->m_req_sense)) &
8810 0xffffffffu;
8811 } else {
8812 arsbuf = mpt->m_req_sense + (mpt->m_req_sense_size * (SMID-1));
8813 cmd->cmd_arq_buf = arsbuf;
8814 ars_size = mpt->m_req_sense_size;
8815 ars_dmaaddrlow = (mpt->m_req_sense_dma_addr +
8816 (mpt->m_req_sense_size * (SMID-1))) &
8817 0xffffffffu;
8818 }
8819 bzero(io_request, sizeof (Mpi2SCSIIORequest_t));
8820 bzero(arsbuf, ars_size);
8821
8822 ddi_put8(acc_hdl, &io_request->SGLOffset0, offsetof
8823 (MPI2_SCSI_IO_REQUEST, SGL) / 4);
8824 mptsas_init_std_hdr(acc_hdl, io_request, ptgt->m_devhdl, Lun(cmd), 0,
8825 MPI2_FUNCTION_SCSI_IO_REQUEST);
8826
8827 (void) ddi_rep_put8(acc_hdl, (uint8_t *)pkt->pkt_cdbp,
8828 io_request->CDB.CDB32, cmd->cmd_cdblen, DDI_DEV_AUTOINCR);
8829
8830 io_flags = cmd->cmd_cdblen;
8831 if (mptsas_use_fastpath &&
8832 ptgt->m_io_flags & MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH) {
8833 io_flags |= MPI25_SCSIIO_IOFLAGS_FAST_PATH;
8834 request_desc = MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO;
8835 } else {
8836 request_desc = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO;
8837 }
8838 ddi_put16(acc_hdl, &io_request->IoFlags, io_flags);
8839 /*
8840 * setup the Scatter/Gather DMA list for this request
8841 */
8842 if (cmd->cmd_cookiec > 0) {
8843 mptsas_sge_setup(mpt, cmd, &control, io_request, acc_hdl);
8844 } else {
8845 ddi_put32(acc_hdl, &io_request->SGL.MpiSimple.FlagsLength,
8846 ((uint32_t)MPI2_SGE_FLAGS_LAST_ELEMENT |
8847 MPI2_SGE_FLAGS_END_OF_BUFFER |
8848 MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
8849 MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT);
8850 }
8851
8852 /*
8853 * save ARQ information
8854 */
8855 ddi_put8(acc_hdl, &io_request->SenseBufferLength, ars_size);
8856 ddi_put32(acc_hdl, &io_request->SenseBufferLowAddress, ars_dmaaddrlow);
8857
8858 ddi_put32(acc_hdl, &io_request->Control, control);
8859
8860 NDBG31(("starting message=%d(0x%p), with cmd=0x%p",
8861 SMID, (void *)io_request, (void *)cmd));
8862
8863 (void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
8864 (void) ddi_dma_sync(mpt->m_dma_req_sense_hdl, 0, 0,
8865 DDI_DMA_SYNC_FORDEV);
8866
8867 /*
8868 * Build request descriptor and write it to the request desc post reg.
8869 */
8870 request_desc |= (SMID << 16);
8871 request_desc |= (uint64_t)ptgt->m_devhdl << 48;
8872 MPTSAS_START_CMD(mpt, request_desc);
8873
8874 /*
8875 * Start timeout.
8876 */
8877 cmd->cmd_active_expiration =
8878 gethrtime() + (hrtime_t)pkt->pkt_time * NANOSEC;
8879 #ifdef MPTSAS_TEST
8880 /*
8881 * Force timeouts to happen immediately.
8882 */
8883 if (mptsas_test_timeouts)
8884 cmd->cmd_active_expiration = gethrtime();
8885 #endif
8886 c = TAILQ_FIRST(&ptgt->m_active_cmdq);
8887 if (c == NULL ||
8888 c->cmd_active_expiration < cmd->cmd_active_expiration) {
8889 /*
8890 * Common case is that this is the last pending expiration
8891 * (or queue is empty). Insert at head of the queue.
8892 */
8893 TAILQ_INSERT_HEAD(&ptgt->m_active_cmdq, cmd, cmd_active_link);
8894 } else {
8895 /*
8896 * Queue is not empty and first element expires later than
8897 * this command. Search for element expiring sooner.
8898 */
8899 while ((c = TAILQ_NEXT(c, cmd_active_link)) != NULL) {
8900 if (c->cmd_active_expiration <
8901 cmd->cmd_active_expiration) {
8902 TAILQ_INSERT_BEFORE(c, cmd, cmd_active_link);
8903 break;
8904 }
8905 }
8906 if (c == NULL) {
8907 /*
8908 * No element found expiring sooner, append to
8909 * non-empty queue.
8910 */
8911 TAILQ_INSERT_TAIL(&ptgt->m_active_cmdq, cmd,
8912 cmd_active_link);
8913 }
8914 }
8915
8916 if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) ||
8917 (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) {
8918 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
8919 return (DDI_FAILURE);
8920 }
8921 return (DDI_SUCCESS);
8922 }
8923
8924 /*
8925 * Select a helper thread to handle current doneq
8926 */
8927 static void
mptsas_deliver_doneq_thread(mptsas_t * mpt)8928 mptsas_deliver_doneq_thread(mptsas_t *mpt)
8929 {
8930 uint64_t t, i;
8931 uint32_t min = 0xffffffff;
8932 mptsas_doneq_thread_list_t *item;
8933
8934 for (i = 0; i < mpt->m_doneq_thread_n; i++) {
8935 item = &mpt->m_doneq_thread_id[i];
8936 /*
8937 * If the completed command on help thread[i] less than
8938 * doneq_thread_threshold, then pick the thread[i]. Otherwise
8939 * pick a thread which has least completed command.
8940 */
8941
8942 mutex_enter(&item->mutex);
8943 if (item->len < mpt->m_doneq_thread_threshold) {
8944 t = i;
8945 mutex_exit(&item->mutex);
8946 break;
8947 }
8948 if (item->len < min) {
8949 min = item->len;
8950 t = i;
8951 }
8952 mutex_exit(&item->mutex);
8953 }
8954 mutex_enter(&mpt->m_doneq_thread_id[t].mutex);
8955 mptsas_doneq_mv(mpt, t);
8956 cv_signal(&mpt->m_doneq_thread_id[t].cv);
8957 mutex_exit(&mpt->m_doneq_thread_id[t].mutex);
8958 }
8959
8960 /*
8961 * move the current global doneq to the doneq of thead[t]
8962 */
8963 static void
mptsas_doneq_mv(mptsas_t * mpt,uint64_t t)8964 mptsas_doneq_mv(mptsas_t *mpt, uint64_t t)
8965 {
8966 mptsas_cmd_t *cmd;
8967 mptsas_doneq_thread_list_t *item = &mpt->m_doneq_thread_id[t];
8968
8969 ASSERT(mutex_owned(&item->mutex));
8970 while ((cmd = mpt->m_doneq) != NULL) {
8971 if ((mpt->m_doneq = cmd->cmd_linkp) == NULL) {
8972 mpt->m_donetail = &mpt->m_doneq;
8973 }
8974 cmd->cmd_linkp = NULL;
8975 *item->donetail = cmd;
8976 item->donetail = &cmd->cmd_linkp;
8977 mpt->m_doneq_len--;
8978 item->len++;
8979 }
8980 }
8981
8982 void
mptsas_fma_check(mptsas_t * mpt,mptsas_cmd_t * cmd)8983 mptsas_fma_check(mptsas_t *mpt, mptsas_cmd_t *cmd)
8984 {
8985 struct scsi_pkt *pkt = CMD2PKT(cmd);
8986
8987 /* Check all acc and dma handles */
8988 if ((mptsas_check_acc_handle(mpt->m_datap) !=
8989 DDI_SUCCESS) ||
8990 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) !=
8991 DDI_SUCCESS) ||
8992 (mptsas_check_acc_handle(mpt->m_acc_req_sense_hdl) !=
8993 DDI_SUCCESS) ||
8994 (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl) !=
8995 DDI_SUCCESS) ||
8996 (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl) !=
8997 DDI_SUCCESS) ||
8998 (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl) !=
8999 DDI_SUCCESS) ||
9000 (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl) !=
9001 DDI_SUCCESS) ||
9002 (mptsas_check_acc_handle(mpt->m_config_handle) !=
9003 DDI_SUCCESS)) {
9004 ddi_fm_service_impact(mpt->m_dip,
9005 DDI_SERVICE_UNAFFECTED);
9006 ddi_fm_acc_err_clear(mpt->m_config_handle,
9007 DDI_FME_VER0);
9008 pkt->pkt_reason = CMD_TRAN_ERR;
9009 pkt->pkt_statistics = 0;
9010 }
9011 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) !=
9012 DDI_SUCCESS) ||
9013 (mptsas_check_dma_handle(mpt->m_dma_req_sense_hdl) !=
9014 DDI_SUCCESS) ||
9015 (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl) !=
9016 DDI_SUCCESS) ||
9017 (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl) !=
9018 DDI_SUCCESS) ||
9019 (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) !=
9020 DDI_SUCCESS) ||
9021 (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl) !=
9022 DDI_SUCCESS)) {
9023 ddi_fm_service_impact(mpt->m_dip,
9024 DDI_SERVICE_UNAFFECTED);
9025 pkt->pkt_reason = CMD_TRAN_ERR;
9026 pkt->pkt_statistics = 0;
9027 }
9028 if (cmd->cmd_dmahandle &&
9029 (mptsas_check_dma_handle(cmd->cmd_dmahandle) != DDI_SUCCESS)) {
9030 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
9031 pkt->pkt_reason = CMD_TRAN_ERR;
9032 pkt->pkt_statistics = 0;
9033 }
9034 if ((cmd->cmd_extra_frames &&
9035 ((mptsas_check_dma_handle(cmd->cmd_extra_frames->m_dma_hdl) !=
9036 DDI_SUCCESS) ||
9037 (mptsas_check_acc_handle(cmd->cmd_extra_frames->m_acc_hdl) !=
9038 DDI_SUCCESS)))) {
9039 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
9040 pkt->pkt_reason = CMD_TRAN_ERR;
9041 pkt->pkt_statistics = 0;
9042 }
9043 }
9044
9045 /*
9046 * These routines manipulate the queue of commands that
9047 * are waiting for their completion routines to be called.
9048 * The queue is usually in FIFO order but on an MP system
9049 * it's possible for the completion routines to get out
9050 * of order. If that's a problem you need to add a global
9051 * mutex around the code that calls the completion routine
9052 * in the interrupt handler.
9053 */
9054 static void
mptsas_doneq_add(mptsas_t * mpt,mptsas_cmd_t * cmd)9055 mptsas_doneq_add(mptsas_t *mpt, mptsas_cmd_t *cmd)
9056 {
9057 struct scsi_pkt *pkt = CMD2PKT(cmd);
9058
9059 NDBG31(("mptsas_doneq_add: cmd=0x%p", (void *)cmd));
9060
9061 ASSERT((cmd->cmd_flags & CFLAG_COMPLETED) == 0);
9062 cmd->cmd_linkp = NULL;
9063 cmd->cmd_flags |= CFLAG_FINISHED;
9064 cmd->cmd_flags &= ~CFLAG_IN_TRANSPORT;
9065
9066 mptsas_fma_check(mpt, cmd);
9067
9068 /*
9069 * only add scsi pkts that have completion routines to
9070 * the doneq. no intr cmds do not have callbacks.
9071 */
9072 if (pkt && (pkt->pkt_comp)) {
9073 *mpt->m_donetail = cmd;
9074 mpt->m_donetail = &cmd->cmd_linkp;
9075 mpt->m_doneq_len++;
9076 }
9077 }
9078
9079 static mptsas_cmd_t *
mptsas_doneq_thread_rm(mptsas_t * mpt,uint64_t t)9080 mptsas_doneq_thread_rm(mptsas_t *mpt, uint64_t t)
9081 {
9082 mptsas_cmd_t *cmd;
9083 mptsas_doneq_thread_list_t *item = &mpt->m_doneq_thread_id[t];
9084
9085 /* pop one off the done queue */
9086 if ((cmd = item->doneq) != NULL) {
9087 /* if the queue is now empty fix the tail pointer */
9088 NDBG31(("mptsas_doneq_thread_rm: cmd=0x%p", (void *)cmd));
9089 if ((item->doneq = cmd->cmd_linkp) == NULL) {
9090 item->donetail = &item->doneq;
9091 }
9092 cmd->cmd_linkp = NULL;
9093 item->len--;
9094 }
9095 return (cmd);
9096 }
9097
9098 static void
mptsas_doneq_empty(mptsas_t * mpt)9099 mptsas_doneq_empty(mptsas_t *mpt)
9100 {
9101 if (mpt->m_doneq && !mpt->m_in_callback) {
9102 mptsas_cmd_t *cmd, *next;
9103 struct scsi_pkt *pkt;
9104
9105 mpt->m_in_callback = 1;
9106 cmd = mpt->m_doneq;
9107 mpt->m_doneq = NULL;
9108 mpt->m_donetail = &mpt->m_doneq;
9109 mpt->m_doneq_len = 0;
9110
9111 mutex_exit(&mpt->m_mutex);
9112 /*
9113 * run the completion routines of all the
9114 * completed commands
9115 */
9116 while (cmd != NULL) {
9117 next = cmd->cmd_linkp;
9118 cmd->cmd_linkp = NULL;
9119 /* run this command's completion routine */
9120 cmd->cmd_flags |= CFLAG_COMPLETED;
9121 pkt = CMD2PKT(cmd);
9122 mptsas_pkt_comp(pkt, cmd);
9123 cmd = next;
9124 }
9125 mutex_enter(&mpt->m_mutex);
9126 mpt->m_in_callback = 0;
9127 }
9128 }
9129
9130 /*
9131 * These routines manipulate the target's queue of pending requests
9132 */
9133 void
mptsas_waitq_add(mptsas_t * mpt,mptsas_cmd_t * cmd)9134 mptsas_waitq_add(mptsas_t *mpt, mptsas_cmd_t *cmd)
9135 {
9136 NDBG7(("mptsas_waitq_add: cmd=0x%p", (void *)cmd));
9137 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
9138 cmd->cmd_queued = TRUE;
9139 if (ptgt)
9140 ptgt->m_t_nwait++;
9141 if (cmd->cmd_pkt_flags & FLAG_HEAD) {
9142 if ((cmd->cmd_linkp = mpt->m_waitq) == NULL) {
9143 mpt->m_waitqtail = &cmd->cmd_linkp;
9144 }
9145 mpt->m_waitq = cmd;
9146 } else {
9147 cmd->cmd_linkp = NULL;
9148 *(mpt->m_waitqtail) = cmd;
9149 mpt->m_waitqtail = &cmd->cmd_linkp;
9150 }
9151 }
9152
9153 static mptsas_cmd_t *
mptsas_waitq_rm(mptsas_t * mpt)9154 mptsas_waitq_rm(mptsas_t *mpt)
9155 {
9156 mptsas_cmd_t *cmd;
9157 mptsas_target_t *ptgt;
9158 NDBG7(("mptsas_waitq_rm"));
9159
9160 MPTSAS_WAITQ_RM(mpt, cmd);
9161
9162 NDBG7(("mptsas_waitq_rm: cmd=0x%p", (void *)cmd));
9163 if (cmd) {
9164 ptgt = cmd->cmd_tgt_addr;
9165 if (ptgt) {
9166 ptgt->m_t_nwait--;
9167 ASSERT(ptgt->m_t_nwait >= 0);
9168 }
9169 }
9170 return (cmd);
9171 }
9172
9173 /*
9174 * remove specified cmd from the middle of the wait queue.
9175 */
9176 static void
mptsas_waitq_delete(mptsas_t * mpt,mptsas_cmd_t * cmd)9177 mptsas_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd)
9178 {
9179 mptsas_cmd_t *prevp = mpt->m_waitq;
9180 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
9181
9182 NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p",
9183 (void *)mpt, (void *)cmd));
9184 if (ptgt) {
9185 ptgt->m_t_nwait--;
9186 ASSERT(ptgt->m_t_nwait >= 0);
9187 }
9188
9189 if (prevp == cmd) {
9190 if ((mpt->m_waitq = cmd->cmd_linkp) == NULL)
9191 mpt->m_waitqtail = &mpt->m_waitq;
9192
9193 cmd->cmd_linkp = NULL;
9194 cmd->cmd_queued = FALSE;
9195 NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p",
9196 (void *)mpt, (void *)cmd));
9197 return;
9198 }
9199
9200 while (prevp != NULL) {
9201 if (prevp->cmd_linkp == cmd) {
9202 if ((prevp->cmd_linkp = cmd->cmd_linkp) == NULL)
9203 mpt->m_waitqtail = &prevp->cmd_linkp;
9204
9205 cmd->cmd_linkp = NULL;
9206 cmd->cmd_queued = FALSE;
9207 NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p",
9208 (void *)mpt, (void *)cmd));
9209 return;
9210 }
9211 prevp = prevp->cmd_linkp;
9212 }
9213 cmn_err(CE_PANIC, "mpt: mptsas_waitq_delete: queue botch");
9214 }
9215
9216 static mptsas_cmd_t *
mptsas_tx_waitq_rm(mptsas_t * mpt)9217 mptsas_tx_waitq_rm(mptsas_t *mpt)
9218 {
9219 mptsas_cmd_t *cmd;
9220 NDBG7(("mptsas_tx_waitq_rm"));
9221
9222 MPTSAS_TX_WAITQ_RM(mpt, cmd);
9223
9224 NDBG7(("mptsas_tx_waitq_rm: cmd=0x%p", (void *)cmd));
9225
9226 return (cmd);
9227 }
9228
9229 /*
9230 * remove specified cmd from the middle of the tx_waitq.
9231 */
9232 static void
mptsas_tx_waitq_delete(mptsas_t * mpt,mptsas_cmd_t * cmd)9233 mptsas_tx_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd)
9234 {
9235 mptsas_cmd_t *prevp = mpt->m_tx_waitq;
9236
9237 NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p",
9238 (void *)mpt, (void *)cmd));
9239
9240 if (prevp == cmd) {
9241 if ((mpt->m_tx_waitq = cmd->cmd_linkp) == NULL)
9242 mpt->m_tx_waitqtail = &mpt->m_tx_waitq;
9243
9244 cmd->cmd_linkp = NULL;
9245 cmd->cmd_queued = FALSE;
9246 NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p",
9247 (void *)mpt, (void *)cmd));
9248 return;
9249 }
9250
9251 while (prevp != NULL) {
9252 if (prevp->cmd_linkp == cmd) {
9253 if ((prevp->cmd_linkp = cmd->cmd_linkp) == NULL)
9254 mpt->m_tx_waitqtail = &prevp->cmd_linkp;
9255
9256 cmd->cmd_linkp = NULL;
9257 cmd->cmd_queued = FALSE;
9258 NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p",
9259 (void *)mpt, (void *)cmd));
9260 return;
9261 }
9262 prevp = prevp->cmd_linkp;
9263 }
9264 cmn_err(CE_PANIC, "mpt: mptsas_tx_waitq_delete: queue botch");
9265 }
9266
9267 /*
9268 * device and bus reset handling
9269 *
9270 * Notes:
9271 * - RESET_ALL: reset the controller
9272 * - RESET_TARGET: reset the target specified in scsi_address
9273 */
9274 static int
mptsas_scsi_reset(struct scsi_address * ap,int level)9275 mptsas_scsi_reset(struct scsi_address *ap, int level)
9276 {
9277 mptsas_t *mpt = ADDR2MPT(ap);
9278 int rval;
9279 mptsas_tgt_private_t *tgt_private;
9280 mptsas_target_t *ptgt = NULL;
9281
9282 tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran->tran_tgt_private;
9283 ptgt = tgt_private->t_private;
9284 if (ptgt == NULL) {
9285 return (FALSE);
9286 }
9287 NDBG22(("mptsas_scsi_reset: target=%d level=%d", ptgt->m_devhdl,
9288 level));
9289
9290 mutex_enter(&mpt->m_mutex);
9291 /*
9292 * if we are not in panic set up a reset delay for this target
9293 */
9294 if (!ddi_in_panic()) {
9295 mptsas_setup_bus_reset_delay(mpt);
9296 } else {
9297 drv_usecwait(mpt->m_scsi_reset_delay * 1000);
9298 }
9299 rval = mptsas_do_scsi_reset(mpt, ptgt->m_devhdl);
9300 mutex_exit(&mpt->m_mutex);
9301
9302 /*
9303 * The transport layer expect to only see TRUE and
9304 * FALSE. Therefore, we will adjust the return value
9305 * if mptsas_do_scsi_reset returns FAILED.
9306 */
9307 if (rval == FAILED)
9308 rval = FALSE;
9309 return (rval);
9310 }
9311
9312 static int
mptsas_do_scsi_reset(mptsas_t * mpt,uint16_t devhdl)9313 mptsas_do_scsi_reset(mptsas_t *mpt, uint16_t devhdl)
9314 {
9315 int rval = FALSE;
9316 uint8_t config, disk;
9317
9318 ASSERT(mutex_owned(&mpt->m_mutex));
9319
9320 if (mptsas_debug_resets) {
9321 mptsas_log(mpt, CE_WARN, "mptsas_do_scsi_reset: target=%d",
9322 devhdl);
9323 }
9324
9325 /*
9326 * Issue a Target Reset message to the target specified but not to a
9327 * disk making up a raid volume. Just look through the RAID config
9328 * Phys Disk list of DevHandles. If the target's DevHandle is in this
9329 * list, then don't reset this target.
9330 */
9331 for (config = 0; config < mpt->m_num_raid_configs; config++) {
9332 for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) {
9333 if (devhdl == mpt->m_raidconfig[config].
9334 m_physdisk_devhdl[disk]) {
9335 return (TRUE);
9336 }
9337 }
9338 }
9339
9340 rval = mptsas_ioc_task_management(mpt,
9341 MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, devhdl, 0, NULL, 0, 0);
9342
9343 mptsas_doneq_empty(mpt);
9344 return (rval);
9345 }
9346
9347 static int
mptsas_scsi_reset_notify(struct scsi_address * ap,int flag,void (* callback)(caddr_t),caddr_t arg)9348 mptsas_scsi_reset_notify(struct scsi_address *ap, int flag,
9349 void (*callback)(caddr_t), caddr_t arg)
9350 {
9351 mptsas_t *mpt = ADDR2MPT(ap);
9352
9353 NDBG22(("mptsas_scsi_reset_notify: tgt=%d", ap->a_target));
9354
9355 return (scsi_hba_reset_notify_setup(ap, flag, callback, arg,
9356 &mpt->m_mutex, &mpt->m_reset_notify_listf));
9357 }
9358
9359 static int
mptsas_get_name(struct scsi_device * sd,char * name,int len)9360 mptsas_get_name(struct scsi_device *sd, char *name, int len)
9361 {
9362 dev_info_t *lun_dip = NULL;
9363
9364 ASSERT(sd != NULL);
9365 ASSERT(name != NULL);
9366 lun_dip = sd->sd_dev;
9367 ASSERT(lun_dip != NULL);
9368
9369 if (mptsas_name_child(lun_dip, name, len) == DDI_SUCCESS) {
9370 return (1);
9371 } else {
9372 return (0);
9373 }
9374 }
9375
9376 static int
mptsas_get_bus_addr(struct scsi_device * sd,char * name,int len)9377 mptsas_get_bus_addr(struct scsi_device *sd, char *name, int len)
9378 {
9379 return (mptsas_get_name(sd, name, len));
9380 }
9381
9382 void
mptsas_set_throttle(mptsas_t * mpt,mptsas_target_t * ptgt,int what)9383 mptsas_set_throttle(mptsas_t *mpt, mptsas_target_t *ptgt, int what)
9384 {
9385
9386 NDBG25(("mptsas_set_throttle: throttle=%x", what));
9387
9388 /*
9389 * if the bus is draining/quiesced, no changes to the throttles
9390 * are allowed. Not allowing change of throttles during draining
9391 * limits error recovery but will reduce draining time
9392 *
9393 * all throttles should have been set to HOLD_THROTTLE
9394 */
9395 if (mpt->m_softstate & (MPTSAS_SS_QUIESCED | MPTSAS_SS_DRAINING)) {
9396 return;
9397 }
9398
9399 if (what == HOLD_THROTTLE) {
9400 ptgt->m_t_throttle = HOLD_THROTTLE;
9401 } else if (ptgt->m_reset_delay == 0) {
9402 ptgt->m_t_throttle = what;
9403 }
9404 }
9405
9406 /*
9407 * Clean up from a device reset.
9408 * For the case of target reset, this function clears the waitq of all
9409 * commands for a particular target. For the case of abort task set, this
9410 * function clears the waitq of all commonds for a particular target/lun.
9411 */
9412 static void
mptsas_flush_target(mptsas_t * mpt,ushort_t target,int lun,uint8_t tasktype)9413 mptsas_flush_target(mptsas_t *mpt, ushort_t target, int lun, uint8_t tasktype)
9414 {
9415 mptsas_slots_t *slots = mpt->m_active;
9416 mptsas_cmd_t *cmd, *next_cmd;
9417 int slot;
9418 uchar_t reason;
9419 uint_t stat;
9420 hrtime_t timestamp;
9421
9422 NDBG25(("mptsas_flush_target: target=%d lun=%d", target, lun));
9423
9424 timestamp = gethrtime();
9425
9426 /*
9427 * Make sure the I/O Controller has flushed all cmds
9428 * that are associated with this target for a target reset
9429 * and target/lun for abort task set.
9430 * Account for TM requests, which use the last SMID.
9431 */
9432 for (slot = 0; slot <= mpt->m_active->m_n_normal; slot++) {
9433 if ((cmd = slots->m_slot[slot]) == NULL)
9434 continue;
9435 reason = CMD_RESET;
9436 stat = STAT_DEV_RESET;
9437 switch (tasktype) {
9438 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
9439 if (Tgt(cmd) == target) {
9440 if (cmd->cmd_active_expiration <= timestamp) {
9441 /*
9442 * When timeout requested, propagate
9443 * proper reason and statistics to
9444 * target drivers.
9445 */
9446 reason = CMD_TIMEOUT;
9447 stat |= STAT_TIMEOUT;
9448 }
9449 NDBG25(("mptsas_flush_target discovered non-"
9450 "NULL cmd in slot %d, tasktype 0x%x", slot,
9451 tasktype));
9452 mptsas_dump_cmd(mpt, cmd);
9453 mptsas_remove_cmd(mpt, cmd);
9454 mptsas_set_pkt_reason(mpt, cmd, reason, stat);
9455 mptsas_doneq_add(mpt, cmd);
9456 }
9457 break;
9458 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
9459 reason = CMD_ABORTED;
9460 stat = STAT_ABORTED;
9461 /*FALLTHROUGH*/
9462 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
9463 if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) {
9464
9465 NDBG25(("mptsas_flush_target discovered non-"
9466 "NULL cmd in slot %d, tasktype 0x%x", slot,
9467 tasktype));
9468 mptsas_dump_cmd(mpt, cmd);
9469 mptsas_remove_cmd(mpt, cmd);
9470 mptsas_set_pkt_reason(mpt, cmd, reason,
9471 stat);
9472 mptsas_doneq_add(mpt, cmd);
9473 }
9474 break;
9475 default:
9476 break;
9477 }
9478 }
9479
9480 /*
9481 * Flush the waitq and tx_waitq of this target's cmds
9482 */
9483 cmd = mpt->m_waitq;
9484
9485 reason = CMD_RESET;
9486 stat = STAT_DEV_RESET;
9487
9488 switch (tasktype) {
9489 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
9490 while (cmd != NULL) {
9491 next_cmd = cmd->cmd_linkp;
9492 if (Tgt(cmd) == target) {
9493 mptsas_waitq_delete(mpt, cmd);
9494 mptsas_set_pkt_reason(mpt, cmd,
9495 reason, stat);
9496 mptsas_doneq_add(mpt, cmd);
9497 }
9498 cmd = next_cmd;
9499 }
9500 mutex_enter(&mpt->m_tx_waitq_mutex);
9501 cmd = mpt->m_tx_waitq;
9502 while (cmd != NULL) {
9503 next_cmd = cmd->cmd_linkp;
9504 if (Tgt(cmd) == target) {
9505 mptsas_tx_waitq_delete(mpt, cmd);
9506 mutex_exit(&mpt->m_tx_waitq_mutex);
9507 mptsas_set_pkt_reason(mpt, cmd,
9508 reason, stat);
9509 mptsas_doneq_add(mpt, cmd);
9510 mutex_enter(&mpt->m_tx_waitq_mutex);
9511 }
9512 cmd = next_cmd;
9513 }
9514 mutex_exit(&mpt->m_tx_waitq_mutex);
9515 break;
9516 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
9517 reason = CMD_ABORTED;
9518 stat = STAT_ABORTED;
9519 /*FALLTHROUGH*/
9520 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
9521 while (cmd != NULL) {
9522 next_cmd = cmd->cmd_linkp;
9523 if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) {
9524 mptsas_waitq_delete(mpt, cmd);
9525 mptsas_set_pkt_reason(mpt, cmd,
9526 reason, stat);
9527 mptsas_doneq_add(mpt, cmd);
9528 }
9529 cmd = next_cmd;
9530 }
9531 mutex_enter(&mpt->m_tx_waitq_mutex);
9532 cmd = mpt->m_tx_waitq;
9533 while (cmd != NULL) {
9534 next_cmd = cmd->cmd_linkp;
9535 if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) {
9536 mptsas_tx_waitq_delete(mpt, cmd);
9537 mutex_exit(&mpt->m_tx_waitq_mutex);
9538 mptsas_set_pkt_reason(mpt, cmd,
9539 reason, stat);
9540 mptsas_doneq_add(mpt, cmd);
9541 mutex_enter(&mpt->m_tx_waitq_mutex);
9542 }
9543 cmd = next_cmd;
9544 }
9545 mutex_exit(&mpt->m_tx_waitq_mutex);
9546 break;
9547 default:
9548 mptsas_log(mpt, CE_WARN, "Unknown task management type %d.",
9549 tasktype);
9550 break;
9551 }
9552 }
9553
9554 /*
9555 * Clean up hba state, abort all outstanding command and commands in waitq
9556 * reset timeout of all targets.
9557 */
9558 static void
mptsas_flush_hba(mptsas_t * mpt)9559 mptsas_flush_hba(mptsas_t *mpt)
9560 {
9561 mptsas_slots_t *slots = mpt->m_active;
9562 mptsas_cmd_t *cmd;
9563 int slot;
9564
9565 NDBG25(("mptsas_flush_hba"));
9566
9567 /*
9568 * The I/O Controller should have already sent back
9569 * all commands via the scsi I/O reply frame. Make
9570 * sure all commands have been flushed.
9571 * Account for TM request, which use the last SMID.
9572 */
9573 for (slot = 0; slot <= mpt->m_active->m_n_normal; slot++) {
9574 if ((cmd = slots->m_slot[slot]) == NULL)
9575 continue;
9576
9577 if (cmd->cmd_flags & CFLAG_CMDIOC) {
9578 /*
9579 * Need to make sure to tell everyone that might be
9580 * waiting on this command that it's going to fail. If
9581 * we get here, this command will never timeout because
9582 * the active command table is going to be re-allocated,
9583 * so there will be nothing to check against a time out.
9584 * Instead, mark the command as failed due to reset.
9585 */
9586 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET,
9587 STAT_BUS_RESET);
9588 if ((cmd->cmd_flags &
9589 (CFLAG_PASSTHRU | CFLAG_CONFIG | CFLAG_FW_DIAG))) {
9590 cmd->cmd_flags |= CFLAG_FINISHED;
9591 cv_broadcast(&mpt->m_passthru_cv);
9592 cv_broadcast(&mpt->m_config_cv);
9593 cv_broadcast(&mpt->m_fw_diag_cv);
9594 }
9595 continue;
9596 }
9597
9598 NDBG25(("mptsas_flush_hba discovered non-NULL cmd in slot %d",
9599 slot));
9600 mptsas_dump_cmd(mpt, cmd);
9601
9602 mptsas_remove_cmd(mpt, cmd);
9603 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET);
9604 mptsas_doneq_add(mpt, cmd);
9605 }
9606
9607 /*
9608 * Flush the waitq.
9609 */
9610 while ((cmd = mptsas_waitq_rm(mpt)) != NULL) {
9611 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET);
9612 if ((cmd->cmd_flags & CFLAG_PASSTHRU) ||
9613 (cmd->cmd_flags & CFLAG_CONFIG) ||
9614 (cmd->cmd_flags & CFLAG_FW_DIAG)) {
9615 cmd->cmd_flags |= CFLAG_FINISHED;
9616 cv_broadcast(&mpt->m_passthru_cv);
9617 cv_broadcast(&mpt->m_config_cv);
9618 cv_broadcast(&mpt->m_fw_diag_cv);
9619 } else {
9620 mptsas_doneq_add(mpt, cmd);
9621 }
9622 }
9623
9624 /*
9625 * Flush the tx_waitq
9626 */
9627 mutex_enter(&mpt->m_tx_waitq_mutex);
9628 while ((cmd = mptsas_tx_waitq_rm(mpt)) != NULL) {
9629 mutex_exit(&mpt->m_tx_waitq_mutex);
9630 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET);
9631 mptsas_doneq_add(mpt, cmd);
9632 mutex_enter(&mpt->m_tx_waitq_mutex);
9633 }
9634 mutex_exit(&mpt->m_tx_waitq_mutex);
9635
9636 /*
9637 * Drain the taskqs prior to reallocating resources. The thread
9638 * passing through here could be launched from either (dr)
9639 * or (event) taskqs so only wait on the 'other' queue since
9640 * waiting on 'this' queue is a deadlock condition.
9641 */
9642 mutex_exit(&mpt->m_mutex);
9643 if (!taskq_member((taskq_t *)mpt->m_event_taskq, curthread))
9644 ddi_taskq_wait(mpt->m_event_taskq);
9645 if (!taskq_member((taskq_t *)mpt->m_dr_taskq, curthread))
9646 ddi_taskq_wait(mpt->m_dr_taskq);
9647
9648 mutex_enter(&mpt->m_mutex);
9649 }
9650
9651 /*
9652 * set pkt_reason and OR in pkt_statistics flag
9653 */
9654 static void
mptsas_set_pkt_reason(mptsas_t * mpt,mptsas_cmd_t * cmd,uchar_t reason,uint_t stat)9655 mptsas_set_pkt_reason(mptsas_t *mpt, mptsas_cmd_t *cmd, uchar_t reason,
9656 uint_t stat)
9657 {
9658 #ifndef __lock_lint
9659 _NOTE(ARGUNUSED(mpt))
9660 #endif
9661
9662 NDBG25(("mptsas_set_pkt_reason: cmd=0x%p reason=%x stat=%x",
9663 (void *)cmd, reason, stat));
9664
9665 if (cmd) {
9666 if (cmd->cmd_pkt->pkt_reason == CMD_CMPLT) {
9667 cmd->cmd_pkt->pkt_reason = reason;
9668 }
9669 cmd->cmd_pkt->pkt_statistics |= stat;
9670 }
9671 }
9672
9673 static void
mptsas_start_watch_reset_delay()9674 mptsas_start_watch_reset_delay()
9675 {
9676 NDBG22(("mptsas_start_watch_reset_delay"));
9677
9678 mutex_enter(&mptsas_global_mutex);
9679 if (mptsas_reset_watch == NULL && mptsas_timeouts_enabled) {
9680 mptsas_reset_watch = timeout(mptsas_watch_reset_delay, NULL,
9681 drv_usectohz((clock_t)
9682 MPTSAS_WATCH_RESET_DELAY_TICK * 1000));
9683 ASSERT(mptsas_reset_watch != NULL);
9684 }
9685 mutex_exit(&mptsas_global_mutex);
9686 }
9687
9688 static void
mptsas_setup_bus_reset_delay(mptsas_t * mpt)9689 mptsas_setup_bus_reset_delay(mptsas_t *mpt)
9690 {
9691 mptsas_target_t *ptgt = NULL;
9692
9693 ASSERT(MUTEX_HELD(&mpt->m_mutex));
9694
9695 NDBG22(("mptsas_setup_bus_reset_delay"));
9696 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
9697 ptgt = refhash_next(mpt->m_targets, ptgt)) {
9698 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
9699 ptgt->m_reset_delay = mpt->m_scsi_reset_delay;
9700 }
9701
9702 mptsas_start_watch_reset_delay();
9703 }
9704
9705 /*
9706 * mptsas_watch_reset_delay(_subr) is invoked by timeout() and checks every
9707 * mpt instance for active reset delays
9708 */
9709 static void
mptsas_watch_reset_delay(void * arg)9710 mptsas_watch_reset_delay(void *arg)
9711 {
9712 #ifndef __lock_lint
9713 _NOTE(ARGUNUSED(arg))
9714 #endif
9715
9716 mptsas_t *mpt;
9717 int not_done = 0;
9718
9719 NDBG22(("mptsas_watch_reset_delay"));
9720
9721 mutex_enter(&mptsas_global_mutex);
9722 mptsas_reset_watch = 0;
9723 mutex_exit(&mptsas_global_mutex);
9724 rw_enter(&mptsas_global_rwlock, RW_READER);
9725 for (mpt = mptsas_head; mpt != NULL; mpt = mpt->m_next) {
9726 if (mpt->m_tran == 0) {
9727 continue;
9728 }
9729 mutex_enter(&mpt->m_mutex);
9730 not_done += mptsas_watch_reset_delay_subr(mpt);
9731 mutex_exit(&mpt->m_mutex);
9732 }
9733 rw_exit(&mptsas_global_rwlock);
9734
9735 if (not_done) {
9736 mptsas_start_watch_reset_delay();
9737 }
9738 }
9739
9740 static int
mptsas_watch_reset_delay_subr(mptsas_t * mpt)9741 mptsas_watch_reset_delay_subr(mptsas_t *mpt)
9742 {
9743 int done = 0;
9744 int restart = 0;
9745 mptsas_target_t *ptgt = NULL;
9746
9747 NDBG22(("mptsas_watch_reset_delay_subr: mpt=0x%p", (void *)mpt));
9748
9749 ASSERT(mutex_owned(&mpt->m_mutex));
9750
9751 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
9752 ptgt = refhash_next(mpt->m_targets, ptgt)) {
9753 if (ptgt->m_reset_delay != 0) {
9754 ptgt->m_reset_delay -=
9755 MPTSAS_WATCH_RESET_DELAY_TICK;
9756 if (ptgt->m_reset_delay <= 0) {
9757 ptgt->m_reset_delay = 0;
9758 mptsas_set_throttle(mpt, ptgt,
9759 MAX_THROTTLE);
9760 restart++;
9761 } else {
9762 done = -1;
9763 }
9764 }
9765 }
9766
9767 if (restart > 0) {
9768 mptsas_restart_hba(mpt);
9769 }
9770 return (done);
9771 }
9772
9773 #ifdef MPTSAS_TEST
9774 static void
mptsas_test_reset(mptsas_t * mpt,int target)9775 mptsas_test_reset(mptsas_t *mpt, int target)
9776 {
9777 mptsas_target_t *ptgt = NULL;
9778
9779 if (mptsas_rtest == target) {
9780 if (mptsas_do_scsi_reset(mpt, target) == TRUE) {
9781 mptsas_rtest = -1;
9782 }
9783 if (mptsas_rtest == -1) {
9784 NDBG22(("mptsas_test_reset success"));
9785 }
9786 }
9787 }
9788 #endif
9789
9790 /*
9791 * abort handling:
9792 *
9793 * Notes:
9794 * - if pkt is not NULL, abort just that command
9795 * - if pkt is NULL, abort all outstanding commands for target
9796 */
9797 static int
mptsas_scsi_abort(struct scsi_address * ap,struct scsi_pkt * pkt)9798 mptsas_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt)
9799 {
9800 mptsas_t *mpt = ADDR2MPT(ap);
9801 int rval;
9802 mptsas_tgt_private_t *tgt_private;
9803 int target, lun;
9804
9805 tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran->
9806 tran_tgt_private;
9807 ASSERT(tgt_private != NULL);
9808 target = tgt_private->t_private->m_devhdl;
9809 lun = tgt_private->t_lun;
9810
9811 NDBG23(("mptsas_scsi_abort: target=%d.%d", target, lun));
9812
9813 mutex_enter(&mpt->m_mutex);
9814 rval = mptsas_do_scsi_abort(mpt, target, lun, pkt);
9815 mutex_exit(&mpt->m_mutex);
9816 return (rval);
9817 }
9818
9819 static int
mptsas_do_scsi_abort(mptsas_t * mpt,int target,int lun,struct scsi_pkt * pkt)9820 mptsas_do_scsi_abort(mptsas_t *mpt, int target, int lun, struct scsi_pkt *pkt)
9821 {
9822 mptsas_cmd_t *sp = NULL;
9823 mptsas_slots_t *slots = mpt->m_active;
9824 int rval = FALSE;
9825
9826 ASSERT(mutex_owned(&mpt->m_mutex));
9827
9828 /*
9829 * Abort the command pkt on the target/lun in ap. If pkt is
9830 * NULL, abort all outstanding commands on that target/lun.
9831 * If you can abort them, return 1, else return 0.
9832 * Each packet that's aborted should be sent back to the target
9833 * driver through the callback routine, with pkt_reason set to
9834 * CMD_ABORTED.
9835 *
9836 * abort cmd pkt on HBA hardware; clean out of outstanding
9837 * command lists, etc.
9838 */
9839 if (pkt != NULL) {
9840 /* abort the specified packet */
9841 sp = PKT2CMD(pkt);
9842
9843 if (sp->cmd_queued) {
9844 NDBG23(("mptsas_do_scsi_abort: queued sp=0x%p aborted",
9845 (void *)sp));
9846 mptsas_waitq_delete(mpt, sp);
9847 mptsas_set_pkt_reason(mpt, sp, CMD_ABORTED,
9848 STAT_ABORTED);
9849 mptsas_doneq_add(mpt, sp);
9850 rval = TRUE;
9851 goto done;
9852 }
9853
9854 /*
9855 * Have mpt firmware abort this command
9856 */
9857
9858 if (slots->m_slot[sp->cmd_slot] != NULL) {
9859 rval = mptsas_ioc_task_management(mpt,
9860 MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, target,
9861 lun, NULL, 0, 0);
9862
9863 /*
9864 * The transport layer expects only TRUE and FALSE.
9865 * Therefore, if mptsas_ioc_task_management returns
9866 * FAILED we will return FALSE.
9867 */
9868 if (rval == FAILED)
9869 rval = FALSE;
9870 goto done;
9871 }
9872 }
9873
9874 /*
9875 * If pkt is NULL then abort task set
9876 */
9877 rval = mptsas_ioc_task_management(mpt,
9878 MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET, target, lun, NULL, 0, 0);
9879
9880 /*
9881 * The transport layer expects only TRUE and FALSE.
9882 * Therefore, if mptsas_ioc_task_management returns
9883 * FAILED we will return FALSE.
9884 */
9885 if (rval == FAILED)
9886 rval = FALSE;
9887
9888 #ifdef MPTSAS_TEST
9889 if (rval && mptsas_test_stop) {
9890 debug_enter("mptsas_do_scsi_abort");
9891 }
9892 #endif
9893
9894 done:
9895 mptsas_doneq_empty(mpt);
9896 return (rval);
9897 }
9898
9899 /*
9900 * capability handling:
9901 * (*tran_getcap). Get the capability named, and return its value.
9902 */
9903 static int
mptsas_scsi_getcap(struct scsi_address * ap,char * cap,int tgtonly)9904 mptsas_scsi_getcap(struct scsi_address *ap, char *cap, int tgtonly)
9905 {
9906 mptsas_t *mpt = ADDR2MPT(ap);
9907 int ckey;
9908 int rval = FALSE;
9909
9910 NDBG24(("mptsas_scsi_getcap: target=%d, cap=%s tgtonly=%x",
9911 ap->a_target, cap, tgtonly));
9912
9913 mutex_enter(&mpt->m_mutex);
9914
9915 if ((mptsas_scsi_capchk(cap, tgtonly, &ckey)) != TRUE) {
9916 mutex_exit(&mpt->m_mutex);
9917 return (UNDEFINED);
9918 }
9919
9920 switch (ckey) {
9921 case SCSI_CAP_DMA_MAX:
9922 rval = (int)mpt->m_msg_dma_attr.dma_attr_maxxfer;
9923 break;
9924 case SCSI_CAP_ARQ:
9925 rval = TRUE;
9926 break;
9927 case SCSI_CAP_MSG_OUT:
9928 case SCSI_CAP_PARITY:
9929 case SCSI_CAP_UNTAGGED_QING:
9930 rval = TRUE;
9931 break;
9932 case SCSI_CAP_TAGGED_QING:
9933 rval = TRUE;
9934 break;
9935 case SCSI_CAP_RESET_NOTIFICATION:
9936 rval = TRUE;
9937 break;
9938 case SCSI_CAP_LINKED_CMDS:
9939 rval = FALSE;
9940 break;
9941 case SCSI_CAP_QFULL_RETRIES:
9942 rval = ((mptsas_tgt_private_t *)(ap->a_hba_tran->
9943 tran_tgt_private))->t_private->m_qfull_retries;
9944 break;
9945 case SCSI_CAP_QFULL_RETRY_INTERVAL:
9946 rval = drv_hztousec(((mptsas_tgt_private_t *)
9947 (ap->a_hba_tran->tran_tgt_private))->
9948 t_private->m_qfull_retry_interval) / 1000;
9949 break;
9950 case SCSI_CAP_CDB_LEN:
9951 rval = CDB_GROUP4;
9952 break;
9953 case SCSI_CAP_INTERCONNECT_TYPE:
9954 rval = INTERCONNECT_SAS;
9955 break;
9956 case SCSI_CAP_TRAN_LAYER_RETRIES:
9957 if (mpt->m_ioc_capabilities &
9958 MPI2_IOCFACTS_CAPABILITY_TLR)
9959 rval = TRUE;
9960 else
9961 rval = FALSE;
9962 break;
9963 default:
9964 rval = UNDEFINED;
9965 break;
9966 }
9967
9968 NDBG24(("mptsas_scsi_getcap: %s, rval=%x", cap, rval));
9969
9970 mutex_exit(&mpt->m_mutex);
9971 return (rval);
9972 }
9973
9974 /*
9975 * (*tran_setcap). Set the capability named to the value given.
9976 */
9977 static int
mptsas_scsi_setcap(struct scsi_address * ap,char * cap,int value,int tgtonly)9978 mptsas_scsi_setcap(struct scsi_address *ap, char *cap, int value, int tgtonly)
9979 {
9980 mptsas_t *mpt = ADDR2MPT(ap);
9981 int ckey;
9982 int rval = FALSE;
9983
9984 NDBG24(("mptsas_scsi_setcap: target=%d, cap=%s value=%x tgtonly=%x",
9985 ap->a_target, cap, value, tgtonly));
9986
9987 if (!tgtonly) {
9988 return (rval);
9989 }
9990
9991 mutex_enter(&mpt->m_mutex);
9992
9993 if ((mptsas_scsi_capchk(cap, tgtonly, &ckey)) != TRUE) {
9994 mutex_exit(&mpt->m_mutex);
9995 return (UNDEFINED);
9996 }
9997
9998 switch (ckey) {
9999 case SCSI_CAP_DMA_MAX:
10000 case SCSI_CAP_MSG_OUT:
10001 case SCSI_CAP_PARITY:
10002 case SCSI_CAP_INITIATOR_ID:
10003 case SCSI_CAP_LINKED_CMDS:
10004 case SCSI_CAP_UNTAGGED_QING:
10005 case SCSI_CAP_RESET_NOTIFICATION:
10006 /*
10007 * None of these are settable via
10008 * the capability interface.
10009 */
10010 break;
10011 case SCSI_CAP_ARQ:
10012 /*
10013 * We cannot turn off arq so return false if asked to
10014 */
10015 if (value) {
10016 rval = TRUE;
10017 } else {
10018 rval = FALSE;
10019 }
10020 break;
10021 case SCSI_CAP_TAGGED_QING:
10022 mptsas_set_throttle(mpt, ((mptsas_tgt_private_t *)
10023 (ap->a_hba_tran->tran_tgt_private))->t_private,
10024 MAX_THROTTLE);
10025 rval = TRUE;
10026 break;
10027 case SCSI_CAP_QFULL_RETRIES:
10028 ((mptsas_tgt_private_t *)(ap->a_hba_tran->tran_tgt_private))->
10029 t_private->m_qfull_retries = (uchar_t)value;
10030 rval = TRUE;
10031 break;
10032 case SCSI_CAP_QFULL_RETRY_INTERVAL:
10033 ((mptsas_tgt_private_t *)(ap->a_hba_tran->tran_tgt_private))->
10034 t_private->m_qfull_retry_interval =
10035 drv_usectohz(value * 1000);
10036 rval = TRUE;
10037 break;
10038 default:
10039 rval = UNDEFINED;
10040 break;
10041 }
10042 mutex_exit(&mpt->m_mutex);
10043 return (rval);
10044 }
10045
10046 /*
10047 * Utility routine for mptsas_ifsetcap/ifgetcap
10048 */
10049 /*ARGSUSED*/
10050 static int
mptsas_scsi_capchk(char * cap,int tgtonly,int * cidxp)10051 mptsas_scsi_capchk(char *cap, int tgtonly, int *cidxp)
10052 {
10053 NDBG24(("mptsas_scsi_capchk: cap=%s", cap));
10054
10055 if (!cap)
10056 return (FALSE);
10057
10058 *cidxp = scsi_hba_lookup_capstr(cap);
10059 return (TRUE);
10060 }
10061
10062 static int
mptsas_alloc_active_slots(mptsas_t * mpt,int flag)10063 mptsas_alloc_active_slots(mptsas_t *mpt, int flag)
10064 {
10065 mptsas_slots_t *old_active = mpt->m_active;
10066 mptsas_slots_t *new_active;
10067 size_t size;
10068
10069 /*
10070 * if there are active commands, then we cannot
10071 * change size of active slots array.
10072 */
10073 ASSERT(mpt->m_ncmds == 0);
10074
10075 size = MPTSAS_SLOTS_SIZE(mpt);
10076 new_active = kmem_zalloc(size, flag);
10077 if (new_active == NULL) {
10078 NDBG1(("new active alloc failed"));
10079 return (-1);
10080 }
10081 /*
10082 * Since SMID 0 is reserved and the TM slot is reserved, the
10083 * number of slots that can be used at any one time is
10084 * m_max_requests - 2.
10085 */
10086 new_active->m_n_normal = (mpt->m_max_requests - 2);
10087 new_active->m_size = size;
10088 new_active->m_rotor = 1;
10089 if (old_active)
10090 mptsas_free_active_slots(mpt);
10091 mpt->m_active = new_active;
10092
10093 return (0);
10094 }
10095
10096 static void
mptsas_free_active_slots(mptsas_t * mpt)10097 mptsas_free_active_slots(mptsas_t *mpt)
10098 {
10099 mptsas_slots_t *active = mpt->m_active;
10100 size_t size;
10101
10102 if (active == NULL)
10103 return;
10104 size = active->m_size;
10105 kmem_free(active, size);
10106 mpt->m_active = NULL;
10107 }
10108
10109 /*
10110 * Error logging, printing, and debug print routines.
10111 */
10112 static char *mptsas_label = "mpt_sas";
10113
10114 /*PRINTFLIKE3*/
10115 void
mptsas_log(mptsas_t * mpt,int level,char * fmt,...)10116 mptsas_log(mptsas_t *mpt, int level, char *fmt, ...)
10117 {
10118 dev_info_t *dev;
10119 va_list ap;
10120
10121 if (mpt) {
10122 dev = mpt->m_dip;
10123 } else {
10124 dev = 0;
10125 }
10126
10127 mutex_enter(&mptsas_log_mutex);
10128
10129 va_start(ap, fmt);
10130 (void) vsprintf(mptsas_log_buf, fmt, ap);
10131 va_end(ap);
10132
10133 if (level == CE_CONT) {
10134 scsi_log(dev, mptsas_label, level, "%s\n", mptsas_log_buf);
10135 } else {
10136 scsi_log(dev, mptsas_label, level, "%s", mptsas_log_buf);
10137 }
10138
10139 mutex_exit(&mptsas_log_mutex);
10140 }
10141
10142 #ifdef MPTSAS_DEBUG
10143 /*
10144 * Use a circular buffer to log messages to private memory.
10145 * Increment idx atomically to minimize risk to miss lines.
10146 * It's fast and does not hold up the proceedings too much.
10147 */
10148 static const size_t mptsas_dbglog_linecnt = MPTSAS_DBGLOG_LINECNT;
10149 static const size_t mptsas_dbglog_linelen = MPTSAS_DBGLOG_LINELEN;
10150 static char mptsas_dbglog_bufs[MPTSAS_DBGLOG_LINECNT][MPTSAS_DBGLOG_LINELEN];
10151 static uint32_t mptsas_dbglog_idx = 0;
10152
10153 /*PRINTFLIKE1*/
10154 void
mptsas_debug_log(char * fmt,...)10155 mptsas_debug_log(char *fmt, ...)
10156 {
10157 va_list ap;
10158 uint32_t idx;
10159
10160 idx = atomic_inc_32_nv(&mptsas_dbglog_idx) &
10161 (mptsas_dbglog_linecnt - 1);
10162
10163 va_start(ap, fmt);
10164 (void) vsnprintf(mptsas_dbglog_bufs[idx],
10165 mptsas_dbglog_linelen, fmt, ap);
10166 va_end(ap);
10167 }
10168
10169 /*PRINTFLIKE1*/
10170 void
mptsas_printf(char * fmt,...)10171 mptsas_printf(char *fmt, ...)
10172 {
10173 dev_info_t *dev = 0;
10174 va_list ap;
10175
10176 mutex_enter(&mptsas_log_mutex);
10177
10178 va_start(ap, fmt);
10179 (void) vsprintf(mptsas_log_buf, fmt, ap);
10180 va_end(ap);
10181
10182 #ifdef PROM_PRINTF
10183 prom_printf("%s:\t%s\n", mptsas_label, mptsas_log_buf);
10184 #else
10185 scsi_log(dev, mptsas_label, CE_CONT, "!%s\n", mptsas_log_buf);
10186 #endif
10187 mutex_exit(&mptsas_log_mutex);
10188 }
10189 #endif
10190
10191 /*
10192 * timeout handling
10193 */
10194 static void
mptsas_watch(void * arg)10195 mptsas_watch(void *arg)
10196 {
10197 #ifndef __lock_lint
10198 _NOTE(ARGUNUSED(arg))
10199 #endif
10200
10201 mptsas_t *mpt;
10202 uint32_t doorbell;
10203
10204 NDBG30(("mptsas_watch"));
10205
10206 rw_enter(&mptsas_global_rwlock, RW_READER);
10207 for (mpt = mptsas_head; mpt != (mptsas_t *)NULL; mpt = mpt->m_next) {
10208
10209 mutex_enter(&mpt->m_mutex);
10210
10211 /* Skip device if not powered on */
10212 if (mpt->m_options & MPTSAS_OPT_PM) {
10213 if (mpt->m_power_level == PM_LEVEL_D0) {
10214 (void) pm_busy_component(mpt->m_dip, 0);
10215 mpt->m_busy = 1;
10216 } else {
10217 mutex_exit(&mpt->m_mutex);
10218 continue;
10219 }
10220 }
10221
10222 /*
10223 * Check if controller is in a FAULT state. If so, reset it.
10224 */
10225 doorbell = mptsas_hirrd(mpt, &mpt->m_reg->Doorbell);
10226 if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) {
10227 doorbell &= MPI2_DOORBELL_DATA_MASK;
10228 mptsas_log(mpt, CE_WARN, "MPT Firmware Fault, "
10229 "code: %04x", doorbell);
10230 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET;
10231 if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) {
10232 mptsas_log(mpt, CE_WARN, "Reset failed"
10233 "after fault was detected");
10234 }
10235 }
10236
10237 /*
10238 * For now, always call mptsas_watchsubr.
10239 */
10240 mptsas_watchsubr(mpt);
10241
10242 if (mpt->m_options & MPTSAS_OPT_PM) {
10243 mpt->m_busy = 0;
10244 (void) pm_idle_component(mpt->m_dip, 0);
10245 }
10246
10247 mutex_exit(&mpt->m_mutex);
10248 }
10249 rw_exit(&mptsas_global_rwlock);
10250
10251 mutex_enter(&mptsas_global_mutex);
10252 if (mptsas_timeouts_enabled)
10253 mptsas_timeout_id = timeout(mptsas_watch, NULL, mptsas_tick);
10254 mutex_exit(&mptsas_global_mutex);
10255 }
10256
10257 static void
mptsas_watchsubr_tgt(mptsas_t * mpt,mptsas_target_t * ptgt,hrtime_t timestamp)10258 mptsas_watchsubr_tgt(mptsas_t *mpt, mptsas_target_t *ptgt, hrtime_t timestamp)
10259 {
10260 mptsas_cmd_t *cmd;
10261
10262 /*
10263 * If we were draining due to a qfull condition,
10264 * go back to full throttle.
10265 */
10266 if ((ptgt->m_t_throttle < MAX_THROTTLE) &&
10267 (ptgt->m_t_throttle > HOLD_THROTTLE) &&
10268 (ptgt->m_t_ncmds < ptgt->m_t_throttle)) {
10269 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
10270 mptsas_restart_hba(mpt);
10271 }
10272
10273 cmd = TAILQ_LAST(&ptgt->m_active_cmdq, mptsas_active_cmdq);
10274 if (cmd == NULL)
10275 return;
10276
10277 if (cmd->cmd_active_expiration <= timestamp) {
10278 /*
10279 * Earliest command timeout expired. Drain throttle.
10280 */
10281 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
10282
10283 /*
10284 * Check for remaining commands.
10285 */
10286 cmd = TAILQ_FIRST(&ptgt->m_active_cmdq);
10287 if (cmd->cmd_active_expiration > timestamp) {
10288 /*
10289 * Wait for remaining commands to complete or
10290 * time out.
10291 */
10292 NDBG23(("command timed out, pending drain"));
10293 return;
10294 }
10295
10296 /*
10297 * All command timeouts expired.
10298 */
10299 mptsas_log(mpt, CE_NOTE, "Timeout of %d seconds "
10300 "expired with %d commands on target %d lun %d.",
10301 cmd->cmd_pkt->pkt_time, ptgt->m_t_ncmds,
10302 ptgt->m_devhdl, Lun(cmd));
10303
10304 mptsas_cmd_timeout(mpt, ptgt);
10305 } else if (cmd->cmd_active_expiration <=
10306 timestamp + (hrtime_t)mptsas_scsi_watchdog_tick * NANOSEC) {
10307 NDBG23(("pending timeout"));
10308 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
10309 }
10310 }
10311
10312 static void
mptsas_watchsubr(mptsas_t * mpt)10313 mptsas_watchsubr(mptsas_t *mpt)
10314 {
10315 int i;
10316 mptsas_cmd_t *cmd;
10317 mptsas_target_t *ptgt = NULL;
10318 hrtime_t timestamp = gethrtime();
10319
10320 ASSERT(MUTEX_HELD(&mpt->m_mutex));
10321
10322 NDBG30(("mptsas_watchsubr: mpt=0x%p", (void *)mpt));
10323
10324 #ifdef MPTSAS_TEST
10325 if (mptsas_enable_untagged) {
10326 mptsas_test_untagged++;
10327 }
10328 #endif
10329
10330 /*
10331 * Check for commands stuck in active slot
10332 * Account for TM requests, which use the last SMID.
10333 */
10334 for (i = 0; i <= mpt->m_active->m_n_normal; i++) {
10335 if ((cmd = mpt->m_active->m_slot[i]) != NULL) {
10336 if (cmd->cmd_active_expiration <= timestamp) {
10337 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) {
10338 /*
10339 * There seems to be a command stuck
10340 * in the active slot. Drain throttle.
10341 */
10342 mptsas_set_throttle(mpt,
10343 cmd->cmd_tgt_addr,
10344 DRAIN_THROTTLE);
10345 } else if (cmd->cmd_flags &
10346 (CFLAG_PASSTHRU | CFLAG_CONFIG |
10347 CFLAG_FW_DIAG)) {
10348 /*
10349 * passthrough command timeout
10350 */
10351 cmd->cmd_flags |= (CFLAG_FINISHED |
10352 CFLAG_TIMEOUT);
10353 cv_broadcast(&mpt->m_passthru_cv);
10354 cv_broadcast(&mpt->m_config_cv);
10355 cv_broadcast(&mpt->m_fw_diag_cv);
10356 }
10357 }
10358 }
10359 }
10360
10361 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
10362 ptgt = refhash_next(mpt->m_targets, ptgt)) {
10363 mptsas_watchsubr_tgt(mpt, ptgt, timestamp);
10364 }
10365
10366 for (ptgt = refhash_first(mpt->m_tmp_targets); ptgt != NULL;
10367 ptgt = refhash_next(mpt->m_tmp_targets, ptgt)) {
10368 mptsas_watchsubr_tgt(mpt, ptgt, timestamp);
10369 }
10370 }
10371
10372 /*
10373 * timeout recovery
10374 */
10375 static void
mptsas_cmd_timeout(mptsas_t * mpt,mptsas_target_t * ptgt)10376 mptsas_cmd_timeout(mptsas_t *mpt, mptsas_target_t *ptgt)
10377 {
10378 uint16_t devhdl;
10379 uint64_t sas_wwn;
10380 uint8_t phy;
10381 char wwn_str[MPTSAS_WWN_STRLEN];
10382
10383 devhdl = ptgt->m_devhdl;
10384 sas_wwn = ptgt->m_addr.mta_wwn;
10385 phy = ptgt->m_phynum;
10386 if (sas_wwn == 0) {
10387 (void) sprintf(wwn_str, "p%x", phy);
10388 } else {
10389 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn);
10390 }
10391
10392 NDBG29(("mptsas_cmd_timeout: target=%d", devhdl));
10393 mptsas_log(mpt, CE_WARN, "Disconnected command timeout for "
10394 "target %d %s, enclosure %u", devhdl, wwn_str,
10395 ptgt->m_enclosure);
10396
10397 /*
10398 * Abort all outstanding commands on the device.
10399 */
10400 NDBG29(("mptsas_cmd_timeout: device reset"));
10401 if (mptsas_do_scsi_reset(mpt, devhdl) != TRUE) {
10402 mptsas_log(mpt, CE_WARN, "Target %d reset for command timeout "
10403 "recovery failed!", devhdl);
10404 }
10405 }
10406
10407 /*
10408 * Device / Hotplug control
10409 */
10410 static int
mptsas_scsi_quiesce(dev_info_t * dip)10411 mptsas_scsi_quiesce(dev_info_t *dip)
10412 {
10413 mptsas_t *mpt;
10414 scsi_hba_tran_t *tran;
10415
10416 tran = ddi_get_driver_private(dip);
10417 if (tran == NULL || (mpt = TRAN2MPT(tran)) == NULL)
10418 return (-1);
10419
10420 return (mptsas_quiesce_bus(mpt));
10421 }
10422
10423 static int
mptsas_scsi_unquiesce(dev_info_t * dip)10424 mptsas_scsi_unquiesce(dev_info_t *dip)
10425 {
10426 mptsas_t *mpt;
10427 scsi_hba_tran_t *tran;
10428
10429 tran = ddi_get_driver_private(dip);
10430 if (tran == NULL || (mpt = TRAN2MPT(tran)) == NULL)
10431 return (-1);
10432
10433 return (mptsas_unquiesce_bus(mpt));
10434 }
10435
10436 static int
mptsas_quiesce_bus(mptsas_t * mpt)10437 mptsas_quiesce_bus(mptsas_t *mpt)
10438 {
10439 mptsas_target_t *ptgt = NULL;
10440
10441 NDBG28(("mptsas_quiesce_bus"));
10442 mutex_enter(&mpt->m_mutex);
10443
10444 /* Set all the throttles to zero */
10445 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
10446 ptgt = refhash_next(mpt->m_targets, ptgt)) {
10447 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
10448 }
10449
10450 /* If there are any outstanding commands in the queue */
10451 if (mpt->m_ncmds) {
10452 mpt->m_softstate |= MPTSAS_SS_DRAINING;
10453 mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain,
10454 mpt, (MPTSAS_QUIESCE_TIMEOUT * drv_usectohz(1000000)));
10455 if (cv_wait_sig(&mpt->m_cv, &mpt->m_mutex) == 0) {
10456 /*
10457 * Quiesce has been interrupted
10458 */
10459 mpt->m_softstate &= ~MPTSAS_SS_DRAINING;
10460 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
10461 ptgt = refhash_next(mpt->m_targets, ptgt)) {
10462 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
10463 }
10464 mptsas_restart_hba(mpt);
10465 if (mpt->m_quiesce_timeid != 0) {
10466 timeout_id_t tid = mpt->m_quiesce_timeid;
10467 mpt->m_quiesce_timeid = 0;
10468 mutex_exit(&mpt->m_mutex);
10469 (void) untimeout(tid);
10470 return (-1);
10471 }
10472 mutex_exit(&mpt->m_mutex);
10473 return (-1);
10474 } else {
10475 /* Bus has been quiesced */
10476 ASSERT(mpt->m_quiesce_timeid == 0);
10477 mpt->m_softstate &= ~MPTSAS_SS_DRAINING;
10478 mpt->m_softstate |= MPTSAS_SS_QUIESCED;
10479 mutex_exit(&mpt->m_mutex);
10480 return (0);
10481 }
10482 }
10483 /* Bus was not busy - QUIESCED */
10484 mutex_exit(&mpt->m_mutex);
10485
10486 return (0);
10487 }
10488
10489 static int
mptsas_unquiesce_bus(mptsas_t * mpt)10490 mptsas_unquiesce_bus(mptsas_t *mpt)
10491 {
10492 mptsas_target_t *ptgt = NULL;
10493
10494 NDBG28(("mptsas_unquiesce_bus"));
10495 mutex_enter(&mpt->m_mutex);
10496 mpt->m_softstate &= ~MPTSAS_SS_QUIESCED;
10497 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
10498 ptgt = refhash_next(mpt->m_targets, ptgt)) {
10499 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
10500 }
10501 mptsas_restart_hba(mpt);
10502 mutex_exit(&mpt->m_mutex);
10503 return (0);
10504 }
10505
10506 static void
mptsas_ncmds_checkdrain(void * arg)10507 mptsas_ncmds_checkdrain(void *arg)
10508 {
10509 mptsas_t *mpt = arg;
10510 mptsas_target_t *ptgt = NULL;
10511
10512 mutex_enter(&mpt->m_mutex);
10513 if (mpt->m_softstate & MPTSAS_SS_DRAINING) {
10514 mpt->m_quiesce_timeid = 0;
10515 if (mpt->m_ncmds == 0) {
10516 /* Command queue has been drained */
10517 cv_signal(&mpt->m_cv);
10518 } else {
10519 /*
10520 * The throttle may have been reset because
10521 * of a SCSI bus reset
10522 */
10523 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
10524 ptgt = refhash_next(mpt->m_targets, ptgt)) {
10525 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
10526 }
10527
10528 mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain,
10529 mpt, (MPTSAS_QUIESCE_TIMEOUT *
10530 drv_usectohz(1000000)));
10531 }
10532 }
10533 mutex_exit(&mpt->m_mutex);
10534 }
10535
10536 /*ARGSUSED*/
10537 static void
mptsas_dump_cmd(mptsas_t * mpt,mptsas_cmd_t * cmd)10538 mptsas_dump_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
10539 {
10540 int i;
10541 uint8_t *cp = (uchar_t *)cmd->cmd_pkt->pkt_cdbp;
10542 char buf[128];
10543
10544 buf[0] = '\0';
10545 NDBG25(("?Cmd (0x%p) dump for Target %d Lun %d:\n", (void *)cmd,
10546 Tgt(cmd), Lun(cmd)));
10547 (void) sprintf(&buf[0], "\tcdb=[");
10548 for (i = 0; i < (int)cmd->cmd_cdblen; i++) {
10549 (void) sprintf(&buf[strlen(buf)], " 0x%x", *cp++);
10550 }
10551 (void) sprintf(&buf[strlen(buf)], " ]");
10552 NDBG25(("?%s\n", buf));
10553 NDBG25(("?pkt_flags=0x%x pkt_statistics=0x%x pkt_state=0x%x\n",
10554 cmd->cmd_pkt->pkt_flags, cmd->cmd_pkt->pkt_statistics,
10555 cmd->cmd_pkt->pkt_state));
10556 NDBG25(("?pkt_scbp=0x%x cmd_flags=0x%x\n", cmd->cmd_pkt->pkt_scbp ?
10557 *(cmd->cmd_pkt->pkt_scbp) : 0, cmd->cmd_flags));
10558 }
10559
10560 static void
mptsas_passthru_sge(ddi_acc_handle_t acc_hdl,mptsas_pt_request_t * pt,pMpi2SGESimple64_t sgep)10561 mptsas_passthru_sge(ddi_acc_handle_t acc_hdl, mptsas_pt_request_t *pt,
10562 pMpi2SGESimple64_t sgep)
10563 {
10564 uint32_t sge_flags;
10565 uint32_t data_size, dataout_size;
10566 ddi_dma_cookie_t data_cookie;
10567 ddi_dma_cookie_t dataout_cookie;
10568
10569 data_size = pt->data_size;
10570 dataout_size = pt->dataout_size;
10571 data_cookie = pt->data_cookie;
10572 dataout_cookie = pt->dataout_cookie;
10573
10574 if (dataout_size) {
10575 sge_flags = dataout_size |
10576 ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
10577 MPI2_SGE_FLAGS_END_OF_BUFFER |
10578 MPI2_SGE_FLAGS_HOST_TO_IOC |
10579 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
10580 MPI2_SGE_FLAGS_SHIFT);
10581 ddi_put32(acc_hdl, &sgep->FlagsLength, sge_flags);
10582 ddi_put32(acc_hdl, &sgep->Address.Low,
10583 (uint32_t)(dataout_cookie.dmac_laddress &
10584 0xffffffffull));
10585 ddi_put32(acc_hdl, &sgep->Address.High,
10586 (uint32_t)(dataout_cookie.dmac_laddress
10587 >> 32));
10588 sgep++;
10589 }
10590 sge_flags = data_size;
10591 sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
10592 MPI2_SGE_FLAGS_LAST_ELEMENT |
10593 MPI2_SGE_FLAGS_END_OF_BUFFER |
10594 MPI2_SGE_FLAGS_END_OF_LIST |
10595 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
10596 MPI2_SGE_FLAGS_SHIFT);
10597 if (pt->direction == MPTSAS_PASS_THRU_DIRECTION_WRITE) {
10598 sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_HOST_TO_IOC) <<
10599 MPI2_SGE_FLAGS_SHIFT);
10600 } else {
10601 sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_IOC_TO_HOST) <<
10602 MPI2_SGE_FLAGS_SHIFT);
10603 }
10604 ddi_put32(acc_hdl, &sgep->FlagsLength,
10605 sge_flags);
10606 ddi_put32(acc_hdl, &sgep->Address.Low,
10607 (uint32_t)(data_cookie.dmac_laddress &
10608 0xffffffffull));
10609 ddi_put32(acc_hdl, &sgep->Address.High,
10610 (uint32_t)(data_cookie.dmac_laddress >> 32));
10611 }
10612
10613 static void
mptsas_passthru_ieee_sge(ddi_acc_handle_t acc_hdl,mptsas_pt_request_t * pt,pMpi2IeeeSgeSimple64_t ieeesgep)10614 mptsas_passthru_ieee_sge(ddi_acc_handle_t acc_hdl, mptsas_pt_request_t *pt,
10615 pMpi2IeeeSgeSimple64_t ieeesgep)
10616 {
10617 uint8_t sge_flags;
10618 uint32_t data_size, dataout_size;
10619 ddi_dma_cookie_t data_cookie;
10620 ddi_dma_cookie_t dataout_cookie;
10621
10622 data_size = pt->data_size;
10623 dataout_size = pt->dataout_size;
10624 data_cookie = pt->data_cookie;
10625 dataout_cookie = pt->dataout_cookie;
10626
10627 sge_flags = (MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT |
10628 MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR);
10629 if (dataout_size) {
10630 ddi_put32(acc_hdl, &ieeesgep->Length, dataout_size);
10631 ddi_put32(acc_hdl, &ieeesgep->Address.Low,
10632 (uint32_t)(dataout_cookie.dmac_laddress &
10633 0xffffffffull));
10634 ddi_put32(acc_hdl, &ieeesgep->Address.High,
10635 (uint32_t)(dataout_cookie.dmac_laddress >> 32));
10636 ddi_put8(acc_hdl, &ieeesgep->Flags, sge_flags);
10637 ieeesgep++;
10638 }
10639 sge_flags |= MPI25_IEEE_SGE_FLAGS_END_OF_LIST;
10640 ddi_put32(acc_hdl, &ieeesgep->Length, data_size);
10641 ddi_put32(acc_hdl, &ieeesgep->Address.Low,
10642 (uint32_t)(data_cookie.dmac_laddress & 0xffffffffull));
10643 ddi_put32(acc_hdl, &ieeesgep->Address.High,
10644 (uint32_t)(data_cookie.dmac_laddress >> 32));
10645 ddi_put8(acc_hdl, &ieeesgep->Flags, sge_flags);
10646 }
10647
10648 static void
mptsas_start_passthru(mptsas_t * mpt,mptsas_cmd_t * cmd)10649 mptsas_start_passthru(mptsas_t *mpt, mptsas_cmd_t *cmd)
10650 {
10651 caddr_t memp;
10652 pMPI2RequestHeader_t request_hdrp;
10653 struct scsi_pkt *pkt = cmd->cmd_pkt;
10654 mptsas_pt_request_t *pt = pkt->pkt_ha_private;
10655 uint32_t request_size;
10656 uint32_t i;
10657 uint64_t request_desc = 0;
10658 uint8_t desc_type;
10659 uint16_t SMID;
10660 uint8_t *request, function;
10661 ddi_dma_handle_t dma_hdl = mpt->m_dma_req_frame_hdl;
10662 ddi_acc_handle_t acc_hdl = mpt->m_acc_req_frame_hdl;
10663
10664 desc_type = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
10665
10666 request = pt->request;
10667 request_size = pt->request_size;
10668
10669 SMID = cmd->cmd_slot;
10670
10671 /*
10672 * Store the passthrough message in memory location
10673 * corresponding to our slot number
10674 */
10675 memp = mpt->m_req_frame + (mpt->m_req_frame_size * SMID);
10676 request_hdrp = (pMPI2RequestHeader_t)memp;
10677 bzero(memp, mpt->m_req_frame_size);
10678
10679 for (i = 0; i < request_size; i++) {
10680 bcopy(request + i, memp + i, 1);
10681 }
10682
10683 NDBG15(("mptsas_start_passthru: Func 0x%x, MsgFlags 0x%x, "
10684 "size=%d, in %d, out %d, SMID %d", request_hdrp->Function,
10685 request_hdrp->MsgFlags, request_size,
10686 pt->data_size, pt->dataout_size, SMID));
10687
10688 /*
10689 * Add an SGE, even if the length is zero.
10690 */
10691 if (mpt->m_MPI25 && pt->simple == 0) {
10692 mptsas_passthru_ieee_sge(acc_hdl, pt,
10693 (pMpi2IeeeSgeSimple64_t)
10694 ((uint8_t *)request_hdrp + pt->sgl_offset));
10695 } else {
10696 mptsas_passthru_sge(acc_hdl, pt,
10697 (pMpi2SGESimple64_t)
10698 ((uint8_t *)request_hdrp + pt->sgl_offset));
10699 }
10700
10701 function = request_hdrp->Function;
10702 if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) ||
10703 (function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
10704 pMpi2SCSIIORequest_t scsi_io_req;
10705 caddr_t arsbuf;
10706 uint8_t ars_size;
10707 uint32_t ars_dmaaddrlow;
10708
10709 NDBG15(("mptsas_start_passthru: Is SCSI IO Req"));
10710 scsi_io_req = (pMpi2SCSIIORequest_t)request_hdrp;
10711
10712 if (cmd->cmd_extrqslen != 0) {
10713 /*
10714 * Mapping of the buffer was done in
10715 * mptsas_do_passthru().
10716 * Calculate the DMA address with the same offset.
10717 */
10718 arsbuf = cmd->cmd_arq_buf;
10719 ars_size = cmd->cmd_extrqslen;
10720 ars_dmaaddrlow = (mpt->m_req_sense_dma_addr +
10721 ((uintptr_t)arsbuf - (uintptr_t)mpt->m_req_sense)) &
10722 0xffffffffu;
10723 } else {
10724 arsbuf = mpt->m_req_sense +
10725 (mpt->m_req_sense_size * (SMID-1));
10726 cmd->cmd_arq_buf = arsbuf;
10727 ars_size = mpt->m_req_sense_size;
10728 ars_dmaaddrlow = (mpt->m_req_sense_dma_addr +
10729 (mpt->m_req_sense_size * (SMID-1))) &
10730 0xffffffffu;
10731 }
10732 bzero(arsbuf, ars_size);
10733
10734 ddi_put8(acc_hdl, &scsi_io_req->SenseBufferLength, ars_size);
10735 ddi_put32(acc_hdl, &scsi_io_req->SenseBufferLowAddress,
10736 ars_dmaaddrlow);
10737
10738 /*
10739 * Put SGE for data and data_out buffer at the end of
10740 * scsi_io_request message header.(64 bytes in total)
10741 * Set SGLOffset0 value
10742 */
10743 ddi_put8(acc_hdl, &scsi_io_req->SGLOffset0,
10744 offsetof(MPI2_SCSI_IO_REQUEST, SGL) / 4);
10745
10746 /*
10747 * Setup descriptor info. RAID passthrough must use the
10748 * default request descriptor which is already set, so if this
10749 * is a SCSI IO request, change the descriptor to SCSI IO.
10750 */
10751 if (function == MPI2_FUNCTION_SCSI_IO_REQUEST) {
10752 desc_type = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO;
10753 request_desc = ((uint64_t)ddi_get16(acc_hdl,
10754 &scsi_io_req->DevHandle) << 48);
10755 }
10756 (void) ddi_dma_sync(mpt->m_dma_req_sense_hdl, 0, 0,
10757 DDI_DMA_SYNC_FORDEV);
10758 }
10759
10760 /*
10761 * We must wait till the message has been completed before
10762 * beginning the next message so we wait for this one to
10763 * finish.
10764 */
10765 (void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
10766 request_desc |= (SMID << 16) + desc_type;
10767 cmd->cmd_rfm = 0;
10768 MPTSAS_START_CMD(mpt, request_desc);
10769 if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) ||
10770 (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) {
10771 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
10772 }
10773 }
10774
10775 typedef void (mptsas_pre_f)(mptsas_t *, mptsas_pt_request_t *);
10776 static mptsas_pre_f mpi_pre_ioc_facts;
10777 static mptsas_pre_f mpi_pre_port_facts;
10778 static mptsas_pre_f mpi_pre_fw_download;
10779 static mptsas_pre_f mpi_pre_fw_25_download;
10780 static mptsas_pre_f mpi_pre_fw_upload;
10781 static mptsas_pre_f mpi_pre_fw_25_upload;
10782 static mptsas_pre_f mpi_pre_sata_passthrough;
10783 static mptsas_pre_f mpi_pre_smp_passthrough;
10784 static mptsas_pre_f mpi_pre_config;
10785 static mptsas_pre_f mpi_pre_sas_io_unit_control;
10786 static mptsas_pre_f mpi_pre_scsi_io_req;
10787
10788 /*
10789 * Prepare the pt for a SAS2 FW_DOWNLOAD request.
10790 */
10791 static void
mpi_pre_fw_download(mptsas_t * mpt,mptsas_pt_request_t * pt)10792 mpi_pre_fw_download(mptsas_t *mpt, mptsas_pt_request_t *pt)
10793 {
10794 pMpi2FWDownloadTCSGE_t tcsge;
10795 pMpi2FWDownloadRequest req;
10796
10797 /*
10798 * If SAS3, call separate function.
10799 */
10800 if (mpt->m_MPI25) {
10801 mpi_pre_fw_25_download(mpt, pt);
10802 return;
10803 }
10804
10805 /*
10806 * User requests should come in with the Transaction
10807 * context element where the SGL will go. Putting the
10808 * SGL after that seems to work, but don't really know
10809 * why. Other drivers tend to create an extra SGL and
10810 * refer to the TCE through that.
10811 */
10812 req = (pMpi2FWDownloadRequest)pt->request;
10813 tcsge = (pMpi2FWDownloadTCSGE_t)&req->SGL;
10814 if (tcsge->ContextSize != 0 || tcsge->DetailsLength != 12 ||
10815 tcsge->Flags != MPI2_SGE_FLAGS_TRANSACTION_ELEMENT) {
10816 mptsas_log(mpt, CE_WARN, "FW Download tce invalid!");
10817 }
10818
10819 pt->sgl_offset = offsetof(MPI2_FW_DOWNLOAD_REQUEST, SGL) +
10820 sizeof (*tcsge);
10821 if (pt->request_size != pt->sgl_offset) {
10822 NDBG15(("mpi_pre_fw_download(): Incorrect req size, "
10823 "0x%x, should be 0x%x, dataoutsz 0x%x",
10824 (int)pt->request_size, (int)pt->sgl_offset,
10825 (int)pt->dataout_size));
10826 }
10827 if (pt->data_size < sizeof (MPI2_FW_DOWNLOAD_REPLY)) {
10828 NDBG15(("mpi_pre_fw_download(): Incorrect rep size, "
10829 "0x%x, should be 0x%x", pt->data_size,
10830 (int)sizeof (MPI2_FW_DOWNLOAD_REPLY)));
10831 }
10832 }
10833
10834 /*
10835 * Prepare the pt for a SAS3 FW_DOWNLOAD request.
10836 */
10837 static void
mpi_pre_fw_25_download(mptsas_t * mpt,mptsas_pt_request_t * pt)10838 mpi_pre_fw_25_download(mptsas_t *mpt, mptsas_pt_request_t *pt)
10839 {
10840 pMpi2FWDownloadTCSGE_t tcsge;
10841 pMpi2FWDownloadRequest req2;
10842 pMpi25FWDownloadRequest req25;
10843
10844 /*
10845 * User requests should come in with the Transaction
10846 * context element where the SGL will go. The new firmware
10847 * Doesn't use TCE and has space in the main request for
10848 * this information. So move to the right place.
10849 */
10850 req2 = (pMpi2FWDownloadRequest)pt->request;
10851 req25 = (pMpi25FWDownloadRequest)pt->request;
10852 tcsge = (pMpi2FWDownloadTCSGE_t)&req2->SGL;
10853 if (tcsge->ContextSize != 0 || tcsge->DetailsLength != 12 ||
10854 tcsge->Flags != MPI2_SGE_FLAGS_TRANSACTION_ELEMENT) {
10855 mptsas_log(mpt, CE_WARN, "FW Download tce invalid!");
10856 }
10857 req25->ImageOffset = tcsge->ImageOffset;
10858 req25->ImageSize = tcsge->ImageSize;
10859
10860 pt->sgl_offset = offsetof(MPI25_FW_DOWNLOAD_REQUEST, SGL);
10861 if (pt->request_size != pt->sgl_offset) {
10862 NDBG15(("mpi_pre_fw_25_download(): Incorrect req size, "
10863 "0x%x, should be 0x%x, dataoutsz 0x%x",
10864 pt->request_size, pt->sgl_offset,
10865 pt->dataout_size));
10866 }
10867 if (pt->data_size < sizeof (MPI2_FW_DOWNLOAD_REPLY)) {
10868 NDBG15(("mpi_pre_fw_25_download(): Incorrect rep size, "
10869 "0x%x, should be 0x%x", pt->data_size,
10870 (int)sizeof (MPI2_FW_UPLOAD_REPLY)));
10871 }
10872 }
10873
10874 /*
10875 * Prepare the pt for a SAS2 FW_UPLOAD request.
10876 */
10877 static void
mpi_pre_fw_upload(mptsas_t * mpt,mptsas_pt_request_t * pt)10878 mpi_pre_fw_upload(mptsas_t *mpt, mptsas_pt_request_t *pt)
10879 {
10880 pMpi2FWUploadTCSGE_t tcsge;
10881 pMpi2FWUploadRequest_t req;
10882
10883 /*
10884 * If SAS3, call separate function.
10885 */
10886 if (mpt->m_MPI25) {
10887 mpi_pre_fw_25_upload(mpt, pt);
10888 return;
10889 }
10890
10891 /*
10892 * User requests should come in with the Transaction
10893 * context element where the SGL will go. Putting the
10894 * SGL after that seems to work, but don't really know
10895 * why. Other drivers tend to create an extra SGL and
10896 * refer to the TCE through that.
10897 */
10898 req = (pMpi2FWUploadRequest_t)pt->request;
10899 tcsge = (pMpi2FWUploadTCSGE_t)&req->SGL;
10900 if (tcsge->ContextSize != 0 || tcsge->DetailsLength != 12 ||
10901 tcsge->Flags != MPI2_SGE_FLAGS_TRANSACTION_ELEMENT) {
10902 mptsas_log(mpt, CE_WARN, "FW Upload tce invalid!");
10903 }
10904
10905 pt->sgl_offset = offsetof(MPI2_FW_UPLOAD_REQUEST, SGL) +
10906 sizeof (*tcsge);
10907 if (pt->request_size != pt->sgl_offset) {
10908 NDBG15(("mpi_pre_fw_upload(): Incorrect req size, "
10909 "0x%x, should be 0x%x, dataoutsz 0x%x",
10910 pt->request_size, pt->sgl_offset,
10911 pt->dataout_size));
10912 }
10913 if (pt->data_size < sizeof (MPI2_FW_UPLOAD_REPLY)) {
10914 NDBG15(("mpi_pre_fw_upload(): Incorrect rep size, "
10915 "0x%x, should be 0x%x", pt->data_size,
10916 (int)sizeof (MPI2_FW_UPLOAD_REPLY)));
10917 }
10918 }
10919
10920 /*
10921 * Prepare the pt a SAS3 FW_UPLOAD request.
10922 */
10923 static void
mpi_pre_fw_25_upload(mptsas_t * mpt,mptsas_pt_request_t * pt)10924 mpi_pre_fw_25_upload(mptsas_t *mpt, mptsas_pt_request_t *pt)
10925 {
10926 pMpi2FWUploadTCSGE_t tcsge;
10927 pMpi2FWUploadRequest_t req2;
10928 pMpi25FWUploadRequest_t req25;
10929
10930 /*
10931 * User requests should come in with the Transaction
10932 * context element where the SGL will go. The new firmware
10933 * Doesn't use TCE and has space in the main request for
10934 * this information. So move to the right place.
10935 */
10936 req2 = (pMpi2FWUploadRequest_t)pt->request;
10937 req25 = (pMpi25FWUploadRequest_t)pt->request;
10938 tcsge = (pMpi2FWUploadTCSGE_t)&req2->SGL;
10939 if (tcsge->ContextSize != 0 || tcsge->DetailsLength != 12 ||
10940 tcsge->Flags != MPI2_SGE_FLAGS_TRANSACTION_ELEMENT) {
10941 mptsas_log(mpt, CE_WARN, "FW Upload tce invalid!");
10942 }
10943 req25->ImageOffset = tcsge->ImageOffset;
10944 req25->ImageSize = tcsge->ImageSize;
10945
10946 pt->sgl_offset = offsetof(MPI25_FW_UPLOAD_REQUEST, SGL);
10947 if (pt->request_size != pt->sgl_offset) {
10948 NDBG15(("mpi_pre_fw_25_upload(): Incorrect req size, "
10949 "0x%x, should be 0x%x, dataoutsz 0x%x",
10950 pt->request_size, pt->sgl_offset,
10951 pt->dataout_size));
10952 }
10953 if (pt->data_size < sizeof (MPI2_FW_UPLOAD_REPLY)) {
10954 NDBG15(("mpi_pre_fw_25_upload(): Incorrect rep size, "
10955 "0x%x, should be 0x%x", pt->data_size,
10956 (int)sizeof (MPI2_FW_UPLOAD_REPLY)));
10957 }
10958 }
10959
10960 /*
10961 * Prepare the pt for an IOC_FACTS request.
10962 */
10963 static void
mpi_pre_ioc_facts(mptsas_t * mpt,mptsas_pt_request_t * pt)10964 mpi_pre_ioc_facts(mptsas_t *mpt, mptsas_pt_request_t *pt)
10965 {
10966 #ifndef __lock_lint
10967 _NOTE(ARGUNUSED(mpt))
10968 #endif
10969 if (pt->request_size != sizeof (MPI2_IOC_FACTS_REQUEST)) {
10970 NDBG15(("mpi_pre_ioc_facts(): Incorrect req size, "
10971 "0x%x, should be 0x%x, dataoutsz 0x%x",
10972 pt->request_size,
10973 (int)sizeof (MPI2_IOC_FACTS_REQUEST),
10974 pt->dataout_size));
10975 }
10976 if (pt->data_size != sizeof (MPI2_IOC_FACTS_REPLY)) {
10977 NDBG15(("mpi_pre_ioc_facts(): Incorrect rep size, "
10978 "0x%x, should be 0x%x", pt->data_size,
10979 (int)sizeof (MPI2_IOC_FACTS_REPLY)));
10980 }
10981 pt->sgl_offset = (uint16_t)pt->request_size;
10982 }
10983
10984 /*
10985 * Prepare the pt for a PORT_FACTS request.
10986 */
10987 static void
mpi_pre_port_facts(mptsas_t * mpt,mptsas_pt_request_t * pt)10988 mpi_pre_port_facts(mptsas_t *mpt, mptsas_pt_request_t *pt)
10989 {
10990 #ifndef __lock_lint
10991 _NOTE(ARGUNUSED(mpt))
10992 #endif
10993 if (pt->request_size != sizeof (MPI2_PORT_FACTS_REQUEST)) {
10994 NDBG15(("mpi_pre_port_facts(): Incorrect req size, "
10995 "0x%x, should be 0x%x, dataoutsz 0x%x",
10996 pt->request_size,
10997 (int)sizeof (MPI2_PORT_FACTS_REQUEST),
10998 pt->dataout_size));
10999 }
11000 if (pt->data_size != sizeof (MPI2_PORT_FACTS_REPLY)) {
11001 NDBG15(("mpi_pre_port_facts(): Incorrect rep size, "
11002 "0x%x, should be 0x%x", pt->data_size,
11003 (int)sizeof (MPI2_PORT_FACTS_REPLY)));
11004 }
11005 pt->sgl_offset = (uint16_t)pt->request_size;
11006 }
11007
11008 /*
11009 * Prepare pt for a SATA_PASSTHROUGH request.
11010 */
11011 static void
mpi_pre_sata_passthrough(mptsas_t * mpt,mptsas_pt_request_t * pt)11012 mpi_pre_sata_passthrough(mptsas_t *mpt, mptsas_pt_request_t *pt)
11013 {
11014 #ifndef __lock_lint
11015 _NOTE(ARGUNUSED(mpt))
11016 #endif
11017 pt->sgl_offset = offsetof(MPI2_SATA_PASSTHROUGH_REQUEST, SGL);
11018 if (pt->request_size != pt->sgl_offset) {
11019 NDBG15(("mpi_pre_sata_passthrough(): Incorrect req size, "
11020 "0x%x, should be 0x%x, dataoutsz 0x%x",
11021 pt->request_size, pt->sgl_offset,
11022 pt->dataout_size));
11023 }
11024 if (pt->data_size != sizeof (MPI2_SATA_PASSTHROUGH_REPLY)) {
11025 NDBG15(("mpi_pre_sata_passthrough(): Incorrect rep size, "
11026 "0x%x, should be 0x%x", pt->data_size,
11027 (int)sizeof (MPI2_SATA_PASSTHROUGH_REPLY)));
11028 }
11029 }
11030
11031 static void
mpi_pre_smp_passthrough(mptsas_t * mpt,mptsas_pt_request_t * pt)11032 mpi_pre_smp_passthrough(mptsas_t *mpt, mptsas_pt_request_t *pt)
11033 {
11034 #ifndef __lock_lint
11035 _NOTE(ARGUNUSED(mpt))
11036 #endif
11037 pt->sgl_offset = offsetof(MPI2_SMP_PASSTHROUGH_REQUEST, SGL);
11038 if (pt->request_size != pt->sgl_offset) {
11039 NDBG15(("mpi_pre_smp_passthrough(): Incorrect req size, "
11040 "0x%x, should be 0x%x, dataoutsz 0x%x",
11041 pt->request_size, pt->sgl_offset,
11042 pt->dataout_size));
11043 }
11044 if (pt->data_size != sizeof (MPI2_SMP_PASSTHROUGH_REPLY)) {
11045 NDBG15(("mpi_pre_smp_passthrough(): Incorrect rep size, "
11046 "0x%x, should be 0x%x", pt->data_size,
11047 (int)sizeof (MPI2_SMP_PASSTHROUGH_REPLY)));
11048 }
11049 }
11050
11051 /*
11052 * Prepare pt for a CONFIG request.
11053 */
11054 static void
mpi_pre_config(mptsas_t * mpt,mptsas_pt_request_t * pt)11055 mpi_pre_config(mptsas_t *mpt, mptsas_pt_request_t *pt)
11056 {
11057 #ifndef __lock_lint
11058 _NOTE(ARGUNUSED(mpt))
11059 #endif
11060 pt->sgl_offset = offsetof(MPI2_CONFIG_REQUEST, PageBufferSGE);
11061 if (pt->request_size != pt->sgl_offset) {
11062 NDBG15(("mpi_pre_config(): Incorrect req size, 0x%x, "
11063 "should be 0x%x, dataoutsz 0x%x", pt->request_size,
11064 pt->sgl_offset, pt->dataout_size));
11065 }
11066 if (pt->data_size != sizeof (MPI2_CONFIG_REPLY)) {
11067 NDBG15(("mpi_pre_config(): Incorrect rep size, 0x%x, "
11068 "should be 0x%x", pt->data_size,
11069 (int)sizeof (MPI2_CONFIG_REPLY)));
11070 }
11071 pt->simple = 1;
11072 }
11073
11074 /*
11075 * Prepare pt for a SCSI_IO_REQ request.
11076 */
11077 static void
mpi_pre_scsi_io_req(mptsas_t * mpt,mptsas_pt_request_t * pt)11078 mpi_pre_scsi_io_req(mptsas_t *mpt, mptsas_pt_request_t *pt)
11079 {
11080 #ifndef __lock_lint
11081 _NOTE(ARGUNUSED(mpt))
11082 #endif
11083 pt->sgl_offset = offsetof(MPI2_SCSI_IO_REQUEST, SGL);
11084 if (pt->request_size != pt->sgl_offset) {
11085 NDBG15(("mpi_pre_config(): Incorrect req size, 0x%x, "
11086 "should be 0x%x, dataoutsz 0x%x", pt->request_size,
11087 pt->sgl_offset,
11088 pt->dataout_size));
11089 }
11090 if (pt->data_size != sizeof (MPI2_SCSI_IO_REPLY)) {
11091 NDBG15(("mpi_pre_config(): Incorrect rep size, 0x%x, "
11092 "should be 0x%x", pt->data_size,
11093 (int)sizeof (MPI2_SCSI_IO_REPLY)));
11094 }
11095 }
11096
11097 /*
11098 * Prepare the mptsas_cmd for a SAS_IO_UNIT_CONTROL request.
11099 */
11100 static void
mpi_pre_sas_io_unit_control(mptsas_t * mpt,mptsas_pt_request_t * pt)11101 mpi_pre_sas_io_unit_control(mptsas_t *mpt, mptsas_pt_request_t *pt)
11102 {
11103 #ifndef __lock_lint
11104 _NOTE(ARGUNUSED(mpt))
11105 #endif
11106 pt->sgl_offset = (uint16_t)pt->request_size;
11107 }
11108
11109 /*
11110 * A set of functions to prepare an mptsas_cmd for the various
11111 * supported requests.
11112 */
11113 static struct mptsas_func {
11114 U8 Function;
11115 char *Name;
11116 mptsas_pre_f *f_pre;
11117 } mptsas_func_list[] = {
11118 { MPI2_FUNCTION_IOC_FACTS, "IOC_FACTS", mpi_pre_ioc_facts },
11119 { MPI2_FUNCTION_PORT_FACTS, "PORT_FACTS", mpi_pre_port_facts },
11120 { MPI2_FUNCTION_FW_DOWNLOAD, "FW_DOWNLOAD", mpi_pre_fw_download },
11121 { MPI2_FUNCTION_FW_UPLOAD, "FW_UPLOAD", mpi_pre_fw_upload },
11122 { MPI2_FUNCTION_SATA_PASSTHROUGH, "SATA_PASSTHROUGH",
11123 mpi_pre_sata_passthrough },
11124 { MPI2_FUNCTION_SMP_PASSTHROUGH, "SMP_PASSTHROUGH",
11125 mpi_pre_smp_passthrough},
11126 { MPI2_FUNCTION_SCSI_IO_REQUEST, "SCSI_IO_REQUEST",
11127 mpi_pre_scsi_io_req},
11128 { MPI2_FUNCTION_CONFIG, "CONFIG", mpi_pre_config},
11129 { MPI2_FUNCTION_SAS_IO_UNIT_CONTROL, "SAS_IO_UNIT_CONTROL",
11130 mpi_pre_sas_io_unit_control },
11131 { 0xFF, NULL, NULL } /* list end */
11132 };
11133
11134 static void
mptsas_prep_sgl_offset(mptsas_t * mpt,mptsas_pt_request_t * pt)11135 mptsas_prep_sgl_offset(mptsas_t *mpt, mptsas_pt_request_t *pt)
11136 {
11137 pMPI2RequestHeader_t hdr;
11138 struct mptsas_func *f;
11139
11140 hdr = (pMPI2RequestHeader_t)pt->request;
11141
11142 for (f = mptsas_func_list; f->f_pre != NULL; f++) {
11143 if (hdr->Function == f->Function) {
11144 f->f_pre(mpt, pt);
11145 NDBG15(("mptsas_prep_sgl_offset: Function %s,"
11146 " sgl_offset 0x%x", f->Name,
11147 pt->sgl_offset));
11148 return;
11149 }
11150 }
11151 NDBG15(("mptsas_prep_sgl_offset: Unknown Function 0x%02x,"
11152 " returning req_size 0x%x for sgl_offset",
11153 hdr->Function, pt->request_size));
11154 pt->sgl_offset = (uint16_t)pt->request_size;
11155 }
11156
11157
11158 static int
mptsas_do_passthru(mptsas_t * mpt,uint8_t * request,uint8_t * reply,uint8_t * data,uint32_t request_size,uint32_t reply_size,uint32_t data_size,uint32_t direction,uint8_t * dataout,uint32_t dataout_size,short timeout,int mode)11159 mptsas_do_passthru(mptsas_t *mpt, uint8_t *request, uint8_t *reply,
11160 uint8_t *data, uint32_t request_size, uint32_t reply_size,
11161 uint32_t data_size, uint32_t direction, uint8_t *dataout,
11162 uint32_t dataout_size, short timeout, int mode)
11163 {
11164 mptsas_pt_request_t pt;
11165 mptsas_dma_alloc_state_t data_dma_state;
11166 mptsas_dma_alloc_state_t dataout_dma_state;
11167 caddr_t memp;
11168 mptsas_cmd_t *cmd = NULL;
11169 struct scsi_pkt *pkt;
11170 uint32_t reply_len = 0, sense_len = 0;
11171 pMPI2RequestHeader_t request_hdrp;
11172 pMPI2RequestHeader_t request_msg;
11173 pMPI2DefaultReply_t reply_msg;
11174 Mpi2SCSIIOReply_t rep_msg;
11175 int rvalue;
11176 int i, status = 0, pt_flags = 0, rv = 0;
11177 uint8_t function;
11178
11179 ASSERT(mutex_owned(&mpt->m_mutex));
11180
11181 reply_msg = (pMPI2DefaultReply_t)(&rep_msg);
11182 bzero(reply_msg, sizeof (MPI2_DEFAULT_REPLY));
11183 request_msg = kmem_zalloc(request_size, KM_SLEEP);
11184
11185 mutex_exit(&mpt->m_mutex);
11186 /*
11187 * copy in the request buffer since it could be used by
11188 * another thread when the pt request into waitq
11189 */
11190 if (ddi_copyin(request, request_msg, request_size, mode)) {
11191 mutex_enter(&mpt->m_mutex);
11192 status = EFAULT;
11193 mptsas_log(mpt, CE_WARN, "failed to copy request data");
11194 goto out;
11195 }
11196 NDBG27(("mptsas_do_passthru: mode 0x%x, size 0x%x, Func 0x%x",
11197 mode, request_size, request_msg->Function));
11198 mutex_enter(&mpt->m_mutex);
11199
11200 function = request_msg->Function;
11201 if (function == MPI2_FUNCTION_SCSI_TASK_MGMT) {
11202 pMpi2SCSITaskManagementRequest_t task;
11203 task = (pMpi2SCSITaskManagementRequest_t)request_msg;
11204 mptsas_setup_bus_reset_delay(mpt);
11205 rv = mptsas_ioc_task_management(mpt, task->TaskType,
11206 task->DevHandle, (int)task->LUN[1], reply, reply_size,
11207 mode);
11208
11209 if (rv != TRUE) {
11210 status = EIO;
11211 mptsas_log(mpt, CE_WARN, "task management failed");
11212 }
11213 goto out;
11214 }
11215
11216 if (data_size != 0) {
11217 data_dma_state.size = data_size;
11218 if (mptsas_dma_alloc(mpt, &data_dma_state) != DDI_SUCCESS) {
11219 status = ENOMEM;
11220 mptsas_log(mpt, CE_WARN, "failed to alloc DMA "
11221 "resource");
11222 goto out;
11223 }
11224 pt_flags |= MPTSAS_DATA_ALLOCATED;
11225 if (direction == MPTSAS_PASS_THRU_DIRECTION_WRITE) {
11226 mutex_exit(&mpt->m_mutex);
11227 for (i = 0; i < data_size; i++) {
11228 if (ddi_copyin(data + i, (uint8_t *)
11229 data_dma_state.memp + i, 1, mode)) {
11230 mutex_enter(&mpt->m_mutex);
11231 status = EFAULT;
11232 mptsas_log(mpt, CE_WARN, "failed to "
11233 "copy read data");
11234 goto out;
11235 }
11236 }
11237 mutex_enter(&mpt->m_mutex);
11238 }
11239 } else {
11240 bzero(&data_dma_state, sizeof (data_dma_state));
11241 }
11242
11243 if (dataout_size != 0) {
11244 dataout_dma_state.size = dataout_size;
11245 if (mptsas_dma_alloc(mpt, &dataout_dma_state) != DDI_SUCCESS) {
11246 status = ENOMEM;
11247 mptsas_log(mpt, CE_WARN, "failed to alloc DMA "
11248 "resource");
11249 goto out;
11250 }
11251 pt_flags |= MPTSAS_DATAOUT_ALLOCATED;
11252 mutex_exit(&mpt->m_mutex);
11253 for (i = 0; i < dataout_size; i++) {
11254 if (ddi_copyin(dataout + i, (uint8_t *)
11255 dataout_dma_state.memp + i, 1, mode)) {
11256 mutex_enter(&mpt->m_mutex);
11257 mptsas_log(mpt, CE_WARN, "failed to copy out"
11258 " data");
11259 status = EFAULT;
11260 goto out;
11261 }
11262 }
11263 mutex_enter(&mpt->m_mutex);
11264 } else {
11265 bzero(&dataout_dma_state, sizeof (dataout_dma_state));
11266 }
11267
11268 if ((rvalue = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) {
11269 status = EAGAIN;
11270 mptsas_log(mpt, CE_NOTE, "event ack command pool is full");
11271 goto out;
11272 }
11273 pt_flags |= MPTSAS_REQUEST_POOL_CMD;
11274
11275 bzero((caddr_t)cmd, sizeof (*cmd));
11276 bzero((caddr_t)pkt, scsi_pkt_size());
11277 bzero((caddr_t)&pt, sizeof (pt));
11278
11279 cmd->ioc_cmd_slot = (uint32_t)(rvalue);
11280
11281 pt.request = (uint8_t *)request_msg;
11282 pt.direction = direction;
11283 pt.simple = 0;
11284 pt.request_size = request_size;
11285 pt.data_size = data_size;
11286 pt.dataout_size = dataout_size;
11287 pt.data_cookie = data_dma_state.cookie;
11288 pt.dataout_cookie = dataout_dma_state.cookie;
11289 mptsas_prep_sgl_offset(mpt, &pt);
11290
11291 /*
11292 * Form a blank cmd/pkt to store the acknowledgement message
11293 */
11294 pkt->pkt_cdbp = (opaque_t)&cmd->cmd_cdb[0];
11295 pkt->pkt_scbp = (opaque_t)&cmd->cmd_scb;
11296 pkt->pkt_ha_private = (opaque_t)&pt;
11297 pkt->pkt_flags = FLAG_HEAD;
11298 pkt->pkt_time = timeout;
11299 cmd->cmd_pkt = pkt;
11300 cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_PASSTHRU;
11301
11302 if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) ||
11303 (function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
11304 uint8_t com, cdb_group_id;
11305 boolean_t ret;
11306
11307 pkt->pkt_cdbp = ((pMpi2SCSIIORequest_t)request_msg)->CDB.CDB32;
11308 com = pkt->pkt_cdbp[0];
11309 cdb_group_id = CDB_GROUPID(com);
11310 switch (cdb_group_id) {
11311 case CDB_GROUPID_0: cmd->cmd_cdblen = CDB_GROUP0; break;
11312 case CDB_GROUPID_1: cmd->cmd_cdblen = CDB_GROUP1; break;
11313 case CDB_GROUPID_2: cmd->cmd_cdblen = CDB_GROUP2; break;
11314 case CDB_GROUPID_4: cmd->cmd_cdblen = CDB_GROUP4; break;
11315 case CDB_GROUPID_5: cmd->cmd_cdblen = CDB_GROUP5; break;
11316 default:
11317 NDBG27(("mptsas_do_passthru: SCSI_IO, reserved "
11318 "CDBGROUP 0x%x requested!", cdb_group_id));
11319 break;
11320 }
11321
11322 reply_len = sizeof (MPI2_SCSI_IO_REPLY);
11323 sense_len = reply_size - reply_len;
11324 ret = mptsas_cmdarqsize(mpt, cmd, sense_len, KM_SLEEP);
11325 VERIFY(ret == B_TRUE);
11326 } else {
11327 reply_len = reply_size;
11328 sense_len = 0;
11329 }
11330
11331 NDBG27(("mptsas_do_passthru: %s, dsz 0x%x, dosz 0x%x, replen 0x%x, "
11332 "snslen 0x%x",
11333 (direction == MPTSAS_PASS_THRU_DIRECTION_WRITE)?"Write":"Read",
11334 data_size, dataout_size, reply_len, sense_len));
11335
11336 /*
11337 * Save the command in a slot
11338 */
11339 if (mptsas_save_cmd(mpt, cmd) == TRUE) {
11340 /*
11341 * Once passthru command get slot, set cmd_flags
11342 * CFLAG_PREPARED.
11343 */
11344 cmd->cmd_flags |= CFLAG_PREPARED;
11345 mptsas_start_passthru(mpt, cmd);
11346 } else {
11347 mptsas_waitq_add(mpt, cmd);
11348 }
11349
11350 while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) {
11351 cv_wait(&mpt->m_passthru_cv, &mpt->m_mutex);
11352 }
11353
11354 NDBG27(("mptsas_do_passthru: Cmd complete, flags 0x%x, rfm 0x%x "
11355 "pktreason 0x%x", cmd->cmd_flags, cmd->cmd_rfm,
11356 pkt->pkt_reason));
11357
11358 if (cmd->cmd_flags & CFLAG_PREPARED) {
11359 memp = mpt->m_req_frame + (mpt->m_req_frame_size *
11360 cmd->cmd_slot);
11361 request_hdrp = (pMPI2RequestHeader_t)memp;
11362 }
11363
11364 if (cmd->cmd_flags & CFLAG_TIMEOUT) {
11365 status = ETIMEDOUT;
11366 mptsas_log(mpt, CE_WARN, "passthrough command timeout");
11367 pt_flags |= MPTSAS_CMD_TIMEOUT;
11368 goto out;
11369 }
11370
11371 if (cmd->cmd_rfm) {
11372 /*
11373 * cmd_rfm is zero means the command reply is a CONTEXT
11374 * reply and no PCI Write to post the free reply SMFA
11375 * because no reply message frame is used.
11376 * cmd_rfm is non-zero means the reply is a ADDRESS
11377 * reply and reply message frame is used.
11378 */
11379 pt_flags |= MPTSAS_ADDRESS_REPLY;
11380 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
11381 DDI_DMA_SYNC_FORCPU);
11382 reply_msg = (pMPI2DefaultReply_t)
11383 (mpt->m_reply_frame + (cmd->cmd_rfm -
11384 (mpt->m_reply_frame_dma_addr & 0xffffffffu)));
11385 }
11386
11387 mptsas_fma_check(mpt, cmd);
11388 if (pkt->pkt_reason == CMD_TRAN_ERR) {
11389 status = EAGAIN;
11390 mptsas_log(mpt, CE_WARN, "passthru fma error");
11391 goto out;
11392 }
11393 if (pkt->pkt_reason == CMD_RESET) {
11394 status = EAGAIN;
11395 mptsas_log(mpt, CE_WARN, "ioc reset abort passthru");
11396 goto out;
11397 }
11398
11399 if (pkt->pkt_reason == CMD_INCOMPLETE) {
11400 status = EIO;
11401 mptsas_log(mpt, CE_WARN, "passthrough command incomplete");
11402 goto out;
11403 }
11404
11405 mutex_exit(&mpt->m_mutex);
11406 if (cmd->cmd_flags & CFLAG_PREPARED) {
11407 function = request_hdrp->Function;
11408 if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) ||
11409 (function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
11410 reply_len = sizeof (MPI2_SCSI_IO_REPLY);
11411 sense_len = cmd->cmd_extrqslen ?
11412 min(sense_len, cmd->cmd_extrqslen) :
11413 min(sense_len, cmd->cmd_rqslen);
11414 } else {
11415 reply_len = reply_size;
11416 sense_len = 0;
11417 }
11418
11419 for (i = 0; i < reply_len; i++) {
11420 if (ddi_copyout((uint8_t *)reply_msg + i, reply + i, 1,
11421 mode)) {
11422 mutex_enter(&mpt->m_mutex);
11423 status = EFAULT;
11424 mptsas_log(mpt, CE_WARN, "failed to copy out "
11425 "reply data");
11426 goto out;
11427 }
11428 }
11429 for (i = 0; i < sense_len; i++) {
11430 if (ddi_copyout((uint8_t *)request_hdrp + 64 + i,
11431 reply + reply_len + i, 1, mode)) {
11432 mutex_enter(&mpt->m_mutex);
11433 status = EFAULT;
11434 mptsas_log(mpt, CE_WARN, "failed to copy out "
11435 "sense data");
11436 goto out;
11437 }
11438 }
11439 }
11440
11441 if (data_size) {
11442 if (direction != MPTSAS_PASS_THRU_DIRECTION_WRITE) {
11443 (void) ddi_dma_sync(data_dma_state.handle, 0, 0,
11444 DDI_DMA_SYNC_FORCPU);
11445 for (i = 0; i < data_size; i++) {
11446 if (ddi_copyout((uint8_t *)(
11447 data_dma_state.memp + i), data + i, 1,
11448 mode)) {
11449 mutex_enter(&mpt->m_mutex);
11450 status = EFAULT;
11451 mptsas_log(mpt, CE_WARN, "failed to "
11452 "copy out the reply data");
11453 goto out;
11454 }
11455 }
11456 }
11457 }
11458 mutex_enter(&mpt->m_mutex);
11459 out:
11460 /*
11461 * Put the reply frame back on the free queue, increment the free
11462 * index, and write the new index to the free index register. But only
11463 * if this reply is an ADDRESS reply.
11464 */
11465 if (pt_flags & MPTSAS_ADDRESS_REPLY) {
11466 ddi_put32(mpt->m_acc_free_queue_hdl,
11467 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index],
11468 cmd->cmd_rfm);
11469 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
11470 DDI_DMA_SYNC_FORDEV);
11471 if (++mpt->m_free_index == mpt->m_free_queue_depth) {
11472 mpt->m_free_index = 0;
11473 }
11474 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
11475 mpt->m_free_index);
11476 }
11477 if (cmd) {
11478 if (cmd->cmd_extrqslen != 0) {
11479 rmfree(mpt->m_erqsense_map, cmd->cmd_extrqschunks,
11480 cmd->cmd_extrqsidx + 1);
11481 }
11482 if (cmd->cmd_flags & CFLAG_PREPARED) {
11483 mptsas_remove_cmd(mpt, cmd);
11484 pt_flags &= (~MPTSAS_REQUEST_POOL_CMD);
11485 }
11486 }
11487 if (pt_flags & MPTSAS_REQUEST_POOL_CMD)
11488 mptsas_return_to_pool(mpt, cmd);
11489 if (pt_flags & MPTSAS_DATA_ALLOCATED) {
11490 if (mptsas_check_dma_handle(data_dma_state.handle) !=
11491 DDI_SUCCESS) {
11492 ddi_fm_service_impact(mpt->m_dip,
11493 DDI_SERVICE_UNAFFECTED);
11494 status = EFAULT;
11495 }
11496 mptsas_dma_free(&data_dma_state);
11497 }
11498 if (pt_flags & MPTSAS_DATAOUT_ALLOCATED) {
11499 if (mptsas_check_dma_handle(dataout_dma_state.handle) !=
11500 DDI_SUCCESS) {
11501 ddi_fm_service_impact(mpt->m_dip,
11502 DDI_SERVICE_UNAFFECTED);
11503 status = EFAULT;
11504 }
11505 mptsas_dma_free(&dataout_dma_state);
11506 }
11507 if (pt_flags & MPTSAS_CMD_TIMEOUT) {
11508 if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) {
11509 mptsas_log(mpt, CE_WARN, "mptsas_restart_ioc failed");
11510 }
11511 }
11512 if (request_msg)
11513 kmem_free(request_msg, request_size);
11514 NDBG27(("mptsas_do_passthru: Done status 0x%x", status));
11515
11516 return (status);
11517 }
11518
11519 static int
mptsas_pass_thru(mptsas_t * mpt,mptsas_pass_thru_t * data,int mode)11520 mptsas_pass_thru(mptsas_t *mpt, mptsas_pass_thru_t *data, int mode)
11521 {
11522 /*
11523 * If timeout is 0, set timeout to default of 60 seconds.
11524 */
11525 if (data->Timeout == 0) {
11526 data->Timeout = MPTSAS_PASS_THRU_TIME_DEFAULT;
11527 }
11528
11529 if (((data->DataSize == 0) &&
11530 (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_NONE)) ||
11531 ((data->DataSize != 0) &&
11532 ((data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_READ) ||
11533 (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_WRITE) ||
11534 ((data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_BOTH) &&
11535 (data->DataOutSize != 0))))) {
11536 if (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_BOTH) {
11537 data->DataDirection = MPTSAS_PASS_THRU_DIRECTION_READ;
11538 } else {
11539 data->DataOutSize = 0;
11540 }
11541 /*
11542 * Send passthru request messages
11543 */
11544 return (mptsas_do_passthru(mpt,
11545 (uint8_t *)((uintptr_t)data->PtrRequest),
11546 (uint8_t *)((uintptr_t)data->PtrReply),
11547 (uint8_t *)((uintptr_t)data->PtrData),
11548 data->RequestSize, data->ReplySize,
11549 data->DataSize, data->DataDirection,
11550 (uint8_t *)((uintptr_t)data->PtrDataOut),
11551 data->DataOutSize, data->Timeout, mode));
11552 } else {
11553 return (EINVAL);
11554 }
11555 }
11556
11557 static uint8_t
mptsas_get_fw_diag_buffer_number(mptsas_t * mpt,uint32_t unique_id)11558 mptsas_get_fw_diag_buffer_number(mptsas_t *mpt, uint32_t unique_id)
11559 {
11560 uint8_t index;
11561
11562 for (index = 0; index < MPI2_DIAG_BUF_TYPE_COUNT; index++) {
11563 if (mpt->m_fw_diag_buffer_list[index].unique_id == unique_id) {
11564 return (index);
11565 }
11566 }
11567
11568 return (MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND);
11569 }
11570
11571 static void
mptsas_start_diag(mptsas_t * mpt,mptsas_cmd_t * cmd)11572 mptsas_start_diag(mptsas_t *mpt, mptsas_cmd_t *cmd)
11573 {
11574 pMpi2DiagBufferPostRequest_t pDiag_post_msg;
11575 pMpi2DiagReleaseRequest_t pDiag_release_msg;
11576 struct scsi_pkt *pkt = cmd->cmd_pkt;
11577 mptsas_diag_request_t *diag = pkt->pkt_ha_private;
11578 uint32_t i;
11579 uint64_t request_desc;
11580
11581 ASSERT(mutex_owned(&mpt->m_mutex));
11582
11583 /*
11584 * Form the diag message depending on the post or release function.
11585 */
11586 if (diag->function == MPI2_FUNCTION_DIAG_BUFFER_POST) {
11587 pDiag_post_msg = (pMpi2DiagBufferPostRequest_t)
11588 (mpt->m_req_frame + (mpt->m_req_frame_size *
11589 cmd->cmd_slot));
11590 bzero(pDiag_post_msg, mpt->m_req_frame_size);
11591 ddi_put8(mpt->m_acc_req_frame_hdl, &pDiag_post_msg->Function,
11592 diag->function);
11593 ddi_put8(mpt->m_acc_req_frame_hdl, &pDiag_post_msg->BufferType,
11594 diag->pBuffer->buffer_type);
11595 ddi_put8(mpt->m_acc_req_frame_hdl,
11596 &pDiag_post_msg->ExtendedType,
11597 diag->pBuffer->extended_type);
11598 ddi_put32(mpt->m_acc_req_frame_hdl,
11599 &pDiag_post_msg->BufferLength,
11600 diag->pBuffer->buffer_data.size);
11601 for (i = 0; i < (sizeof (pDiag_post_msg->ProductSpecific) / 4);
11602 i++) {
11603 ddi_put32(mpt->m_acc_req_frame_hdl,
11604 &pDiag_post_msg->ProductSpecific[i],
11605 diag->pBuffer->product_specific[i]);
11606 }
11607 ddi_put32(mpt->m_acc_req_frame_hdl,
11608 &pDiag_post_msg->BufferAddress.Low,
11609 (uint32_t)(diag->pBuffer->buffer_data.cookie.dmac_laddress
11610 & 0xffffffffull));
11611 ddi_put32(mpt->m_acc_req_frame_hdl,
11612 &pDiag_post_msg->BufferAddress.High,
11613 (uint32_t)(diag->pBuffer->buffer_data.cookie.dmac_laddress
11614 >> 32));
11615 } else {
11616 pDiag_release_msg = (pMpi2DiagReleaseRequest_t)
11617 (mpt->m_req_frame + (mpt->m_req_frame_size *
11618 cmd->cmd_slot));
11619 bzero(pDiag_release_msg, mpt->m_req_frame_size);
11620 ddi_put8(mpt->m_acc_req_frame_hdl,
11621 &pDiag_release_msg->Function, diag->function);
11622 ddi_put8(mpt->m_acc_req_frame_hdl,
11623 &pDiag_release_msg->BufferType,
11624 diag->pBuffer->buffer_type);
11625 }
11626
11627 /*
11628 * Send the message
11629 */
11630 (void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0,
11631 DDI_DMA_SYNC_FORDEV);
11632 request_desc = (cmd->cmd_slot << 16) +
11633 MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
11634 cmd->cmd_rfm = 0;
11635 MPTSAS_START_CMD(mpt, request_desc);
11636 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) !=
11637 DDI_SUCCESS) ||
11638 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) !=
11639 DDI_SUCCESS)) {
11640 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
11641 }
11642 }
11643
11644 static int
mptsas_post_fw_diag_buffer(mptsas_t * mpt,mptsas_fw_diagnostic_buffer_t * pBuffer,uint32_t * return_code)11645 mptsas_post_fw_diag_buffer(mptsas_t *mpt,
11646 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code)
11647 {
11648 mptsas_diag_request_t diag;
11649 int status, slot_num, post_flags = 0;
11650 mptsas_cmd_t *cmd = NULL;
11651 struct scsi_pkt *pkt;
11652 pMpi2DiagBufferPostReply_t reply;
11653 uint16_t iocstatus;
11654 uint32_t iocloginfo, transfer_length;
11655
11656 /*
11657 * If buffer is not enabled, just leave.
11658 */
11659 *return_code = MPTSAS_FW_DIAG_ERROR_POST_FAILED;
11660 if (!pBuffer->enabled) {
11661 status = DDI_FAILURE;
11662 goto out;
11663 }
11664
11665 /*
11666 * Clear some flags initially.
11667 */
11668 pBuffer->force_release = FALSE;
11669 pBuffer->valid_data = FALSE;
11670 pBuffer->owned_by_firmware = FALSE;
11671
11672 /*
11673 * Get a cmd buffer from the cmd buffer pool
11674 */
11675 if ((slot_num = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) {
11676 status = DDI_FAILURE;
11677 mptsas_log(mpt, CE_NOTE, "command pool is full: Post FW Diag");
11678 goto out;
11679 }
11680 post_flags |= MPTSAS_REQUEST_POOL_CMD;
11681
11682 bzero((caddr_t)cmd, sizeof (*cmd));
11683 bzero((caddr_t)pkt, scsi_pkt_size());
11684
11685 cmd->ioc_cmd_slot = (uint32_t)(slot_num);
11686
11687 diag.pBuffer = pBuffer;
11688 diag.function = MPI2_FUNCTION_DIAG_BUFFER_POST;
11689
11690 /*
11691 * Form a blank cmd/pkt to store the acknowledgement message
11692 */
11693 pkt->pkt_ha_private = (opaque_t)&diag;
11694 pkt->pkt_flags = FLAG_HEAD;
11695 pkt->pkt_time = 60;
11696 cmd->cmd_pkt = pkt;
11697 cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_FW_DIAG;
11698
11699 /*
11700 * Save the command in a slot
11701 */
11702 if (mptsas_save_cmd(mpt, cmd) == TRUE) {
11703 /*
11704 * Once passthru command get slot, set cmd_flags
11705 * CFLAG_PREPARED.
11706 */
11707 cmd->cmd_flags |= CFLAG_PREPARED;
11708 mptsas_start_diag(mpt, cmd);
11709 } else {
11710 mptsas_waitq_add(mpt, cmd);
11711 }
11712
11713 while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) {
11714 cv_wait(&mpt->m_fw_diag_cv, &mpt->m_mutex);
11715 }
11716
11717 if (cmd->cmd_flags & CFLAG_TIMEOUT) {
11718 status = DDI_FAILURE;
11719 mptsas_log(mpt, CE_WARN, "Post FW Diag command timeout");
11720 goto out;
11721 }
11722
11723 /*
11724 * cmd_rfm points to the reply message if a reply was given. Check the
11725 * IOCStatus to make sure everything went OK with the FW diag request
11726 * and set buffer flags.
11727 */
11728 if (cmd->cmd_rfm) {
11729 post_flags |= MPTSAS_ADDRESS_REPLY;
11730 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
11731 DDI_DMA_SYNC_FORCPU);
11732 reply = (pMpi2DiagBufferPostReply_t)(mpt->m_reply_frame +
11733 (cmd->cmd_rfm -
11734 (mpt->m_reply_frame_dma_addr & 0xffffffffu)));
11735
11736 /*
11737 * Get the reply message data
11738 */
11739 iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
11740 &reply->IOCStatus);
11741 iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl,
11742 &reply->IOCLogInfo);
11743 transfer_length = ddi_get32(mpt->m_acc_reply_frame_hdl,
11744 &reply->TransferLength);
11745
11746 /*
11747 * If post failed quit.
11748 */
11749 if (iocstatus != MPI2_IOCSTATUS_SUCCESS) {
11750 status = DDI_FAILURE;
11751 NDBG13(("post FW Diag Buffer failed: IOCStatus=0x%x, "
11752 "IOCLogInfo=0x%x, TransferLength=0x%x", iocstatus,
11753 iocloginfo, transfer_length));
11754 goto out;
11755 }
11756
11757 /*
11758 * Post was successful.
11759 */
11760 pBuffer->valid_data = TRUE;
11761 pBuffer->owned_by_firmware = TRUE;
11762 *return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS;
11763 status = DDI_SUCCESS;
11764 }
11765
11766 out:
11767 /*
11768 * Put the reply frame back on the free queue, increment the free
11769 * index, and write the new index to the free index register. But only
11770 * if this reply is an ADDRESS reply.
11771 */
11772 if (post_flags & MPTSAS_ADDRESS_REPLY) {
11773 ddi_put32(mpt->m_acc_free_queue_hdl,
11774 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index],
11775 cmd->cmd_rfm);
11776 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
11777 DDI_DMA_SYNC_FORDEV);
11778 if (++mpt->m_free_index == mpt->m_free_queue_depth) {
11779 mpt->m_free_index = 0;
11780 }
11781 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
11782 mpt->m_free_index);
11783 }
11784 if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) {
11785 mptsas_remove_cmd(mpt, cmd);
11786 post_flags &= (~MPTSAS_REQUEST_POOL_CMD);
11787 }
11788 if (post_flags & MPTSAS_REQUEST_POOL_CMD) {
11789 mptsas_return_to_pool(mpt, cmd);
11790 }
11791
11792 return (status);
11793 }
11794
11795 static int
mptsas_release_fw_diag_buffer(mptsas_t * mpt,mptsas_fw_diagnostic_buffer_t * pBuffer,uint32_t * return_code,uint32_t diag_type)11796 mptsas_release_fw_diag_buffer(mptsas_t *mpt,
11797 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code,
11798 uint32_t diag_type)
11799 {
11800 mptsas_diag_request_t diag;
11801 int status, slot_num, rel_flags = 0;
11802 mptsas_cmd_t *cmd = NULL;
11803 struct scsi_pkt *pkt;
11804 pMpi2DiagReleaseReply_t reply;
11805 uint16_t iocstatus;
11806 uint32_t iocloginfo;
11807
11808 /*
11809 * If buffer is not enabled, just leave.
11810 */
11811 *return_code = MPTSAS_FW_DIAG_ERROR_RELEASE_FAILED;
11812 if (!pBuffer->enabled) {
11813 mptsas_log(mpt, CE_NOTE, "This buffer type is not supported "
11814 "by the IOC");
11815 status = DDI_FAILURE;
11816 goto out;
11817 }
11818
11819 /*
11820 * Clear some flags initially.
11821 */
11822 pBuffer->force_release = FALSE;
11823 pBuffer->valid_data = FALSE;
11824 pBuffer->owned_by_firmware = FALSE;
11825
11826 /*
11827 * Get a cmd buffer from the cmd buffer pool
11828 */
11829 if ((slot_num = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) {
11830 status = DDI_FAILURE;
11831 mptsas_log(mpt, CE_NOTE, "command pool is full: Release FW "
11832 "Diag");
11833 goto out;
11834 }
11835 rel_flags |= MPTSAS_REQUEST_POOL_CMD;
11836
11837 bzero((caddr_t)cmd, sizeof (*cmd));
11838 bzero((caddr_t)pkt, scsi_pkt_size());
11839
11840 cmd->ioc_cmd_slot = (uint32_t)(slot_num);
11841
11842 diag.pBuffer = pBuffer;
11843 diag.function = MPI2_FUNCTION_DIAG_RELEASE;
11844
11845 /*
11846 * Form a blank cmd/pkt to store the acknowledgement message
11847 */
11848 pkt->pkt_ha_private = (opaque_t)&diag;
11849 pkt->pkt_flags = FLAG_HEAD;
11850 pkt->pkt_time = 60;
11851 cmd->cmd_pkt = pkt;
11852 cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_FW_DIAG;
11853
11854 /*
11855 * Save the command in a slot
11856 */
11857 if (mptsas_save_cmd(mpt, cmd) == TRUE) {
11858 /*
11859 * Once passthru command get slot, set cmd_flags
11860 * CFLAG_PREPARED.
11861 */
11862 cmd->cmd_flags |= CFLAG_PREPARED;
11863 mptsas_start_diag(mpt, cmd);
11864 } else {
11865 mptsas_waitq_add(mpt, cmd);
11866 }
11867
11868 while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) {
11869 cv_wait(&mpt->m_fw_diag_cv, &mpt->m_mutex);
11870 }
11871
11872 if (cmd->cmd_flags & CFLAG_TIMEOUT) {
11873 status = DDI_FAILURE;
11874 mptsas_log(mpt, CE_WARN, "Release FW Diag command timeout");
11875 goto out;
11876 }
11877
11878 /*
11879 * cmd_rfm points to the reply message if a reply was given. Check the
11880 * IOCStatus to make sure everything went OK with the FW diag request
11881 * and set buffer flags.
11882 */
11883 if (cmd->cmd_rfm) {
11884 rel_flags |= MPTSAS_ADDRESS_REPLY;
11885 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
11886 DDI_DMA_SYNC_FORCPU);
11887 reply = (pMpi2DiagReleaseReply_t)(mpt->m_reply_frame +
11888 (cmd->cmd_rfm -
11889 (mpt->m_reply_frame_dma_addr & 0xffffffffu)));
11890
11891 /*
11892 * Get the reply message data
11893 */
11894 iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
11895 &reply->IOCStatus);
11896 iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl,
11897 &reply->IOCLogInfo);
11898
11899 /*
11900 * If release failed quit.
11901 */
11902 if ((iocstatus != MPI2_IOCSTATUS_SUCCESS) ||
11903 pBuffer->owned_by_firmware) {
11904 status = DDI_FAILURE;
11905 NDBG13(("release FW Diag Buffer failed: "
11906 "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus,
11907 iocloginfo));
11908 goto out;
11909 }
11910
11911 /*
11912 * Release was successful.
11913 */
11914 *return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS;
11915 status = DDI_SUCCESS;
11916
11917 /*
11918 * If this was for an UNREGISTER diag type command, clear the
11919 * unique ID.
11920 */
11921 if (diag_type == MPTSAS_FW_DIAG_TYPE_UNREGISTER) {
11922 pBuffer->unique_id = MPTSAS_FW_DIAG_INVALID_UID;
11923 }
11924 }
11925
11926 out:
11927 /*
11928 * Put the reply frame back on the free queue, increment the free
11929 * index, and write the new index to the free index register. But only
11930 * if this reply is an ADDRESS reply.
11931 */
11932 if (rel_flags & MPTSAS_ADDRESS_REPLY) {
11933 ddi_put32(mpt->m_acc_free_queue_hdl,
11934 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index],
11935 cmd->cmd_rfm);
11936 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
11937 DDI_DMA_SYNC_FORDEV);
11938 if (++mpt->m_free_index == mpt->m_free_queue_depth) {
11939 mpt->m_free_index = 0;
11940 }
11941 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
11942 mpt->m_free_index);
11943 }
11944 if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) {
11945 mptsas_remove_cmd(mpt, cmd);
11946 rel_flags &= (~MPTSAS_REQUEST_POOL_CMD);
11947 }
11948 if (rel_flags & MPTSAS_REQUEST_POOL_CMD) {
11949 mptsas_return_to_pool(mpt, cmd);
11950 }
11951
11952 return (status);
11953 }
11954
11955 static int
mptsas_diag_register(mptsas_t * mpt,mptsas_fw_diag_register_t * diag_register,uint32_t * return_code)11956 mptsas_diag_register(mptsas_t *mpt, mptsas_fw_diag_register_t *diag_register,
11957 uint32_t *return_code)
11958 {
11959 mptsas_fw_diagnostic_buffer_t *pBuffer;
11960 uint8_t extended_type, buffer_type, i;
11961 uint32_t buffer_size;
11962 uint32_t unique_id;
11963 int status;
11964
11965 ASSERT(mutex_owned(&mpt->m_mutex));
11966
11967 extended_type = diag_register->ExtendedType;
11968 buffer_type = diag_register->BufferType;
11969 buffer_size = diag_register->RequestedBufferSize;
11970 unique_id = diag_register->UniqueId;
11971
11972 /*
11973 * Check for valid buffer type
11974 */
11975 if (buffer_type >= MPI2_DIAG_BUF_TYPE_COUNT) {
11976 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
11977 return (DDI_FAILURE);
11978 }
11979
11980 /*
11981 * Get the current buffer and look up the unique ID. The unique ID
11982 * should not be found. If it is, the ID is already in use.
11983 */
11984 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id);
11985 pBuffer = &mpt->m_fw_diag_buffer_list[buffer_type];
11986 if (i != MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) {
11987 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
11988 return (DDI_FAILURE);
11989 }
11990
11991 /*
11992 * The buffer's unique ID should not be registered yet, and the given
11993 * unique ID cannot be 0.
11994 */
11995 if ((pBuffer->unique_id != MPTSAS_FW_DIAG_INVALID_UID) ||
11996 (unique_id == MPTSAS_FW_DIAG_INVALID_UID)) {
11997 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
11998 return (DDI_FAILURE);
11999 }
12000
12001 /*
12002 * If this buffer is already posted as immediate, just change owner.
12003 */
12004 if (pBuffer->immediate && pBuffer->owned_by_firmware &&
12005 (pBuffer->unique_id == MPTSAS_FW_DIAG_INVALID_UID)) {
12006 pBuffer->immediate = FALSE;
12007 pBuffer->unique_id = unique_id;
12008 return (DDI_SUCCESS);
12009 }
12010
12011 /*
12012 * Post a new buffer after checking if it's enabled. The DMA buffer
12013 * that is allocated will be contiguous (sgl_len = 1).
12014 */
12015 if (!pBuffer->enabled) {
12016 *return_code = MPTSAS_FW_DIAG_ERROR_NO_BUFFER;
12017 return (DDI_FAILURE);
12018 }
12019 bzero(&pBuffer->buffer_data, sizeof (mptsas_dma_alloc_state_t));
12020 pBuffer->buffer_data.size = buffer_size;
12021 if (mptsas_dma_alloc(mpt, &pBuffer->buffer_data) != DDI_SUCCESS) {
12022 mptsas_log(mpt, CE_WARN, "failed to alloc DMA resource for "
12023 "diag buffer: size = %d bytes", buffer_size);
12024 *return_code = MPTSAS_FW_DIAG_ERROR_NO_BUFFER;
12025 return (DDI_FAILURE);
12026 }
12027
12028 /*
12029 * Copy the given info to the diag buffer and post the buffer.
12030 */
12031 pBuffer->buffer_type = buffer_type;
12032 pBuffer->immediate = FALSE;
12033 if (buffer_type == MPI2_DIAG_BUF_TYPE_TRACE) {
12034 for (i = 0; i < (sizeof (pBuffer->product_specific) / 4);
12035 i++) {
12036 pBuffer->product_specific[i] =
12037 diag_register->ProductSpecific[i];
12038 }
12039 }
12040 pBuffer->extended_type = extended_type;
12041 pBuffer->unique_id = unique_id;
12042 status = mptsas_post_fw_diag_buffer(mpt, pBuffer, return_code);
12043
12044 if (mptsas_check_dma_handle(pBuffer->buffer_data.handle) !=
12045 DDI_SUCCESS) {
12046 mptsas_log(mpt, CE_WARN, "Check of DMA handle failed in "
12047 "mptsas_diag_register.");
12048 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
12049 status = DDI_FAILURE;
12050 }
12051
12052 /*
12053 * In case there was a failure, free the DMA buffer.
12054 */
12055 if (status == DDI_FAILURE) {
12056 mptsas_dma_free(&pBuffer->buffer_data);
12057 }
12058
12059 return (status);
12060 }
12061
12062 static int
mptsas_diag_unregister(mptsas_t * mpt,mptsas_fw_diag_unregister_t * diag_unregister,uint32_t * return_code)12063 mptsas_diag_unregister(mptsas_t *mpt,
12064 mptsas_fw_diag_unregister_t *diag_unregister, uint32_t *return_code)
12065 {
12066 mptsas_fw_diagnostic_buffer_t *pBuffer;
12067 uint8_t i;
12068 uint32_t unique_id;
12069 int status;
12070
12071 ASSERT(mutex_owned(&mpt->m_mutex));
12072
12073 unique_id = diag_unregister->UniqueId;
12074
12075 /*
12076 * Get the current buffer and look up the unique ID. The unique ID
12077 * should be there.
12078 */
12079 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id);
12080 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) {
12081 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
12082 return (DDI_FAILURE);
12083 }
12084
12085 pBuffer = &mpt->m_fw_diag_buffer_list[i];
12086
12087 /*
12088 * Try to release the buffer from FW before freeing it. If release
12089 * fails, don't free the DMA buffer in case FW tries to access it
12090 * later. If buffer is not owned by firmware, can't release it.
12091 */
12092 if (!pBuffer->owned_by_firmware) {
12093 status = DDI_SUCCESS;
12094 } else {
12095 status = mptsas_release_fw_diag_buffer(mpt, pBuffer,
12096 return_code, MPTSAS_FW_DIAG_TYPE_UNREGISTER);
12097 }
12098
12099 /*
12100 * At this point, return the current status no matter what happens with
12101 * the DMA buffer.
12102 */
12103 pBuffer->unique_id = MPTSAS_FW_DIAG_INVALID_UID;
12104 if (status == DDI_SUCCESS) {
12105 if (mptsas_check_dma_handle(pBuffer->buffer_data.handle) !=
12106 DDI_SUCCESS) {
12107 mptsas_log(mpt, CE_WARN, "Check of DMA handle failed "
12108 "in mptsas_diag_unregister.");
12109 ddi_fm_service_impact(mpt->m_dip,
12110 DDI_SERVICE_UNAFFECTED);
12111 }
12112 mptsas_dma_free(&pBuffer->buffer_data);
12113 }
12114
12115 return (status);
12116 }
12117
12118 static int
mptsas_diag_query(mptsas_t * mpt,mptsas_fw_diag_query_t * diag_query,uint32_t * return_code)12119 mptsas_diag_query(mptsas_t *mpt, mptsas_fw_diag_query_t *diag_query,
12120 uint32_t *return_code)
12121 {
12122 mptsas_fw_diagnostic_buffer_t *pBuffer;
12123 uint8_t i;
12124 uint32_t unique_id;
12125
12126 ASSERT(mutex_owned(&mpt->m_mutex));
12127
12128 unique_id = diag_query->UniqueId;
12129
12130 /*
12131 * If ID is valid, query on ID.
12132 * If ID is invalid, query on buffer type.
12133 */
12134 if (unique_id == MPTSAS_FW_DIAG_INVALID_UID) {
12135 i = diag_query->BufferType;
12136 if (i >= MPI2_DIAG_BUF_TYPE_COUNT) {
12137 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
12138 return (DDI_FAILURE);
12139 }
12140 } else {
12141 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id);
12142 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) {
12143 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
12144 return (DDI_FAILURE);
12145 }
12146 }
12147
12148 /*
12149 * Fill query structure with the diag buffer info.
12150 */
12151 pBuffer = &mpt->m_fw_diag_buffer_list[i];
12152 diag_query->BufferType = pBuffer->buffer_type;
12153 diag_query->ExtendedType = pBuffer->extended_type;
12154 if (diag_query->BufferType == MPI2_DIAG_BUF_TYPE_TRACE) {
12155 for (i = 0; i < (sizeof (diag_query->ProductSpecific) / 4);
12156 i++) {
12157 diag_query->ProductSpecific[i] =
12158 pBuffer->product_specific[i];
12159 }
12160 }
12161 diag_query->TotalBufferSize = pBuffer->buffer_data.size;
12162 diag_query->DriverAddedBufferSize = 0;
12163 diag_query->UniqueId = pBuffer->unique_id;
12164 diag_query->ApplicationFlags = 0;
12165 diag_query->DiagnosticFlags = 0;
12166
12167 /*
12168 * Set/Clear application flags
12169 */
12170 if (pBuffer->immediate) {
12171 diag_query->ApplicationFlags &= ~MPTSAS_FW_DIAG_FLAG_APP_OWNED;
12172 } else {
12173 diag_query->ApplicationFlags |= MPTSAS_FW_DIAG_FLAG_APP_OWNED;
12174 }
12175 if (pBuffer->valid_data || pBuffer->owned_by_firmware) {
12176 diag_query->ApplicationFlags |=
12177 MPTSAS_FW_DIAG_FLAG_BUFFER_VALID;
12178 } else {
12179 diag_query->ApplicationFlags &=
12180 ~MPTSAS_FW_DIAG_FLAG_BUFFER_VALID;
12181 }
12182 if (pBuffer->owned_by_firmware) {
12183 diag_query->ApplicationFlags |=
12184 MPTSAS_FW_DIAG_FLAG_FW_BUFFER_ACCESS;
12185 } else {
12186 diag_query->ApplicationFlags &=
12187 ~MPTSAS_FW_DIAG_FLAG_FW_BUFFER_ACCESS;
12188 }
12189
12190 return (DDI_SUCCESS);
12191 }
12192
12193 static int
mptsas_diag_read_buffer(mptsas_t * mpt,mptsas_diag_read_buffer_t * diag_read_buffer,uint8_t * ioctl_buf,uint32_t * return_code,int ioctl_mode)12194 mptsas_diag_read_buffer(mptsas_t *mpt,
12195 mptsas_diag_read_buffer_t *diag_read_buffer, uint8_t *ioctl_buf,
12196 uint32_t *return_code, int ioctl_mode)
12197 {
12198 mptsas_fw_diagnostic_buffer_t *pBuffer;
12199 uint8_t i, *pData;
12200 uint32_t unique_id, byte;
12201 int status;
12202
12203 ASSERT(mutex_owned(&mpt->m_mutex));
12204
12205 unique_id = diag_read_buffer->UniqueId;
12206
12207 /*
12208 * Get the current buffer and look up the unique ID. The unique ID
12209 * should be there.
12210 */
12211 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id);
12212 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) {
12213 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
12214 return (DDI_FAILURE);
12215 }
12216
12217 pBuffer = &mpt->m_fw_diag_buffer_list[i];
12218
12219 /*
12220 * Make sure requested read is within limits
12221 */
12222 if (diag_read_buffer->StartingOffset + diag_read_buffer->BytesToRead >
12223 pBuffer->buffer_data.size) {
12224 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
12225 return (DDI_FAILURE);
12226 }
12227
12228 /*
12229 * Copy the requested data from DMA to the diag_read_buffer. The DMA
12230 * buffer that was allocated is one contiguous buffer.
12231 */
12232 pData = (uint8_t *)(pBuffer->buffer_data.memp +
12233 diag_read_buffer->StartingOffset);
12234 (void) ddi_dma_sync(pBuffer->buffer_data.handle, 0, 0,
12235 DDI_DMA_SYNC_FORCPU);
12236 for (byte = 0; byte < diag_read_buffer->BytesToRead; byte++) {
12237 if (ddi_copyout(pData + byte, ioctl_buf + byte, 1, ioctl_mode)
12238 != 0) {
12239 return (DDI_FAILURE);
12240 }
12241 }
12242 diag_read_buffer->Status = 0;
12243
12244 /*
12245 * Set or clear the Force Release flag.
12246 */
12247 if (pBuffer->force_release) {
12248 diag_read_buffer->Flags |= MPTSAS_FW_DIAG_FLAG_FORCE_RELEASE;
12249 } else {
12250 diag_read_buffer->Flags &= ~MPTSAS_FW_DIAG_FLAG_FORCE_RELEASE;
12251 }
12252
12253 /*
12254 * If buffer is to be reregistered, make sure it's not already owned by
12255 * firmware first.
12256 */
12257 status = DDI_SUCCESS;
12258 if (!pBuffer->owned_by_firmware) {
12259 if (diag_read_buffer->Flags & MPTSAS_FW_DIAG_FLAG_REREGISTER) {
12260 status = mptsas_post_fw_diag_buffer(mpt, pBuffer,
12261 return_code);
12262 }
12263 }
12264
12265 return (status);
12266 }
12267
12268 static int
mptsas_diag_release(mptsas_t * mpt,mptsas_fw_diag_release_t * diag_release,uint32_t * return_code)12269 mptsas_diag_release(mptsas_t *mpt, mptsas_fw_diag_release_t *diag_release,
12270 uint32_t *return_code)
12271 {
12272 mptsas_fw_diagnostic_buffer_t *pBuffer;
12273 uint8_t i;
12274 uint32_t unique_id;
12275 int status;
12276
12277 ASSERT(mutex_owned(&mpt->m_mutex));
12278
12279 unique_id = diag_release->UniqueId;
12280
12281 /*
12282 * Get the current buffer and look up the unique ID. The unique ID
12283 * should be there.
12284 */
12285 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id);
12286 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) {
12287 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
12288 return (DDI_FAILURE);
12289 }
12290
12291 pBuffer = &mpt->m_fw_diag_buffer_list[i];
12292
12293 /*
12294 * If buffer is not owned by firmware, it's already been released.
12295 */
12296 if (!pBuffer->owned_by_firmware) {
12297 *return_code = MPTSAS_FW_DIAG_ERROR_ALREADY_RELEASED;
12298 return (DDI_FAILURE);
12299 }
12300
12301 /*
12302 * Release the buffer.
12303 */
12304 status = mptsas_release_fw_diag_buffer(mpt, pBuffer, return_code,
12305 MPTSAS_FW_DIAG_TYPE_RELEASE);
12306 return (status);
12307 }
12308
12309 static int
mptsas_do_diag_action(mptsas_t * mpt,uint32_t action,uint8_t * diag_action,uint32_t length,uint32_t * return_code,int ioctl_mode)12310 mptsas_do_diag_action(mptsas_t *mpt, uint32_t action, uint8_t *diag_action,
12311 uint32_t length, uint32_t *return_code, int ioctl_mode)
12312 {
12313 mptsas_fw_diag_register_t diag_register;
12314 mptsas_fw_diag_unregister_t diag_unregister;
12315 mptsas_fw_diag_query_t diag_query;
12316 mptsas_diag_read_buffer_t diag_read_buffer;
12317 mptsas_fw_diag_release_t diag_release;
12318 int status = DDI_SUCCESS;
12319 uint32_t original_return_code, read_buf_len;
12320
12321 ASSERT(mutex_owned(&mpt->m_mutex));
12322
12323 original_return_code = *return_code;
12324 *return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS;
12325
12326 switch (action) {
12327 case MPTSAS_FW_DIAG_TYPE_REGISTER:
12328 if (!length) {
12329 *return_code =
12330 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
12331 status = DDI_FAILURE;
12332 break;
12333 }
12334 if (ddi_copyin(diag_action, &diag_register,
12335 sizeof (diag_register), ioctl_mode) != 0) {
12336 return (DDI_FAILURE);
12337 }
12338 status = mptsas_diag_register(mpt, &diag_register,
12339 return_code);
12340 break;
12341
12342 case MPTSAS_FW_DIAG_TYPE_UNREGISTER:
12343 if (length < sizeof (diag_unregister)) {
12344 *return_code =
12345 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
12346 status = DDI_FAILURE;
12347 break;
12348 }
12349 if (ddi_copyin(diag_action, &diag_unregister,
12350 sizeof (diag_unregister), ioctl_mode) != 0) {
12351 return (DDI_FAILURE);
12352 }
12353 status = mptsas_diag_unregister(mpt, &diag_unregister,
12354 return_code);
12355 break;
12356
12357 case MPTSAS_FW_DIAG_TYPE_QUERY:
12358 if (length < sizeof (diag_query)) {
12359 *return_code =
12360 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
12361 status = DDI_FAILURE;
12362 break;
12363 }
12364 if (ddi_copyin(diag_action, &diag_query,
12365 sizeof (diag_query), ioctl_mode) != 0) {
12366 return (DDI_FAILURE);
12367 }
12368 status = mptsas_diag_query(mpt, &diag_query,
12369 return_code);
12370 if (status == DDI_SUCCESS) {
12371 if (ddi_copyout(&diag_query, diag_action,
12372 sizeof (diag_query), ioctl_mode) != 0) {
12373 return (DDI_FAILURE);
12374 }
12375 }
12376 break;
12377
12378 case MPTSAS_FW_DIAG_TYPE_READ_BUFFER:
12379 if (ddi_copyin(diag_action, &diag_read_buffer,
12380 sizeof (diag_read_buffer) - 4, ioctl_mode) != 0) {
12381 return (DDI_FAILURE);
12382 }
12383 read_buf_len = sizeof (diag_read_buffer) -
12384 sizeof (diag_read_buffer.DataBuffer) +
12385 diag_read_buffer.BytesToRead;
12386 if (length < read_buf_len) {
12387 *return_code =
12388 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
12389 status = DDI_FAILURE;
12390 break;
12391 }
12392 status = mptsas_diag_read_buffer(mpt,
12393 &diag_read_buffer, diag_action +
12394 sizeof (diag_read_buffer) - 4, return_code,
12395 ioctl_mode);
12396 if (status == DDI_SUCCESS) {
12397 if (ddi_copyout(&diag_read_buffer, diag_action,
12398 sizeof (diag_read_buffer) - 4, ioctl_mode)
12399 != 0) {
12400 return (DDI_FAILURE);
12401 }
12402 }
12403 break;
12404
12405 case MPTSAS_FW_DIAG_TYPE_RELEASE:
12406 if (length < sizeof (diag_release)) {
12407 *return_code =
12408 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
12409 status = DDI_FAILURE;
12410 break;
12411 }
12412 if (ddi_copyin(diag_action, &diag_release,
12413 sizeof (diag_release), ioctl_mode) != 0) {
12414 return (DDI_FAILURE);
12415 }
12416 status = mptsas_diag_release(mpt, &diag_release,
12417 return_code);
12418 break;
12419
12420 default:
12421 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
12422 status = DDI_FAILURE;
12423 break;
12424 }
12425
12426 if ((status == DDI_FAILURE) &&
12427 (original_return_code == MPTSAS_FW_DIAG_NEW) &&
12428 (*return_code != MPTSAS_FW_DIAG_ERROR_SUCCESS)) {
12429 status = DDI_SUCCESS;
12430 }
12431
12432 return (status);
12433 }
12434
12435 static int
mptsas_diag_action(mptsas_t * mpt,mptsas_diag_action_t * user_data,int mode)12436 mptsas_diag_action(mptsas_t *mpt, mptsas_diag_action_t *user_data, int mode)
12437 {
12438 int status;
12439 mptsas_diag_action_t driver_data;
12440
12441 ASSERT(mutex_owned(&mpt->m_mutex));
12442
12443 /*
12444 * Copy the user data to a driver data buffer.
12445 */
12446 if (ddi_copyin(user_data, &driver_data, sizeof (mptsas_diag_action_t),
12447 mode) == 0) {
12448 /*
12449 * Send diag action request if Action is valid
12450 */
12451 if (driver_data.Action == MPTSAS_FW_DIAG_TYPE_REGISTER ||
12452 driver_data.Action == MPTSAS_FW_DIAG_TYPE_UNREGISTER ||
12453 driver_data.Action == MPTSAS_FW_DIAG_TYPE_QUERY ||
12454 driver_data.Action == MPTSAS_FW_DIAG_TYPE_READ_BUFFER ||
12455 driver_data.Action == MPTSAS_FW_DIAG_TYPE_RELEASE) {
12456 status = mptsas_do_diag_action(mpt, driver_data.Action,
12457 (void *)(uintptr_t)driver_data.PtrDiagAction,
12458 driver_data.Length, &driver_data.ReturnCode,
12459 mode);
12460 if (status == DDI_SUCCESS) {
12461 if (ddi_copyout(&driver_data.ReturnCode,
12462 &user_data->ReturnCode,
12463 sizeof (user_data->ReturnCode), mode)
12464 != 0) {
12465 status = EFAULT;
12466 } else {
12467 status = 0;
12468 }
12469 } else {
12470 status = EIO;
12471 }
12472 } else {
12473 status = EINVAL;
12474 }
12475 } else {
12476 status = EFAULT;
12477 }
12478
12479 return (status);
12480 }
12481
12482 /*
12483 * This routine handles the "event query" ioctl.
12484 */
12485 static int
mptsas_event_query(mptsas_t * mpt,mptsas_event_query_t * data,int mode,int * rval)12486 mptsas_event_query(mptsas_t *mpt, mptsas_event_query_t *data, int mode,
12487 int *rval)
12488 {
12489 int status;
12490 mptsas_event_query_t driverdata;
12491 uint8_t i;
12492
12493 driverdata.Entries = MPTSAS_EVENT_QUEUE_SIZE;
12494
12495 mutex_enter(&mpt->m_mutex);
12496 for (i = 0; i < 4; i++) {
12497 driverdata.Types[i] = mpt->m_event_mask[i];
12498 }
12499 mutex_exit(&mpt->m_mutex);
12500
12501 if (ddi_copyout(&driverdata, data, sizeof (driverdata), mode) != 0) {
12502 status = EFAULT;
12503 } else {
12504 *rval = MPTIOCTL_STATUS_GOOD;
12505 status = 0;
12506 }
12507
12508 return (status);
12509 }
12510
12511 /*
12512 * This routine handles the "event enable" ioctl.
12513 */
12514 static int
mptsas_event_enable(mptsas_t * mpt,mptsas_event_enable_t * data,int mode,int * rval)12515 mptsas_event_enable(mptsas_t *mpt, mptsas_event_enable_t *data, int mode,
12516 int *rval)
12517 {
12518 int status;
12519 mptsas_event_enable_t driverdata;
12520 uint8_t i;
12521
12522 if (ddi_copyin(data, &driverdata, sizeof (driverdata), mode) == 0) {
12523 mutex_enter(&mpt->m_mutex);
12524 for (i = 0; i < 4; i++) {
12525 mpt->m_event_mask[i] = driverdata.Types[i];
12526 }
12527 mutex_exit(&mpt->m_mutex);
12528
12529 *rval = MPTIOCTL_STATUS_GOOD;
12530 status = 0;
12531 } else {
12532 status = EFAULT;
12533 }
12534 return (status);
12535 }
12536
12537 /*
12538 * This routine handles the "event report" ioctl.
12539 */
12540 static int
mptsas_event_report(mptsas_t * mpt,mptsas_event_report_t * data,int mode,int * rval)12541 mptsas_event_report(mptsas_t *mpt, mptsas_event_report_t *data, int mode,
12542 int *rval)
12543 {
12544 int status;
12545 mptsas_event_report_t driverdata;
12546
12547 mutex_enter(&mpt->m_mutex);
12548
12549 if (ddi_copyin(&data->Size, &driverdata.Size, sizeof (driverdata.Size),
12550 mode) == 0) {
12551 if (driverdata.Size >= sizeof (mpt->m_events)) {
12552 if (ddi_copyout(mpt->m_events, data->Events,
12553 sizeof (mpt->m_events), mode) != 0) {
12554 status = EFAULT;
12555 } else {
12556 if (driverdata.Size > sizeof (mpt->m_events)) {
12557 driverdata.Size =
12558 sizeof (mpt->m_events);
12559 if (ddi_copyout(&driverdata.Size,
12560 &data->Size,
12561 sizeof (driverdata.Size),
12562 mode) != 0) {
12563 status = EFAULT;
12564 } else {
12565 *rval = MPTIOCTL_STATUS_GOOD;
12566 status = 0;
12567 }
12568 } else {
12569 *rval = MPTIOCTL_STATUS_GOOD;
12570 status = 0;
12571 }
12572 }
12573 } else {
12574 *rval = MPTIOCTL_STATUS_LEN_TOO_SHORT;
12575 status = 0;
12576 }
12577 } else {
12578 status = EFAULT;
12579 }
12580
12581 mutex_exit(&mpt->m_mutex);
12582 return (status);
12583 }
12584
12585 static void
mptsas_lookup_pci_data(mptsas_t * mpt,mptsas_adapter_data_t * adapter_data)12586 mptsas_lookup_pci_data(mptsas_t *mpt, mptsas_adapter_data_t *adapter_data)
12587 {
12588 int *reg_data;
12589 uint_t reglen;
12590
12591 /*
12592 * Lookup the 'reg' property and extract the other data
12593 */
12594 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, mpt->m_dip,
12595 DDI_PROP_DONTPASS, "reg", ®_data, ®len) ==
12596 DDI_PROP_SUCCESS) {
12597 /*
12598 * Extract the PCI data from the 'reg' property first DWORD.
12599 * The entry looks like the following:
12600 * First DWORD:
12601 * Bits 0 - 7 8-bit Register number
12602 * Bits 8 - 10 3-bit Function number
12603 * Bits 11 - 15 5-bit Device number
12604 * Bits 16 - 23 8-bit Bus number
12605 * Bits 24 - 25 2-bit Address Space type identifier
12606 *
12607 */
12608 adapter_data->PciInformation.u.bits.BusNumber =
12609 (reg_data[0] & 0x00FF0000) >> 16;
12610 adapter_data->PciInformation.u.bits.DeviceNumber =
12611 (reg_data[0] & 0x0000F800) >> 11;
12612 adapter_data->PciInformation.u.bits.FunctionNumber =
12613 (reg_data[0] & 0x00000700) >> 8;
12614 ddi_prop_free((void *)reg_data);
12615 } else {
12616 /*
12617 * If we can't determine the PCI data then we fill in FF's for
12618 * the data to indicate this.
12619 */
12620 adapter_data->PCIDeviceHwId = 0xFFFFFFFF;
12621 adapter_data->MpiPortNumber = 0xFFFFFFFF;
12622 adapter_data->PciInformation.u.AsDWORD = 0xFFFFFFFF;
12623 }
12624
12625 /*
12626 * Saved in the mpt->m_fwversion
12627 */
12628 adapter_data->MpiFirmwareVersion = mpt->m_fwversion;
12629 }
12630
12631 static void
mptsas_read_adapter_data(mptsas_t * mpt,mptsas_adapter_data_t * adapter_data)12632 mptsas_read_adapter_data(mptsas_t *mpt, mptsas_adapter_data_t *adapter_data)
12633 {
12634 char *driver_verstr = MPTSAS_MOD_STRING;
12635
12636 mptsas_lookup_pci_data(mpt, adapter_data);
12637 adapter_data->AdapterType = mpt->m_MPI25 ?
12638 MPTIOCTL_ADAPTER_TYPE_SAS3 :
12639 MPTIOCTL_ADAPTER_TYPE_SAS2;
12640 adapter_data->PCIDeviceHwId = (uint32_t)mpt->m_devid;
12641 adapter_data->PCIDeviceHwRev = (uint32_t)mpt->m_revid;
12642 adapter_data->SubSystemId = (uint32_t)mpt->m_ssid;
12643 adapter_data->SubsystemVendorId = (uint32_t)mpt->m_svid;
12644 (void) strcpy((char *)&adapter_data->DriverVersion[0], driver_verstr);
12645 adapter_data->BiosVersion = 0;
12646 (void) mptsas_get_bios_page3(mpt, &adapter_data->BiosVersion);
12647 }
12648
12649 static void
mptsas_read_pci_info(mptsas_t * mpt,mptsas_pci_info_t * pci_info)12650 mptsas_read_pci_info(mptsas_t *mpt, mptsas_pci_info_t *pci_info)
12651 {
12652 int *reg_data, i;
12653 uint_t reglen;
12654
12655 /*
12656 * Lookup the 'reg' property and extract the other data
12657 */
12658 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, mpt->m_dip,
12659 DDI_PROP_DONTPASS, "reg", ®_data, ®len) ==
12660 DDI_PROP_SUCCESS) {
12661 /*
12662 * Extract the PCI data from the 'reg' property first DWORD.
12663 * The entry looks like the following:
12664 * First DWORD:
12665 * Bits 8 - 10 3-bit Function number
12666 * Bits 11 - 15 5-bit Device number
12667 * Bits 16 - 23 8-bit Bus number
12668 */
12669 pci_info->BusNumber = (reg_data[0] & 0x00FF0000) >> 16;
12670 pci_info->DeviceNumber = (reg_data[0] & 0x0000F800) >> 11;
12671 pci_info->FunctionNumber = (reg_data[0] & 0x00000700) >> 8;
12672 ddi_prop_free((void *)reg_data);
12673 } else {
12674 /*
12675 * If we can't determine the PCI info then we fill in FF's for
12676 * the data to indicate this.
12677 */
12678 pci_info->BusNumber = 0xFFFFFFFF;
12679 pci_info->DeviceNumber = 0xFF;
12680 pci_info->FunctionNumber = 0xFF;
12681 }
12682
12683 /*
12684 * Now get the interrupt vector and the pci header. The vector can
12685 * only be 0 right now. The header is the first 256 bytes of config
12686 * space.
12687 */
12688 pci_info->InterruptVector = 0;
12689 for (i = 0; i < sizeof (pci_info->PciHeader); i++) {
12690 pci_info->PciHeader[i] = pci_config_get8(mpt->m_config_handle,
12691 i);
12692 }
12693 }
12694
12695 static int
mptsas_reg_access(mptsas_t * mpt,mptsas_reg_access_t * data,int mode)12696 mptsas_reg_access(mptsas_t *mpt, mptsas_reg_access_t *data, int mode)
12697 {
12698 int status = 0;
12699 mptsas_reg_access_t driverdata;
12700
12701 mutex_enter(&mpt->m_mutex);
12702 if (ddi_copyin(data, &driverdata, sizeof (driverdata), mode) == 0) {
12703 switch (driverdata.Command) {
12704 /*
12705 * IO access is not supported.
12706 */
12707 case REG_IO_READ:
12708 case REG_IO_WRITE:
12709 mptsas_log(mpt, CE_WARN, "IO access is not "
12710 "supported. Use memory access.");
12711 status = EINVAL;
12712 break;
12713
12714 case REG_MEM_READ:
12715 driverdata.RegData = mptsas_hirrd(mpt,
12716 (uint32_t *)(void *)mpt->m_reg +
12717 driverdata.RegOffset);
12718 if (ddi_copyout(&driverdata.RegData,
12719 &data->RegData,
12720 sizeof (driverdata.RegData), mode) != 0) {
12721 mptsas_log(mpt, CE_WARN, "Register "
12722 "Read Failed");
12723 status = EFAULT;
12724 }
12725 break;
12726
12727 case REG_MEM_WRITE:
12728 ddi_put32(mpt->m_datap,
12729 (uint32_t *)(void *)mpt->m_reg +
12730 driverdata.RegOffset,
12731 driverdata.RegData);
12732 break;
12733
12734 default:
12735 status = EINVAL;
12736 break;
12737 }
12738 } else {
12739 status = EFAULT;
12740 }
12741
12742 mutex_exit(&mpt->m_mutex);
12743 return (status);
12744 }
12745
12746 static int
led_control(mptsas_t * mpt,intptr_t data,int mode)12747 led_control(mptsas_t *mpt, intptr_t data, int mode)
12748 {
12749 int ret = 0;
12750 mptsas_led_control_t lc;
12751 mptsas_enclosure_t *mep;
12752 uint16_t slotidx;
12753
12754 if (ddi_copyin((void *)data, &lc, sizeof (lc), mode) != 0) {
12755 return (EFAULT);
12756 }
12757
12758 if ((lc.Command != MPTSAS_LEDCTL_FLAG_SET &&
12759 lc.Command != MPTSAS_LEDCTL_FLAG_GET) ||
12760 lc.Led < MPTSAS_LEDCTL_LED_MIN ||
12761 lc.Led > MPTSAS_LEDCTL_LED_MAX ||
12762 (lc.Command == MPTSAS_LEDCTL_FLAG_SET && lc.LedStatus != 0 &&
12763 lc.LedStatus != 1)) {
12764 return (EINVAL);
12765 }
12766
12767 if ((lc.Command == MPTSAS_LEDCTL_FLAG_SET && (mode & FWRITE) == 0) ||
12768 (lc.Command == MPTSAS_LEDCTL_FLAG_GET && (mode & FREAD) == 0))
12769 return (EACCES);
12770
12771 /* Locate the required enclosure */
12772 mutex_enter(&mpt->m_mutex);
12773 mep = mptsas_enc_lookup(mpt, lc.Enclosure);
12774 if (mep == NULL) {
12775 mutex_exit(&mpt->m_mutex);
12776 return (ENOENT);
12777 }
12778
12779 if (lc.Slot < mep->me_fslot) {
12780 mutex_exit(&mpt->m_mutex);
12781 return (ENOENT);
12782 }
12783
12784 /*
12785 * Slots on the enclosure are maintained in array where me_fslot is
12786 * entry zero. We normalize the requested slot.
12787 */
12788 slotidx = lc.Slot - mep->me_fslot;
12789 if (slotidx >= mep->me_nslots) {
12790 mutex_exit(&mpt->m_mutex);
12791 return (ENOENT);
12792 }
12793
12794 if (lc.Command == MPTSAS_LEDCTL_FLAG_SET) {
12795 /* Update our internal LED state. */
12796 mep->me_slotleds[slotidx] &= ~(1 << (lc.Led - 1));
12797 mep->me_slotleds[slotidx] |= lc.LedStatus << (lc.Led - 1);
12798
12799 /* Flush it to the controller. */
12800 ret = mptsas_flush_led_status(mpt, mep, slotidx);
12801 mutex_exit(&mpt->m_mutex);
12802 return (ret);
12803 }
12804
12805 /* Return our internal LED state. */
12806 lc.LedStatus = (mep->me_slotleds[slotidx] >> (lc.Led - 1)) & 1;
12807 mutex_exit(&mpt->m_mutex);
12808
12809 if (ddi_copyout(&lc, (void *)data, sizeof (lc), mode) != 0) {
12810 return (EFAULT);
12811 }
12812
12813 return (0);
12814 }
12815
12816 static int
get_disk_info(mptsas_t * mpt,intptr_t data,int mode)12817 get_disk_info(mptsas_t *mpt, intptr_t data, int mode)
12818 {
12819 uint16_t i = 0;
12820 uint16_t count = 0;
12821 int ret = 0;
12822 mptsas_target_t *ptgt;
12823 mptsas_disk_info_t *di;
12824 STRUCT_DECL(mptsas_get_disk_info, gdi);
12825
12826 if ((mode & FREAD) == 0)
12827 return (EACCES);
12828
12829 STRUCT_INIT(gdi, get_udatamodel());
12830
12831 if (ddi_copyin((void *)data, STRUCT_BUF(gdi), STRUCT_SIZE(gdi),
12832 mode) != 0) {
12833 return (EFAULT);
12834 }
12835
12836 /* Find out how many targets there are. */
12837 mutex_enter(&mpt->m_mutex);
12838 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
12839 ptgt = refhash_next(mpt->m_targets, ptgt)) {
12840 count++;
12841 }
12842 mutex_exit(&mpt->m_mutex);
12843
12844 /*
12845 * If we haven't been asked to copy out information on each target,
12846 * then just return the count.
12847 */
12848 STRUCT_FSET(gdi, DiskCount, count);
12849 if (STRUCT_FGETP(gdi, PtrDiskInfoArray) == NULL)
12850 goto copy_out;
12851
12852 /*
12853 * If we haven't been given a large enough buffer to copy out into,
12854 * let the caller know.
12855 */
12856 if (STRUCT_FGET(gdi, DiskInfoArraySize) <
12857 count * sizeof (mptsas_disk_info_t)) {
12858 ret = ENOSPC;
12859 goto copy_out;
12860 }
12861
12862 di = kmem_zalloc(count * sizeof (mptsas_disk_info_t), KM_SLEEP);
12863
12864 mutex_enter(&mpt->m_mutex);
12865 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
12866 ptgt = refhash_next(mpt->m_targets, ptgt)) {
12867 if (i >= count) {
12868 /*
12869 * The number of targets changed while we weren't
12870 * looking, so give up.
12871 */
12872 refhash_rele(mpt->m_targets, ptgt);
12873 mutex_exit(&mpt->m_mutex);
12874 kmem_free(di, count * sizeof (mptsas_disk_info_t));
12875 return (EAGAIN);
12876 }
12877 di[i].Instance = mpt->m_instance;
12878 di[i].Enclosure = ptgt->m_enclosure;
12879 di[i].Slot = ptgt->m_slot_num;
12880 di[i].SasAddress = ptgt->m_addr.mta_wwn;
12881 i++;
12882 }
12883 mutex_exit(&mpt->m_mutex);
12884 STRUCT_FSET(gdi, DiskCount, i);
12885
12886 /* Copy out the disk information to the caller. */
12887 if (ddi_copyout((void *)di, STRUCT_FGETP(gdi, PtrDiskInfoArray),
12888 i * sizeof (mptsas_disk_info_t), mode) != 0) {
12889 ret = EFAULT;
12890 }
12891
12892 kmem_free(di, count * sizeof (mptsas_disk_info_t));
12893
12894 copy_out:
12895 if (ddi_copyout(STRUCT_BUF(gdi), (void *)data, STRUCT_SIZE(gdi),
12896 mode) != 0) {
12897 ret = EFAULT;
12898 }
12899
12900 return (ret);
12901 }
12902
12903 static int
mptsas_ioctl(dev_t dev,int cmd,intptr_t data,int mode,cred_t * credp,int * rval)12904 mptsas_ioctl(dev_t dev, int cmd, intptr_t data, int mode, cred_t *credp,
12905 int *rval)
12906 {
12907 int status = 0;
12908 mptsas_t *mpt;
12909 mptsas_update_flash_t flashdata;
12910 mptsas_pass_thru_t passthru_data;
12911 mptsas_adapter_data_t adapter_data;
12912 mptsas_pci_info_t pci_info;
12913 int copylen;
12914
12915 int iport_flag = 0;
12916 dev_info_t *dip = NULL;
12917 mptsas_phymask_t phymask = 0;
12918 struct devctl_iocdata *dcp = NULL;
12919 char *addr = NULL;
12920 mptsas_target_t *ptgt = NULL;
12921
12922 *rval = MPTIOCTL_STATUS_GOOD;
12923 if (secpolicy_sys_config(credp, B_FALSE) != 0) {
12924 return (EPERM);
12925 }
12926
12927 mpt = ddi_get_soft_state(mptsas_state, MINOR2INST(getminor(dev)));
12928 if (mpt == NULL) {
12929 /*
12930 * Called from iport node, get the states
12931 */
12932 iport_flag = 1;
12933 dip = mptsas_get_dip_from_dev(dev, &phymask);
12934 if (dip == NULL) {
12935 return (ENXIO);
12936 }
12937 mpt = DIP2MPT(dip);
12938 }
12939 /* Make sure power level is D0 before accessing registers */
12940 mutex_enter(&mpt->m_mutex);
12941 if (mpt->m_options & MPTSAS_OPT_PM) {
12942 (void) pm_busy_component(mpt->m_dip, 0);
12943 if (mpt->m_power_level != PM_LEVEL_D0) {
12944 mutex_exit(&mpt->m_mutex);
12945 if (pm_raise_power(mpt->m_dip, 0, PM_LEVEL_D0) !=
12946 DDI_SUCCESS) {
12947 mptsas_log(mpt, CE_WARN,
12948 "mptsas%d: mptsas_ioctl: Raise power "
12949 "request failed.", mpt->m_instance);
12950 (void) pm_idle_component(mpt->m_dip, 0);
12951 return (ENXIO);
12952 }
12953 } else {
12954 mutex_exit(&mpt->m_mutex);
12955 }
12956 } else {
12957 mutex_exit(&mpt->m_mutex);
12958 }
12959
12960 if (iport_flag) {
12961 status = scsi_hba_ioctl(dev, cmd, data, mode, credp, rval);
12962 if (status != 0) {
12963 goto out;
12964 }
12965 /*
12966 * The following code control the OK2RM LED, it doesn't affect
12967 * the ioctl return status.
12968 */
12969 if ((cmd == DEVCTL_DEVICE_ONLINE) ||
12970 (cmd == DEVCTL_DEVICE_OFFLINE)) {
12971 if (ndi_dc_allochdl((void *)data, &dcp) !=
12972 NDI_SUCCESS) {
12973 goto out;
12974 }
12975 addr = ndi_dc_getaddr(dcp);
12976 ptgt = mptsas_addr_to_ptgt(mpt, addr, phymask);
12977 if (ptgt == NULL) {
12978 NDBG14(("mptsas_ioctl led control: tgt %s not "
12979 "found", addr));
12980 ndi_dc_freehdl(dcp);
12981 goto out;
12982 }
12983 ndi_dc_freehdl(dcp);
12984 }
12985 goto out;
12986 }
12987 switch (cmd) {
12988 case MPTIOCTL_GET_DISK_INFO:
12989 status = get_disk_info(mpt, data, mode);
12990 break;
12991 case MPTIOCTL_LED_CONTROL:
12992 status = led_control(mpt, data, mode);
12993 break;
12994 case MPTIOCTL_UPDATE_FLASH:
12995 if (ddi_copyin((void *)data, &flashdata,
12996 sizeof (struct mptsas_update_flash), mode)) {
12997 status = EFAULT;
12998 break;
12999 }
13000
13001 mutex_enter(&mpt->m_mutex);
13002 if (mptsas_update_flash(mpt,
13003 (caddr_t)(long)flashdata.PtrBuffer,
13004 flashdata.ImageSize, flashdata.ImageType, mode)) {
13005 status = EFAULT;
13006 }
13007
13008 /*
13009 * Reset the chip to start using the new
13010 * firmware. Reset if failed also.
13011 */
13012 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET;
13013 if (mptsas_restart_ioc(mpt) == DDI_FAILURE) {
13014 status = EFAULT;
13015 }
13016 mutex_exit(&mpt->m_mutex);
13017 break;
13018 case MPTIOCTL_PASS_THRU:
13019 /*
13020 * The user has requested to pass through a command to
13021 * be executed by the MPT firmware. Call our routine
13022 * which does this. Only allow one passthru IOCTL at
13023 * one time. Other threads will block on
13024 * m_passthru_mutex, which is of adaptive variant.
13025 */
13026 if (ddi_copyin((void *)data, &passthru_data,
13027 sizeof (mptsas_pass_thru_t), mode)) {
13028 status = EFAULT;
13029 break;
13030 }
13031 mutex_enter(&mpt->m_passthru_mutex);
13032 mutex_enter(&mpt->m_mutex);
13033 status = mptsas_pass_thru(mpt, &passthru_data, mode);
13034 mutex_exit(&mpt->m_mutex);
13035 mutex_exit(&mpt->m_passthru_mutex);
13036
13037 break;
13038 case MPTIOCTL_GET_ADAPTER_DATA:
13039 /*
13040 * The user has requested to read adapter data. Call
13041 * our routine which does this.
13042 */
13043 bzero(&adapter_data, sizeof (mptsas_adapter_data_t));
13044 if (ddi_copyin((void *)data, (void *)&adapter_data,
13045 sizeof (mptsas_adapter_data_t), mode)) {
13046 status = EFAULT;
13047 break;
13048 }
13049 if (adapter_data.StructureLength >=
13050 sizeof (mptsas_adapter_data_t)) {
13051 adapter_data.StructureLength = (uint32_t)
13052 sizeof (mptsas_adapter_data_t);
13053 copylen = sizeof (mptsas_adapter_data_t);
13054 mutex_enter(&mpt->m_mutex);
13055 mptsas_read_adapter_data(mpt, &adapter_data);
13056 mutex_exit(&mpt->m_mutex);
13057 } else {
13058 adapter_data.StructureLength = (uint32_t)
13059 sizeof (mptsas_adapter_data_t);
13060 copylen = sizeof (adapter_data.StructureLength);
13061 *rval = MPTIOCTL_STATUS_LEN_TOO_SHORT;
13062 }
13063 if (ddi_copyout((void *)(&adapter_data), (void *)data,
13064 copylen, mode) != 0) {
13065 status = EFAULT;
13066 }
13067 break;
13068 case MPTIOCTL_GET_PCI_INFO:
13069 /*
13070 * The user has requested to read pci info. Call
13071 * our routine which does this.
13072 */
13073 bzero(&pci_info, sizeof (mptsas_pci_info_t));
13074 mutex_enter(&mpt->m_mutex);
13075 mptsas_read_pci_info(mpt, &pci_info);
13076 mutex_exit(&mpt->m_mutex);
13077 if (ddi_copyout((void *)(&pci_info), (void *)data,
13078 sizeof (mptsas_pci_info_t), mode) != 0) {
13079 status = EFAULT;
13080 }
13081 break;
13082 case MPTIOCTL_RESET_ADAPTER:
13083 mutex_enter(&mpt->m_mutex);
13084 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET;
13085 if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) {
13086 mptsas_log(mpt, CE_WARN, "reset adapter IOCTL "
13087 "failed");
13088 status = EFAULT;
13089 }
13090 mutex_exit(&mpt->m_mutex);
13091 break;
13092 case MPTIOCTL_DIAG_ACTION:
13093 /*
13094 * The user has done a diag buffer action. Call our
13095 * routine which does this. Only allow one diag action
13096 * at one time.
13097 */
13098 mutex_enter(&mpt->m_mutex);
13099 if (mpt->m_diag_action_in_progress) {
13100 mutex_exit(&mpt->m_mutex);
13101 return (EBUSY);
13102 }
13103 mpt->m_diag_action_in_progress = 1;
13104 status = mptsas_diag_action(mpt,
13105 (mptsas_diag_action_t *)data, mode);
13106 mpt->m_diag_action_in_progress = 0;
13107 mutex_exit(&mpt->m_mutex);
13108 break;
13109 case MPTIOCTL_EVENT_QUERY:
13110 /*
13111 * The user has done an event query. Call our routine
13112 * which does this.
13113 */
13114 status = mptsas_event_query(mpt,
13115 (mptsas_event_query_t *)data, mode, rval);
13116 break;
13117 case MPTIOCTL_EVENT_ENABLE:
13118 /*
13119 * The user has done an event enable. Call our routine
13120 * which does this.
13121 */
13122 status = mptsas_event_enable(mpt,
13123 (mptsas_event_enable_t *)data, mode, rval);
13124 break;
13125 case MPTIOCTL_EVENT_REPORT:
13126 /*
13127 * The user has done an event report. Call our routine
13128 * which does this.
13129 */
13130 status = mptsas_event_report(mpt,
13131 (mptsas_event_report_t *)data, mode, rval);
13132 break;
13133 case MPTIOCTL_REG_ACCESS:
13134 /*
13135 * The user has requested register access. Call our
13136 * routine which does this.
13137 */
13138 status = mptsas_reg_access(mpt,
13139 (mptsas_reg_access_t *)data, mode);
13140 break;
13141 default:
13142 status = scsi_hba_ioctl(dev, cmd, data, mode, credp,
13143 rval);
13144 break;
13145 }
13146
13147 out:
13148 return (status);
13149 }
13150
13151 int
mptsas_restart_ioc(mptsas_t * mpt)13152 mptsas_restart_ioc(mptsas_t *mpt)
13153 {
13154 int rval = DDI_SUCCESS;
13155 mptsas_target_t *ptgt = NULL;
13156
13157 ASSERT(mutex_owned(&mpt->m_mutex));
13158
13159 /*
13160 * Set a flag telling I/O path that we're processing a reset. This is
13161 * needed because after the reset is complete, the hash table still
13162 * needs to be rebuilt. If I/Os are started before the hash table is
13163 * rebuilt, I/O errors will occur. This flag allows I/Os to be marked
13164 * so that they can be retried.
13165 */
13166 mpt->m_in_reset = TRUE;
13167
13168 /*
13169 * Wait until all the allocated sense data buffers for DMA are freed.
13170 */
13171 while (mpt->m_extreq_sense_refcount > 0)
13172 cv_wait(&mpt->m_extreq_sense_refcount_cv, &mpt->m_mutex);
13173
13174 /*
13175 * Set all throttles to HOLD
13176 */
13177 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
13178 ptgt = refhash_next(mpt->m_targets, ptgt)) {
13179 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
13180 }
13181
13182 /*
13183 * Disable interrupts
13184 */
13185 MPTSAS_DISABLE_INTR(mpt);
13186
13187 /*
13188 * Abort all commands: outstanding commands, commands in waitq and
13189 * tx_waitq.
13190 */
13191 mptsas_flush_hba(mpt);
13192
13193 /*
13194 * Reinitialize the chip.
13195 */
13196 if (mptsas_init_chip(mpt, FALSE) == DDI_FAILURE) {
13197 rval = DDI_FAILURE;
13198 }
13199
13200 /*
13201 * Enable interrupts again
13202 */
13203 MPTSAS_ENABLE_INTR(mpt);
13204
13205 /*
13206 * If mptsas_init_chip was successful, update the driver data.
13207 */
13208 if (rval == DDI_SUCCESS) {
13209 mptsas_update_driver_data(mpt);
13210 }
13211
13212 /*
13213 * Reset the throttles
13214 */
13215 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
13216 ptgt = refhash_next(mpt->m_targets, ptgt)) {
13217 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
13218 }
13219
13220 mptsas_doneq_empty(mpt);
13221 mptsas_restart_hba(mpt);
13222
13223 if (rval != DDI_SUCCESS) {
13224 mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE);
13225 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST);
13226 }
13227
13228 /*
13229 * Clear the reset flag so that I/Os can continue.
13230 */
13231 mpt->m_in_reset = FALSE;
13232
13233 return (rval);
13234 }
13235
13236 static int
mptsas_init_chip(mptsas_t * mpt,int first_time)13237 mptsas_init_chip(mptsas_t *mpt, int first_time)
13238 {
13239 ddi_dma_cookie_t cookie;
13240 uint32_t i;
13241 int rval;
13242
13243 /*
13244 * Setup configuration space
13245 */
13246 if (mptsas_config_space_init(mpt) == FALSE) {
13247 mptsas_log(mpt, CE_WARN, "mptsas_config_space_init "
13248 "failed!");
13249 goto fail;
13250 }
13251
13252 /*
13253 * Check to see if the firmware image is valid
13254 */
13255 if (mptsas_hirrd(mpt, &mpt->m_reg->HostDiagnostic) &
13256 MPI2_DIAG_FLASH_BAD_SIG) {
13257 mptsas_log(mpt, CE_WARN, "mptsas bad flash signature!");
13258 goto fail;
13259 }
13260
13261 /*
13262 * Reset the chip
13263 */
13264 rval = mptsas_ioc_reset(mpt, first_time);
13265 if (rval == MPTSAS_RESET_FAIL) {
13266 mptsas_log(mpt, CE_WARN, "hard reset failed!");
13267 goto fail;
13268 }
13269
13270 if ((rval == MPTSAS_SUCCESS_MUR) && (!first_time)) {
13271 goto mur;
13272 }
13273 /*
13274 * IOC facts can change after a diag reset so all buffers that are
13275 * based on these numbers must be de-allocated and re-allocated. Get
13276 * new IOC facts each time chip is initialized.
13277 */
13278 if (mptsas_ioc_get_facts(mpt) == DDI_FAILURE) {
13279 mptsas_log(mpt, CE_WARN, "mptsas_ioc_get_facts failed");
13280 goto fail;
13281 }
13282
13283 if (mptsas_alloc_active_slots(mpt, KM_SLEEP)) {
13284 goto fail;
13285 }
13286 /*
13287 * Allocate request message frames, reply free queue, reply descriptor
13288 * post queue, and reply message frames using latest IOC facts.
13289 */
13290 if (mptsas_alloc_request_frames(mpt) == DDI_FAILURE) {
13291 mptsas_log(mpt, CE_WARN, "mptsas_alloc_request_frames failed");
13292 goto fail;
13293 }
13294 if (mptsas_alloc_sense_bufs(mpt) == DDI_FAILURE) {
13295 mptsas_log(mpt, CE_WARN, "mptsas_alloc_sense_bufs failed");
13296 goto fail;
13297 }
13298 if (mptsas_alloc_free_queue(mpt) == DDI_FAILURE) {
13299 mptsas_log(mpt, CE_WARN, "mptsas_alloc_free_queue failed!");
13300 goto fail;
13301 }
13302 if (mptsas_alloc_post_queue(mpt) == DDI_FAILURE) {
13303 mptsas_log(mpt, CE_WARN, "mptsas_alloc_post_queue failed!");
13304 goto fail;
13305 }
13306 if (mptsas_alloc_reply_frames(mpt) == DDI_FAILURE) {
13307 mptsas_log(mpt, CE_WARN, "mptsas_alloc_reply_frames failed!");
13308 goto fail;
13309 }
13310
13311 mur:
13312 /*
13313 * Re-Initialize ioc to operational state
13314 */
13315 if (mptsas_ioc_init(mpt) == DDI_FAILURE) {
13316 mptsas_log(mpt, CE_WARN, "mptsas_ioc_init failed");
13317 goto fail;
13318 }
13319
13320 mptsas_alloc_reply_args(mpt);
13321
13322 /*
13323 * Initialize reply post index. Reply free index is initialized after
13324 * the next loop.
13325 */
13326 mpt->m_post_index = 0;
13327
13328 /*
13329 * Initialize the Reply Free Queue with the physical addresses of our
13330 * reply frames.
13331 */
13332 cookie.dmac_address = mpt->m_reply_frame_dma_addr & 0xffffffffu;
13333 for (i = 0; i < mpt->m_max_replies; i++) {
13334 ddi_put32(mpt->m_acc_free_queue_hdl,
13335 &((uint32_t *)(void *)mpt->m_free_queue)[i],
13336 cookie.dmac_address);
13337 cookie.dmac_address += mpt->m_reply_frame_size;
13338 }
13339 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
13340 DDI_DMA_SYNC_FORDEV);
13341
13342 /*
13343 * Initialize the reply free index to one past the last frame on the
13344 * queue. This will signify that the queue is empty to start with.
13345 */
13346 mpt->m_free_index = i;
13347 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, i);
13348
13349 /*
13350 * Initialize the reply post queue to 0xFFFFFFFF,0xFFFFFFFF's.
13351 */
13352 for (i = 0; i < mpt->m_post_queue_depth; i++) {
13353 ddi_put64(mpt->m_acc_post_queue_hdl,
13354 &((uint64_t *)(void *)mpt->m_post_queue)[i],
13355 0xFFFFFFFFFFFFFFFF);
13356 }
13357 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0,
13358 DDI_DMA_SYNC_FORDEV);
13359
13360 /*
13361 * Enable ports
13362 */
13363 if (mptsas_ioc_enable_port(mpt) == DDI_FAILURE) {
13364 mptsas_log(mpt, CE_WARN, "mptsas_ioc_enable_port failed");
13365 goto fail;
13366 }
13367
13368 /*
13369 * enable events
13370 */
13371 if (mptsas_ioc_enable_event_notification(mpt)) {
13372 mptsas_log(mpt, CE_WARN,
13373 "mptsas_ioc_enable_event_notification failed");
13374 goto fail;
13375 }
13376
13377 /*
13378 * We need checks in attach and these.
13379 * chip_init is called in mult. places
13380 */
13381
13382 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) !=
13383 DDI_SUCCESS) ||
13384 (mptsas_check_dma_handle(mpt->m_dma_req_sense_hdl) !=
13385 DDI_SUCCESS) ||
13386 (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl) !=
13387 DDI_SUCCESS) ||
13388 (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl) !=
13389 DDI_SUCCESS) ||
13390 (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) !=
13391 DDI_SUCCESS) ||
13392 (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl) !=
13393 DDI_SUCCESS)) {
13394 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
13395 goto fail;
13396 }
13397
13398 /* Check all acc handles */
13399 if ((mptsas_check_acc_handle(mpt->m_datap) != DDI_SUCCESS) ||
13400 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) !=
13401 DDI_SUCCESS) ||
13402 (mptsas_check_acc_handle(mpt->m_acc_req_sense_hdl) !=
13403 DDI_SUCCESS) ||
13404 (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl) !=
13405 DDI_SUCCESS) ||
13406 (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl) !=
13407 DDI_SUCCESS) ||
13408 (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl) !=
13409 DDI_SUCCESS) ||
13410 (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl) !=
13411 DDI_SUCCESS) ||
13412 (mptsas_check_acc_handle(mpt->m_config_handle) !=
13413 DDI_SUCCESS)) {
13414 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
13415 goto fail;
13416 }
13417
13418 return (DDI_SUCCESS);
13419
13420 fail:
13421 return (DDI_FAILURE);
13422 }
13423
13424 static int
mptsas_get_pci_cap(mptsas_t * mpt)13425 mptsas_get_pci_cap(mptsas_t *mpt)
13426 {
13427 ushort_t caps_ptr, cap, cap_count;
13428
13429 if (mpt->m_config_handle == NULL)
13430 return (FALSE);
13431 /*
13432 * Check if capabilities list is supported and if so,
13433 * get initial capabilities pointer and clear bits 0,1.
13434 */
13435 if (pci_config_get16(mpt->m_config_handle, PCI_CONF_STAT)
13436 & PCI_STAT_CAP) {
13437 caps_ptr = P2ALIGN(pci_config_get8(mpt->m_config_handle,
13438 PCI_CONF_CAP_PTR), 4);
13439 } else {
13440 caps_ptr = PCI_CAP_NEXT_PTR_NULL;
13441 }
13442
13443 /*
13444 * Walk capabilities if supported.
13445 */
13446 for (cap_count = 0; caps_ptr != PCI_CAP_NEXT_PTR_NULL; ) {
13447
13448 /*
13449 * Check that we haven't exceeded the maximum number of
13450 * capabilities and that the pointer is in a valid range.
13451 */
13452 if (++cap_count > 48) {
13453 mptsas_log(mpt, CE_WARN,
13454 "too many device capabilities.\n");
13455 break;
13456 }
13457 if (caps_ptr < 64) {
13458 mptsas_log(mpt, CE_WARN,
13459 "capabilities pointer 0x%x out of range.\n",
13460 caps_ptr);
13461 break;
13462 }
13463
13464 /*
13465 * Get next capability and check that it is valid.
13466 * For now, we only support power management.
13467 */
13468 cap = pci_config_get8(mpt->m_config_handle, caps_ptr);
13469 switch (cap) {
13470 case PCI_CAP_ID_PM:
13471 mptsas_log(mpt, CE_NOTE,
13472 "?mptsas%d supports power management.\n",
13473 mpt->m_instance);
13474 mpt->m_options |= MPTSAS_OPT_PM;
13475
13476 /* Save PMCSR offset */
13477 mpt->m_pmcsr_offset = caps_ptr + PCI_PMCSR;
13478 break;
13479 /*
13480 * The following capabilities are valid. Any others
13481 * will cause a message to be logged.
13482 */
13483 case PCI_CAP_ID_VPD:
13484 case PCI_CAP_ID_MSI:
13485 case PCI_CAP_ID_PCIX:
13486 case PCI_CAP_ID_PCI_E:
13487 case PCI_CAP_ID_MSI_X:
13488 break;
13489 default:
13490 mptsas_log(mpt, CE_NOTE,
13491 "?mptsas%d unrecognized capability "
13492 "0x%x.\n", mpt->m_instance, cap);
13493 break;
13494 }
13495
13496 /*
13497 * Get next capabilities pointer and clear bits 0,1.
13498 */
13499 caps_ptr = P2ALIGN(pci_config_get8(mpt->m_config_handle,
13500 (caps_ptr + PCI_CAP_NEXT_PTR)), 4);
13501 }
13502 return (TRUE);
13503 }
13504
13505 static int
mptsas_init_pm(mptsas_t * mpt)13506 mptsas_init_pm(mptsas_t *mpt)
13507 {
13508 char pmc_name[16];
13509 char *pmc[] = {
13510 NULL,
13511 "0=Off (PCI D3 State)",
13512 "3=On (PCI D0 State)",
13513 NULL
13514 };
13515 uint16_t pmcsr_stat;
13516
13517 if (mptsas_get_pci_cap(mpt) == FALSE) {
13518 return (DDI_FAILURE);
13519 }
13520 /*
13521 * If PCI's capability does not support PM, then don't need
13522 * to registe the pm-components
13523 */
13524 if (!(mpt->m_options & MPTSAS_OPT_PM))
13525 return (DDI_SUCCESS);
13526 /*
13527 * If power management is supported by this chip, create
13528 * pm-components property for the power management framework
13529 */
13530 (void) sprintf(pmc_name, "NAME=mptsas%d", mpt->m_instance);
13531 pmc[0] = pmc_name;
13532 if (ddi_prop_update_string_array(DDI_DEV_T_NONE, mpt->m_dip,
13533 "pm-components", pmc, 3) != DDI_PROP_SUCCESS) {
13534 mpt->m_options &= ~MPTSAS_OPT_PM;
13535 mptsas_log(mpt, CE_WARN,
13536 "mptsas%d: pm-component property creation failed.",
13537 mpt->m_instance);
13538 return (DDI_FAILURE);
13539 }
13540
13541 /*
13542 * Power on device.
13543 */
13544 (void) pm_busy_component(mpt->m_dip, 0);
13545 pmcsr_stat = pci_config_get16(mpt->m_config_handle,
13546 mpt->m_pmcsr_offset);
13547 if ((pmcsr_stat & PCI_PMCSR_STATE_MASK) != PCI_PMCSR_D0) {
13548 mptsas_log(mpt, CE_WARN, "mptsas%d: Power up the device",
13549 mpt->m_instance);
13550 pci_config_put16(mpt->m_config_handle, mpt->m_pmcsr_offset,
13551 PCI_PMCSR_D0);
13552 }
13553 if (pm_power_has_changed(mpt->m_dip, 0, PM_LEVEL_D0) != DDI_SUCCESS) {
13554 mptsas_log(mpt, CE_WARN, "pm_power_has_changed failed");
13555 return (DDI_FAILURE);
13556 }
13557 mpt->m_power_level = PM_LEVEL_D0;
13558 /*
13559 * Set pm idle delay.
13560 */
13561 mpt->m_pm_idle_delay = ddi_prop_get_int(DDI_DEV_T_ANY,
13562 mpt->m_dip, 0, "mptsas-pm-idle-delay", MPTSAS_PM_IDLE_TIMEOUT);
13563
13564 return (DDI_SUCCESS);
13565 }
13566
13567 static int
mptsas_register_intrs(mptsas_t * mpt)13568 mptsas_register_intrs(mptsas_t *mpt)
13569 {
13570 dev_info_t *dip;
13571 int intr_types;
13572
13573 dip = mpt->m_dip;
13574
13575 /* Get supported interrupt types */
13576 if (ddi_intr_get_supported_types(dip, &intr_types) != DDI_SUCCESS) {
13577 mptsas_log(mpt, CE_WARN, "ddi_intr_get_supported_types "
13578 "failed\n");
13579 return (FALSE);
13580 }
13581
13582 NDBG6(("ddi_intr_get_supported_types() returned: 0x%x", intr_types));
13583
13584 /*
13585 * Try MSI, but fall back to FIXED
13586 */
13587 if (mptsas_enable_msi && (intr_types & DDI_INTR_TYPE_MSI)) {
13588 if (mptsas_add_intrs(mpt, DDI_INTR_TYPE_MSI) == DDI_SUCCESS) {
13589 NDBG0(("Using MSI interrupt type"));
13590 mpt->m_intr_type = DDI_INTR_TYPE_MSI;
13591 return (TRUE);
13592 }
13593 }
13594 if (intr_types & DDI_INTR_TYPE_FIXED) {
13595 if (mptsas_add_intrs(mpt, DDI_INTR_TYPE_FIXED) == DDI_SUCCESS) {
13596 NDBG0(("Using FIXED interrupt type"));
13597 mpt->m_intr_type = DDI_INTR_TYPE_FIXED;
13598 return (TRUE);
13599 } else {
13600 NDBG0(("FIXED interrupt registration failed"));
13601 return (FALSE);
13602 }
13603 }
13604
13605 return (FALSE);
13606 }
13607
13608 static void
mptsas_unregister_intrs(mptsas_t * mpt)13609 mptsas_unregister_intrs(mptsas_t *mpt)
13610 {
13611 mptsas_rem_intrs(mpt);
13612 }
13613
13614 /*
13615 * mptsas_add_intrs:
13616 *
13617 * Register FIXED or MSI interrupts.
13618 */
13619 static int
mptsas_add_intrs(mptsas_t * mpt,int intr_type)13620 mptsas_add_intrs(mptsas_t *mpt, int intr_type)
13621 {
13622 dev_info_t *dip = mpt->m_dip;
13623 int avail, actual, count = 0;
13624 int i, flag, ret;
13625
13626 NDBG6(("mptsas_add_intrs:interrupt type 0x%x", intr_type));
13627
13628 /* Get number of interrupts */
13629 ret = ddi_intr_get_nintrs(dip, intr_type, &count);
13630 if ((ret != DDI_SUCCESS) || (count <= 0)) {
13631 mptsas_log(mpt, CE_WARN, "ddi_intr_get_nintrs() failed, "
13632 "ret %d count %d\n", ret, count);
13633
13634 return (DDI_FAILURE);
13635 }
13636
13637 /* Get number of available interrupts */
13638 ret = ddi_intr_get_navail(dip, intr_type, &avail);
13639 if ((ret != DDI_SUCCESS) || (avail == 0)) {
13640 mptsas_log(mpt, CE_WARN, "ddi_intr_get_navail() failed, "
13641 "ret %d avail %d\n", ret, avail);
13642
13643 return (DDI_FAILURE);
13644 }
13645
13646 if (avail < count) {
13647 mptsas_log(mpt, CE_NOTE, "ddi_intr_get_nvail returned %d, "
13648 "navail() returned %d", count, avail);
13649 }
13650
13651 /* Mpt only have one interrupt routine */
13652 if ((intr_type == DDI_INTR_TYPE_MSI) && (count > 1)) {
13653 count = 1;
13654 }
13655
13656 /* Allocate an array of interrupt handles */
13657 mpt->m_intr_size = count * sizeof (ddi_intr_handle_t);
13658 mpt->m_htable = kmem_alloc(mpt->m_intr_size, KM_SLEEP);
13659
13660 flag = DDI_INTR_ALLOC_NORMAL;
13661
13662 /* call ddi_intr_alloc() */
13663 ret = ddi_intr_alloc(dip, mpt->m_htable, intr_type, 0,
13664 count, &actual, flag);
13665
13666 if ((ret != DDI_SUCCESS) || (actual == 0)) {
13667 mptsas_log(mpt, CE_WARN, "ddi_intr_alloc() failed, ret %d\n",
13668 ret);
13669 kmem_free(mpt->m_htable, mpt->m_intr_size);
13670 return (DDI_FAILURE);
13671 }
13672
13673 /* use interrupt count returned or abort? */
13674 if (actual < count) {
13675 mptsas_log(mpt, CE_NOTE, "Requested: %d, Received: %d\n",
13676 count, actual);
13677 }
13678
13679 mpt->m_intr_cnt = actual;
13680
13681 /*
13682 * Get priority for first msi, assume remaining are all the same
13683 */
13684 if ((ret = ddi_intr_get_pri(mpt->m_htable[0],
13685 &mpt->m_intr_pri)) != DDI_SUCCESS) {
13686 mptsas_log(mpt, CE_WARN, "ddi_intr_get_pri() failed %d\n", ret);
13687
13688 /* Free already allocated intr */
13689 for (i = 0; i < actual; i++) {
13690 (void) ddi_intr_free(mpt->m_htable[i]);
13691 }
13692
13693 kmem_free(mpt->m_htable, mpt->m_intr_size);
13694 return (DDI_FAILURE);
13695 }
13696
13697 /* Test for high level mutex */
13698 if (mpt->m_intr_pri >= ddi_intr_get_hilevel_pri()) {
13699 mptsas_log(mpt, CE_WARN, "mptsas_add_intrs: "
13700 "Hi level interrupt not supported\n");
13701
13702 /* Free already allocated intr */
13703 for (i = 0; i < actual; i++) {
13704 (void) ddi_intr_free(mpt->m_htable[i]);
13705 }
13706
13707 kmem_free(mpt->m_htable, mpt->m_intr_size);
13708 return (DDI_FAILURE);
13709 }
13710
13711 /* Call ddi_intr_add_handler() */
13712 for (i = 0; i < actual; i++) {
13713 if ((ret = ddi_intr_add_handler(mpt->m_htable[i], mptsas_intr,
13714 (caddr_t)mpt, (caddr_t)(uintptr_t)i)) != DDI_SUCCESS) {
13715 mptsas_log(mpt, CE_WARN, "ddi_intr_add_handler() "
13716 "failed %d\n", ret);
13717
13718 /* Free already allocated intr */
13719 for (i = 0; i < actual; i++) {
13720 (void) ddi_intr_free(mpt->m_htable[i]);
13721 }
13722
13723 kmem_free(mpt->m_htable, mpt->m_intr_size);
13724 return (DDI_FAILURE);
13725 }
13726 }
13727
13728 if ((ret = ddi_intr_get_cap(mpt->m_htable[0], &mpt->m_intr_cap))
13729 != DDI_SUCCESS) {
13730 mptsas_log(mpt, CE_WARN, "ddi_intr_get_cap() failed %d\n", ret);
13731
13732 /* Free already allocated intr */
13733 for (i = 0; i < actual; i++) {
13734 (void) ddi_intr_free(mpt->m_htable[i]);
13735 }
13736
13737 kmem_free(mpt->m_htable, mpt->m_intr_size);
13738 return (DDI_FAILURE);
13739 }
13740
13741 /*
13742 * Enable interrupts
13743 */
13744 if (mpt->m_intr_cap & DDI_INTR_FLAG_BLOCK) {
13745 /* Call ddi_intr_block_enable() for MSI interrupts */
13746 (void) ddi_intr_block_enable(mpt->m_htable, mpt->m_intr_cnt);
13747 } else {
13748 /* Call ddi_intr_enable for MSI or FIXED interrupts */
13749 for (i = 0; i < mpt->m_intr_cnt; i++) {
13750 (void) ddi_intr_enable(mpt->m_htable[i]);
13751 }
13752 }
13753 return (DDI_SUCCESS);
13754 }
13755
13756 /*
13757 * mptsas_rem_intrs:
13758 *
13759 * Unregister FIXED or MSI interrupts
13760 */
13761 static void
mptsas_rem_intrs(mptsas_t * mpt)13762 mptsas_rem_intrs(mptsas_t *mpt)
13763 {
13764 int i;
13765
13766 NDBG6(("mptsas_rem_intrs"));
13767
13768 /* Disable all interrupts */
13769 if (mpt->m_intr_cap & DDI_INTR_FLAG_BLOCK) {
13770 /* Call ddi_intr_block_disable() */
13771 (void) ddi_intr_block_disable(mpt->m_htable, mpt->m_intr_cnt);
13772 } else {
13773 for (i = 0; i < mpt->m_intr_cnt; i++) {
13774 (void) ddi_intr_disable(mpt->m_htable[i]);
13775 }
13776 }
13777
13778 /* Call ddi_intr_remove_handler() */
13779 for (i = 0; i < mpt->m_intr_cnt; i++) {
13780 (void) ddi_intr_remove_handler(mpt->m_htable[i]);
13781 (void) ddi_intr_free(mpt->m_htable[i]);
13782 }
13783
13784 kmem_free(mpt->m_htable, mpt->m_intr_size);
13785 }
13786
13787 /*
13788 * The IO fault service error handling callback function
13789 */
13790 /*ARGSUSED*/
13791 static int
mptsas_fm_error_cb(dev_info_t * dip,ddi_fm_error_t * err,const void * impl_data)13792 mptsas_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data)
13793 {
13794 /*
13795 * as the driver can always deal with an error in any dma or
13796 * access handle, we can just return the fme_status value.
13797 */
13798 pci_ereport_post(dip, err, NULL);
13799 return (err->fme_status);
13800 }
13801
13802 /*
13803 * mptsas_fm_init - initialize fma capabilities and register with IO
13804 * fault services.
13805 */
13806 static void
mptsas_fm_init(mptsas_t * mpt)13807 mptsas_fm_init(mptsas_t *mpt)
13808 {
13809 /*
13810 * Need to change iblock to priority for new MSI intr
13811 */
13812 ddi_iblock_cookie_t fm_ibc;
13813
13814 /* Only register with IO Fault Services if we have some capability */
13815 if (mpt->m_fm_capabilities) {
13816 /* Adjust access and dma attributes for FMA */
13817 mpt->m_reg_acc_attr.devacc_attr_access = DDI_FLAGERR_ACC;
13818 mpt->m_msg_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
13819 mpt->m_io_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
13820
13821 /*
13822 * Register capabilities with IO Fault Services.
13823 * mpt->m_fm_capabilities will be updated to indicate
13824 * capabilities actually supported (not requested.)
13825 */
13826 ddi_fm_init(mpt->m_dip, &mpt->m_fm_capabilities, &fm_ibc);
13827
13828 /*
13829 * Initialize pci ereport capabilities if ereport
13830 * capable (should always be.)
13831 */
13832 if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities) ||
13833 DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) {
13834 pci_ereport_setup(mpt->m_dip);
13835 }
13836
13837 /*
13838 * Register error callback if error callback capable.
13839 */
13840 if (DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) {
13841 ddi_fm_handler_register(mpt->m_dip,
13842 mptsas_fm_error_cb, (void *) mpt);
13843 }
13844 }
13845 }
13846
13847 /*
13848 * mptsas_fm_fini - Releases fma capabilities and un-registers with IO
13849 * fault services.
13850 *
13851 */
13852 static void
mptsas_fm_fini(mptsas_t * mpt)13853 mptsas_fm_fini(mptsas_t *mpt)
13854 {
13855 /* Only unregister FMA capabilities if registered */
13856 if (mpt->m_fm_capabilities) {
13857
13858 /*
13859 * Un-register error callback if error callback capable.
13860 */
13861
13862 if (DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) {
13863 ddi_fm_handler_unregister(mpt->m_dip);
13864 }
13865
13866 /*
13867 * Release any resources allocated by pci_ereport_setup()
13868 */
13869
13870 if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities) ||
13871 DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) {
13872 pci_ereport_teardown(mpt->m_dip);
13873 }
13874
13875 /* Unregister from IO Fault Services */
13876 ddi_fm_fini(mpt->m_dip);
13877
13878 /* Adjust access and dma attributes for FMA */
13879 mpt->m_reg_acc_attr.devacc_attr_access = DDI_DEFAULT_ACC;
13880 mpt->m_msg_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
13881 mpt->m_io_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
13882
13883 }
13884 }
13885
13886 int
mptsas_check_acc_handle(ddi_acc_handle_t handle)13887 mptsas_check_acc_handle(ddi_acc_handle_t handle)
13888 {
13889 ddi_fm_error_t de;
13890
13891 if (handle == NULL)
13892 return (DDI_FAILURE);
13893 ddi_fm_acc_err_get(handle, &de, DDI_FME_VER0);
13894 return (de.fme_status);
13895 }
13896
13897 int
mptsas_check_dma_handle(ddi_dma_handle_t handle)13898 mptsas_check_dma_handle(ddi_dma_handle_t handle)
13899 {
13900 ddi_fm_error_t de;
13901
13902 if (handle == NULL)
13903 return (DDI_FAILURE);
13904 ddi_fm_dma_err_get(handle, &de, DDI_FME_VER0);
13905 return (de.fme_status);
13906 }
13907
13908 void
mptsas_fm_ereport(mptsas_t * mpt,char * detail)13909 mptsas_fm_ereport(mptsas_t *mpt, char *detail)
13910 {
13911 uint64_t ena;
13912 char buf[FM_MAX_CLASS];
13913
13914 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail);
13915 ena = fm_ena_generate(0, FM_ENA_FMT1);
13916 if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities)) {
13917 ddi_fm_ereport_post(mpt->m_dip, buf, ena, DDI_NOSLEEP,
13918 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, NULL);
13919 }
13920 }
13921
13922 static int
mptsas_get_target_device_info(mptsas_t * mpt,uint32_t page_address,uint16_t * dev_handle,mptsas_target_t ** pptgt)13923 mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address,
13924 uint16_t *dev_handle, mptsas_target_t **pptgt)
13925 {
13926 int rval;
13927 uint32_t dev_info;
13928 uint64_t sas_wwn;
13929 mptsas_phymask_t phymask;
13930 uint8_t physport, phynum, config, disk;
13931 uint64_t devicename;
13932 uint16_t pdev_hdl;
13933 mptsas_target_t *tmp_tgt = NULL;
13934 uint16_t bay_num, enclosure, io_flags;
13935
13936 ASSERT(*pptgt == NULL);
13937
13938 rval = mptsas_get_sas_device_page0(mpt, page_address, dev_handle,
13939 &sas_wwn, &dev_info, &physport, &phynum, &pdev_hdl,
13940 &bay_num, &enclosure, &io_flags);
13941 if (rval != DDI_SUCCESS) {
13942 rval = DEV_INFO_FAIL_PAGE0;
13943 return (rval);
13944 }
13945
13946 if ((dev_info & (MPI2_SAS_DEVICE_INFO_SSP_TARGET |
13947 MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
13948 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) == 0) {
13949 rval = DEV_INFO_WRONG_DEVICE_TYPE;
13950 return (rval);
13951 }
13952
13953 /*
13954 * Check if the dev handle is for a Phys Disk. If so, set return value
13955 * and exit. Don't add Phys Disks to hash.
13956 */
13957 for (config = 0; config < mpt->m_num_raid_configs; config++) {
13958 for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) {
13959 if (*dev_handle == mpt->m_raidconfig[config].
13960 m_physdisk_devhdl[disk]) {
13961 rval = DEV_INFO_PHYS_DISK;
13962 return (rval);
13963 }
13964 }
13965 }
13966
13967 /*
13968 * Get SATA Device Name from SAS device page0 for
13969 * sata device, if device name doesn't exist, set mta_wwn to
13970 * 0 for direct attached SATA. For the device behind the expander
13971 * we still can use STP address assigned by expander.
13972 */
13973 if (dev_info & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
13974 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
13975 /* alloc a temporary target to send the cmd to */
13976 tmp_tgt = mptsas_tgt_alloc(mpt->m_tmp_targets, *dev_handle,
13977 0, dev_info, 0, 0);
13978 mutex_exit(&mpt->m_mutex);
13979
13980 devicename = mptsas_get_sata_guid(mpt, tmp_tgt, 0);
13981
13982 if (devicename == -1) {
13983 mutex_enter(&mpt->m_mutex);
13984 refhash_remove(mpt->m_tmp_targets, tmp_tgt);
13985 rval = DEV_INFO_FAIL_GUID;
13986 return (rval);
13987 }
13988
13989 if (devicename != 0 && (((devicename >> 56) & 0xf0) == 0x50)) {
13990 sas_wwn = devicename;
13991 } else if (dev_info & MPI2_SAS_DEVICE_INFO_DIRECT_ATTACH) {
13992 sas_wwn = 0;
13993 }
13994
13995 mutex_enter(&mpt->m_mutex);
13996 refhash_remove(mpt->m_tmp_targets, tmp_tgt);
13997 }
13998
13999 phymask = mptsas_physport_to_phymask(mpt, physport);
14000 *pptgt = mptsas_tgt_alloc(mpt->m_targets, *dev_handle, sas_wwn,
14001 dev_info, phymask, phynum);
14002 if (*pptgt == NULL) {
14003 mptsas_log(mpt, CE_WARN, "Failed to allocated target"
14004 "structure!");
14005 rval = DEV_INFO_FAIL_ALLOC;
14006 return (rval);
14007 }
14008 (*pptgt)->m_io_flags = io_flags;
14009 (*pptgt)->m_enclosure = enclosure;
14010 (*pptgt)->m_slot_num = bay_num;
14011 return (DEV_INFO_SUCCESS);
14012 }
14013
14014 uint64_t
mptsas_get_sata_guid(mptsas_t * mpt,mptsas_target_t * ptgt,int lun)14015 mptsas_get_sata_guid(mptsas_t *mpt, mptsas_target_t *ptgt, int lun)
14016 {
14017 uint64_t sata_guid = 0, *pwwn = NULL;
14018 int target = ptgt->m_devhdl;
14019 uchar_t *inq83 = NULL;
14020 int inq83_len = 0xFF;
14021 uchar_t *dblk = NULL;
14022 int inq83_retry = 3;
14023 int rval = DDI_FAILURE;
14024
14025 inq83 = kmem_zalloc(inq83_len, KM_SLEEP);
14026
14027 inq83_retry:
14028 rval = mptsas_inquiry(mpt, ptgt, lun, 0x83, inq83,
14029 inq83_len, NULL, 1);
14030 if (rval != DDI_SUCCESS) {
14031 mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page "
14032 "0x83 for target:%x, lun:%x failed!", target, lun);
14033 sata_guid = -1;
14034 goto out;
14035 }
14036 /* According to SAT2, the first descriptor is logic unit name */
14037 dblk = &inq83[4];
14038 if ((dblk[1] & 0x30) != 0) {
14039 mptsas_log(mpt, CE_WARN, "!Descriptor is not lun associated.");
14040 goto out;
14041 }
14042 pwwn = (uint64_t *)(void *)(&dblk[4]);
14043 if ((dblk[4] & 0xf0) == 0x50) {
14044 sata_guid = BE_64(*pwwn);
14045 goto out;
14046 } else if (dblk[4] == 'A') {
14047 NDBG20(("SATA drive has no NAA format GUID."));
14048 goto out;
14049 } else {
14050 /* The data is not ready, wait and retry */
14051 inq83_retry--;
14052 if (inq83_retry <= 0) {
14053 goto out;
14054 }
14055 NDBG20(("The GUID is not ready, retry..."));
14056 delay(1 * drv_usectohz(1000000));
14057 goto inq83_retry;
14058 }
14059 out:
14060 kmem_free(inq83, inq83_len);
14061 return (sata_guid);
14062 }
14063
14064 static int
mptsas_inquiry(mptsas_t * mpt,mptsas_target_t * ptgt,int lun,uchar_t page,unsigned char * buf,int len,int * reallen,uchar_t evpd)14065 mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun, uchar_t page,
14066 unsigned char *buf, int len, int *reallen, uchar_t evpd)
14067 {
14068 uchar_t cdb[CDB_GROUP0];
14069 struct scsi_address ap;
14070 struct buf *data_bp = NULL;
14071 int resid = 0;
14072 int ret = DDI_FAILURE;
14073
14074 ASSERT(len <= 0xffff);
14075
14076 ap.a_target = MPTSAS_INVALID_DEVHDL;
14077 ap.a_lun = (uchar_t)(lun);
14078 ap.a_hba_tran = mpt->m_tran;
14079
14080 data_bp = scsi_alloc_consistent_buf(&ap,
14081 (struct buf *)NULL, len, B_READ, NULL_FUNC, NULL);
14082 if (data_bp == NULL) {
14083 return (ret);
14084 }
14085 bzero(cdb, CDB_GROUP0);
14086 cdb[0] = SCMD_INQUIRY;
14087 cdb[1] = evpd;
14088 cdb[2] = page;
14089 cdb[3] = (len & 0xff00) >> 8;
14090 cdb[4] = (len & 0x00ff);
14091 cdb[5] = 0;
14092
14093 ret = mptsas_send_scsi_cmd(mpt, &ap, ptgt, &cdb[0], CDB_GROUP0, data_bp,
14094 &resid);
14095 if (ret == DDI_SUCCESS) {
14096 if (reallen) {
14097 *reallen = len - resid;
14098 }
14099 bcopy((caddr_t)data_bp->b_un.b_addr, buf, len);
14100 }
14101 if (data_bp) {
14102 scsi_free_consistent_buf(data_bp);
14103 }
14104 return (ret);
14105 }
14106
14107 static int
mptsas_send_scsi_cmd(mptsas_t * mpt,struct scsi_address * ap,mptsas_target_t * ptgt,uchar_t * cdb,int cdblen,struct buf * data_bp,int * resid)14108 mptsas_send_scsi_cmd(mptsas_t *mpt, struct scsi_address *ap,
14109 mptsas_target_t *ptgt, uchar_t *cdb, int cdblen, struct buf *data_bp,
14110 int *resid)
14111 {
14112 struct scsi_pkt *pktp = NULL;
14113 scsi_hba_tran_t *tran_clone = NULL;
14114 mptsas_tgt_private_t *tgt_private = NULL;
14115 int ret = DDI_FAILURE;
14116
14117 /*
14118 * scsi_hba_tran_t->tran_tgt_private is used to pass the address
14119 * information to scsi_init_pkt, allocate a scsi_hba_tran structure
14120 * to simulate the cmds from sd
14121 */
14122 tran_clone = kmem_alloc(
14123 sizeof (scsi_hba_tran_t), KM_SLEEP);
14124 if (tran_clone == NULL) {
14125 goto out;
14126 }
14127 bcopy((caddr_t)mpt->m_tran,
14128 (caddr_t)tran_clone, sizeof (scsi_hba_tran_t));
14129 tgt_private = kmem_alloc(
14130 sizeof (mptsas_tgt_private_t), KM_SLEEP);
14131 if (tgt_private == NULL) {
14132 goto out;
14133 }
14134 tgt_private->t_lun = ap->a_lun;
14135 tgt_private->t_private = ptgt;
14136 tran_clone->tran_tgt_private = tgt_private;
14137 ap->a_hba_tran = tran_clone;
14138
14139 pktp = scsi_init_pkt(ap, (struct scsi_pkt *)NULL,
14140 data_bp, cdblen, sizeof (struct scsi_arq_status),
14141 0, PKT_CONSISTENT, NULL, NULL);
14142 if (pktp == NULL) {
14143 goto out;
14144 }
14145 bcopy(cdb, pktp->pkt_cdbp, cdblen);
14146 pktp->pkt_flags = FLAG_NOPARITY;
14147 if (scsi_poll(pktp) < 0) {
14148 goto out;
14149 }
14150 if (((struct scsi_status *)pktp->pkt_scbp)->sts_chk) {
14151 goto out;
14152 }
14153 if (resid != NULL) {
14154 *resid = pktp->pkt_resid;
14155 }
14156
14157 ret = DDI_SUCCESS;
14158 out:
14159 if (pktp) {
14160 scsi_destroy_pkt(pktp);
14161 }
14162 if (tran_clone) {
14163 kmem_free(tran_clone, sizeof (scsi_hba_tran_t));
14164 }
14165 if (tgt_private) {
14166 kmem_free(tgt_private, sizeof (mptsas_tgt_private_t));
14167 }
14168 return (ret);
14169 }
14170 static int
mptsas_parse_address(char * name,uint64_t * wwid,uint8_t * phy,int * lun)14171 mptsas_parse_address(char *name, uint64_t *wwid, uint8_t *phy, int *lun)
14172 {
14173 char *cp = NULL;
14174 char *ptr = NULL;
14175 size_t s = 0;
14176 char *wwid_str = NULL;
14177 char *lun_str = NULL;
14178 long lunnum;
14179 long phyid = -1;
14180 int rc = DDI_FAILURE;
14181
14182 ptr = name;
14183 ASSERT(ptr[0] == 'w' || ptr[0] == 'p');
14184 ptr++;
14185 if ((cp = strchr(ptr, ',')) == NULL) {
14186 return (DDI_FAILURE);
14187 }
14188
14189 wwid_str = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
14190 s = (uintptr_t)cp - (uintptr_t)ptr;
14191
14192 bcopy(ptr, wwid_str, s);
14193 wwid_str[s] = '\0';
14194
14195 ptr = ++cp;
14196
14197 if ((cp = strchr(ptr, '\0')) == NULL) {
14198 goto out;
14199 }
14200 lun_str = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
14201 s = (uintptr_t)cp - (uintptr_t)ptr;
14202
14203 bcopy(ptr, lun_str, s);
14204 lun_str[s] = '\0';
14205
14206 if (name[0] == 'p') {
14207 rc = ddi_strtol(wwid_str, NULL, 0x10, &phyid);
14208 } else {
14209 rc = scsi_wwnstr_to_wwn(wwid_str, wwid);
14210 }
14211 if (rc != DDI_SUCCESS)
14212 goto out;
14213
14214 if (phyid != -1) {
14215 ASSERT(phyid < MPTSAS_MAX_PHYS);
14216 *phy = (uint8_t)phyid;
14217 }
14218 rc = ddi_strtol(lun_str, NULL, 0x10, &lunnum);
14219 if (rc != 0)
14220 goto out;
14221
14222 *lun = (int)lunnum;
14223 rc = DDI_SUCCESS;
14224 out:
14225 if (wwid_str)
14226 kmem_free(wwid_str, SCSI_MAXNAMELEN);
14227 if (lun_str)
14228 kmem_free(lun_str, SCSI_MAXNAMELEN);
14229
14230 return (rc);
14231 }
14232
14233 /*
14234 * mptsas_parse_smp_name() is to parse sas wwn string
14235 * which format is "wWWN"
14236 */
14237 static int
mptsas_parse_smp_name(char * name,uint64_t * wwn)14238 mptsas_parse_smp_name(char *name, uint64_t *wwn)
14239 {
14240 char *ptr = name;
14241
14242 if (*ptr != 'w') {
14243 return (DDI_FAILURE);
14244 }
14245
14246 ptr++;
14247 if (scsi_wwnstr_to_wwn(ptr, wwn)) {
14248 return (DDI_FAILURE);
14249 }
14250 return (DDI_SUCCESS);
14251 }
14252
14253 static int
mptsas_bus_config(dev_info_t * pdip,uint_t flag,ddi_bus_config_op_t op,void * arg,dev_info_t ** childp)14254 mptsas_bus_config(dev_info_t *pdip, uint_t flag,
14255 ddi_bus_config_op_t op, void *arg, dev_info_t **childp)
14256 {
14257 int ret = NDI_FAILURE;
14258 mptsas_t *mpt;
14259 char *ptr = NULL;
14260 char *devnm = NULL;
14261 uint64_t wwid = 0;
14262 uint8_t phy = 0xFF;
14263 int lun = 0;
14264 uint_t mflags = flag;
14265 int bconfig = TRUE;
14266
14267 if (scsi_hba_iport_unit_address(pdip) == 0) {
14268 return (DDI_FAILURE);
14269 }
14270
14271 mpt = DIP2MPT(pdip);
14272 if (!mpt) {
14273 return (DDI_FAILURE);
14274 }
14275 /*
14276 * Hold the nexus across the bus_config
14277 */
14278 ndi_devi_enter(scsi_vhci_dip);
14279 ndi_devi_enter(pdip);
14280 switch (op) {
14281 case BUS_CONFIG_ONE:
14282 /* parse wwid/target name out of name given */
14283 if ((ptr = strchr((char *)arg, '@')) == NULL) {
14284 ret = NDI_FAILURE;
14285 break;
14286 }
14287 ptr++;
14288 if (strncmp((char *)arg, "smp", 3) == 0) {
14289 /*
14290 * This is a SMP target device
14291 */
14292 ret = mptsas_parse_smp_name(ptr, &wwid);
14293 if (ret != DDI_SUCCESS) {
14294 ret = NDI_FAILURE;
14295 break;
14296 }
14297 ret = mptsas_config_smp(pdip, wwid, childp);
14298 } else if ((ptr[0] == 'w') || (ptr[0] == 'p')) {
14299 /*
14300 * OBP could pass down a non-canonical form
14301 * bootpath without LUN part when LUN is 0.
14302 * So driver need adjust the string.
14303 */
14304 if (strchr(ptr, ',') == NULL) {
14305 devnm = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
14306 (void) sprintf(devnm, "%s,0", (char *)arg);
14307 ptr = strchr(devnm, '@');
14308 ptr++;
14309 }
14310
14311 /*
14312 * The device path is wWWID format and the device
14313 * is not SMP target device.
14314 */
14315 ret = mptsas_parse_address(ptr, &wwid, &phy, &lun);
14316 if (ret != DDI_SUCCESS) {
14317 ret = NDI_FAILURE;
14318 break;
14319 }
14320 *childp = NULL;
14321 if (ptr[0] == 'w') {
14322 ret = mptsas_config_one_addr(pdip, wwid,
14323 lun, childp);
14324 } else if (ptr[0] == 'p') {
14325 ret = mptsas_config_one_phy(pdip, phy, lun,
14326 childp);
14327 }
14328
14329 /*
14330 * If this is CD/DVD device in OBP path, the
14331 * ndi_busop_bus_config can be skipped as config one
14332 * operation is done above.
14333 */
14334 if ((ret == NDI_SUCCESS) && (*childp != NULL) &&
14335 (strcmp(ddi_node_name(*childp), "cdrom") == 0) &&
14336 (strncmp((char *)arg, "disk", 4) == 0)) {
14337 bconfig = FALSE;
14338 ndi_hold_devi(*childp);
14339 }
14340 } else {
14341 ret = NDI_FAILURE;
14342 break;
14343 }
14344
14345 /*
14346 * DDI group instructed us to use this flag.
14347 */
14348 mflags |= NDI_MDI_FALLBACK;
14349 break;
14350 case BUS_CONFIG_DRIVER:
14351 case BUS_CONFIG_ALL:
14352 mptsas_config_all(pdip);
14353 ret = NDI_SUCCESS;
14354 break;
14355 default:
14356 ret = NDI_FAILURE;
14357 break;
14358 }
14359
14360 if ((ret == NDI_SUCCESS) && bconfig) {
14361 ret = ndi_busop_bus_config(pdip, mflags, op,
14362 (devnm == NULL) ? arg : devnm, childp, 0);
14363 }
14364
14365 ndi_devi_exit(pdip);
14366 ndi_devi_exit(scsi_vhci_dip);
14367 if (devnm != NULL)
14368 kmem_free(devnm, SCSI_MAXNAMELEN);
14369 return (ret);
14370 }
14371
14372 static int
mptsas_probe_lun(dev_info_t * pdip,int lun,dev_info_t ** dip,mptsas_target_t * ptgt)14373 mptsas_probe_lun(dev_info_t *pdip, int lun, dev_info_t **dip,
14374 mptsas_target_t *ptgt)
14375 {
14376 int rval = DDI_FAILURE;
14377 struct scsi_inquiry *sd_inq = NULL;
14378 mptsas_t *mpt = DIP2MPT(pdip);
14379
14380 sd_inq = (struct scsi_inquiry *)kmem_alloc(SUN_INQSIZE, KM_SLEEP);
14381
14382 rval = mptsas_inquiry(mpt, ptgt, lun, 0, (uchar_t *)sd_inq,
14383 SUN_INQSIZE, 0, (uchar_t)0);
14384
14385 if ((rval == DDI_SUCCESS) && MPTSAS_VALID_LUN(sd_inq)) {
14386 rval = mptsas_create_lun(pdip, sd_inq, dip, ptgt, lun);
14387 } else {
14388 rval = DDI_FAILURE;
14389 }
14390
14391 kmem_free(sd_inq, SUN_INQSIZE);
14392 return (rval);
14393 }
14394
14395 static int
mptsas_config_one_addr(dev_info_t * pdip,uint64_t sasaddr,int lun,dev_info_t ** lundip)14396 mptsas_config_one_addr(dev_info_t *pdip, uint64_t sasaddr, int lun,
14397 dev_info_t **lundip)
14398 {
14399 int rval;
14400 mptsas_t *mpt = DIP2MPT(pdip);
14401 int phymask;
14402 mptsas_target_t *ptgt = NULL;
14403
14404 /*
14405 * Get the physical port associated to the iport
14406 */
14407 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
14408 "phymask", 0);
14409
14410 ptgt = mptsas_wwid_to_ptgt(mpt, phymask, sasaddr);
14411 if (ptgt == NULL) {
14412 /*
14413 * didn't match any device by searching
14414 */
14415 return (DDI_FAILURE);
14416 }
14417 /*
14418 * If the LUN already exists and the status is online,
14419 * we just return the pointer to dev_info_t directly.
14420 * For the mdi_pathinfo node, we'll handle it in
14421 * mptsas_create_virt_lun()
14422 * TODO should be also in mptsas_handle_dr
14423 */
14424
14425 *lundip = mptsas_find_child_addr(pdip, sasaddr, lun);
14426 if (*lundip != NULL) {
14427 /*
14428 * TODO Another senario is, we hotplug the same disk
14429 * on the same slot, the devhdl changed, is this
14430 * possible?
14431 * tgt_private->t_private != ptgt
14432 */
14433 if (sasaddr != ptgt->m_addr.mta_wwn) {
14434 /*
14435 * The device has changed although the devhdl is the
14436 * same (Enclosure mapping mode, change drive on the
14437 * same slot)
14438 */
14439 return (DDI_FAILURE);
14440 }
14441 return (DDI_SUCCESS);
14442 }
14443
14444 if (phymask == 0) {
14445 /*
14446 * Configure IR volume
14447 */
14448 rval = mptsas_config_raid(pdip, ptgt->m_devhdl, lundip);
14449 return (rval);
14450 }
14451 rval = mptsas_probe_lun(pdip, lun, lundip, ptgt);
14452
14453 return (rval);
14454 }
14455
14456 static int
mptsas_config_one_phy(dev_info_t * pdip,uint8_t phy,int lun,dev_info_t ** lundip)14457 mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun,
14458 dev_info_t **lundip)
14459 {
14460 int rval;
14461 mptsas_t *mpt = DIP2MPT(pdip);
14462 mptsas_phymask_t phymask;
14463 mptsas_target_t *ptgt = NULL;
14464
14465 /*
14466 * Get the physical port associated to the iport
14467 */
14468 phymask = (mptsas_phymask_t)ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
14469 "phymask", 0);
14470
14471 ptgt = mptsas_phy_to_tgt(mpt, phymask, phy);
14472 if (ptgt == NULL) {
14473 /*
14474 * didn't match any device by searching
14475 */
14476 return (DDI_FAILURE);
14477 }
14478
14479 /*
14480 * If the LUN already exists and the status is online,
14481 * we just return the pointer to dev_info_t directly.
14482 * For the mdi_pathinfo node, we'll handle it in
14483 * mptsas_create_virt_lun().
14484 */
14485
14486 *lundip = mptsas_find_child_phy(pdip, phy);
14487 if (*lundip != NULL) {
14488 return (DDI_SUCCESS);
14489 }
14490
14491 rval = mptsas_probe_lun(pdip, lun, lundip, ptgt);
14492
14493 return (rval);
14494 }
14495
14496 static int
mptsas_retrieve_lundata(int lun_cnt,uint8_t * buf,uint16_t * lun_num,uint8_t * lun_addr_type)14497 mptsas_retrieve_lundata(int lun_cnt, uint8_t *buf, uint16_t *lun_num,
14498 uint8_t *lun_addr_type)
14499 {
14500 uint32_t lun_idx = 0;
14501
14502 ASSERT(lun_num != NULL);
14503 ASSERT(lun_addr_type != NULL);
14504
14505 lun_idx = (lun_cnt + 1) * MPTSAS_SCSI_REPORTLUNS_ADDRESS_SIZE;
14506 /* determine report luns addressing type */
14507 switch (buf[lun_idx] & MPTSAS_SCSI_REPORTLUNS_ADDRESS_MASK) {
14508 /*
14509 * Vendors in the field have been found to be concatenating
14510 * bus/target/lun to equal the complete lun value instead
14511 * of switching to flat space addressing
14512 */
14513 /* 00b - peripheral device addressing method */
14514 case MPTSAS_SCSI_REPORTLUNS_ADDRESS_PERIPHERAL:
14515 /* FALLTHRU */
14516 /* 10b - logical unit addressing method */
14517 case MPTSAS_SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT:
14518 /* FALLTHRU */
14519 /* 01b - flat space addressing method */
14520 case MPTSAS_SCSI_REPORTLUNS_ADDRESS_FLAT_SPACE:
14521 /* byte0 bit0-5=msb lun byte1 bit0-7=lsb lun */
14522 *lun_addr_type = (buf[lun_idx] &
14523 MPTSAS_SCSI_REPORTLUNS_ADDRESS_MASK) >> 6;
14524 *lun_num = (buf[lun_idx] & 0x3F) << 8;
14525 *lun_num |= buf[lun_idx + 1];
14526 return (DDI_SUCCESS);
14527 default:
14528 return (DDI_FAILURE);
14529 }
14530 }
14531
14532 static int
mptsas_config_luns(dev_info_t * pdip,mptsas_target_t * ptgt)14533 mptsas_config_luns(dev_info_t *pdip, mptsas_target_t *ptgt)
14534 {
14535 struct buf *repluns_bp = NULL;
14536 struct scsi_address ap;
14537 uchar_t cdb[CDB_GROUP5];
14538 int ret = DDI_FAILURE;
14539 int retry = 0;
14540 int lun_list_len = 0;
14541 uint16_t lun_num = 0;
14542 uint8_t lun_addr_type = 0;
14543 uint32_t lun_cnt = 0;
14544 uint32_t lun_total = 0;
14545 dev_info_t *cdip = NULL;
14546 uint16_t *saved_repluns = NULL;
14547 char *buffer = NULL;
14548 int buf_len = 128;
14549 mptsas_t *mpt = DIP2MPT(pdip);
14550 uint64_t sas_wwn = 0;
14551 uint8_t phy = 0xFF;
14552 uint32_t dev_info = 0;
14553
14554 mutex_enter(&mpt->m_mutex);
14555 sas_wwn = ptgt->m_addr.mta_wwn;
14556 phy = ptgt->m_phynum;
14557 dev_info = ptgt->m_deviceinfo;
14558 mutex_exit(&mpt->m_mutex);
14559
14560 if (sas_wwn == 0) {
14561 /*
14562 * It's a SATA without Device Name
14563 * So don't try multi-LUNs
14564 */
14565 if (mptsas_find_child_phy(pdip, phy)) {
14566 return (DDI_SUCCESS);
14567 } else {
14568 /*
14569 * need configure and create node
14570 */
14571 return (DDI_FAILURE);
14572 }
14573 }
14574
14575 /*
14576 * WWN (SAS address or Device Name exist)
14577 */
14578 if (dev_info & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
14579 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
14580 /*
14581 * SATA device with Device Name
14582 * So don't try multi-LUNs
14583 */
14584 if (mptsas_find_child_addr(pdip, sas_wwn, 0)) {
14585 return (DDI_SUCCESS);
14586 } else {
14587 return (DDI_FAILURE);
14588 }
14589 }
14590
14591 do {
14592 ap.a_target = MPTSAS_INVALID_DEVHDL;
14593 ap.a_lun = 0;
14594 ap.a_hba_tran = mpt->m_tran;
14595 repluns_bp = scsi_alloc_consistent_buf(&ap,
14596 (struct buf *)NULL, buf_len, B_READ, NULL_FUNC, NULL);
14597 if (repluns_bp == NULL) {
14598 retry++;
14599 continue;
14600 }
14601 bzero(cdb, CDB_GROUP5);
14602 cdb[0] = SCMD_REPORT_LUNS;
14603 cdb[6] = (buf_len & 0xff000000) >> 24;
14604 cdb[7] = (buf_len & 0x00ff0000) >> 16;
14605 cdb[8] = (buf_len & 0x0000ff00) >> 8;
14606 cdb[9] = (buf_len & 0x000000ff);
14607
14608 ret = mptsas_send_scsi_cmd(mpt, &ap, ptgt, &cdb[0], CDB_GROUP5,
14609 repluns_bp, NULL);
14610 if (ret != DDI_SUCCESS) {
14611 scsi_free_consistent_buf(repluns_bp);
14612 retry++;
14613 continue;
14614 }
14615 lun_list_len = BE_32(*(int *)((void *)(
14616 repluns_bp->b_un.b_addr)));
14617 if (buf_len >= lun_list_len + 8) {
14618 ret = DDI_SUCCESS;
14619 break;
14620 }
14621 scsi_free_consistent_buf(repluns_bp);
14622 buf_len = lun_list_len + 8;
14623
14624 } while (retry < 3);
14625
14626 if (ret != DDI_SUCCESS)
14627 return (ret);
14628 buffer = (char *)repluns_bp->b_un.b_addr;
14629 /*
14630 * find out the number of luns returned by the SCSI ReportLun call
14631 * and allocate buffer space
14632 */
14633 lun_total = lun_list_len / MPTSAS_SCSI_REPORTLUNS_ADDRESS_SIZE;
14634 saved_repluns = kmem_zalloc(sizeof (uint16_t) * lun_total, KM_SLEEP);
14635 if (saved_repluns == NULL) {
14636 scsi_free_consistent_buf(repluns_bp);
14637 return (DDI_FAILURE);
14638 }
14639 for (lun_cnt = 0; lun_cnt < lun_total; lun_cnt++) {
14640 if (mptsas_retrieve_lundata(lun_cnt, (uint8_t *)(buffer),
14641 &lun_num, &lun_addr_type) != DDI_SUCCESS) {
14642 continue;
14643 }
14644 saved_repluns[lun_cnt] = lun_num;
14645 if ((cdip = mptsas_find_child_addr(pdip, sas_wwn, lun_num)) !=
14646 NULL) {
14647 ret = DDI_SUCCESS;
14648 } else {
14649 ret = mptsas_probe_lun(pdip, lun_num, &cdip,
14650 ptgt);
14651 }
14652 if ((ret == DDI_SUCCESS) && (cdip != NULL)) {
14653 (void) ndi_prop_remove(DDI_DEV_T_NONE, cdip,
14654 MPTSAS_DEV_GONE);
14655 }
14656 }
14657 mptsas_offline_missed_luns(pdip, saved_repluns, lun_total, ptgt);
14658 kmem_free(saved_repluns, sizeof (uint16_t) * lun_total);
14659 scsi_free_consistent_buf(repluns_bp);
14660 return (DDI_SUCCESS);
14661 }
14662
14663 static int
mptsas_config_raid(dev_info_t * pdip,uint16_t target,dev_info_t ** dip)14664 mptsas_config_raid(dev_info_t *pdip, uint16_t target, dev_info_t **dip)
14665 {
14666 int rval = DDI_FAILURE;
14667 struct scsi_inquiry *sd_inq = NULL;
14668 mptsas_t *mpt = DIP2MPT(pdip);
14669 mptsas_target_t *ptgt = NULL;
14670
14671 mutex_enter(&mpt->m_mutex);
14672 ptgt = refhash_linear_search(mpt->m_targets,
14673 mptsas_target_eval_devhdl, &target);
14674 mutex_exit(&mpt->m_mutex);
14675 if (ptgt == NULL) {
14676 mptsas_log(mpt, CE_WARN, "Volume with VolDevHandle of 0x%x "
14677 "not found.", target);
14678 return (rval);
14679 }
14680
14681 sd_inq = (struct scsi_inquiry *)kmem_alloc(SUN_INQSIZE, KM_SLEEP);
14682 rval = mptsas_inquiry(mpt, ptgt, 0, 0, (uchar_t *)sd_inq,
14683 SUN_INQSIZE, 0, (uchar_t)0);
14684
14685 if ((rval == DDI_SUCCESS) && MPTSAS_VALID_LUN(sd_inq)) {
14686 rval = mptsas_create_phys_lun(pdip, sd_inq, NULL, dip, ptgt,
14687 0);
14688 } else {
14689 rval = DDI_FAILURE;
14690 }
14691
14692 kmem_free(sd_inq, SUN_INQSIZE);
14693 return (rval);
14694 }
14695
14696 /*
14697 * configure all RAID volumes for virtual iport
14698 */
14699 static void
mptsas_config_all_viport(dev_info_t * pdip)14700 mptsas_config_all_viport(dev_info_t *pdip)
14701 {
14702 mptsas_t *mpt = DIP2MPT(pdip);
14703 int config, vol;
14704 int target;
14705 dev_info_t *lundip = NULL;
14706
14707 /*
14708 * Get latest RAID info and search for any Volume DevHandles. If any
14709 * are found, configure the volume.
14710 */
14711 mutex_enter(&mpt->m_mutex);
14712 for (config = 0; config < mpt->m_num_raid_configs; config++) {
14713 for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) {
14714 if (mpt->m_raidconfig[config].m_raidvol[vol].m_israid
14715 == 1) {
14716 target = mpt->m_raidconfig[config].
14717 m_raidvol[vol].m_raidhandle;
14718 mutex_exit(&mpt->m_mutex);
14719 (void) mptsas_config_raid(pdip, target,
14720 &lundip);
14721 mutex_enter(&mpt->m_mutex);
14722 }
14723 }
14724 }
14725 mutex_exit(&mpt->m_mutex);
14726 }
14727
14728 static void
mptsas_offline_missed_luns(dev_info_t * pdip,uint16_t * repluns,int lun_cnt,mptsas_target_t * ptgt)14729 mptsas_offline_missed_luns(dev_info_t *pdip, uint16_t *repluns,
14730 int lun_cnt, mptsas_target_t *ptgt)
14731 {
14732 dev_info_t *child = NULL, *savechild = NULL;
14733 mdi_pathinfo_t *pip = NULL, *savepip = NULL;
14734 uint64_t sas_wwn, wwid;
14735 uint8_t phy;
14736 int lun;
14737 int i;
14738 int find;
14739 char *addr;
14740 char *nodename;
14741 mptsas_t *mpt = DIP2MPT(pdip);
14742
14743 mutex_enter(&mpt->m_mutex);
14744 wwid = ptgt->m_addr.mta_wwn;
14745 mutex_exit(&mpt->m_mutex);
14746
14747 child = ddi_get_child(pdip);
14748 while (child) {
14749 find = 0;
14750 savechild = child;
14751 child = ddi_get_next_sibling(child);
14752
14753 nodename = ddi_node_name(savechild);
14754 if (strcmp(nodename, "smp") == 0) {
14755 continue;
14756 }
14757
14758 addr = ddi_get_name_addr(savechild);
14759 if (addr == NULL) {
14760 continue;
14761 }
14762
14763 if (mptsas_parse_address(addr, &sas_wwn, &phy, &lun) !=
14764 DDI_SUCCESS) {
14765 continue;
14766 }
14767
14768 if (wwid == sas_wwn) {
14769 for (i = 0; i < lun_cnt; i++) {
14770 if (repluns[i] == lun) {
14771 find = 1;
14772 break;
14773 }
14774 }
14775 } else {
14776 continue;
14777 }
14778 if (find == 0) {
14779 /*
14780 * The lun has not been there already
14781 */
14782 (void) mptsas_offline_lun(pdip, savechild, NULL,
14783 NDI_DEVI_REMOVE);
14784 }
14785 }
14786
14787 pip = mdi_get_next_client_path(pdip, NULL);
14788 while (pip) {
14789 find = 0;
14790 savepip = pip;
14791 addr = MDI_PI(pip)->pi_addr;
14792
14793 pip = mdi_get_next_client_path(pdip, pip);
14794
14795 if (addr == NULL) {
14796 continue;
14797 }
14798
14799 if (mptsas_parse_address(addr, &sas_wwn, &phy,
14800 &lun) != DDI_SUCCESS) {
14801 continue;
14802 }
14803
14804 if (sas_wwn == wwid) {
14805 for (i = 0; i < lun_cnt; i++) {
14806 if (repluns[i] == lun) {
14807 find = 1;
14808 break;
14809 }
14810 }
14811 } else {
14812 continue;
14813 }
14814
14815 if (find == 0) {
14816 /*
14817 * The lun has not been there already
14818 */
14819 (void) mptsas_offline_lun(pdip, NULL, savepip,
14820 NDI_DEVI_REMOVE);
14821 }
14822 }
14823 }
14824
14825 /*
14826 * If this enclosure doesn't exist in the enclosure list, add it. If it does,
14827 * update it.
14828 */
14829 static void
mptsas_enclosure_update(mptsas_t * mpt,mptsas_enclosure_t * mep)14830 mptsas_enclosure_update(mptsas_t *mpt, mptsas_enclosure_t *mep)
14831 {
14832 mptsas_enclosure_t *m;
14833
14834 ASSERT(MUTEX_HELD(&mpt->m_mutex));
14835 m = mptsas_enc_lookup(mpt, mep->me_enchdl);
14836 if (m != NULL) {
14837 uint8_t *ledp;
14838 m->me_flags = mep->me_flags;
14839
14840
14841 /*
14842 * If the number of slots and the first slot entry in the
14843 * enclosure has not changed, then we don't need to do anything
14844 * here. Otherwise, we need to allocate a new array for the LED
14845 * status of the slot.
14846 */
14847 if (m->me_fslot == mep->me_fslot &&
14848 m->me_nslots == mep->me_nslots)
14849 return;
14850
14851 /*
14852 * If the number of slots or the first slot has changed, it's
14853 * not clear that we're really in a place that we can continue
14854 * to honor the existing flags.
14855 */
14856 if (mep->me_nslots > 0) {
14857 ledp = kmem_zalloc(sizeof (uint8_t) * mep->me_nslots,
14858 KM_SLEEP);
14859 } else {
14860 ledp = NULL;
14861 }
14862
14863 if (m->me_slotleds != NULL) {
14864 kmem_free(m->me_slotleds, sizeof (uint8_t) *
14865 m->me_nslots);
14866 }
14867 m->me_slotleds = ledp;
14868 m->me_fslot = mep->me_fslot;
14869 m->me_nslots = mep->me_nslots;
14870 return;
14871 }
14872
14873 m = kmem_zalloc(sizeof (*m), KM_SLEEP);
14874 m->me_enchdl = mep->me_enchdl;
14875 m->me_flags = mep->me_flags;
14876 m->me_nslots = mep->me_nslots;
14877 m->me_fslot = mep->me_fslot;
14878 if (m->me_nslots > 0) {
14879 m->me_slotleds = kmem_zalloc(sizeof (uint8_t) * mep->me_nslots,
14880 KM_SLEEP);
14881 /*
14882 * It may make sense to optionally flush all of the slots and/or
14883 * read the slot status flag here to synchronize between
14884 * ourselves and the card. So far, that hasn't been needed
14885 * annecdotally when enumerating something new. If we do, we
14886 * should kick that off in a taskq potentially.
14887 */
14888 }
14889 list_insert_tail(&mpt->m_enclosures, m);
14890 }
14891
14892 static void
mptsas_update_hashtab(struct mptsas * mpt)14893 mptsas_update_hashtab(struct mptsas *mpt)
14894 {
14895 uint32_t page_address;
14896 int rval = 0;
14897 uint16_t dev_handle;
14898 mptsas_target_t *ptgt = NULL;
14899 mptsas_smp_t smp_node;
14900
14901 /*
14902 * Get latest RAID info.
14903 */
14904 (void) mptsas_get_raid_info(mpt);
14905
14906 dev_handle = mpt->m_smp_devhdl;
14907 while (mpt->m_done_traverse_smp == 0) {
14908 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL &
14909 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)dev_handle;
14910 if (mptsas_get_sas_expander_page0(mpt, page_address, &smp_node)
14911 != DDI_SUCCESS) {
14912 break;
14913 }
14914 mpt->m_smp_devhdl = dev_handle = smp_node.m_devhdl;
14915 (void) mptsas_smp_alloc(mpt, &smp_node);
14916 }
14917
14918 /*
14919 * Loop over enclosures so we can understand what's there.
14920 */
14921 dev_handle = MPTSAS_INVALID_DEVHDL;
14922 while (mpt->m_done_traverse_enc == 0) {
14923 mptsas_enclosure_t me;
14924
14925 page_address = (MPI2_SAS_ENCLOS_PGAD_FORM_GET_NEXT_HANDLE &
14926 MPI2_SAS_ENCLOS_PGAD_FORM_MASK) | (uint32_t)dev_handle;
14927
14928 if (mptsas_get_enclosure_page0(mpt, page_address, &me) !=
14929 DDI_SUCCESS) {
14930 break;
14931 }
14932 dev_handle = me.me_enchdl;
14933 mptsas_enclosure_update(mpt, &me);
14934 }
14935
14936 /*
14937 * Config target devices
14938 */
14939 dev_handle = mpt->m_dev_handle;
14940
14941 /*
14942 * Loop to get sas device page 0 by GetNextHandle till the
14943 * the last handle. If the sas device is a SATA/SSP target,
14944 * we try to config it.
14945 */
14946 while (mpt->m_done_traverse_dev == 0) {
14947 ptgt = NULL;
14948 page_address =
14949 (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE &
14950 MPI2_SAS_DEVICE_PGAD_FORM_MASK) |
14951 (uint32_t)dev_handle;
14952 rval = mptsas_get_target_device_info(mpt, page_address,
14953 &dev_handle, &ptgt);
14954 if ((rval == DEV_INFO_FAIL_PAGE0) ||
14955 (rval == DEV_INFO_FAIL_ALLOC)) {
14956 break;
14957 }
14958 if (rval == DEV_INFO_FAIL_GUID) {
14959 continue;
14960 }
14961
14962 mpt->m_dev_handle = dev_handle;
14963 }
14964
14965 }
14966
14967 void
mptsas_update_driver_data(struct mptsas * mpt)14968 mptsas_update_driver_data(struct mptsas *mpt)
14969 {
14970 mptsas_target_t *tp;
14971 mptsas_smp_t *sp;
14972
14973 ASSERT(MUTEX_HELD(&mpt->m_mutex));
14974
14975 /*
14976 * TODO after hard reset, update the driver data structures
14977 * 1. update port/phymask mapping table mpt->m_phy_info
14978 * 2. invalid all the entries in hash table
14979 * m_devhdl = 0xffff and m_deviceinfo = 0
14980 * 3. call sas_device_page/expander_page to update hash table
14981 */
14982 mptsas_update_phymask(mpt);
14983
14984 /*
14985 * Remove all the devhdls for existing entries but leave their
14986 * addresses alone. In update_hashtab() below, we'll find all
14987 * targets that are still present and reassociate them with
14988 * their potentially new devhdls. Leaving the targets around in
14989 * this fashion allows them to be used on the tx waitq even
14990 * while IOC reset is occurring.
14991 */
14992 for (tp = refhash_first(mpt->m_targets); tp != NULL;
14993 tp = refhash_next(mpt->m_targets, tp)) {
14994 tp->m_devhdl = MPTSAS_INVALID_DEVHDL;
14995 tp->m_deviceinfo = 0;
14996 tp->m_dr_flag = MPTSAS_DR_INACTIVE;
14997 }
14998 for (sp = refhash_first(mpt->m_smp_targets); sp != NULL;
14999 sp = refhash_next(mpt->m_smp_targets, sp)) {
15000 sp->m_devhdl = MPTSAS_INVALID_DEVHDL;
15001 sp->m_deviceinfo = 0;
15002 }
15003 mpt->m_done_traverse_dev = 0;
15004 mpt->m_done_traverse_smp = 0;
15005 mpt->m_done_traverse_enc = 0;
15006 mpt->m_dev_handle = mpt->m_smp_devhdl = MPTSAS_INVALID_DEVHDL;
15007 mptsas_update_hashtab(mpt);
15008 }
15009
15010 static void
mptsas_config_all(dev_info_t * pdip)15011 mptsas_config_all(dev_info_t *pdip)
15012 {
15013 dev_info_t *smpdip = NULL;
15014 mptsas_t *mpt = DIP2MPT(pdip);
15015 int phymask = 0;
15016 mptsas_phymask_t phy_mask;
15017 mptsas_target_t *ptgt = NULL;
15018 mptsas_smp_t *psmp;
15019
15020 /*
15021 * Get the phymask associated to the iport
15022 */
15023 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
15024 "phymask", 0);
15025
15026 /*
15027 * Enumerate RAID volumes here (phymask == 0).
15028 */
15029 if (phymask == 0) {
15030 mptsas_config_all_viport(pdip);
15031 return;
15032 }
15033
15034 mutex_enter(&mpt->m_mutex);
15035
15036 if (!mpt->m_done_traverse_dev || !mpt->m_done_traverse_smp ||
15037 !mpt->m_done_traverse_enc) {
15038 mptsas_update_hashtab(mpt);
15039 }
15040
15041 for (psmp = refhash_first(mpt->m_smp_targets); psmp != NULL;
15042 psmp = refhash_next(mpt->m_smp_targets, psmp)) {
15043 phy_mask = psmp->m_addr.mta_phymask;
15044 if (phy_mask == phymask) {
15045 smpdip = NULL;
15046 mutex_exit(&mpt->m_mutex);
15047 (void) mptsas_online_smp(pdip, psmp, &smpdip);
15048 mutex_enter(&mpt->m_mutex);
15049 }
15050 }
15051
15052 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
15053 ptgt = refhash_next(mpt->m_targets, ptgt)) {
15054 phy_mask = ptgt->m_addr.mta_phymask;
15055 if (phy_mask == phymask) {
15056 mutex_exit(&mpt->m_mutex);
15057 (void) mptsas_config_target(pdip, ptgt);
15058 mutex_enter(&mpt->m_mutex);
15059 }
15060 }
15061 mutex_exit(&mpt->m_mutex);
15062 }
15063
15064 static int
mptsas_config_target(dev_info_t * pdip,mptsas_target_t * ptgt)15065 mptsas_config_target(dev_info_t *pdip, mptsas_target_t *ptgt)
15066 {
15067 int rval = DDI_FAILURE;
15068 dev_info_t *tdip;
15069
15070 rval = mptsas_config_luns(pdip, ptgt);
15071 if (rval != DDI_SUCCESS) {
15072 /*
15073 * The return value means the SCMD_REPORT_LUNS
15074 * did not execute successfully. The target maybe
15075 * doesn't support such command.
15076 */
15077 rval = mptsas_probe_lun(pdip, 0, &tdip, ptgt);
15078 }
15079 return (rval);
15080 }
15081
15082 /*
15083 * Return fail if not all the childs/paths are freed.
15084 * if there is any path under the HBA, the return value will be always fail
15085 * because we didn't call mdi_pi_free for path
15086 */
15087 static int
mptsas_offline_target(dev_info_t * pdip,char * name)15088 mptsas_offline_target(dev_info_t *pdip, char *name)
15089 {
15090 dev_info_t *child = NULL, *prechild = NULL;
15091 mdi_pathinfo_t *pip = NULL, *savepip = NULL;
15092 int tmp_rval, rval = DDI_SUCCESS;
15093 char *addr, *cp;
15094 size_t s;
15095 mptsas_t *mpt = DIP2MPT(pdip);
15096
15097 child = ddi_get_child(pdip);
15098 while (child) {
15099 addr = ddi_get_name_addr(child);
15100 prechild = child;
15101 child = ddi_get_next_sibling(child);
15102
15103 if (addr == NULL) {
15104 continue;
15105 }
15106 if ((cp = strchr(addr, ',')) == NULL) {
15107 continue;
15108 }
15109
15110 s = (uintptr_t)cp - (uintptr_t)addr;
15111
15112 if (strncmp(addr, name, s) != 0) {
15113 continue;
15114 }
15115
15116 tmp_rval = mptsas_offline_lun(pdip, prechild, NULL,
15117 NDI_DEVI_REMOVE);
15118 if (tmp_rval != DDI_SUCCESS) {
15119 rval = DDI_FAILURE;
15120 if (ndi_prop_create_boolean(DDI_DEV_T_NONE,
15121 prechild, MPTSAS_DEV_GONE) !=
15122 DDI_PROP_SUCCESS) {
15123 mptsas_log(mpt, CE_WARN, "mptsas driver "
15124 "unable to create property for "
15125 "SAS %s (MPTSAS_DEV_GONE)", addr);
15126 }
15127 }
15128 }
15129
15130 pip = mdi_get_next_client_path(pdip, NULL);
15131 while (pip) {
15132 addr = MDI_PI(pip)->pi_addr;
15133 savepip = pip;
15134 pip = mdi_get_next_client_path(pdip, pip);
15135 if (addr == NULL) {
15136 continue;
15137 }
15138
15139 if ((cp = strchr(addr, ',')) == NULL) {
15140 continue;
15141 }
15142
15143 s = (uintptr_t)cp - (uintptr_t)addr;
15144
15145 if (strncmp(addr, name, s) != 0) {
15146 continue;
15147 }
15148
15149 (void) mptsas_offline_lun(pdip, NULL, savepip,
15150 NDI_DEVI_REMOVE);
15151 /*
15152 * driver will not invoke mdi_pi_free, so path will not
15153 * be freed forever, return DDI_FAILURE.
15154 */
15155 rval = DDI_FAILURE;
15156 }
15157 return (rval);
15158 }
15159
15160 static int
mptsas_offline_lun(dev_info_t * pdip,dev_info_t * rdip,mdi_pathinfo_t * rpip,uint_t flags)15161 mptsas_offline_lun(dev_info_t *pdip, dev_info_t *rdip,
15162 mdi_pathinfo_t *rpip, uint_t flags)
15163 {
15164 int rval = DDI_FAILURE;
15165 char *devname;
15166 dev_info_t *cdip, *parent;
15167
15168 if (rpip != NULL) {
15169 parent = scsi_vhci_dip;
15170 cdip = mdi_pi_get_client(rpip);
15171 } else if (rdip != NULL) {
15172 parent = pdip;
15173 cdip = rdip;
15174 } else {
15175 return (DDI_FAILURE);
15176 }
15177
15178 /*
15179 * Make sure node is attached otherwise
15180 * it won't have related cache nodes to
15181 * clean up. i_ddi_devi_attached is
15182 * similiar to i_ddi_node_state(cdip) >=
15183 * DS_ATTACHED.
15184 */
15185 if (i_ddi_devi_attached(cdip)) {
15186
15187 /* Get full devname */
15188 devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP);
15189 (void) ddi_deviname(cdip, devname);
15190 /* Clean cache */
15191 (void) devfs_clean(parent, devname + 1,
15192 DV_CLEAN_FORCE);
15193 kmem_free(devname, MAXNAMELEN + 1);
15194 }
15195 if (rpip != NULL) {
15196 if (MDI_PI_IS_OFFLINE(rpip)) {
15197 rval = DDI_SUCCESS;
15198 } else {
15199 rval = mdi_pi_offline(rpip, 0);
15200 }
15201 } else {
15202 rval = ndi_devi_offline(cdip, flags);
15203 }
15204
15205 return (rval);
15206 }
15207
15208 static dev_info_t *
mptsas_find_smp_child(dev_info_t * parent,char * str_wwn)15209 mptsas_find_smp_child(dev_info_t *parent, char *str_wwn)
15210 {
15211 dev_info_t *child = NULL;
15212 char *smp_wwn = NULL;
15213
15214 child = ddi_get_child(parent);
15215 while (child) {
15216 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child,
15217 DDI_PROP_DONTPASS, SMP_WWN, &smp_wwn)
15218 != DDI_SUCCESS) {
15219 child = ddi_get_next_sibling(child);
15220 continue;
15221 }
15222
15223 if (strcmp(smp_wwn, str_wwn) == 0) {
15224 ddi_prop_free(smp_wwn);
15225 break;
15226 }
15227 child = ddi_get_next_sibling(child);
15228 ddi_prop_free(smp_wwn);
15229 }
15230 return (child);
15231 }
15232
15233 static int
mptsas_offline_smp(dev_info_t * pdip,mptsas_smp_t * smp_node,uint_t flags)15234 mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, uint_t flags)
15235 {
15236 int rval = DDI_FAILURE;
15237 char *devname;
15238 char wwn_str[MPTSAS_WWN_STRLEN];
15239 dev_info_t *cdip;
15240
15241 (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_addr.mta_wwn);
15242
15243 cdip = mptsas_find_smp_child(pdip, wwn_str);
15244
15245 if (cdip == NULL)
15246 return (DDI_SUCCESS);
15247
15248 /*
15249 * Make sure node is attached otherwise
15250 * it won't have related cache nodes to
15251 * clean up. i_ddi_devi_attached is
15252 * similiar to i_ddi_node_state(cdip) >=
15253 * DS_ATTACHED.
15254 */
15255 if (i_ddi_devi_attached(cdip)) {
15256
15257 /* Get full devname */
15258 devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP);
15259 (void) ddi_deviname(cdip, devname);
15260 /* Clean cache */
15261 (void) devfs_clean(pdip, devname + 1,
15262 DV_CLEAN_FORCE);
15263 kmem_free(devname, MAXNAMELEN + 1);
15264 }
15265
15266 rval = ndi_devi_offline(cdip, flags);
15267
15268 return (rval);
15269 }
15270
15271 static dev_info_t *
mptsas_find_child(dev_info_t * pdip,char * name)15272 mptsas_find_child(dev_info_t *pdip, char *name)
15273 {
15274 dev_info_t *child = NULL;
15275 char *rname = NULL;
15276 int rval = DDI_FAILURE;
15277
15278 rname = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
15279
15280 child = ddi_get_child(pdip);
15281 while (child) {
15282 rval = mptsas_name_child(child, rname, SCSI_MAXNAMELEN);
15283 if (rval != DDI_SUCCESS) {
15284 child = ddi_get_next_sibling(child);
15285 bzero(rname, SCSI_MAXNAMELEN);
15286 continue;
15287 }
15288
15289 if (strcmp(rname, name) == 0) {
15290 break;
15291 }
15292 child = ddi_get_next_sibling(child);
15293 bzero(rname, SCSI_MAXNAMELEN);
15294 }
15295
15296 kmem_free(rname, SCSI_MAXNAMELEN);
15297
15298 return (child);
15299 }
15300
15301
15302 static dev_info_t *
mptsas_find_child_addr(dev_info_t * pdip,uint64_t sasaddr,int lun)15303 mptsas_find_child_addr(dev_info_t *pdip, uint64_t sasaddr, int lun)
15304 {
15305 dev_info_t *child = NULL;
15306 char *name = NULL;
15307 char *addr = NULL;
15308
15309 name = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
15310 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
15311 (void) sprintf(name, "%016"PRIx64, sasaddr);
15312 (void) sprintf(addr, "w%s,%x", name, lun);
15313 child = mptsas_find_child(pdip, addr);
15314 kmem_free(name, SCSI_MAXNAMELEN);
15315 kmem_free(addr, SCSI_MAXNAMELEN);
15316 return (child);
15317 }
15318
15319 static dev_info_t *
mptsas_find_child_phy(dev_info_t * pdip,uint8_t phy)15320 mptsas_find_child_phy(dev_info_t *pdip, uint8_t phy)
15321 {
15322 dev_info_t *child;
15323 char *addr;
15324
15325 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
15326 (void) sprintf(addr, "p%x,0", phy);
15327 child = mptsas_find_child(pdip, addr);
15328 kmem_free(addr, SCSI_MAXNAMELEN);
15329 return (child);
15330 }
15331
15332 static mdi_pathinfo_t *
mptsas_find_path_phy(dev_info_t * pdip,uint8_t phy)15333 mptsas_find_path_phy(dev_info_t *pdip, uint8_t phy)
15334 {
15335 mdi_pathinfo_t *path;
15336 char *addr = NULL;
15337
15338 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
15339 (void) sprintf(addr, "p%x,0", phy);
15340 path = mdi_pi_find(pdip, NULL, addr);
15341 kmem_free(addr, SCSI_MAXNAMELEN);
15342 return (path);
15343 }
15344
15345 static mdi_pathinfo_t *
mptsas_find_path_addr(dev_info_t * parent,uint64_t sasaddr,int lun)15346 mptsas_find_path_addr(dev_info_t *parent, uint64_t sasaddr, int lun)
15347 {
15348 mdi_pathinfo_t *path;
15349 char *name = NULL;
15350 char *addr = NULL;
15351
15352 name = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
15353 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
15354 (void) sprintf(name, "%016"PRIx64, sasaddr);
15355 (void) sprintf(addr, "w%s,%x", name, lun);
15356 path = mdi_pi_find(parent, NULL, addr);
15357 kmem_free(name, SCSI_MAXNAMELEN);
15358 kmem_free(addr, SCSI_MAXNAMELEN);
15359
15360 return (path);
15361 }
15362
15363 static int
mptsas_create_lun(dev_info_t * pdip,struct scsi_inquiry * sd_inq,dev_info_t ** lun_dip,mptsas_target_t * ptgt,int lun)15364 mptsas_create_lun(dev_info_t *pdip, struct scsi_inquiry *sd_inq,
15365 dev_info_t **lun_dip, mptsas_target_t *ptgt, int lun)
15366 {
15367 int i = 0;
15368 uchar_t *inq83 = NULL;
15369 int inq83_len1 = 0xFF;
15370 int inq83_len = 0;
15371 int rval = DDI_FAILURE;
15372 ddi_devid_t devid;
15373 char *guid = NULL;
15374 int target = ptgt->m_devhdl;
15375 mdi_pathinfo_t *pip = NULL;
15376 mptsas_t *mpt = DIP2MPT(pdip);
15377
15378 /*
15379 * For DVD/CD ROM and tape devices and optical
15380 * devices, we won't try to enumerate them under
15381 * scsi_vhci, so no need to try page83
15382 */
15383 if (sd_inq && (sd_inq->inq_dtype == DTYPE_RODIRECT ||
15384 sd_inq->inq_dtype == DTYPE_OPTICAL ||
15385 sd_inq->inq_dtype == DTYPE_ESI))
15386 goto create_lun;
15387
15388 /*
15389 * The LCA returns good SCSI status, but corrupt page 83 data the first
15390 * time it is queried. The solution is to keep trying to request page83
15391 * and verify the GUID is not (DDI_NOT_WELL_FORMED) in
15392 * mptsas_inq83_retry_timeout seconds. If the timeout expires, driver
15393 * give up to get VPD page at this stage and fail the enumeration.
15394 */
15395
15396 inq83 = kmem_zalloc(inq83_len1, KM_SLEEP);
15397
15398 for (i = 0; i < mptsas_inq83_retry_timeout; i++) {
15399 rval = mptsas_inquiry(mpt, ptgt, lun, 0x83, inq83,
15400 inq83_len1, &inq83_len, 1);
15401 if (rval != 0) {
15402 mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page "
15403 "0x83 for target:%x, lun:%x failed!", target, lun);
15404 if (mptsas_physical_bind_failed_page_83 != B_FALSE)
15405 goto create_lun;
15406 goto out;
15407 }
15408 /*
15409 * create DEVID from inquiry data
15410 */
15411 if ((rval = ddi_devid_scsi_encode(
15412 DEVID_SCSI_ENCODE_VERSION_LATEST, NULL, (uchar_t *)sd_inq,
15413 sizeof (struct scsi_inquiry), NULL, 0, inq83,
15414 (size_t)inq83_len, &devid)) == DDI_SUCCESS) {
15415 /*
15416 * extract GUID from DEVID
15417 */
15418 guid = ddi_devid_to_guid(devid);
15419
15420 /*
15421 * Do not enable MPXIO if the strlen(guid) is greater
15422 * than MPTSAS_MAX_GUID_LEN, this constrain would be
15423 * handled by framework later.
15424 */
15425 if (guid && (strlen(guid) > MPTSAS_MAX_GUID_LEN)) {
15426 ddi_devid_free_guid(guid);
15427 guid = NULL;
15428 if (mpt->m_mpxio_enable == TRUE) {
15429 mptsas_log(mpt, CE_NOTE, "!Target:%x, "
15430 "lun:%x doesn't have a valid GUID, "
15431 "multipathing for this drive is "
15432 "not enabled", target, lun);
15433 }
15434 }
15435
15436 /*
15437 * devid no longer needed
15438 */
15439 ddi_devid_free(devid);
15440 break;
15441 } else if (rval == DDI_NOT_WELL_FORMED) {
15442 /*
15443 * return value of ddi_devid_scsi_encode equal to
15444 * DDI_NOT_WELL_FORMED means DEVID_RETRY, it worth
15445 * to retry inquiry page 0x83 and get GUID.
15446 */
15447 NDBG20(("Not well formed devid, retry..."));
15448 delay(1 * drv_usectohz(1000000));
15449 continue;
15450 } else {
15451 mptsas_log(mpt, CE_WARN, "!Encode devid failed for "
15452 "path target:%x, lun:%x", target, lun);
15453 rval = DDI_FAILURE;
15454 goto create_lun;
15455 }
15456 }
15457
15458 if (i == mptsas_inq83_retry_timeout) {
15459 mptsas_log(mpt, CE_WARN, "!Repeated page83 requests timeout "
15460 "for path target:%x, lun:%x", target, lun);
15461 }
15462
15463 rval = DDI_FAILURE;
15464
15465 create_lun:
15466 if ((guid != NULL) && (mpt->m_mpxio_enable == TRUE)) {
15467 rval = mptsas_create_virt_lun(pdip, sd_inq, guid, lun_dip, &pip,
15468 ptgt, lun);
15469 }
15470 if (rval != DDI_SUCCESS) {
15471 rval = mptsas_create_phys_lun(pdip, sd_inq, guid, lun_dip,
15472 ptgt, lun);
15473
15474 }
15475 out:
15476 if (guid != NULL) {
15477 /*
15478 * guid no longer needed
15479 */
15480 ddi_devid_free_guid(guid);
15481 }
15482 if (inq83 != NULL)
15483 kmem_free(inq83, inq83_len1);
15484 return (rval);
15485 }
15486
15487 static int
mptsas_create_virt_lun(dev_info_t * pdip,struct scsi_inquiry * inq,char * guid,dev_info_t ** lun_dip,mdi_pathinfo_t ** pip,mptsas_target_t * ptgt,int lun)15488 mptsas_create_virt_lun(dev_info_t *pdip, struct scsi_inquiry *inq, char *guid,
15489 dev_info_t **lun_dip, mdi_pathinfo_t **pip, mptsas_target_t *ptgt, int lun)
15490 {
15491 int target;
15492 char *nodename = NULL;
15493 char **compatible = NULL;
15494 int ncompatible = 0;
15495 int mdi_rtn = MDI_FAILURE;
15496 int rval = DDI_FAILURE;
15497 char *old_guid = NULL;
15498 mptsas_t *mpt = DIP2MPT(pdip);
15499 char *lun_addr = NULL;
15500 char *wwn_str = NULL;
15501 char *attached_wwn_str = NULL;
15502 char *component = NULL;
15503 uint8_t phy = 0xFF;
15504 uint64_t sas_wwn;
15505 int64_t lun64 = 0;
15506 uint32_t devinfo;
15507 uint16_t dev_hdl;
15508 uint16_t pdev_hdl;
15509 uint64_t dev_sas_wwn;
15510 uint64_t pdev_sas_wwn;
15511 uint32_t pdev_info;
15512 uint8_t physport;
15513 uint8_t phy_id;
15514 uint32_t page_address;
15515 uint16_t bay_num, enclosure, io_flags;
15516 char pdev_wwn_str[MPTSAS_WWN_STRLEN];
15517 uint32_t dev_info;
15518
15519 mutex_enter(&mpt->m_mutex);
15520 target = ptgt->m_devhdl;
15521 sas_wwn = ptgt->m_addr.mta_wwn;
15522 devinfo = ptgt->m_deviceinfo;
15523 phy = ptgt->m_phynum;
15524 mutex_exit(&mpt->m_mutex);
15525
15526 if (sas_wwn) {
15527 *pip = mptsas_find_path_addr(pdip, sas_wwn, lun);
15528 } else {
15529 *pip = mptsas_find_path_phy(pdip, phy);
15530 }
15531
15532 if (*pip != NULL) {
15533 *lun_dip = MDI_PI(*pip)->pi_client->ct_dip;
15534 ASSERT(*lun_dip != NULL);
15535 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, *lun_dip,
15536 (DDI_PROP_DONTPASS | DDI_PROP_NOTPROM),
15537 MDI_CLIENT_GUID_PROP, &old_guid) == DDI_SUCCESS) {
15538 if (strncmp(guid, old_guid, strlen(guid)) == 0) {
15539 /*
15540 * Same path back online again.
15541 */
15542 (void) ddi_prop_free(old_guid);
15543 if ((!MDI_PI_IS_ONLINE(*pip)) &&
15544 (!MDI_PI_IS_STANDBY(*pip)) &&
15545 (ptgt->m_tgt_unconfigured == 0)) {
15546 rval = mdi_pi_online(*pip, 0);
15547 } else {
15548 rval = DDI_SUCCESS;
15549 }
15550 if (rval != DDI_SUCCESS) {
15551 mptsas_log(mpt, CE_WARN, "path:target: "
15552 "%x, lun:%x online failed!", target,
15553 lun);
15554 *pip = NULL;
15555 *lun_dip = NULL;
15556 }
15557 return (rval);
15558 } else {
15559 /*
15560 * The GUID of the LUN has changed which maybe
15561 * because customer mapped another volume to the
15562 * same LUN.
15563 */
15564 mptsas_log(mpt, CE_WARN, "The GUID of the "
15565 "target:%x, lun:%x was changed, maybe "
15566 "because someone mapped another volume "
15567 "to the same LUN", target, lun);
15568 (void) ddi_prop_free(old_guid);
15569 if (!MDI_PI_IS_OFFLINE(*pip)) {
15570 rval = mdi_pi_offline(*pip, 0);
15571 if (rval != MDI_SUCCESS) {
15572 mptsas_log(mpt, CE_WARN, "path:"
15573 "target:%x, lun:%x offline "
15574 "failed!", target, lun);
15575 *pip = NULL;
15576 *lun_dip = NULL;
15577 return (DDI_FAILURE);
15578 }
15579 }
15580 if (mdi_pi_free(*pip, 0) != MDI_SUCCESS) {
15581 mptsas_log(mpt, CE_WARN, "path:target:"
15582 "%x, lun:%x free failed!", target,
15583 lun);
15584 *pip = NULL;
15585 *lun_dip = NULL;
15586 return (DDI_FAILURE);
15587 }
15588 }
15589 } else {
15590 mptsas_log(mpt, CE_WARN, "Can't get client-guid "
15591 "property for path:target:%x, lun:%x", target, lun);
15592 *pip = NULL;
15593 *lun_dip = NULL;
15594 return (DDI_FAILURE);
15595 }
15596 }
15597 scsi_hba_nodename_compatible_get(inq, NULL,
15598 inq->inq_dtype, NULL, &nodename, &compatible, &ncompatible);
15599
15600 /*
15601 * if nodename can't be determined then print a message and skip it
15602 */
15603 if (nodename == NULL) {
15604 mptsas_log(mpt, CE_WARN, "mptsas driver found no compatible "
15605 "driver for target%d lun %d dtype:0x%02x", target, lun,
15606 inq->inq_dtype);
15607 return (DDI_FAILURE);
15608 }
15609
15610 wwn_str = kmem_zalloc(MPTSAS_WWN_STRLEN, KM_SLEEP);
15611 /* The property is needed by MPAPI */
15612 (void) sprintf(wwn_str, "%016"PRIx64, sas_wwn);
15613
15614 lun_addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
15615 if (guid) {
15616 (void) sprintf(lun_addr, "w%s,%x", wwn_str, lun);
15617 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn);
15618 } else {
15619 (void) sprintf(lun_addr, "p%x,%x", phy, lun);
15620 (void) sprintf(wwn_str, "p%x", phy);
15621 }
15622
15623 mdi_rtn = mdi_pi_alloc_compatible(pdip, nodename,
15624 guid, lun_addr, compatible, ncompatible,
15625 0, pip);
15626 if (mdi_rtn == MDI_SUCCESS) {
15627
15628 if (mdi_prop_update_string(*pip, MDI_GUID,
15629 guid) != DDI_SUCCESS) {
15630 mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
15631 "create prop for target %d lun %d (MDI_GUID)",
15632 target, lun);
15633 mdi_rtn = MDI_FAILURE;
15634 goto virt_create_done;
15635 }
15636
15637 if (mdi_prop_update_int(*pip, LUN_PROP,
15638 lun) != DDI_SUCCESS) {
15639 mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
15640 "create prop for target %d lun %d (LUN_PROP)",
15641 target, lun);
15642 mdi_rtn = MDI_FAILURE;
15643 goto virt_create_done;
15644 }
15645 lun64 = (int64_t)lun;
15646 if (mdi_prop_update_int64(*pip, LUN64_PROP,
15647 lun64) != DDI_SUCCESS) {
15648 mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
15649 "create prop for target %d (LUN64_PROP)",
15650 target);
15651 mdi_rtn = MDI_FAILURE;
15652 goto virt_create_done;
15653 }
15654 if (mdi_prop_update_string_array(*pip, "compatible",
15655 compatible, ncompatible) !=
15656 DDI_PROP_SUCCESS) {
15657 mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
15658 "create prop for target %d lun %d (COMPATIBLE)",
15659 target, lun);
15660 mdi_rtn = MDI_FAILURE;
15661 goto virt_create_done;
15662 }
15663 if (sas_wwn && (mdi_prop_update_string(*pip,
15664 SCSI_ADDR_PROP_TARGET_PORT, wwn_str) != DDI_PROP_SUCCESS)) {
15665 mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
15666 "create prop for target %d lun %d "
15667 "(target-port)", target, lun);
15668 mdi_rtn = MDI_FAILURE;
15669 goto virt_create_done;
15670 } else if ((sas_wwn == 0) && (mdi_prop_update_int(*pip,
15671 "sata-phy", phy) != DDI_PROP_SUCCESS)) {
15672 /*
15673 * Direct attached SATA device without DeviceName
15674 */
15675 mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
15676 "create prop for SAS target %d lun %d "
15677 "(sata-phy)", target, lun);
15678 mdi_rtn = MDI_FAILURE;
15679 goto virt_create_done;
15680 }
15681 mutex_enter(&mpt->m_mutex);
15682
15683 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
15684 MPI2_SAS_DEVICE_PGAD_FORM_MASK) |
15685 (uint32_t)ptgt->m_devhdl;
15686 rval = mptsas_get_sas_device_page0(mpt, page_address,
15687 &dev_hdl, &dev_sas_wwn, &dev_info, &physport,
15688 &phy_id, &pdev_hdl, &bay_num, &enclosure, &io_flags);
15689 if (rval != DDI_SUCCESS) {
15690 mutex_exit(&mpt->m_mutex);
15691 mptsas_log(mpt, CE_WARN, "mptsas unable to get "
15692 "parent device for handle %d", page_address);
15693 mdi_rtn = MDI_FAILURE;
15694 goto virt_create_done;
15695 }
15696
15697 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
15698 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)pdev_hdl;
15699 rval = mptsas_get_sas_device_page0(mpt, page_address,
15700 &dev_hdl, &pdev_sas_wwn, &pdev_info, &physport,
15701 &phy_id, &pdev_hdl, &bay_num, &enclosure, &io_flags);
15702 if (rval != DDI_SUCCESS) {
15703 mutex_exit(&mpt->m_mutex);
15704 mptsas_log(mpt, CE_WARN, "mptsas unable to get"
15705 "device info for handle %d", page_address);
15706 mdi_rtn = MDI_FAILURE;
15707 goto virt_create_done;
15708 }
15709
15710 mutex_exit(&mpt->m_mutex);
15711
15712 /*
15713 * If this device direct attached to the controller
15714 * set the attached-port to the base wwid
15715 */
15716 if ((ptgt->m_deviceinfo & DEVINFO_DIRECT_ATTACHED)
15717 != DEVINFO_DIRECT_ATTACHED) {
15718 (void) sprintf(pdev_wwn_str, "w%016"PRIx64,
15719 pdev_sas_wwn);
15720 } else {
15721 /*
15722 * Update the iport's attached-port to guid
15723 */
15724 if (sas_wwn == 0) {
15725 (void) sprintf(wwn_str, "p%x", phy);
15726 } else {
15727 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn);
15728 }
15729 if (ddi_prop_update_string(DDI_DEV_T_NONE,
15730 pdip, SCSI_ADDR_PROP_ATTACHED_PORT, wwn_str) !=
15731 DDI_PROP_SUCCESS) {
15732 mptsas_log(mpt, CE_WARN,
15733 "mptsas unable to create "
15734 "property for iport target-port"
15735 " %s (sas_wwn)",
15736 wwn_str);
15737 mdi_rtn = MDI_FAILURE;
15738 goto virt_create_done;
15739 }
15740
15741 (void) sprintf(pdev_wwn_str, "w%016"PRIx64,
15742 mpt->un.m_base_wwid);
15743 }
15744
15745 if (IS_SATA_DEVICE(ptgt->m_deviceinfo)) {
15746 char uabuf[SCSI_WWN_BUFLEN];
15747
15748 if (scsi_wwn_to_wwnstr(dev_sas_wwn, 1, uabuf) == NULL) {
15749 mptsas_log(mpt, CE_WARN,
15750 "mptsas unable to format SATA bridge WWN");
15751 mdi_rtn = MDI_FAILURE;
15752 goto virt_create_done;
15753 }
15754
15755 if (mdi_prop_update_string(*pip,
15756 SCSI_ADDR_PROP_BRIDGE_PORT, uabuf) !=
15757 DDI_SUCCESS) {
15758 mptsas_log(mpt, CE_WARN,
15759 "mptsas unable to create SCSI bridge port "
15760 "property for SATA device");
15761 mdi_rtn = MDI_FAILURE;
15762 goto virt_create_done;
15763 }
15764 }
15765
15766 if (mdi_prop_update_string(*pip,
15767 SCSI_ADDR_PROP_ATTACHED_PORT, pdev_wwn_str) !=
15768 DDI_PROP_SUCCESS) {
15769 mptsas_log(mpt, CE_WARN, "mptsas unable to create "
15770 "property for iport attached-port %s (sas_wwn)",
15771 attached_wwn_str);
15772 mdi_rtn = MDI_FAILURE;
15773 goto virt_create_done;
15774 }
15775
15776
15777 if (inq->inq_dtype == 0) {
15778 component = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
15779 /*
15780 * set obp path for pathinfo
15781 */
15782 (void) snprintf(component, MAXPATHLEN,
15783 "disk@%s", lun_addr);
15784
15785 if (mdi_pi_pathname_obp_set(*pip, component) !=
15786 DDI_SUCCESS) {
15787 mptsas_log(mpt, CE_WARN, "mpt_sas driver "
15788 "unable to set obp-path for object %s",
15789 component);
15790 mdi_rtn = MDI_FAILURE;
15791 goto virt_create_done;
15792 }
15793 }
15794
15795 *lun_dip = MDI_PI(*pip)->pi_client->ct_dip;
15796 if (devinfo & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
15797 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
15798 if ((ndi_prop_update_int(DDI_DEV_T_NONE, *lun_dip,
15799 "pm-capable", 1)) !=
15800 DDI_PROP_SUCCESS) {
15801 mptsas_log(mpt, CE_WARN, "mptsas driver"
15802 "failed to create pm-capable "
15803 "property, target %d", target);
15804 mdi_rtn = MDI_FAILURE;
15805 goto virt_create_done;
15806 }
15807 }
15808 /*
15809 * Create the phy-num property
15810 */
15811 if (mdi_prop_update_int(*pip, "phy-num",
15812 ptgt->m_phynum) != DDI_SUCCESS) {
15813 mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
15814 "create phy-num property for target %d lun %d",
15815 target, lun);
15816 mdi_rtn = MDI_FAILURE;
15817 goto virt_create_done;
15818 }
15819 NDBG20(("new path:%s onlining,", MDI_PI(*pip)->pi_addr));
15820 mdi_rtn = mdi_pi_online(*pip, 0);
15821 if (mdi_rtn == MDI_NOT_SUPPORTED) {
15822 mdi_rtn = MDI_FAILURE;
15823 }
15824 virt_create_done:
15825 if (*pip && mdi_rtn != MDI_SUCCESS) {
15826 (void) mdi_pi_free(*pip, 0);
15827 *pip = NULL;
15828 *lun_dip = NULL;
15829 }
15830 }
15831
15832 scsi_hba_nodename_compatible_free(nodename, compatible);
15833 if (lun_addr != NULL) {
15834 kmem_free(lun_addr, SCSI_MAXNAMELEN);
15835 }
15836 if (wwn_str != NULL) {
15837 kmem_free(wwn_str, MPTSAS_WWN_STRLEN);
15838 }
15839 if (component != NULL) {
15840 kmem_free(component, MAXPATHLEN);
15841 }
15842
15843 return ((mdi_rtn == MDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
15844 }
15845
15846 static int
mptsas_create_phys_lun(dev_info_t * pdip,struct scsi_inquiry * inq,char * guid,dev_info_t ** lun_dip,mptsas_target_t * ptgt,int lun)15847 mptsas_create_phys_lun(dev_info_t *pdip, struct scsi_inquiry *inq,
15848 char *guid, dev_info_t **lun_dip, mptsas_target_t *ptgt, int lun)
15849 {
15850 int target;
15851 int rval;
15852 int ndi_rtn = NDI_FAILURE;
15853 uint64_t be_sas_wwn;
15854 char *nodename = NULL;
15855 char **compatible = NULL;
15856 int ncompatible = 0;
15857 int instance = 0;
15858 mptsas_t *mpt = DIP2MPT(pdip);
15859 char *wwn_str = NULL;
15860 char *component = NULL;
15861 char *attached_wwn_str = NULL;
15862 uint8_t phy = 0xFF;
15863 uint64_t sas_wwn;
15864 uint32_t devinfo;
15865 uint16_t dev_hdl;
15866 uint16_t pdev_hdl;
15867 uint64_t pdev_sas_wwn;
15868 uint64_t dev_sas_wwn;
15869 uint32_t pdev_info;
15870 uint8_t physport;
15871 uint8_t phy_id;
15872 uint32_t page_address;
15873 uint16_t bay_num, enclosure, io_flags;
15874 char pdev_wwn_str[MPTSAS_WWN_STRLEN];
15875 uint32_t dev_info;
15876 int64_t lun64 = 0;
15877
15878 mutex_enter(&mpt->m_mutex);
15879 target = ptgt->m_devhdl;
15880 sas_wwn = ptgt->m_addr.mta_wwn;
15881 devinfo = ptgt->m_deviceinfo;
15882 phy = ptgt->m_phynum;
15883 mutex_exit(&mpt->m_mutex);
15884
15885 /*
15886 * generate compatible property with binding-set "mpt"
15887 */
15888 scsi_hba_nodename_compatible_get(inq, NULL, inq->inq_dtype, NULL,
15889 &nodename, &compatible, &ncompatible);
15890
15891 /*
15892 * if nodename can't be determined then print a message and skip it
15893 */
15894 if (nodename == NULL) {
15895 mptsas_log(mpt, CE_WARN, "mptsas found no compatible driver "
15896 "for target %d lun %d", target, lun);
15897 return (DDI_FAILURE);
15898 }
15899
15900 ndi_rtn = ndi_devi_alloc(pdip, nodename,
15901 DEVI_SID_NODEID, lun_dip);
15902
15903 /*
15904 * if lun alloc success, set props
15905 */
15906 if (ndi_rtn == NDI_SUCCESS) {
15907
15908 if (ndi_prop_update_int(DDI_DEV_T_NONE,
15909 *lun_dip, LUN_PROP, lun) !=
15910 DDI_PROP_SUCCESS) {
15911 mptsas_log(mpt, CE_WARN, "mptsas unable to create "
15912 "property for target %d lun %d (LUN_PROP)",
15913 target, lun);
15914 ndi_rtn = NDI_FAILURE;
15915 goto phys_create_done;
15916 }
15917
15918 lun64 = (int64_t)lun;
15919 if (ndi_prop_update_int64(DDI_DEV_T_NONE,
15920 *lun_dip, LUN64_PROP, lun64) !=
15921 DDI_PROP_SUCCESS) {
15922 mptsas_log(mpt, CE_WARN, "mptsas unable to create "
15923 "property for target %d lun64 %d (LUN64_PROP)",
15924 target, lun);
15925 ndi_rtn = NDI_FAILURE;
15926 goto phys_create_done;
15927 }
15928 if (ndi_prop_update_string_array(DDI_DEV_T_NONE,
15929 *lun_dip, "compatible", compatible, ncompatible)
15930 != DDI_PROP_SUCCESS) {
15931 mptsas_log(mpt, CE_WARN, "mptsas unable to create "
15932 "property for target %d lun %d (COMPATIBLE)",
15933 target, lun);
15934 ndi_rtn = NDI_FAILURE;
15935 goto phys_create_done;
15936 }
15937
15938 /*
15939 * We need the SAS WWN for non-multipath devices, so
15940 * we'll use the same property as that multipathing
15941 * devices need to present for MPAPI. If we don't have
15942 * a WWN (e.g. parallel SCSI), don't create the prop.
15943 */
15944 wwn_str = kmem_zalloc(MPTSAS_WWN_STRLEN, KM_SLEEP);
15945 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn);
15946 if (sas_wwn && ndi_prop_update_string(DDI_DEV_T_NONE,
15947 *lun_dip, SCSI_ADDR_PROP_TARGET_PORT, wwn_str)
15948 != DDI_PROP_SUCCESS) {
15949 mptsas_log(mpt, CE_WARN, "mptsas unable to "
15950 "create property for SAS target %d lun %d "
15951 "(target-port)", target, lun);
15952 ndi_rtn = NDI_FAILURE;
15953 goto phys_create_done;
15954 }
15955
15956 be_sas_wwn = BE_64(sas_wwn);
15957 if (sas_wwn && ndi_prop_update_byte_array(
15958 DDI_DEV_T_NONE, *lun_dip, "port-wwn",
15959 (uchar_t *)&be_sas_wwn, 8) != DDI_PROP_SUCCESS) {
15960 mptsas_log(mpt, CE_WARN, "mptsas unable to "
15961 "create property for SAS target %d lun %d "
15962 "(port-wwn)", target, lun);
15963 ndi_rtn = NDI_FAILURE;
15964 goto phys_create_done;
15965 } else if ((sas_wwn == 0) && (ndi_prop_update_int(
15966 DDI_DEV_T_NONE, *lun_dip, "sata-phy", phy) !=
15967 DDI_PROP_SUCCESS)) {
15968 /*
15969 * Direct attached SATA device without DeviceName
15970 */
15971 mptsas_log(mpt, CE_WARN, "mptsas unable to "
15972 "create property for SAS target %d lun %d "
15973 "(sata-phy)", target, lun);
15974 ndi_rtn = NDI_FAILURE;
15975 goto phys_create_done;
15976 }
15977
15978 if (ndi_prop_create_boolean(DDI_DEV_T_NONE,
15979 *lun_dip, SAS_PROP) != DDI_PROP_SUCCESS) {
15980 mptsas_log(mpt, CE_WARN, "mptsas unable to"
15981 "create property for SAS target %d lun %d"
15982 " (SAS_PROP)", target, lun);
15983 ndi_rtn = NDI_FAILURE;
15984 goto phys_create_done;
15985 }
15986 if (guid && (ndi_prop_update_string(DDI_DEV_T_NONE,
15987 *lun_dip, NDI_GUID, guid) != DDI_SUCCESS)) {
15988 mptsas_log(mpt, CE_WARN, "mptsas unable "
15989 "to create guid property for target %d "
15990 "lun %d", target, lun);
15991 ndi_rtn = NDI_FAILURE;
15992 goto phys_create_done;
15993 }
15994
15995 /*
15996 * The following code is to set properties for SM-HBA support,
15997 * it doesn't apply to RAID volumes
15998 */
15999 if (ptgt->m_addr.mta_phymask == 0)
16000 goto phys_raid_lun;
16001
16002 mutex_enter(&mpt->m_mutex);
16003
16004 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
16005 MPI2_SAS_DEVICE_PGAD_FORM_MASK) |
16006 (uint32_t)ptgt->m_devhdl;
16007 rval = mptsas_get_sas_device_page0(mpt, page_address,
16008 &dev_hdl, &dev_sas_wwn, &dev_info,
16009 &physport, &phy_id, &pdev_hdl,
16010 &bay_num, &enclosure, &io_flags);
16011 if (rval != DDI_SUCCESS) {
16012 mutex_exit(&mpt->m_mutex);
16013 mptsas_log(mpt, CE_WARN, "mptsas unable to get"
16014 "parent device for handle %d.", page_address);
16015 ndi_rtn = NDI_FAILURE;
16016 goto phys_create_done;
16017 }
16018
16019 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
16020 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)pdev_hdl;
16021 rval = mptsas_get_sas_device_page0(mpt, page_address,
16022 &dev_hdl, &pdev_sas_wwn, &pdev_info, &physport,
16023 &phy_id, &pdev_hdl, &bay_num, &enclosure, &io_flags);
16024 if (rval != DDI_SUCCESS) {
16025 mutex_exit(&mpt->m_mutex);
16026 mptsas_log(mpt, CE_WARN, "mptsas unable to create "
16027 "device for handle %d.", page_address);
16028 ndi_rtn = NDI_FAILURE;
16029 goto phys_create_done;
16030 }
16031
16032 mutex_exit(&mpt->m_mutex);
16033
16034 /*
16035 * If this device direct attached to the controller
16036 * set the attached-port to the base wwid
16037 */
16038 if ((ptgt->m_deviceinfo & DEVINFO_DIRECT_ATTACHED)
16039 != DEVINFO_DIRECT_ATTACHED) {
16040 (void) sprintf(pdev_wwn_str, "w%016"PRIx64,
16041 pdev_sas_wwn);
16042 } else {
16043 /*
16044 * Update the iport's attached-port to guid
16045 */
16046 if (sas_wwn == 0) {
16047 (void) sprintf(wwn_str, "p%x", phy);
16048 } else {
16049 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn);
16050 }
16051 if (ddi_prop_update_string(DDI_DEV_T_NONE,
16052 pdip, SCSI_ADDR_PROP_ATTACHED_PORT, wwn_str) !=
16053 DDI_PROP_SUCCESS) {
16054 mptsas_log(mpt, CE_WARN,
16055 "mptsas unable to create "
16056 "property for iport target-port"
16057 " %s (sas_wwn)",
16058 wwn_str);
16059 ndi_rtn = NDI_FAILURE;
16060 goto phys_create_done;
16061 }
16062
16063 (void) sprintf(pdev_wwn_str, "w%016"PRIx64,
16064 mpt->un.m_base_wwid);
16065 }
16066
16067 if (ndi_prop_update_string(DDI_DEV_T_NONE,
16068 *lun_dip, SCSI_ADDR_PROP_ATTACHED_PORT, pdev_wwn_str) !=
16069 DDI_PROP_SUCCESS) {
16070 mptsas_log(mpt, CE_WARN,
16071 "mptsas unable to create "
16072 "property for iport attached-port %s (sas_wwn)",
16073 attached_wwn_str);
16074 ndi_rtn = NDI_FAILURE;
16075 goto phys_create_done;
16076 }
16077
16078 if (IS_SATA_DEVICE(dev_info)) {
16079 char uabuf[SCSI_WWN_BUFLEN];
16080
16081 if (ndi_prop_update_string(DDI_DEV_T_NONE,
16082 *lun_dip, MPTSAS_VARIANT, "sata") !=
16083 DDI_PROP_SUCCESS) {
16084 mptsas_log(mpt, CE_WARN,
16085 "mptsas unable to create "
16086 "property for device variant ");
16087 ndi_rtn = NDI_FAILURE;
16088 goto phys_create_done;
16089 }
16090
16091 if (scsi_wwn_to_wwnstr(dev_sas_wwn, 1, uabuf) == NULL) {
16092 mptsas_log(mpt, CE_WARN,
16093 "mptsas unable to format SATA bridge WWN");
16094 ndi_rtn = NDI_FAILURE;
16095 goto phys_create_done;
16096 }
16097
16098 if (ndi_prop_update_string(DDI_DEV_T_NONE, *lun_dip,
16099 SCSI_ADDR_PROP_BRIDGE_PORT, uabuf) !=
16100 DDI_PROP_SUCCESS) {
16101 mptsas_log(mpt, CE_WARN,
16102 "mptsas unable to create SCSI bridge port "
16103 "property for SATA device");
16104 ndi_rtn = NDI_FAILURE;
16105 goto phys_create_done;
16106 }
16107 }
16108
16109 if (IS_ATAPI_DEVICE(dev_info)) {
16110 if (ndi_prop_update_string(DDI_DEV_T_NONE,
16111 *lun_dip, MPTSAS_VARIANT, "atapi") !=
16112 DDI_PROP_SUCCESS) {
16113 mptsas_log(mpt, CE_WARN,
16114 "mptsas unable to create "
16115 "property for device variant ");
16116 ndi_rtn = NDI_FAILURE;
16117 goto phys_create_done;
16118 }
16119 }
16120
16121 phys_raid_lun:
16122 /*
16123 * if this is a SAS controller, and the target is a SATA
16124 * drive, set the 'pm-capable' property for sd and if on
16125 * an OPL platform, also check if this is an ATAPI
16126 * device.
16127 */
16128 instance = ddi_get_instance(mpt->m_dip);
16129 if (devinfo & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
16130 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
16131 NDBG2(("mptsas%d: creating pm-capable property, "
16132 "target %d", instance, target));
16133
16134 if ((ndi_prop_update_int(DDI_DEV_T_NONE,
16135 *lun_dip, "pm-capable", 1)) !=
16136 DDI_PROP_SUCCESS) {
16137 mptsas_log(mpt, CE_WARN, "mptsas "
16138 "failed to create pm-capable "
16139 "property, target %d", target);
16140 ndi_rtn = NDI_FAILURE;
16141 goto phys_create_done;
16142 }
16143
16144 }
16145
16146 if ((inq->inq_dtype == 0) || (inq->inq_dtype == 5)) {
16147 /*
16148 * add 'obp-path' properties for devinfo
16149 */
16150 bzero(wwn_str, sizeof (wwn_str));
16151 (void) sprintf(wwn_str, "%016"PRIx64, sas_wwn);
16152 component = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
16153 if (guid) {
16154 (void) snprintf(component, MAXPATHLEN,
16155 "disk@w%s,%x", wwn_str, lun);
16156 } else {
16157 (void) snprintf(component, MAXPATHLEN,
16158 "disk@p%x,%x", phy, lun);
16159 }
16160 if (ddi_pathname_obp_set(*lun_dip, component)
16161 != DDI_SUCCESS) {
16162 mptsas_log(mpt, CE_WARN, "mpt_sas driver "
16163 "unable to set obp-path for SAS "
16164 "object %s", component);
16165 ndi_rtn = NDI_FAILURE;
16166 goto phys_create_done;
16167 }
16168 }
16169 /*
16170 * Create the phy-num property for non-raid disk
16171 */
16172 if (ptgt->m_addr.mta_phymask != 0) {
16173 if (ndi_prop_update_int(DDI_DEV_T_NONE,
16174 *lun_dip, "phy-num", ptgt->m_phynum) !=
16175 DDI_PROP_SUCCESS) {
16176 mptsas_log(mpt, CE_WARN, "mptsas driver "
16177 "failed to create phy-num property for "
16178 "target %d", target);
16179 ndi_rtn = NDI_FAILURE;
16180 goto phys_create_done;
16181 }
16182 }
16183 phys_create_done:
16184 /*
16185 * If props were setup ok, online the lun
16186 */
16187 if (ndi_rtn == NDI_SUCCESS) {
16188 /*
16189 * Try to online the new node
16190 */
16191 ndi_rtn = ndi_devi_online(*lun_dip, NDI_ONLINE_ATTACH);
16192 }
16193
16194 /*
16195 * If success set rtn flag, else unwire alloc'd lun
16196 */
16197 if (ndi_rtn != NDI_SUCCESS) {
16198 NDBG12(("mptsas driver unable to online "
16199 "target %d lun %d", target, lun));
16200 ndi_prop_remove_all(*lun_dip);
16201 (void) ndi_devi_free(*lun_dip);
16202 *lun_dip = NULL;
16203 }
16204 }
16205
16206 scsi_hba_nodename_compatible_free(nodename, compatible);
16207
16208 if (wwn_str != NULL) {
16209 kmem_free(wwn_str, MPTSAS_WWN_STRLEN);
16210 }
16211 if (component != NULL) {
16212 kmem_free(component, MAXPATHLEN);
16213 }
16214
16215
16216 return ((ndi_rtn == NDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
16217 }
16218
16219 static int
mptsas_probe_smp(dev_info_t * pdip,uint64_t wwn)16220 mptsas_probe_smp(dev_info_t *pdip, uint64_t wwn)
16221 {
16222 mptsas_t *mpt = DIP2MPT(pdip);
16223 struct smp_device smp_sd;
16224
16225 /* XXX An HBA driver should not be allocating an smp_device. */
16226 bzero(&smp_sd, sizeof (struct smp_device));
16227 smp_sd.smp_sd_address.smp_a_hba_tran = mpt->m_smptran;
16228 bcopy(&wwn, smp_sd.smp_sd_address.smp_a_wwn, SAS_WWN_BYTE_SIZE);
16229
16230 if (smp_probe(&smp_sd) != DDI_PROBE_SUCCESS)
16231 return (NDI_FAILURE);
16232 return (NDI_SUCCESS);
16233 }
16234
16235 static int
mptsas_config_smp(dev_info_t * pdip,uint64_t sas_wwn,dev_info_t ** smp_dip)16236 mptsas_config_smp(dev_info_t *pdip, uint64_t sas_wwn, dev_info_t **smp_dip)
16237 {
16238 mptsas_t *mpt = DIP2MPT(pdip);
16239 mptsas_smp_t *psmp = NULL;
16240 int rval;
16241 int phymask;
16242
16243 /*
16244 * Get the physical port associated to the iport
16245 * PHYMASK TODO
16246 */
16247 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
16248 "phymask", 0);
16249 /*
16250 * Find the smp node in hash table with specified sas address and
16251 * physical port
16252 */
16253 psmp = mptsas_wwid_to_psmp(mpt, phymask, sas_wwn);
16254 if (psmp == NULL) {
16255 return (DDI_FAILURE);
16256 }
16257
16258 rval = mptsas_online_smp(pdip, psmp, smp_dip);
16259
16260 return (rval);
16261 }
16262
16263 static int
mptsas_online_smp(dev_info_t * pdip,mptsas_smp_t * smp_node,dev_info_t ** smp_dip)16264 mptsas_online_smp(dev_info_t *pdip, mptsas_smp_t *smp_node,
16265 dev_info_t **smp_dip)
16266 {
16267 char wwn_str[MPTSAS_WWN_STRLEN];
16268 char attached_wwn_str[MPTSAS_WWN_STRLEN];
16269 int ndi_rtn = NDI_FAILURE;
16270 int rval = 0;
16271 mptsas_smp_t dev_info;
16272 uint32_t page_address;
16273 mptsas_t *mpt = DIP2MPT(pdip);
16274 uint16_t dev_hdl;
16275 uint64_t sas_wwn;
16276 uint64_t smp_sas_wwn;
16277 uint8_t physport;
16278 uint8_t phy_id;
16279 uint16_t pdev_hdl;
16280 uint8_t numphys = 0;
16281 uint16_t i = 0;
16282 char phymask[MPTSAS_MAX_PHYS];
16283 char *iport = NULL;
16284 mptsas_phymask_t phy_mask = 0;
16285 uint16_t attached_devhdl;
16286 uint16_t bay_num, enclosure, io_flags;
16287
16288 (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_addr.mta_wwn);
16289
16290 /*
16291 * Probe smp device, prevent the node of removed device from being
16292 * configured succesfully
16293 */
16294 if (mptsas_probe_smp(pdip, smp_node->m_addr.mta_wwn) != NDI_SUCCESS) {
16295 return (DDI_FAILURE);
16296 }
16297
16298 if ((*smp_dip = mptsas_find_smp_child(pdip, wwn_str)) != NULL) {
16299 return (DDI_SUCCESS);
16300 }
16301
16302 ndi_rtn = ndi_devi_alloc(pdip, "smp", DEVI_SID_NODEID, smp_dip);
16303
16304 /*
16305 * if lun alloc success, set props
16306 */
16307 if (ndi_rtn == NDI_SUCCESS) {
16308 /*
16309 * Set the flavor of the child to be SMP flavored
16310 */
16311 ndi_flavor_set(*smp_dip, SCSA_FLAVOR_SMP);
16312
16313 if (ndi_prop_update_string(DDI_DEV_T_NONE,
16314 *smp_dip, SMP_WWN, wwn_str) !=
16315 DDI_PROP_SUCCESS) {
16316 mptsas_log(mpt, CE_WARN, "mptsas unable to create "
16317 "property for smp device %s (sas_wwn)",
16318 wwn_str);
16319 ndi_rtn = NDI_FAILURE;
16320 goto smp_create_done;
16321 }
16322 (void) sprintf(wwn_str, "w%"PRIx64, smp_node->m_addr.mta_wwn);
16323 if (ndi_prop_update_string(DDI_DEV_T_NONE,
16324 *smp_dip, SCSI_ADDR_PROP_TARGET_PORT, wwn_str) !=
16325 DDI_PROP_SUCCESS) {
16326 mptsas_log(mpt, CE_WARN, "mptsas unable to create "
16327 "property for iport target-port %s (sas_wwn)",
16328 wwn_str);
16329 ndi_rtn = NDI_FAILURE;
16330 goto smp_create_done;
16331 }
16332
16333 mutex_enter(&mpt->m_mutex);
16334
16335 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_HNDL &
16336 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | smp_node->m_devhdl;
16337 rval = mptsas_get_sas_expander_page0(mpt, page_address,
16338 &dev_info);
16339 if (rval != DDI_SUCCESS) {
16340 mutex_exit(&mpt->m_mutex);
16341 mptsas_log(mpt, CE_WARN,
16342 "mptsas unable to get expander "
16343 "parent device info for %x", page_address);
16344 ndi_rtn = NDI_FAILURE;
16345 goto smp_create_done;
16346 }
16347
16348 smp_node->m_pdevhdl = dev_info.m_pdevhdl;
16349 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
16350 MPI2_SAS_DEVICE_PGAD_FORM_MASK) |
16351 (uint32_t)dev_info.m_pdevhdl;
16352 rval = mptsas_get_sas_device_page0(mpt, page_address,
16353 &dev_hdl, &sas_wwn, &smp_node->m_pdevinfo, &physport,
16354 &phy_id, &pdev_hdl, &bay_num, &enclosure, &io_flags);
16355 if (rval != DDI_SUCCESS) {
16356 mutex_exit(&mpt->m_mutex);
16357 mptsas_log(mpt, CE_WARN, "mptsas unable to get "
16358 "device info for %x", page_address);
16359 ndi_rtn = NDI_FAILURE;
16360 goto smp_create_done;
16361 }
16362
16363 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
16364 MPI2_SAS_DEVICE_PGAD_FORM_MASK) |
16365 (uint32_t)dev_info.m_devhdl;
16366 rval = mptsas_get_sas_device_page0(mpt, page_address,
16367 &dev_hdl, &smp_sas_wwn, &smp_node->m_deviceinfo,
16368 &physport, &phy_id, &pdev_hdl, &bay_num, &enclosure,
16369 &io_flags);
16370 if (rval != DDI_SUCCESS) {
16371 mutex_exit(&mpt->m_mutex);
16372 mptsas_log(mpt, CE_WARN, "mptsas unable to get "
16373 "device info for %x", page_address);
16374 ndi_rtn = NDI_FAILURE;
16375 goto smp_create_done;
16376 }
16377 mutex_exit(&mpt->m_mutex);
16378
16379 /*
16380 * If this smp direct attached to the controller
16381 * set the attached-port to the base wwid
16382 */
16383 if ((smp_node->m_deviceinfo & DEVINFO_DIRECT_ATTACHED)
16384 != DEVINFO_DIRECT_ATTACHED) {
16385 (void) sprintf(attached_wwn_str, "w%016"PRIx64,
16386 sas_wwn);
16387 } else {
16388 (void) sprintf(attached_wwn_str, "w%016"PRIx64,
16389 mpt->un.m_base_wwid);
16390 }
16391
16392 if (ndi_prop_update_string(DDI_DEV_T_NONE,
16393 *smp_dip, SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwn_str) !=
16394 DDI_PROP_SUCCESS) {
16395 mptsas_log(mpt, CE_WARN, "mptsas unable to create "
16396 "property for smp attached-port %s (sas_wwn)",
16397 attached_wwn_str);
16398 ndi_rtn = NDI_FAILURE;
16399 goto smp_create_done;
16400 }
16401
16402 if (ndi_prop_create_boolean(DDI_DEV_T_NONE,
16403 *smp_dip, SMP_PROP) != DDI_PROP_SUCCESS) {
16404 mptsas_log(mpt, CE_WARN, "mptsas unable to "
16405 "create property for SMP %s (SMP_PROP) ",
16406 wwn_str);
16407 ndi_rtn = NDI_FAILURE;
16408 goto smp_create_done;
16409 }
16410
16411 /*
16412 * check the smp to see whether it direct
16413 * attached to the controller
16414 */
16415 if ((smp_node->m_deviceinfo & DEVINFO_DIRECT_ATTACHED)
16416 != DEVINFO_DIRECT_ATTACHED) {
16417 goto smp_create_done;
16418 }
16419 numphys = ddi_prop_get_int(DDI_DEV_T_ANY, pdip,
16420 DDI_PROP_DONTPASS, MPTSAS_NUM_PHYS, -1);
16421 if (numphys > 0) {
16422 goto smp_create_done;
16423 }
16424 /*
16425 * this iport is an old iport, we need to
16426 * reconfig the props for it.
16427 */
16428 if (ddi_prop_update_int(DDI_DEV_T_NONE, pdip,
16429 MPTSAS_VIRTUAL_PORT, 0) !=
16430 DDI_PROP_SUCCESS) {
16431 (void) ddi_prop_remove(DDI_DEV_T_NONE, pdip,
16432 MPTSAS_VIRTUAL_PORT);
16433 mptsas_log(mpt, CE_WARN, "mptsas virtual port "
16434 "prop update failed");
16435 goto smp_create_done;
16436 }
16437
16438 mutex_enter(&mpt->m_mutex);
16439 numphys = 0;
16440 iport = ddi_get_name_addr(pdip);
16441 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
16442 bzero(phymask, sizeof (phymask));
16443 (void) sprintf(phymask,
16444 "%x", mpt->m_phy_info[i].phy_mask);
16445 if (strcmp(phymask, iport) == 0) {
16446 phy_mask = mpt->m_phy_info[i].phy_mask;
16447 break;
16448 }
16449 }
16450
16451 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
16452 if ((phy_mask >> i) & 0x01) {
16453 numphys++;
16454 }
16455 }
16456 /*
16457 * Update PHY info for smhba
16458 */
16459 if (mptsas_smhba_phy_init(mpt)) {
16460 mutex_exit(&mpt->m_mutex);
16461 mptsas_log(mpt, CE_WARN, "mptsas phy update "
16462 "failed");
16463 goto smp_create_done;
16464 }
16465 mutex_exit(&mpt->m_mutex);
16466
16467 mptsas_smhba_set_all_phy_props(mpt, pdip, numphys, phy_mask,
16468 &attached_devhdl);
16469
16470 if (ddi_prop_update_int(DDI_DEV_T_NONE, pdip,
16471 MPTSAS_NUM_PHYS, numphys) !=
16472 DDI_PROP_SUCCESS) {
16473 (void) ddi_prop_remove(DDI_DEV_T_NONE, pdip,
16474 MPTSAS_NUM_PHYS);
16475 mptsas_log(mpt, CE_WARN, "mptsas update "
16476 "num phys props failed");
16477 goto smp_create_done;
16478 }
16479 /*
16480 * Add parent's props for SMHBA support
16481 */
16482 if (ddi_prop_update_string(DDI_DEV_T_NONE, pdip,
16483 SCSI_ADDR_PROP_ATTACHED_PORT, wwn_str) !=
16484 DDI_PROP_SUCCESS) {
16485 (void) ddi_prop_remove(DDI_DEV_T_NONE, pdip,
16486 SCSI_ADDR_PROP_ATTACHED_PORT);
16487 mptsas_log(mpt, CE_WARN, "mptsas update iport"
16488 "attached-port failed");
16489 goto smp_create_done;
16490 }
16491
16492 smp_create_done:
16493 /*
16494 * If props were setup ok, online the lun
16495 */
16496 if (ndi_rtn == NDI_SUCCESS) {
16497 /*
16498 * Try to online the new node
16499 */
16500 ndi_rtn = ndi_devi_online(*smp_dip, NDI_ONLINE_ATTACH);
16501 }
16502
16503 /*
16504 * If success set rtn flag, else unwire alloc'd lun
16505 */
16506 if (ndi_rtn != NDI_SUCCESS) {
16507 NDBG12(("mptsas unable to online "
16508 "SMP target %s", wwn_str));
16509 ndi_prop_remove_all(*smp_dip);
16510 (void) ndi_devi_free(*smp_dip);
16511 }
16512 }
16513
16514 return ((ndi_rtn == NDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
16515 }
16516
16517 /* smp transport routine */
mptsas_smp_start(struct smp_pkt * smp_pkt)16518 static int mptsas_smp_start(struct smp_pkt *smp_pkt)
16519 {
16520 uint64_t wwn;
16521 Mpi2SmpPassthroughRequest_t req;
16522 Mpi2SmpPassthroughReply_t rep;
16523 uint32_t direction = 0;
16524 mptsas_t *mpt;
16525 int ret;
16526 uint64_t tmp64;
16527
16528 mpt = (mptsas_t *)smp_pkt->smp_pkt_address->
16529 smp_a_hba_tran->smp_tran_hba_private;
16530
16531 bcopy(smp_pkt->smp_pkt_address->smp_a_wwn, &wwn, SAS_WWN_BYTE_SIZE);
16532 /*
16533 * Need to compose a SMP request message
16534 * and call mptsas_do_passthru() function
16535 */
16536 bzero(&req, sizeof (req));
16537 bzero(&rep, sizeof (rep));
16538 req.PassthroughFlags = 0;
16539 req.PhysicalPort = 0xff;
16540 req.ChainOffset = 0;
16541 req.Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
16542
16543 if ((smp_pkt->smp_pkt_reqsize & 0xffff0000ul) != 0) {
16544 smp_pkt->smp_pkt_reason = ERANGE;
16545 return (DDI_FAILURE);
16546 }
16547 req.RequestDataLength = LE_16((uint16_t)(smp_pkt->smp_pkt_reqsize - 4));
16548
16549 req.MsgFlags = 0;
16550 tmp64 = LE_64(wwn);
16551 bcopy(&tmp64, &req.SASAddress, SAS_WWN_BYTE_SIZE);
16552 if (smp_pkt->smp_pkt_rspsize > 0) {
16553 direction |= MPTSAS_PASS_THRU_DIRECTION_READ;
16554 }
16555 if (smp_pkt->smp_pkt_reqsize > 0) {
16556 direction |= MPTSAS_PASS_THRU_DIRECTION_WRITE;
16557 }
16558
16559 mutex_enter(&mpt->m_mutex);
16560 ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep,
16561 (uint8_t *)smp_pkt->smp_pkt_rsp,
16562 offsetof(Mpi2SmpPassthroughRequest_t, SGL), sizeof (rep),
16563 smp_pkt->smp_pkt_rspsize - 4, direction,
16564 (uint8_t *)smp_pkt->smp_pkt_req, smp_pkt->smp_pkt_reqsize - 4,
16565 smp_pkt->smp_pkt_timeout, FKIOCTL);
16566 mutex_exit(&mpt->m_mutex);
16567 if (ret != 0) {
16568 cmn_err(CE_WARN, "smp_start do passthru error %d", ret);
16569 smp_pkt->smp_pkt_reason = (uchar_t)(ret);
16570 return (DDI_FAILURE);
16571 }
16572 /* do passthrough success, check the smp status */
16573 if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) {
16574 switch (LE_16(rep.IOCStatus)) {
16575 case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
16576 smp_pkt->smp_pkt_reason = ENODEV;
16577 break;
16578 case MPI2_IOCSTATUS_SAS_SMP_DATA_OVERRUN:
16579 smp_pkt->smp_pkt_reason = EOVERFLOW;
16580 break;
16581 case MPI2_IOCSTATUS_SAS_SMP_REQUEST_FAILED:
16582 smp_pkt->smp_pkt_reason = EIO;
16583 break;
16584 default:
16585 mptsas_log(mpt, CE_NOTE, "smp_start: get unknown ioc"
16586 "status:%x", LE_16(rep.IOCStatus));
16587 smp_pkt->smp_pkt_reason = EIO;
16588 break;
16589 }
16590 return (DDI_FAILURE);
16591 }
16592 if (rep.SASStatus != MPI2_SASSTATUS_SUCCESS) {
16593 mptsas_log(mpt, CE_NOTE, "smp_start: get error SAS status:%x",
16594 rep.SASStatus);
16595 smp_pkt->smp_pkt_reason = EIO;
16596 return (DDI_FAILURE);
16597 }
16598
16599 return (DDI_SUCCESS);
16600 }
16601
16602 /*
16603 * If we didn't get a match, we need to get sas page0 for each device, and
16604 * untill we get a match. If failed, return NULL
16605 */
16606 static mptsas_target_t *
mptsas_phy_to_tgt(mptsas_t * mpt,mptsas_phymask_t phymask,uint8_t phy)16607 mptsas_phy_to_tgt(mptsas_t *mpt, mptsas_phymask_t phymask, uint8_t phy)
16608 {
16609 int i, j = 0;
16610 int rval = 0;
16611 uint16_t cur_handle;
16612 uint32_t page_address;
16613 mptsas_target_t *ptgt = NULL;
16614
16615 /*
16616 * PHY named device must be direct attached and attaches to
16617 * narrow port, if the iport is not parent of the device which
16618 * we are looking for.
16619 */
16620 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
16621 if ((1 << i) & phymask)
16622 j++;
16623 }
16624
16625 if (j > 1)
16626 return (NULL);
16627
16628 /*
16629 * Must be a narrow port and single device attached to the narrow port
16630 * So the physical port num of device which is equal to the iport's
16631 * port num is the device what we are looking for.
16632 */
16633
16634 if (mpt->m_phy_info[phy].phy_mask != phymask)
16635 return (NULL);
16636
16637 mutex_enter(&mpt->m_mutex);
16638
16639 ptgt = refhash_linear_search(mpt->m_targets, mptsas_target_eval_nowwn,
16640 &phy);
16641 if (ptgt != NULL) {
16642 mutex_exit(&mpt->m_mutex);
16643 return (ptgt);
16644 }
16645
16646 if (mpt->m_done_traverse_dev) {
16647 mutex_exit(&mpt->m_mutex);
16648 return (NULL);
16649 }
16650
16651 /* If didn't get a match, come here */
16652 cur_handle = mpt->m_dev_handle;
16653 for (; ; ) {
16654 ptgt = NULL;
16655 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE &
16656 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)cur_handle;
16657 rval = mptsas_get_target_device_info(mpt, page_address,
16658 &cur_handle, &ptgt);
16659 if ((rval == DEV_INFO_FAIL_PAGE0) ||
16660 (rval == DEV_INFO_FAIL_ALLOC)) {
16661 break;
16662 }
16663 if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) ||
16664 (rval == DEV_INFO_PHYS_DISK) ||
16665 (rval == DEV_INFO_FAIL_GUID)) {
16666 continue;
16667 }
16668 mpt->m_dev_handle = cur_handle;
16669
16670 if ((ptgt->m_addr.mta_wwn == 0) && (ptgt->m_phynum == phy)) {
16671 break;
16672 }
16673 }
16674
16675 mutex_exit(&mpt->m_mutex);
16676 return (ptgt);
16677 }
16678
16679 /*
16680 * The ptgt->m_addr.mta_wwn contains the wwid for each disk.
16681 * For Raid volumes, we need to check m_raidvol[x].m_raidwwid
16682 * If we didn't get a match, we need to get sas page0 for each device, and
16683 * untill we get a match
16684 * If failed, return NULL
16685 */
16686 static mptsas_target_t *
mptsas_wwid_to_ptgt(mptsas_t * mpt,mptsas_phymask_t phymask,uint64_t wwid)16687 mptsas_wwid_to_ptgt(mptsas_t *mpt, mptsas_phymask_t phymask, uint64_t wwid)
16688 {
16689 int rval = 0;
16690 uint16_t cur_handle;
16691 uint32_t page_address;
16692 mptsas_target_t *tmp_tgt = NULL;
16693 mptsas_target_addr_t addr;
16694
16695 addr.mta_wwn = wwid;
16696 addr.mta_phymask = phymask;
16697 mutex_enter(&mpt->m_mutex);
16698 tmp_tgt = refhash_lookup(mpt->m_targets, &addr);
16699 if (tmp_tgt != NULL) {
16700 mutex_exit(&mpt->m_mutex);
16701 return (tmp_tgt);
16702 }
16703
16704 if (phymask == 0) {
16705 /*
16706 * It's IR volume
16707 */
16708 rval = mptsas_get_raid_info(mpt);
16709 if (rval) {
16710 tmp_tgt = refhash_lookup(mpt->m_targets, &addr);
16711 }
16712 mutex_exit(&mpt->m_mutex);
16713 return (tmp_tgt);
16714 }
16715
16716 if (mpt->m_done_traverse_dev) {
16717 mutex_exit(&mpt->m_mutex);
16718 return (NULL);
16719 }
16720
16721 /* If didn't get a match, come here */
16722 cur_handle = mpt->m_dev_handle;
16723 for (;;) {
16724 tmp_tgt = NULL;
16725 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE &
16726 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | cur_handle;
16727 rval = mptsas_get_target_device_info(mpt, page_address,
16728 &cur_handle, &tmp_tgt);
16729 if ((rval == DEV_INFO_FAIL_PAGE0) ||
16730 (rval == DEV_INFO_FAIL_ALLOC)) {
16731 tmp_tgt = NULL;
16732 break;
16733 }
16734 if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) ||
16735 (rval == DEV_INFO_PHYS_DISK) ||
16736 (rval == DEV_INFO_FAIL_GUID)) {
16737 continue;
16738 }
16739 mpt->m_dev_handle = cur_handle;
16740 if ((tmp_tgt->m_addr.mta_wwn) &&
16741 (tmp_tgt->m_addr.mta_wwn == wwid) &&
16742 (tmp_tgt->m_addr.mta_phymask == phymask)) {
16743 break;
16744 }
16745 }
16746
16747 mutex_exit(&mpt->m_mutex);
16748 return (tmp_tgt);
16749 }
16750
16751 static mptsas_smp_t *
mptsas_wwid_to_psmp(mptsas_t * mpt,mptsas_phymask_t phymask,uint64_t wwid)16752 mptsas_wwid_to_psmp(mptsas_t *mpt, mptsas_phymask_t phymask, uint64_t wwid)
16753 {
16754 int rval = 0;
16755 uint16_t cur_handle;
16756 uint32_t page_address;
16757 mptsas_smp_t smp_node, *psmp = NULL;
16758 mptsas_target_addr_t addr;
16759
16760 addr.mta_wwn = wwid;
16761 addr.mta_phymask = phymask;
16762 mutex_enter(&mpt->m_mutex);
16763 psmp = refhash_lookup(mpt->m_smp_targets, &addr);
16764 if (psmp != NULL) {
16765 mutex_exit(&mpt->m_mutex);
16766 return (psmp);
16767 }
16768
16769 if (mpt->m_done_traverse_smp) {
16770 mutex_exit(&mpt->m_mutex);
16771 return (NULL);
16772 }
16773
16774 /* If didn't get a match, come here */
16775 cur_handle = mpt->m_smp_devhdl;
16776 for (;;) {
16777 psmp = NULL;
16778 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL &
16779 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)cur_handle;
16780 rval = mptsas_get_sas_expander_page0(mpt, page_address,
16781 &smp_node);
16782 if (rval != DDI_SUCCESS) {
16783 break;
16784 }
16785 mpt->m_smp_devhdl = cur_handle = smp_node.m_devhdl;
16786 psmp = mptsas_smp_alloc(mpt, &smp_node);
16787 ASSERT(psmp);
16788 if ((psmp->m_addr.mta_wwn) && (psmp->m_addr.mta_wwn == wwid) &&
16789 (psmp->m_addr.mta_phymask == phymask)) {
16790 break;
16791 }
16792 }
16793
16794 mutex_exit(&mpt->m_mutex);
16795 return (psmp);
16796 }
16797
16798 mptsas_target_t *
mptsas_tgt_alloc(refhash_t * refhash,uint16_t devhdl,uint64_t wwid,uint32_t devinfo,mptsas_phymask_t phymask,uint8_t phynum)16799 mptsas_tgt_alloc(refhash_t *refhash, uint16_t devhdl, uint64_t wwid,
16800 uint32_t devinfo, mptsas_phymask_t phymask, uint8_t phynum)
16801 {
16802 mptsas_target_t *tmp_tgt = NULL;
16803 mptsas_target_addr_t addr;
16804
16805 addr.mta_wwn = wwid;
16806 addr.mta_phymask = phymask;
16807 tmp_tgt = refhash_lookup(refhash, &addr);
16808 if (tmp_tgt != NULL) {
16809 NDBG20(("Hash item already exist"));
16810 tmp_tgt->m_deviceinfo = devinfo;
16811 tmp_tgt->m_devhdl = devhdl; /* XXX - duplicate? */
16812 return (tmp_tgt);
16813 }
16814 tmp_tgt = kmem_zalloc(sizeof (struct mptsas_target), KM_SLEEP);
16815 if (tmp_tgt == NULL) {
16816 cmn_err(CE_WARN, "Fatal, allocated tgt failed");
16817 return (NULL);
16818 }
16819 tmp_tgt->m_devhdl = devhdl;
16820 tmp_tgt->m_addr.mta_wwn = wwid;
16821 tmp_tgt->m_deviceinfo = devinfo;
16822 tmp_tgt->m_addr.mta_phymask = phymask;
16823 tmp_tgt->m_phynum = phynum;
16824 /* Initialized the tgt structure */
16825 tmp_tgt->m_qfull_retries = QFULL_RETRIES;
16826 tmp_tgt->m_qfull_retry_interval =
16827 drv_usectohz(QFULL_RETRY_INTERVAL * 1000);
16828 tmp_tgt->m_t_throttle = MAX_THROTTLE;
16829 TAILQ_INIT(&tmp_tgt->m_active_cmdq);
16830
16831 refhash_insert(refhash, tmp_tgt);
16832
16833 return (tmp_tgt);
16834 }
16835
16836 static void
mptsas_smp_target_copy(mptsas_smp_t * src,mptsas_smp_t * dst)16837 mptsas_smp_target_copy(mptsas_smp_t *src, mptsas_smp_t *dst)
16838 {
16839 dst->m_devhdl = src->m_devhdl;
16840 dst->m_deviceinfo = src->m_deviceinfo;
16841 dst->m_pdevhdl = src->m_pdevhdl;
16842 dst->m_pdevinfo = src->m_pdevinfo;
16843 }
16844
16845 static mptsas_smp_t *
mptsas_smp_alloc(mptsas_t * mpt,mptsas_smp_t * data)16846 mptsas_smp_alloc(mptsas_t *mpt, mptsas_smp_t *data)
16847 {
16848 mptsas_target_addr_t addr;
16849 mptsas_smp_t *ret_data;
16850
16851 addr.mta_wwn = data->m_addr.mta_wwn;
16852 addr.mta_phymask = data->m_addr.mta_phymask;
16853 ret_data = refhash_lookup(mpt->m_smp_targets, &addr);
16854 /*
16855 * If there's already a matching SMP target, update its fields
16856 * in place. Since the address is not changing, it's safe to do
16857 * this. We cannot just bcopy() here because the structure we've
16858 * been given has invalid hash links.
16859 */
16860 if (ret_data != NULL) {
16861 mptsas_smp_target_copy(data, ret_data);
16862 return (ret_data);
16863 }
16864
16865 ret_data = kmem_alloc(sizeof (mptsas_smp_t), KM_SLEEP);
16866 bcopy(data, ret_data, sizeof (mptsas_smp_t));
16867 refhash_insert(mpt->m_smp_targets, ret_data);
16868 return (ret_data);
16869 }
16870
16871 /*
16872 * Functions for SGPIO LED support
16873 */
16874 static dev_info_t *
mptsas_get_dip_from_dev(dev_t dev,mptsas_phymask_t * phymask)16875 mptsas_get_dip_from_dev(dev_t dev, mptsas_phymask_t *phymask)
16876 {
16877 dev_info_t *dip;
16878 int prop;
16879 dip = e_ddi_hold_devi_by_dev(dev, 0);
16880 if (dip == NULL)
16881 return (dip);
16882 prop = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0,
16883 "phymask", 0);
16884 *phymask = (mptsas_phymask_t)prop;
16885 ddi_release_devi(dip);
16886 return (dip);
16887 }
16888 static mptsas_target_t *
mptsas_addr_to_ptgt(mptsas_t * mpt,char * addr,mptsas_phymask_t phymask)16889 mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr, mptsas_phymask_t phymask)
16890 {
16891 uint8_t phynum;
16892 uint64_t wwn;
16893 int lun;
16894 mptsas_target_t *ptgt = NULL;
16895
16896 if (mptsas_parse_address(addr, &wwn, &phynum, &lun) != DDI_SUCCESS) {
16897 return (NULL);
16898 }
16899 if (addr[0] == 'w') {
16900 ptgt = mptsas_wwid_to_ptgt(mpt, (int)phymask, wwn);
16901 } else {
16902 ptgt = mptsas_phy_to_tgt(mpt, (int)phymask, phynum);
16903 }
16904 return (ptgt);
16905 }
16906
16907 static int
mptsas_flush_led_status(mptsas_t * mpt,mptsas_enclosure_t * mep,uint16_t idx)16908 mptsas_flush_led_status(mptsas_t *mpt, mptsas_enclosure_t *mep, uint16_t idx)
16909 {
16910 uint32_t slotstatus = 0;
16911
16912 ASSERT3U(idx, <, mep->me_nslots);
16913
16914 /* Build an MPI2 Slot Status based on our view of the world */
16915 if (mep->me_slotleds[idx] & (1 << (MPTSAS_LEDCTL_LED_IDENT - 1)))
16916 slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_IDENTIFY_REQUEST;
16917 if (mep->me_slotleds[idx] & (1 << (MPTSAS_LEDCTL_LED_FAIL - 1)))
16918 slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT;
16919 if (mep->me_slotleds[idx] & (1 << (MPTSAS_LEDCTL_LED_OK2RM - 1)))
16920 slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE;
16921
16922 /* Write it to the controller */
16923 NDBG14(("mptsas_ioctl: set LED status %x for slot %x",
16924 slotstatus, idx + mep->me_fslot));
16925 return (mptsas_send_sep(mpt, mep, idx, &slotstatus,
16926 MPI2_SEP_REQ_ACTION_WRITE_STATUS));
16927 }
16928
16929 /*
16930 * send sep request, use enclosure/slot addressing
16931 */
16932 static int
mptsas_send_sep(mptsas_t * mpt,mptsas_enclosure_t * mep,uint16_t idx,uint32_t * status,uint8_t act)16933 mptsas_send_sep(mptsas_t *mpt, mptsas_enclosure_t *mep, uint16_t idx,
16934 uint32_t *status, uint8_t act)
16935 {
16936 Mpi2SepRequest_t req;
16937 Mpi2SepReply_t rep;
16938 int ret;
16939 uint16_t enctype;
16940 uint16_t slot;
16941
16942 ASSERT(mutex_owned(&mpt->m_mutex));
16943
16944 /*
16945 * Look through the enclosures and make sure that this enclosure is
16946 * something that is directly attached device. If we didn't find an
16947 * enclosure for this device, don't send the ioctl.
16948 */
16949 enctype = mep->me_flags & MPI2_SAS_ENCLS0_FLAGS_MNG_MASK;
16950 if (enctype != MPI2_SAS_ENCLS0_FLAGS_MNG_IOC_SES &&
16951 enctype != MPI2_SAS_ENCLS0_FLAGS_MNG_IOC_SGPIO &&
16952 enctype != MPI2_SAS_ENCLS0_FLAGS_MNG_IOC_GPIO) {
16953 return (ENOTTY);
16954 }
16955 slot = idx + mep->me_fslot;
16956
16957 bzero(&req, sizeof (req));
16958 bzero(&rep, sizeof (rep));
16959
16960 req.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
16961 req.Action = act;
16962 req.Flags = MPI2_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS;
16963 req.EnclosureHandle = LE_16(mep->me_enchdl);
16964 req.Slot = LE_16(slot);
16965 if (act == MPI2_SEP_REQ_ACTION_WRITE_STATUS) {
16966 req.SlotStatus = LE_32(*status);
16967 }
16968 ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, NULL,
16969 sizeof (req), sizeof (rep), 0, MPTSAS_PASS_THRU_DIRECTION_NONE,
16970 NULL, 0, 60, FKIOCTL);
16971 if (ret != 0) {
16972 mptsas_log(mpt, CE_NOTE, "mptsas_send_sep: passthru SEP "
16973 "Processor Request message error %d", ret);
16974 return (ret);
16975 }
16976 /* do passthrough success, check the ioc status */
16977 if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) {
16978 mptsas_log(mpt, CE_NOTE, "send_sep act %x: ioc "
16979 "status:%x loginfo %x", act, LE_16(rep.IOCStatus),
16980 LE_32(rep.IOCLogInfo));
16981 switch (LE_16(rep.IOCStatus) & MPI2_IOCSTATUS_MASK) {
16982 case MPI2_IOCSTATUS_INVALID_FUNCTION:
16983 case MPI2_IOCSTATUS_INVALID_VPID:
16984 case MPI2_IOCSTATUS_INVALID_FIELD:
16985 case MPI2_IOCSTATUS_INVALID_STATE:
16986 case MPI2_IOCSTATUS_OP_STATE_NOT_SUPPORTED:
16987 case MPI2_IOCSTATUS_CONFIG_INVALID_ACTION:
16988 case MPI2_IOCSTATUS_CONFIG_INVALID_TYPE:
16989 case MPI2_IOCSTATUS_CONFIG_INVALID_PAGE:
16990 case MPI2_IOCSTATUS_CONFIG_INVALID_DATA:
16991 case MPI2_IOCSTATUS_CONFIG_NO_DEFAULTS:
16992 return (EINVAL);
16993 case MPI2_IOCSTATUS_BUSY:
16994 return (EBUSY);
16995 case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES:
16996 return (EAGAIN);
16997 case MPI2_IOCSTATUS_INVALID_SGL:
16998 case MPI2_IOCSTATUS_INTERNAL_ERROR:
16999 case MPI2_IOCSTATUS_CONFIG_CANT_COMMIT:
17000 default:
17001 return (EIO);
17002 }
17003 }
17004 if (act != MPI2_SEP_REQ_ACTION_WRITE_STATUS) {
17005 *status = LE_32(rep.SlotStatus);
17006 }
17007
17008 return (0);
17009 }
17010
17011 int
mptsas_dma_addr_create(mptsas_t * mpt,ddi_dma_attr_t dma_attr,ddi_dma_handle_t * dma_hdp,ddi_acc_handle_t * acc_hdp,caddr_t * dma_memp,uint32_t alloc_size,ddi_dma_cookie_t * cookiep)17012 mptsas_dma_addr_create(mptsas_t *mpt, ddi_dma_attr_t dma_attr,
17013 ddi_dma_handle_t *dma_hdp, ddi_acc_handle_t *acc_hdp, caddr_t *dma_memp,
17014 uint32_t alloc_size, ddi_dma_cookie_t *cookiep)
17015 {
17016 ddi_dma_cookie_t new_cookie;
17017 size_t alloc_len;
17018 uint_t ncookie;
17019
17020 if (cookiep == NULL)
17021 cookiep = &new_cookie;
17022
17023 if (ddi_dma_alloc_handle(mpt->m_dip, &dma_attr, DDI_DMA_SLEEP,
17024 NULL, dma_hdp) != DDI_SUCCESS) {
17025 return (FALSE);
17026 }
17027
17028 if (ddi_dma_mem_alloc(*dma_hdp, alloc_size, &mpt->m_dev_acc_attr,
17029 DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, dma_memp, &alloc_len,
17030 acc_hdp) != DDI_SUCCESS) {
17031 ddi_dma_free_handle(dma_hdp);
17032 *dma_hdp = NULL;
17033 return (FALSE);
17034 }
17035
17036 if (ddi_dma_addr_bind_handle(*dma_hdp, NULL, *dma_memp, alloc_len,
17037 (DDI_DMA_RDWR | DDI_DMA_CONSISTENT), DDI_DMA_SLEEP, NULL,
17038 cookiep, &ncookie) != DDI_DMA_MAPPED) {
17039 (void) ddi_dma_mem_free(acc_hdp);
17040 ddi_dma_free_handle(dma_hdp);
17041 *dma_hdp = NULL;
17042 return (FALSE);
17043 }
17044
17045 return (TRUE);
17046 }
17047
17048 void
mptsas_dma_addr_destroy(ddi_dma_handle_t * dma_hdp,ddi_acc_handle_t * acc_hdp)17049 mptsas_dma_addr_destroy(ddi_dma_handle_t *dma_hdp, ddi_acc_handle_t *acc_hdp)
17050 {
17051 if (*dma_hdp == NULL)
17052 return;
17053
17054 (void) ddi_dma_unbind_handle(*dma_hdp);
17055 (void) ddi_dma_mem_free(acc_hdp);
17056 ddi_dma_free_handle(dma_hdp);
17057 *dma_hdp = NULL;
17058 }
17059
17060 /*
17061 * DDI UFM Callbacks
17062 */
17063 static int
mptsas_ufm_fill_image(ddi_ufm_handle_t * ufmh,void * arg,uint_t imgno,ddi_ufm_image_t * img)17064 mptsas_ufm_fill_image(ddi_ufm_handle_t *ufmh, void *arg, uint_t imgno,
17065 ddi_ufm_image_t *img)
17066 {
17067 if (imgno != 0)
17068 return (EINVAL);
17069
17070 ddi_ufm_image_set_desc(img, "IOC Firmware");
17071 ddi_ufm_image_set_nslots(img, 1);
17072
17073 return (0);
17074 }
17075
17076 static int
mptsas_ufm_fill_slot(ddi_ufm_handle_t * ufmh,void * arg,uint_t imgno,uint_t slotno,ddi_ufm_slot_t * slot)17077 mptsas_ufm_fill_slot(ddi_ufm_handle_t *ufmh, void *arg, uint_t imgno,
17078 uint_t slotno, ddi_ufm_slot_t *slot)
17079 {
17080 mptsas_t *mpt = (mptsas_t *)arg;
17081 char *buf;
17082
17083 if (imgno != 0 || slotno != 0 ||
17084 ddi_prop_lookup_string(DDI_DEV_T_ANY, mpt->m_dip,
17085 DDI_PROP_DONTPASS, "firmware-version", &buf) != DDI_PROP_SUCCESS)
17086 return (EINVAL);
17087
17088 ddi_ufm_slot_set_attrs(slot, DDI_UFM_ATTR_ACTIVE);
17089 ddi_ufm_slot_set_version(slot, buf);
17090
17091 ddi_prop_free(buf);
17092
17093 return (0);
17094 }
17095
17096 static int
mptsas_ufm_getcaps(ddi_ufm_handle_t * ufmh,void * arg,ddi_ufm_cap_t * caps)17097 mptsas_ufm_getcaps(ddi_ufm_handle_t *ufmh, void *arg, ddi_ufm_cap_t *caps)
17098 {
17099 *caps = DDI_UFM_CAP_REPORT;
17100
17101 return (0);
17102 }
17103