1 /*-
2 * FreeBSD/CAM specific routines for LSI '909 FC adapters.
3 * FreeBSD Version.
4 *
5 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD AND BSD-3-Clause
6 *
7 * Copyright (c) 2000, 2001 by Greg Ansley
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice immediately at the beginning of the file, without modification,
14 * this list of conditions, and the following disclaimer.
15 * 2. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
22 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30 /*-
31 * Copyright (c) 2002, 2006 by Matthew Jacob
32 * All rights reserved.
33 *
34 * Redistribution and use in source and binary forms, with or without
35 * modification, are permitted provided that the following conditions are
36 * met:
37 * 1. Redistributions of source code must retain the above copyright
38 * notice, this list of conditions and the following disclaimer.
39 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
40 * substantially similar to the "NO WARRANTY" disclaimer below
41 * ("Disclaimer") and any redistribution must be conditioned upon including
42 * a substantially similar Disclaimer requirement for further binary
43 * redistribution.
44 * 3. Neither the names of the above listed copyright holders nor the names
45 * of any contributors may be used to endorse or promote products derived
46 * from this software without specific prior written permission.
47 *
48 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
49 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
52 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
53 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
54 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
55 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
56 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
57 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF THE COPYRIGHT
58 * OWNER OR CONTRIBUTOR IS ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59 *
60 * Support from Chris Ellsworth in order to make SAS adapters work
61 * is gratefully acknowledged.
62 *
63 * Support from LSI-Logic has also gone a great deal toward making this a
64 * workable subsystem and is gratefully acknowledged.
65 */
66 /*-
67 * Copyright (c) 2004, Avid Technology, Inc. and its contributors.
68 * Copyright (c) 2005, WHEEL Sp. z o.o.
69 * Copyright (c) 2004, 2005 Justin T. Gibbs
70 * All rights reserved.
71 *
72 * Redistribution and use in source and binary forms, with or without
73 * modification, are permitted provided that the following conditions are
74 * met:
75 * 1. Redistributions of source code must retain the above copyright
76 * notice, this list of conditions and the following disclaimer.
77 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
78 * substantially similar to the "NO WARRANTY" disclaimer below
79 * ("Disclaimer") and any redistribution must be conditioned upon including
80 * a substantially similar Disclaimer requirement for further binary
81 * redistribution.
82 * 3. Neither the names of the above listed copyright holders nor the names
83 * of any contributors may be used to endorse or promote products derived
84 * from this software without specific prior written permission.
85 *
86 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
87 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
88 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
89 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
90 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
91 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
92 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
93 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
94 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
95 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF THE COPYRIGHT
96 * OWNER OR CONTRIBUTOR IS ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97 */
98 #include <sys/cdefs.h>
99 __FBSDID("$FreeBSD$");
100
101 #include <dev/mpt/mpt.h>
102 #include <dev/mpt/mpt_cam.h>
103 #include <dev/mpt/mpt_raid.h>
104
105 #include "dev/mpt/mpilib/mpi_ioc.h" /* XXX Fix Event Handling!!! */
106 #include "dev/mpt/mpilib/mpi_init.h"
107 #include "dev/mpt/mpilib/mpi_targ.h"
108 #include "dev/mpt/mpilib/mpi_fc.h"
109 #include "dev/mpt/mpilib/mpi_sas.h"
110
111 #include <sys/callout.h>
112 #include <sys/kthread.h>
113 #include <sys/sysctl.h>
114
115 static void mpt_poll(struct cam_sim *);
116 static callout_func_t mpt_timeout;
117 static void mpt_action(struct cam_sim *, union ccb *);
118 static int
119 mpt_get_spi_settings(struct mpt_softc *, struct ccb_trans_settings *);
120 static void mpt_setwidth(struct mpt_softc *, int, int);
121 static void mpt_setsync(struct mpt_softc *, int, int, int);
122 static int mpt_update_spi_config(struct mpt_softc *, int);
123
124 static mpt_reply_handler_t mpt_scsi_reply_handler;
125 static mpt_reply_handler_t mpt_scsi_tmf_reply_handler;
126 static mpt_reply_handler_t mpt_fc_els_reply_handler;
127 static int mpt_scsi_reply_frame_handler(struct mpt_softc *, request_t *,
128 MSG_DEFAULT_REPLY *);
129 static int mpt_bus_reset(struct mpt_softc *, target_id_t, lun_id_t, int);
130 static int mpt_fc_reset_link(struct mpt_softc *, int);
131
132 static int mpt_spawn_recovery_thread(struct mpt_softc *mpt);
133 static void mpt_terminate_recovery_thread(struct mpt_softc *mpt);
134 static void mpt_recovery_thread(void *arg);
135 static void mpt_recover_commands(struct mpt_softc *mpt);
136
137 static int mpt_scsi_send_tmf(struct mpt_softc *, u_int, u_int, u_int,
138 target_id_t, lun_id_t, u_int, int);
139
140 static void mpt_fc_post_els(struct mpt_softc *mpt, request_t *, int);
141 static void mpt_post_target_command(struct mpt_softc *, request_t *, int);
142 static int mpt_add_els_buffers(struct mpt_softc *mpt);
143 static int mpt_add_target_commands(struct mpt_softc *mpt);
144 static int mpt_enable_lun(struct mpt_softc *, target_id_t, lun_id_t);
145 static int mpt_disable_lun(struct mpt_softc *, target_id_t, lun_id_t);
146 static void mpt_target_start_io(struct mpt_softc *, union ccb *);
147 static cam_status mpt_abort_target_ccb(struct mpt_softc *, union ccb *);
148 static int mpt_abort_target_cmd(struct mpt_softc *, request_t *);
149 static void mpt_scsi_tgt_status(struct mpt_softc *, union ccb *, request_t *,
150 uint8_t, uint8_t const *, u_int);
151 static void
152 mpt_scsi_tgt_tsk_mgmt(struct mpt_softc *, request_t *, mpt_task_mgmt_t,
153 tgt_resource_t *, int);
154 static void mpt_tgt_dump_tgt_state(struct mpt_softc *, request_t *);
155 static void mpt_tgt_dump_req_state(struct mpt_softc *, request_t *);
156 static mpt_reply_handler_t mpt_scsi_tgt_reply_handler;
157 static mpt_reply_handler_t mpt_sata_pass_reply_handler;
158
159 static uint32_t scsi_io_handler_id = MPT_HANDLER_ID_NONE;
160 static uint32_t scsi_tmf_handler_id = MPT_HANDLER_ID_NONE;
161 static uint32_t fc_els_handler_id = MPT_HANDLER_ID_NONE;
162 static uint32_t sata_pass_handler_id = MPT_HANDLER_ID_NONE;
163
164 static mpt_probe_handler_t mpt_cam_probe;
165 static mpt_attach_handler_t mpt_cam_attach;
166 static mpt_enable_handler_t mpt_cam_enable;
167 static mpt_ready_handler_t mpt_cam_ready;
168 static mpt_event_handler_t mpt_cam_event;
169 static mpt_reset_handler_t mpt_cam_ioc_reset;
170 static mpt_detach_handler_t mpt_cam_detach;
171
172 static struct mpt_personality mpt_cam_personality =
173 {
174 .name = "mpt_cam",
175 .probe = mpt_cam_probe,
176 .attach = mpt_cam_attach,
177 .enable = mpt_cam_enable,
178 .ready = mpt_cam_ready,
179 .event = mpt_cam_event,
180 .reset = mpt_cam_ioc_reset,
181 .detach = mpt_cam_detach,
182 };
183
184 DECLARE_MPT_PERSONALITY(mpt_cam, SI_ORDER_SECOND);
185 MODULE_DEPEND(mpt_cam, cam, 1, 1, 1);
186
187 int mpt_enable_sata_wc = -1;
188 TUNABLE_INT("hw.mpt.enable_sata_wc", &mpt_enable_sata_wc);
189
190 static int
mpt_cam_probe(struct mpt_softc * mpt)191 mpt_cam_probe(struct mpt_softc *mpt)
192 {
193 int role;
194
195 /*
196 * Only attach to nodes that support the initiator or target role
197 * (or want to) or have RAID physical devices that need CAM pass-thru
198 * support.
199 */
200 if (mpt->do_cfg_role) {
201 role = mpt->cfg_role;
202 } else {
203 role = mpt->role;
204 }
205 if ((role & (MPT_ROLE_TARGET|MPT_ROLE_INITIATOR)) != 0 ||
206 (mpt->ioc_page2 != NULL && mpt->ioc_page2->MaxPhysDisks != 0)) {
207 return (0);
208 }
209 return (ENODEV);
210 }
211
212 static int
mpt_cam_attach(struct mpt_softc * mpt)213 mpt_cam_attach(struct mpt_softc *mpt)
214 {
215 struct cam_devq *devq;
216 mpt_handler_t handler;
217 int maxq;
218 int error;
219
220 MPT_LOCK(mpt);
221 TAILQ_INIT(&mpt->request_timeout_list);
222 maxq = (mpt->ioc_facts.GlobalCredits < MPT_MAX_REQUESTS(mpt))?
223 mpt->ioc_facts.GlobalCredits : MPT_MAX_REQUESTS(mpt);
224
225 handler.reply_handler = mpt_scsi_reply_handler;
226 error = mpt_register_handler(mpt, MPT_HANDLER_REPLY, handler,
227 &scsi_io_handler_id);
228 if (error != 0) {
229 MPT_UNLOCK(mpt);
230 goto cleanup;
231 }
232
233 handler.reply_handler = mpt_scsi_tmf_reply_handler;
234 error = mpt_register_handler(mpt, MPT_HANDLER_REPLY, handler,
235 &scsi_tmf_handler_id);
236 if (error != 0) {
237 MPT_UNLOCK(mpt);
238 goto cleanup;
239 }
240
241 /*
242 * If we're fibre channel and could support target mode, we register
243 * an ELS reply handler and give it resources.
244 */
245 if (mpt->is_fc && (mpt->role & MPT_ROLE_TARGET) != 0) {
246 handler.reply_handler = mpt_fc_els_reply_handler;
247 error = mpt_register_handler(mpt, MPT_HANDLER_REPLY, handler,
248 &fc_els_handler_id);
249 if (error != 0) {
250 MPT_UNLOCK(mpt);
251 goto cleanup;
252 }
253 if (mpt_add_els_buffers(mpt) == FALSE) {
254 error = ENOMEM;
255 MPT_UNLOCK(mpt);
256 goto cleanup;
257 }
258 maxq -= mpt->els_cmds_allocated;
259 }
260
261 /*
262 * If we support target mode, we register a reply handler for it,
263 * but don't add command resources until we actually enable target
264 * mode.
265 */
266 if (mpt->is_fc && (mpt->role & MPT_ROLE_TARGET) != 0) {
267 handler.reply_handler = mpt_scsi_tgt_reply_handler;
268 error = mpt_register_handler(mpt, MPT_HANDLER_REPLY, handler,
269 &mpt->scsi_tgt_handler_id);
270 if (error != 0) {
271 MPT_UNLOCK(mpt);
272 goto cleanup;
273 }
274 }
275
276 if (mpt->is_sas) {
277 handler.reply_handler = mpt_sata_pass_reply_handler;
278 error = mpt_register_handler(mpt, MPT_HANDLER_REPLY, handler,
279 &sata_pass_handler_id);
280 if (error != 0) {
281 MPT_UNLOCK(mpt);
282 goto cleanup;
283 }
284 }
285
286 /*
287 * We keep one request reserved for timeout TMF requests.
288 */
289 mpt->tmf_req = mpt_get_request(mpt, FALSE);
290 if (mpt->tmf_req == NULL) {
291 mpt_prt(mpt, "Unable to allocate dedicated TMF request!\n");
292 error = ENOMEM;
293 MPT_UNLOCK(mpt);
294 goto cleanup;
295 }
296
297 /*
298 * Mark the request as free even though not on the free list.
299 * There is only one TMF request allowed to be outstanding at
300 * a time and the TMF routines perform their own allocation
301 * tracking using the standard state flags.
302 */
303 mpt->tmf_req->state = REQ_STATE_FREE;
304 maxq--;
305
306 /*
307 * The rest of this is CAM foo, for which we need to drop our lock
308 */
309 MPT_UNLOCK(mpt);
310
311 if (mpt_spawn_recovery_thread(mpt) != 0) {
312 mpt_prt(mpt, "Unable to spawn recovery thread!\n");
313 error = ENOMEM;
314 goto cleanup;
315 }
316
317 /*
318 * Create the device queue for our SIM(s).
319 */
320 devq = cam_simq_alloc(maxq);
321 if (devq == NULL) {
322 mpt_prt(mpt, "Unable to allocate CAM SIMQ!\n");
323 error = ENOMEM;
324 goto cleanup;
325 }
326
327 /*
328 * Construct our SIM entry.
329 */
330 mpt->sim =
331 mpt_sim_alloc(mpt_action, mpt_poll, "mpt", mpt, 1, maxq, devq);
332 if (mpt->sim == NULL) {
333 mpt_prt(mpt, "Unable to allocate CAM SIM!\n");
334 cam_simq_free(devq);
335 error = ENOMEM;
336 goto cleanup;
337 }
338
339 /*
340 * Register exactly this bus.
341 */
342 MPT_LOCK(mpt);
343 if (xpt_bus_register(mpt->sim, mpt->dev, 0) != CAM_SUCCESS) {
344 mpt_prt(mpt, "Bus registration Failed!\n");
345 error = ENOMEM;
346 MPT_UNLOCK(mpt);
347 goto cleanup;
348 }
349
350 if (xpt_create_path(&mpt->path, NULL, cam_sim_path(mpt->sim),
351 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
352 mpt_prt(mpt, "Unable to allocate Path!\n");
353 error = ENOMEM;
354 MPT_UNLOCK(mpt);
355 goto cleanup;
356 }
357 MPT_UNLOCK(mpt);
358
359 /*
360 * Only register a second bus for RAID physical
361 * devices if the controller supports RAID.
362 */
363 if (mpt->ioc_page2 == NULL || mpt->ioc_page2->MaxPhysDisks == 0) {
364 return (0);
365 }
366
367 /*
368 * Create a "bus" to export all hidden disks to CAM.
369 */
370 mpt->phydisk_sim =
371 mpt_sim_alloc(mpt_action, mpt_poll, "mpt", mpt, 1, maxq, devq);
372 if (mpt->phydisk_sim == NULL) {
373 mpt_prt(mpt, "Unable to allocate Physical Disk CAM SIM!\n");
374 error = ENOMEM;
375 goto cleanup;
376 }
377
378 /*
379 * Register this bus.
380 */
381 MPT_LOCK(mpt);
382 if (xpt_bus_register(mpt->phydisk_sim, mpt->dev, 1) !=
383 CAM_SUCCESS) {
384 mpt_prt(mpt, "Physical Disk Bus registration Failed!\n");
385 error = ENOMEM;
386 MPT_UNLOCK(mpt);
387 goto cleanup;
388 }
389
390 if (xpt_create_path(&mpt->phydisk_path, NULL,
391 cam_sim_path(mpt->phydisk_sim),
392 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
393 mpt_prt(mpt, "Unable to allocate Physical Disk Path!\n");
394 error = ENOMEM;
395 MPT_UNLOCK(mpt);
396 goto cleanup;
397 }
398 MPT_UNLOCK(mpt);
399 mpt_lprt(mpt, MPT_PRT_DEBUG, "attached cam\n");
400 return (0);
401
402 cleanup:
403 mpt_cam_detach(mpt);
404 return (error);
405 }
406
407 /*
408 * Read FC configuration information
409 */
410 static int
mpt_read_config_info_fc(struct mpt_softc * mpt)411 mpt_read_config_info_fc(struct mpt_softc *mpt)
412 {
413 struct sysctl_ctx_list *ctx;
414 struct sysctl_oid *tree;
415 char *topology = NULL;
416 int rv;
417
418 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_FC_PORT, 0,
419 0, &mpt->mpt_fcport_page0.Header, FALSE, 5000);
420 if (rv) {
421 return (-1);
422 }
423 mpt_lprt(mpt, MPT_PRT_DEBUG, "FC Port Page 0 Header: %x %x %x %x\n",
424 mpt->mpt_fcport_page0.Header.PageVersion,
425 mpt->mpt_fcport_page0.Header.PageLength,
426 mpt->mpt_fcport_page0.Header.PageNumber,
427 mpt->mpt_fcport_page0.Header.PageType);
428
429 rv = mpt_read_cur_cfg_page(mpt, 0, &mpt->mpt_fcport_page0.Header,
430 sizeof(mpt->mpt_fcport_page0), FALSE, 5000);
431 if (rv) {
432 mpt_prt(mpt, "failed to read FC Port Page 0\n");
433 return (-1);
434 }
435 mpt2host_config_page_fc_port_0(&mpt->mpt_fcport_page0);
436
437 switch (mpt->mpt_fcport_page0.CurrentSpeed) {
438 case MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT:
439 mpt->mpt_fcport_speed = 1;
440 break;
441 case MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT:
442 mpt->mpt_fcport_speed = 2;
443 break;
444 case MPI_FCPORTPAGE0_CURRENT_SPEED_10GBIT:
445 mpt->mpt_fcport_speed = 10;
446 break;
447 case MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT:
448 mpt->mpt_fcport_speed = 4;
449 break;
450 default:
451 mpt->mpt_fcport_speed = 0;
452 break;
453 }
454
455 switch (mpt->mpt_fcport_page0.Flags &
456 MPI_FCPORTPAGE0_FLAGS_ATTACH_TYPE_MASK) {
457 case MPI_FCPORTPAGE0_FLAGS_ATTACH_NO_INIT:
458 mpt->mpt_fcport_speed = 0;
459 topology = "<NO LOOP>";
460 break;
461 case MPI_FCPORTPAGE0_FLAGS_ATTACH_POINT_TO_POINT:
462 topology = "N-Port";
463 break;
464 case MPI_FCPORTPAGE0_FLAGS_ATTACH_PRIVATE_LOOP:
465 topology = "NL-Port";
466 break;
467 case MPI_FCPORTPAGE0_FLAGS_ATTACH_FABRIC_DIRECT:
468 topology = "F-Port";
469 break;
470 case MPI_FCPORTPAGE0_FLAGS_ATTACH_PUBLIC_LOOP:
471 topology = "FL-Port";
472 break;
473 default:
474 mpt->mpt_fcport_speed = 0;
475 topology = "?";
476 break;
477 }
478
479 mpt->scinfo.fc.wwnn = ((uint64_t)mpt->mpt_fcport_page0.WWNN.High << 32)
480 | mpt->mpt_fcport_page0.WWNN.Low;
481 mpt->scinfo.fc.wwpn = ((uint64_t)mpt->mpt_fcport_page0.WWPN.High << 32)
482 | mpt->mpt_fcport_page0.WWPN.Low;
483 mpt->scinfo.fc.portid = mpt->mpt_fcport_page0.PortIdentifier;
484
485 mpt_lprt(mpt, MPT_PRT_INFO,
486 "FC Port Page 0: Topology <%s> WWNN 0x%16jx WWPN 0x%16jx "
487 "Speed %u-Gbit\n", topology,
488 (uintmax_t)mpt->scinfo.fc.wwnn, (uintmax_t)mpt->scinfo.fc.wwpn,
489 mpt->mpt_fcport_speed);
490 MPT_UNLOCK(mpt);
491 ctx = device_get_sysctl_ctx(mpt->dev);
492 tree = device_get_sysctl_tree(mpt->dev);
493
494 SYSCTL_ADD_QUAD(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
495 "wwnn", CTLFLAG_RD, &mpt->scinfo.fc.wwnn,
496 "World Wide Node Name");
497
498 SYSCTL_ADD_QUAD(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
499 "wwpn", CTLFLAG_RD, &mpt->scinfo.fc.wwpn,
500 "World Wide Port Name");
501
502 MPT_LOCK(mpt);
503 return (0);
504 }
505
506 /*
507 * Set FC configuration information.
508 */
509 static int
mpt_set_initial_config_fc(struct mpt_softc * mpt)510 mpt_set_initial_config_fc(struct mpt_softc *mpt)
511 {
512 CONFIG_PAGE_FC_PORT_1 fc;
513 U32 fl;
514 int r, doit = 0;
515 int role;
516
517 r = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_FC_PORT, 1, 0,
518 &fc.Header, FALSE, 5000);
519 if (r) {
520 mpt_prt(mpt, "failed to read FC page 1 header\n");
521 return (mpt_fc_reset_link(mpt, 1));
522 }
523
524 r = mpt_read_cfg_page(mpt, MPI_CONFIG_ACTION_PAGE_READ_NVRAM, 0,
525 &fc.Header, sizeof (fc), FALSE, 5000);
526 if (r) {
527 mpt_prt(mpt, "failed to read FC page 1\n");
528 return (mpt_fc_reset_link(mpt, 1));
529 }
530 mpt2host_config_page_fc_port_1(&fc);
531
532 /*
533 * Check our flags to make sure we support the role we want.
534 */
535 doit = 0;
536 role = 0;
537 fl = fc.Flags;
538
539 if (fl & MPI_FCPORTPAGE1_FLAGS_PROT_FCP_INIT) {
540 role |= MPT_ROLE_INITIATOR;
541 }
542 if (fl & MPI_FCPORTPAGE1_FLAGS_PROT_FCP_TARG) {
543 role |= MPT_ROLE_TARGET;
544 }
545
546 fl &= ~MPI_FCPORTPAGE1_FLAGS_PROT_MASK;
547
548 if (mpt->do_cfg_role == 0) {
549 role = mpt->cfg_role;
550 } else {
551 mpt->do_cfg_role = 0;
552 }
553
554 if (role != mpt->cfg_role) {
555 if (mpt->cfg_role & MPT_ROLE_INITIATOR) {
556 if ((role & MPT_ROLE_INITIATOR) == 0) {
557 mpt_prt(mpt, "adding initiator role\n");
558 fl |= MPI_FCPORTPAGE1_FLAGS_PROT_FCP_INIT;
559 doit++;
560 } else {
561 mpt_prt(mpt, "keeping initiator role\n");
562 }
563 } else if (role & MPT_ROLE_INITIATOR) {
564 mpt_prt(mpt, "removing initiator role\n");
565 doit++;
566 }
567 if (mpt->cfg_role & MPT_ROLE_TARGET) {
568 if ((role & MPT_ROLE_TARGET) == 0) {
569 mpt_prt(mpt, "adding target role\n");
570 fl |= MPI_FCPORTPAGE1_FLAGS_PROT_FCP_TARG;
571 doit++;
572 } else {
573 mpt_prt(mpt, "keeping target role\n");
574 }
575 } else if (role & MPT_ROLE_TARGET) {
576 mpt_prt(mpt, "removing target role\n");
577 doit++;
578 }
579 mpt->role = mpt->cfg_role;
580 }
581
582 if (fl & MPI_FCPORTPAGE1_FLAGS_PROT_FCP_TARG) {
583 if ((fl & MPI_FCPORTPAGE1_FLAGS_TARGET_MODE_OXID) == 0) {
584 mpt_prt(mpt, "adding OXID option\n");
585 fl |= MPI_FCPORTPAGE1_FLAGS_TARGET_MODE_OXID;
586 doit++;
587 }
588 }
589
590 if (doit) {
591 fc.Flags = fl;
592 host2mpt_config_page_fc_port_1(&fc);
593 r = mpt_write_cfg_page(mpt,
594 MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM, 0, &fc.Header,
595 sizeof(fc), FALSE, 5000);
596 if (r != 0) {
597 mpt_prt(mpt, "failed to update NVRAM with changes\n");
598 return (0);
599 }
600 mpt_prt(mpt, "NOTE: NVRAM changes will not take "
601 "effect until next reboot or IOC reset\n");
602 }
603 return (0);
604 }
605
606 static int
mptsas_sas_io_unit_pg0(struct mpt_softc * mpt,struct mptsas_portinfo * portinfo)607 mptsas_sas_io_unit_pg0(struct mpt_softc *mpt, struct mptsas_portinfo *portinfo)
608 {
609 ConfigExtendedPageHeader_t hdr;
610 struct mptsas_phyinfo *phyinfo;
611 SasIOUnitPage0_t *buffer;
612 int error, len, i;
613
614 error = mpt_read_extcfg_header(mpt, MPI_SASIOUNITPAGE0_PAGEVERSION,
615 0, 0, MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT,
616 &hdr, 0, 10000);
617 if (error)
618 goto out;
619 if (hdr.ExtPageLength == 0) {
620 error = ENXIO;
621 goto out;
622 }
623
624 len = hdr.ExtPageLength * 4;
625 buffer = malloc(len, M_DEVBUF, M_NOWAIT|M_ZERO);
626 if (buffer == NULL) {
627 error = ENOMEM;
628 goto out;
629 }
630
631 error = mpt_read_extcfg_page(mpt, MPI_CONFIG_ACTION_PAGE_READ_CURRENT,
632 0, &hdr, buffer, len, 0, 10000);
633 if (error) {
634 free(buffer, M_DEVBUF);
635 goto out;
636 }
637
638 portinfo->num_phys = buffer->NumPhys;
639 portinfo->phy_info = malloc(sizeof(*portinfo->phy_info) *
640 portinfo->num_phys, M_DEVBUF, M_NOWAIT|M_ZERO);
641 if (portinfo->phy_info == NULL) {
642 free(buffer, M_DEVBUF);
643 error = ENOMEM;
644 goto out;
645 }
646
647 for (i = 0; i < portinfo->num_phys; i++) {
648 phyinfo = &portinfo->phy_info[i];
649 phyinfo->phy_num = i;
650 phyinfo->port_id = buffer->PhyData[i].Port;
651 phyinfo->negotiated_link_rate =
652 buffer->PhyData[i].NegotiatedLinkRate;
653 phyinfo->handle =
654 le16toh(buffer->PhyData[i].ControllerDevHandle);
655 }
656
657 free(buffer, M_DEVBUF);
658 out:
659 return (error);
660 }
661
662 static int
mptsas_sas_phy_pg0(struct mpt_softc * mpt,struct mptsas_phyinfo * phy_info,uint32_t form,uint32_t form_specific)663 mptsas_sas_phy_pg0(struct mpt_softc *mpt, struct mptsas_phyinfo *phy_info,
664 uint32_t form, uint32_t form_specific)
665 {
666 ConfigExtendedPageHeader_t hdr;
667 SasPhyPage0_t *buffer;
668 int error;
669
670 error = mpt_read_extcfg_header(mpt, MPI_SASPHY0_PAGEVERSION, 0, 0,
671 MPI_CONFIG_EXTPAGETYPE_SAS_PHY, &hdr,
672 0, 10000);
673 if (error)
674 goto out;
675 if (hdr.ExtPageLength == 0) {
676 error = ENXIO;
677 goto out;
678 }
679
680 buffer = malloc(sizeof(SasPhyPage0_t), M_DEVBUF, M_NOWAIT|M_ZERO);
681 if (buffer == NULL) {
682 error = ENOMEM;
683 goto out;
684 }
685
686 error = mpt_read_extcfg_page(mpt, MPI_CONFIG_ACTION_PAGE_READ_CURRENT,
687 form + form_specific, &hdr, buffer,
688 sizeof(SasPhyPage0_t), 0, 10000);
689 if (error) {
690 free(buffer, M_DEVBUF);
691 goto out;
692 }
693
694 phy_info->hw_link_rate = buffer->HwLinkRate;
695 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
696 phy_info->identify.dev_handle = le16toh(buffer->OwnerDevHandle);
697 phy_info->attached.dev_handle = le16toh(buffer->AttachedDevHandle);
698
699 free(buffer, M_DEVBUF);
700 out:
701 return (error);
702 }
703
704 static int
mptsas_sas_device_pg0(struct mpt_softc * mpt,struct mptsas_devinfo * device_info,uint32_t form,uint32_t form_specific)705 mptsas_sas_device_pg0(struct mpt_softc *mpt, struct mptsas_devinfo *device_info,
706 uint32_t form, uint32_t form_specific)
707 {
708 ConfigExtendedPageHeader_t hdr;
709 SasDevicePage0_t *buffer;
710 uint64_t sas_address;
711 int error = 0;
712
713 bzero(device_info, sizeof(*device_info));
714 error = mpt_read_extcfg_header(mpt, MPI_SASDEVICE0_PAGEVERSION, 0, 0,
715 MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE,
716 &hdr, 0, 10000);
717 if (error)
718 goto out;
719 if (hdr.ExtPageLength == 0) {
720 error = ENXIO;
721 goto out;
722 }
723
724 buffer = malloc(sizeof(SasDevicePage0_t), M_DEVBUF, M_NOWAIT|M_ZERO);
725 if (buffer == NULL) {
726 error = ENOMEM;
727 goto out;
728 }
729
730 error = mpt_read_extcfg_page(mpt, MPI_CONFIG_ACTION_PAGE_READ_CURRENT,
731 form + form_specific, &hdr, buffer,
732 sizeof(SasDevicePage0_t), 0, 10000);
733 if (error) {
734 free(buffer, M_DEVBUF);
735 goto out;
736 }
737
738 device_info->dev_handle = le16toh(buffer->DevHandle);
739 device_info->parent_dev_handle = le16toh(buffer->ParentDevHandle);
740 device_info->enclosure_handle = le16toh(buffer->EnclosureHandle);
741 device_info->slot = le16toh(buffer->Slot);
742 device_info->phy_num = buffer->PhyNum;
743 device_info->physical_port = buffer->PhysicalPort;
744 device_info->target_id = buffer->TargetID;
745 device_info->bus = buffer->Bus;
746 bcopy(&buffer->SASAddress, &sas_address, sizeof(uint64_t));
747 device_info->sas_address = le64toh(sas_address);
748 device_info->device_info = le32toh(buffer->DeviceInfo);
749
750 free(buffer, M_DEVBUF);
751 out:
752 return (error);
753 }
754
755 /*
756 * Read SAS configuration information. Nothing to do yet.
757 */
758 static int
mpt_read_config_info_sas(struct mpt_softc * mpt)759 mpt_read_config_info_sas(struct mpt_softc *mpt)
760 {
761 struct mptsas_portinfo *portinfo;
762 struct mptsas_phyinfo *phyinfo;
763 int error, i;
764
765 portinfo = malloc(sizeof(*portinfo), M_DEVBUF, M_NOWAIT|M_ZERO);
766 if (portinfo == NULL)
767 return (ENOMEM);
768
769 error = mptsas_sas_io_unit_pg0(mpt, portinfo);
770 if (error) {
771 free(portinfo, M_DEVBUF);
772 return (0);
773 }
774
775 for (i = 0; i < portinfo->num_phys; i++) {
776 phyinfo = &portinfo->phy_info[i];
777 error = mptsas_sas_phy_pg0(mpt, phyinfo,
778 (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
779 MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
780 if (error)
781 break;
782 error = mptsas_sas_device_pg0(mpt, &phyinfo->identify,
783 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
784 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
785 phyinfo->handle);
786 if (error)
787 break;
788 phyinfo->identify.phy_num = phyinfo->phy_num = i;
789 if (phyinfo->attached.dev_handle)
790 error = mptsas_sas_device_pg0(mpt,
791 &phyinfo->attached,
792 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
793 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
794 phyinfo->attached.dev_handle);
795 if (error)
796 break;
797 }
798 mpt->sas_portinfo = portinfo;
799 return (0);
800 }
801
802 static void
mptsas_set_sata_wc(struct mpt_softc * mpt,struct mptsas_devinfo * devinfo,int enabled)803 mptsas_set_sata_wc(struct mpt_softc *mpt, struct mptsas_devinfo *devinfo,
804 int enabled)
805 {
806 SataPassthroughRequest_t *pass;
807 request_t *req;
808 int error, status;
809
810 req = mpt_get_request(mpt, 0);
811 if (req == NULL)
812 return;
813
814 pass = req->req_vbuf;
815 bzero(pass, sizeof(SataPassthroughRequest_t));
816 pass->Function = MPI_FUNCTION_SATA_PASSTHROUGH;
817 pass->TargetID = devinfo->target_id;
818 pass->Bus = devinfo->bus;
819 pass->PassthroughFlags = 0;
820 pass->ConnectionRate = MPI_SATA_PT_REQ_CONNECT_RATE_NEGOTIATED;
821 pass->DataLength = 0;
822 pass->MsgContext = htole32(req->index | sata_pass_handler_id);
823 pass->CommandFIS[0] = 0x27;
824 pass->CommandFIS[1] = 0x80;
825 pass->CommandFIS[2] = 0xef;
826 pass->CommandFIS[3] = (enabled) ? 0x02 : 0x82;
827 pass->CommandFIS[7] = 0x40;
828 pass->CommandFIS[15] = 0x08;
829
830 mpt_check_doorbell(mpt);
831 mpt_send_cmd(mpt, req);
832 error = mpt_wait_req(mpt, req, REQ_STATE_DONE, REQ_STATE_DONE, 0,
833 10 * 1000);
834 if (error) {
835 mpt_free_request(mpt, req);
836 printf("error %d sending passthrough\n", error);
837 return;
838 }
839
840 status = le16toh(req->IOCStatus);
841 if (status != MPI_IOCSTATUS_SUCCESS) {
842 mpt_free_request(mpt, req);
843 printf("IOCSTATUS %d\n", status);
844 return;
845 }
846
847 mpt_free_request(mpt, req);
848 }
849
850 /*
851 * Set SAS configuration information. Nothing to do yet.
852 */
853 static int
mpt_set_initial_config_sas(struct mpt_softc * mpt)854 mpt_set_initial_config_sas(struct mpt_softc *mpt)
855 {
856 struct mptsas_phyinfo *phyinfo;
857 int i;
858
859 if ((mpt_enable_sata_wc != -1) && (mpt->sas_portinfo != NULL)) {
860 for (i = 0; i < mpt->sas_portinfo->num_phys; i++) {
861 phyinfo = &mpt->sas_portinfo->phy_info[i];
862 if (phyinfo->attached.dev_handle == 0)
863 continue;
864 if ((phyinfo->attached.device_info &
865 MPI_SAS_DEVICE_INFO_SATA_DEVICE) == 0)
866 continue;
867 if (bootverbose)
868 device_printf(mpt->dev,
869 "%sabling SATA WC on phy %d\n",
870 (mpt_enable_sata_wc) ? "En" : "Dis", i);
871 mptsas_set_sata_wc(mpt, &phyinfo->attached,
872 mpt_enable_sata_wc);
873 }
874 }
875
876 return (0);
877 }
878
879 static int
mpt_sata_pass_reply_handler(struct mpt_softc * mpt,request_t * req,uint32_t reply_desc,MSG_DEFAULT_REPLY * reply_frame)880 mpt_sata_pass_reply_handler(struct mpt_softc *mpt, request_t *req,
881 uint32_t reply_desc, MSG_DEFAULT_REPLY *reply_frame)
882 {
883
884 if (req != NULL) {
885 if (reply_frame != NULL) {
886 req->IOCStatus = le16toh(reply_frame->IOCStatus);
887 }
888 req->state &= ~REQ_STATE_QUEUED;
889 req->state |= REQ_STATE_DONE;
890 TAILQ_REMOVE(&mpt->request_pending_list, req, links);
891 if ((req->state & REQ_STATE_NEED_WAKEUP) != 0) {
892 wakeup(req);
893 } else if ((req->state & REQ_STATE_TIMEDOUT) != 0) {
894 /*
895 * Whew- we can free this request (late completion)
896 */
897 mpt_free_request(mpt, req);
898 }
899 }
900
901 return (TRUE);
902 }
903
904 /*
905 * Read SCSI configuration information
906 */
907 static int
mpt_read_config_info_spi(struct mpt_softc * mpt)908 mpt_read_config_info_spi(struct mpt_softc *mpt)
909 {
910 int rv, i;
911
912 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 0, 0,
913 &mpt->mpt_port_page0.Header, FALSE, 5000);
914 if (rv) {
915 return (-1);
916 }
917 mpt_lprt(mpt, MPT_PRT_DEBUG, "SPI Port Page 0 Header: %x %x %x %x\n",
918 mpt->mpt_port_page0.Header.PageVersion,
919 mpt->mpt_port_page0.Header.PageLength,
920 mpt->mpt_port_page0.Header.PageNumber,
921 mpt->mpt_port_page0.Header.PageType);
922
923 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 1, 0,
924 &mpt->mpt_port_page1.Header, FALSE, 5000);
925 if (rv) {
926 return (-1);
927 }
928 mpt_lprt(mpt, MPT_PRT_DEBUG, "SPI Port Page 1 Header: %x %x %x %x\n",
929 mpt->mpt_port_page1.Header.PageVersion,
930 mpt->mpt_port_page1.Header.PageLength,
931 mpt->mpt_port_page1.Header.PageNumber,
932 mpt->mpt_port_page1.Header.PageType);
933
934 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 2, 0,
935 &mpt->mpt_port_page2.Header, FALSE, 5000);
936 if (rv) {
937 return (-1);
938 }
939 mpt_lprt(mpt, MPT_PRT_DEBUG, "SPI Port Page 2 Header: %x %x %x %x\n",
940 mpt->mpt_port_page2.Header.PageVersion,
941 mpt->mpt_port_page2.Header.PageLength,
942 mpt->mpt_port_page2.Header.PageNumber,
943 mpt->mpt_port_page2.Header.PageType);
944
945 for (i = 0; i < 16; i++) {
946 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_DEVICE,
947 0, i, &mpt->mpt_dev_page0[i].Header, FALSE, 5000);
948 if (rv) {
949 return (-1);
950 }
951 mpt_lprt(mpt, MPT_PRT_DEBUG,
952 "SPI Target %d Device Page 0 Header: %x %x %x %x\n", i,
953 mpt->mpt_dev_page0[i].Header.PageVersion,
954 mpt->mpt_dev_page0[i].Header.PageLength,
955 mpt->mpt_dev_page0[i].Header.PageNumber,
956 mpt->mpt_dev_page0[i].Header.PageType);
957
958 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_DEVICE,
959 1, i, &mpt->mpt_dev_page1[i].Header, FALSE, 5000);
960 if (rv) {
961 return (-1);
962 }
963 mpt_lprt(mpt, MPT_PRT_DEBUG,
964 "SPI Target %d Device Page 1 Header: %x %x %x %x\n", i,
965 mpt->mpt_dev_page1[i].Header.PageVersion,
966 mpt->mpt_dev_page1[i].Header.PageLength,
967 mpt->mpt_dev_page1[i].Header.PageNumber,
968 mpt->mpt_dev_page1[i].Header.PageType);
969 }
970
971 /*
972 * At this point, we don't *have* to fail. As long as we have
973 * valid config header information, we can (barely) lurch
974 * along.
975 */
976
977 rv = mpt_read_cur_cfg_page(mpt, 0, &mpt->mpt_port_page0.Header,
978 sizeof(mpt->mpt_port_page0), FALSE, 5000);
979 if (rv) {
980 mpt_prt(mpt, "failed to read SPI Port Page 0\n");
981 } else {
982 mpt2host_config_page_scsi_port_0(&mpt->mpt_port_page0);
983 mpt_lprt(mpt, MPT_PRT_NEGOTIATION,
984 "SPI Port Page 0: Capabilities %x PhysicalInterface %x\n",
985 mpt->mpt_port_page0.Capabilities,
986 mpt->mpt_port_page0.PhysicalInterface);
987 }
988
989 rv = mpt_read_cur_cfg_page(mpt, 0, &mpt->mpt_port_page1.Header,
990 sizeof(mpt->mpt_port_page1), FALSE, 5000);
991 if (rv) {
992 mpt_prt(mpt, "failed to read SPI Port Page 1\n");
993 } else {
994 mpt2host_config_page_scsi_port_1(&mpt->mpt_port_page1);
995 mpt_lprt(mpt, MPT_PRT_DEBUG,
996 "SPI Port Page 1: Configuration %x OnBusTimerValue %x\n",
997 mpt->mpt_port_page1.Configuration,
998 mpt->mpt_port_page1.OnBusTimerValue);
999 }
1000
1001 rv = mpt_read_cur_cfg_page(mpt, 0, &mpt->mpt_port_page2.Header,
1002 sizeof(mpt->mpt_port_page2), FALSE, 5000);
1003 if (rv) {
1004 mpt_prt(mpt, "failed to read SPI Port Page 2\n");
1005 } else {
1006 mpt_lprt(mpt, MPT_PRT_NEGOTIATION,
1007 "Port Page 2: Flags %x Settings %x\n",
1008 mpt->mpt_port_page2.PortFlags,
1009 mpt->mpt_port_page2.PortSettings);
1010 mpt2host_config_page_scsi_port_2(&mpt->mpt_port_page2);
1011 for (i = 0; i < 16; i++) {
1012 mpt_lprt(mpt, MPT_PRT_NEGOTIATION,
1013 " Port Page 2 Tgt %d: timo %x SF %x Flags %x\n",
1014 i, mpt->mpt_port_page2.DeviceSettings[i].Timeout,
1015 mpt->mpt_port_page2.DeviceSettings[i].SyncFactor,
1016 mpt->mpt_port_page2.DeviceSettings[i].DeviceFlags);
1017 }
1018 }
1019
1020 for (i = 0; i < 16; i++) {
1021 rv = mpt_read_cur_cfg_page(mpt, i,
1022 &mpt->mpt_dev_page0[i].Header, sizeof(*mpt->mpt_dev_page0),
1023 FALSE, 5000);
1024 if (rv) {
1025 mpt_prt(mpt,
1026 "cannot read SPI Target %d Device Page 0\n", i);
1027 continue;
1028 }
1029 mpt2host_config_page_scsi_device_0(&mpt->mpt_dev_page0[i]);
1030 mpt_lprt(mpt, MPT_PRT_NEGOTIATION,
1031 "target %d page 0: Negotiated Params %x Information %x\n",
1032 i, mpt->mpt_dev_page0[i].NegotiatedParameters,
1033 mpt->mpt_dev_page0[i].Information);
1034
1035 rv = mpt_read_cur_cfg_page(mpt, i,
1036 &mpt->mpt_dev_page1[i].Header, sizeof(*mpt->mpt_dev_page1),
1037 FALSE, 5000);
1038 if (rv) {
1039 mpt_prt(mpt,
1040 "cannot read SPI Target %d Device Page 1\n", i);
1041 continue;
1042 }
1043 mpt2host_config_page_scsi_device_1(&mpt->mpt_dev_page1[i]);
1044 mpt_lprt(mpt, MPT_PRT_NEGOTIATION,
1045 "target %d page 1: Requested Params %x Configuration %x\n",
1046 i, mpt->mpt_dev_page1[i].RequestedParameters,
1047 mpt->mpt_dev_page1[i].Configuration);
1048 }
1049 return (0);
1050 }
1051
1052 /*
1053 * Validate SPI configuration information.
1054 *
1055 * In particular, validate SPI Port Page 1.
1056 */
1057 static int
mpt_set_initial_config_spi(struct mpt_softc * mpt)1058 mpt_set_initial_config_spi(struct mpt_softc *mpt)
1059 {
1060 int error, i, pp1val;
1061
1062 mpt->mpt_disc_enable = 0xff;
1063 mpt->mpt_tag_enable = 0;
1064
1065 pp1val = ((1 << mpt->mpt_ini_id) <<
1066 MPI_SCSIPORTPAGE1_CFG_SHIFT_PORT_RESPONSE_ID) | mpt->mpt_ini_id;
1067 if (mpt->mpt_port_page1.Configuration != pp1val) {
1068 CONFIG_PAGE_SCSI_PORT_1 tmp;
1069
1070 mpt_prt(mpt, "SPI Port Page 1 Config value bad (%x)- should "
1071 "be %x\n", mpt->mpt_port_page1.Configuration, pp1val);
1072 tmp = mpt->mpt_port_page1;
1073 tmp.Configuration = pp1val;
1074 host2mpt_config_page_scsi_port_1(&tmp);
1075 error = mpt_write_cur_cfg_page(mpt, 0,
1076 &tmp.Header, sizeof(tmp), FALSE, 5000);
1077 if (error) {
1078 return (-1);
1079 }
1080 error = mpt_read_cur_cfg_page(mpt, 0,
1081 &tmp.Header, sizeof(tmp), FALSE, 5000);
1082 if (error) {
1083 return (-1);
1084 }
1085 mpt2host_config_page_scsi_port_1(&tmp);
1086 if (tmp.Configuration != pp1val) {
1087 mpt_prt(mpt,
1088 "failed to reset SPI Port Page 1 Config value\n");
1089 return (-1);
1090 }
1091 mpt->mpt_port_page1 = tmp;
1092 }
1093
1094 /*
1095 * The purpose of this exercise is to get
1096 * all targets back to async/narrow.
1097 *
1098 * We skip this step if the BIOS has already negotiated
1099 * speeds with the targets.
1100 */
1101 i = mpt->mpt_port_page2.PortSettings &
1102 MPI_SCSIPORTPAGE2_PORT_MASK_NEGO_MASTER_SETTINGS;
1103 if (i == MPI_SCSIPORTPAGE2_PORT_ALL_MASTER_SETTINGS) {
1104 mpt_lprt(mpt, MPT_PRT_NEGOTIATION,
1105 "honoring BIOS transfer negotiations\n");
1106 } else {
1107 for (i = 0; i < 16; i++) {
1108 mpt->mpt_dev_page1[i].RequestedParameters = 0;
1109 mpt->mpt_dev_page1[i].Configuration = 0;
1110 (void) mpt_update_spi_config(mpt, i);
1111 }
1112 }
1113 return (0);
1114 }
1115
1116 static int
mpt_cam_enable(struct mpt_softc * mpt)1117 mpt_cam_enable(struct mpt_softc *mpt)
1118 {
1119 int error;
1120
1121 MPT_LOCK(mpt);
1122
1123 error = EIO;
1124 if (mpt->is_fc) {
1125 if (mpt_read_config_info_fc(mpt)) {
1126 goto out;
1127 }
1128 if (mpt_set_initial_config_fc(mpt)) {
1129 goto out;
1130 }
1131 } else if (mpt->is_sas) {
1132 if (mpt_read_config_info_sas(mpt)) {
1133 goto out;
1134 }
1135 if (mpt_set_initial_config_sas(mpt)) {
1136 goto out;
1137 }
1138 } else if (mpt->is_spi) {
1139 if (mpt_read_config_info_spi(mpt)) {
1140 goto out;
1141 }
1142 if (mpt_set_initial_config_spi(mpt)) {
1143 goto out;
1144 }
1145 }
1146 error = 0;
1147
1148 out:
1149 MPT_UNLOCK(mpt);
1150 return (error);
1151 }
1152
1153 static void
mpt_cam_ready(struct mpt_softc * mpt)1154 mpt_cam_ready(struct mpt_softc *mpt)
1155 {
1156
1157 /*
1158 * If we're in target mode, hang out resources now
1159 * so we don't cause the world to hang talking to us.
1160 */
1161 if (mpt->is_fc && (mpt->role & MPT_ROLE_TARGET)) {
1162 /*
1163 * Try to add some target command resources
1164 */
1165 MPT_LOCK(mpt);
1166 if (mpt_add_target_commands(mpt) == FALSE) {
1167 mpt_prt(mpt, "failed to add target commands\n");
1168 }
1169 MPT_UNLOCK(mpt);
1170 }
1171 mpt->ready = 1;
1172 }
1173
1174 static void
mpt_cam_detach(struct mpt_softc * mpt)1175 mpt_cam_detach(struct mpt_softc *mpt)
1176 {
1177 mpt_handler_t handler;
1178
1179 MPT_LOCK(mpt);
1180 mpt->ready = 0;
1181 mpt_terminate_recovery_thread(mpt);
1182
1183 handler.reply_handler = mpt_scsi_reply_handler;
1184 mpt_deregister_handler(mpt, MPT_HANDLER_REPLY, handler,
1185 scsi_io_handler_id);
1186 handler.reply_handler = mpt_scsi_tmf_reply_handler;
1187 mpt_deregister_handler(mpt, MPT_HANDLER_REPLY, handler,
1188 scsi_tmf_handler_id);
1189 handler.reply_handler = mpt_fc_els_reply_handler;
1190 mpt_deregister_handler(mpt, MPT_HANDLER_REPLY, handler,
1191 fc_els_handler_id);
1192 handler.reply_handler = mpt_scsi_tgt_reply_handler;
1193 mpt_deregister_handler(mpt, MPT_HANDLER_REPLY, handler,
1194 mpt->scsi_tgt_handler_id);
1195 handler.reply_handler = mpt_sata_pass_reply_handler;
1196 mpt_deregister_handler(mpt, MPT_HANDLER_REPLY, handler,
1197 sata_pass_handler_id);
1198
1199 if (mpt->tmf_req != NULL) {
1200 mpt->tmf_req->state = REQ_STATE_ALLOCATED;
1201 mpt_free_request(mpt, mpt->tmf_req);
1202 mpt->tmf_req = NULL;
1203 }
1204 if (mpt->sas_portinfo != NULL) {
1205 free(mpt->sas_portinfo, M_DEVBUF);
1206 mpt->sas_portinfo = NULL;
1207 }
1208
1209 if (mpt->sim != NULL) {
1210 xpt_free_path(mpt->path);
1211 xpt_bus_deregister(cam_sim_path(mpt->sim));
1212 cam_sim_free(mpt->sim, TRUE);
1213 mpt->sim = NULL;
1214 }
1215
1216 if (mpt->phydisk_sim != NULL) {
1217 xpt_free_path(mpt->phydisk_path);
1218 xpt_bus_deregister(cam_sim_path(mpt->phydisk_sim));
1219 cam_sim_free(mpt->phydisk_sim, TRUE);
1220 mpt->phydisk_sim = NULL;
1221 }
1222 MPT_UNLOCK(mpt);
1223 }
1224
1225 /* This routine is used after a system crash to dump core onto the swap device.
1226 */
1227 static void
mpt_poll(struct cam_sim * sim)1228 mpt_poll(struct cam_sim *sim)
1229 {
1230 struct mpt_softc *mpt;
1231
1232 mpt = (struct mpt_softc *)cam_sim_softc(sim);
1233 mpt_intr(mpt);
1234 }
1235
1236 /*
1237 * Watchdog timeout routine for SCSI requests.
1238 */
1239 static void
mpt_timeout(void * arg)1240 mpt_timeout(void *arg)
1241 {
1242 union ccb *ccb;
1243 struct mpt_softc *mpt;
1244 request_t *req;
1245
1246 ccb = (union ccb *)arg;
1247 mpt = ccb->ccb_h.ccb_mpt_ptr;
1248
1249 MPT_LOCK_ASSERT(mpt);
1250 req = ccb->ccb_h.ccb_req_ptr;
1251 mpt_prt(mpt, "request %p:%u timed out for ccb %p (req->ccb %p)\n", req,
1252 req->serno, ccb, req->ccb);
1253 /* XXX: WHAT ARE WE TRYING TO DO HERE? */
1254 if ((req->state & REQ_STATE_QUEUED) == REQ_STATE_QUEUED) {
1255 TAILQ_REMOVE(&mpt->request_pending_list, req, links);
1256 TAILQ_INSERT_TAIL(&mpt->request_timeout_list, req, links);
1257 req->state |= REQ_STATE_TIMEDOUT;
1258 mpt_wakeup_recovery_thread(mpt);
1259 }
1260 }
1261
1262 /*
1263 * Callback routine from bus_dmamap_load_ccb(9) or, in simple cases, called
1264 * directly.
1265 *
1266 * Takes a list of physical segments and builds the SGL for SCSI IO command
1267 * and forwards the commard to the IOC after one last check that CAM has not
1268 * aborted the transaction.
1269 */
1270 static void
mpt_execute_req_a64(void * arg,bus_dma_segment_t * dm_segs,int nseg,int error)1271 mpt_execute_req_a64(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
1272 {
1273 request_t *req, *trq;
1274 char *mpt_off;
1275 union ccb *ccb;
1276 struct mpt_softc *mpt;
1277 bus_addr_t chain_list_addr;
1278 int first_lim, seg, this_seg_lim;
1279 uint32_t addr, cur_off, flags, nxt_off, tf;
1280 void *sglp = NULL;
1281 MSG_REQUEST_HEADER *hdrp;
1282 SGE_SIMPLE64 *se;
1283 SGE_CHAIN64 *ce;
1284 int istgt = 0;
1285
1286 req = (request_t *)arg;
1287 ccb = req->ccb;
1288
1289 mpt = ccb->ccb_h.ccb_mpt_ptr;
1290 req = ccb->ccb_h.ccb_req_ptr;
1291
1292 hdrp = req->req_vbuf;
1293 mpt_off = req->req_vbuf;
1294
1295 if (error == 0) {
1296 switch (hdrp->Function) {
1297 case MPI_FUNCTION_SCSI_IO_REQUEST:
1298 case MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH:
1299 istgt = 0;
1300 sglp = &((PTR_MSG_SCSI_IO_REQUEST)hdrp)->SGL;
1301 break;
1302 case MPI_FUNCTION_TARGET_ASSIST:
1303 istgt = 1;
1304 sglp = &((PTR_MSG_TARGET_ASSIST_REQUEST)hdrp)->SGL;
1305 break;
1306 default:
1307 mpt_prt(mpt, "bad fct 0x%x in mpt_execute_req_a64\n",
1308 hdrp->Function);
1309 error = EINVAL;
1310 break;
1311 }
1312 }
1313
1314 bad:
1315 if (error != 0) {
1316 if (error != EFBIG && error != ENOMEM) {
1317 mpt_prt(mpt, "mpt_execute_req_a64: err %d\n", error);
1318 }
1319 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG) {
1320 cam_status status;
1321 mpt_freeze_ccb(ccb);
1322 if (error == EFBIG) {
1323 status = CAM_REQ_TOO_BIG;
1324 } else if (error == ENOMEM) {
1325 if (mpt->outofbeer == 0) {
1326 mpt->outofbeer = 1;
1327 xpt_freeze_simq(mpt->sim, 1);
1328 mpt_lprt(mpt, MPT_PRT_DEBUG,
1329 "FREEZEQ\n");
1330 }
1331 status = CAM_REQUEUE_REQ;
1332 } else {
1333 status = CAM_REQ_CMP_ERR;
1334 }
1335 mpt_set_ccb_status(ccb, status);
1336 }
1337 if (hdrp->Function == MPI_FUNCTION_TARGET_ASSIST) {
1338 request_t *cmd_req =
1339 MPT_TAG_2_REQ(mpt, ccb->csio.tag_id);
1340 MPT_TGT_STATE(mpt, cmd_req)->state = TGT_STATE_IN_CAM;
1341 MPT_TGT_STATE(mpt, cmd_req)->ccb = NULL;
1342 MPT_TGT_STATE(mpt, cmd_req)->req = NULL;
1343 }
1344 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
1345 KASSERT(ccb->ccb_h.status, ("zero ccb sts at %d", __LINE__));
1346 xpt_done(ccb);
1347 mpt_free_request(mpt, req);
1348 return;
1349 }
1350
1351 /*
1352 * No data to transfer?
1353 * Just make a single simple SGL with zero length.
1354 */
1355
1356 if (mpt->verbose >= MPT_PRT_DEBUG) {
1357 int tidx = ((char *)sglp) - mpt_off;
1358 memset(&mpt_off[tidx], 0xff, MPT_REQUEST_AREA - tidx);
1359 }
1360
1361 if (nseg == 0) {
1362 SGE_SIMPLE32 *se1 = (SGE_SIMPLE32 *) sglp;
1363 MPI_pSGE_SET_FLAGS(se1,
1364 (MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER |
1365 MPI_SGE_FLAGS_SIMPLE_ELEMENT | MPI_SGE_FLAGS_END_OF_LIST));
1366 se1->FlagsLength = htole32(se1->FlagsLength);
1367 goto out;
1368 }
1369
1370 flags = MPI_SGE_FLAGS_SIMPLE_ELEMENT | MPI_SGE_FLAGS_64_BIT_ADDRESSING;
1371 if (istgt == 0) {
1372 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) {
1373 flags |= MPI_SGE_FLAGS_HOST_TO_IOC;
1374 }
1375 } else {
1376 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
1377 flags |= MPI_SGE_FLAGS_HOST_TO_IOC;
1378 }
1379 }
1380
1381 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
1382 bus_dmasync_op_t op;
1383 if (istgt == 0) {
1384 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
1385 op = BUS_DMASYNC_PREREAD;
1386 } else {
1387 op = BUS_DMASYNC_PREWRITE;
1388 }
1389 } else {
1390 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
1391 op = BUS_DMASYNC_PREWRITE;
1392 } else {
1393 op = BUS_DMASYNC_PREREAD;
1394 }
1395 }
1396 bus_dmamap_sync(mpt->buffer_dmat, req->dmap, op);
1397 }
1398
1399 /*
1400 * Okay, fill in what we can at the end of the command frame.
1401 * If we have up to MPT_NSGL_FIRST, we can fit them all into
1402 * the command frame.
1403 *
1404 * Otherwise, we fill up through MPT_NSGL_FIRST less one
1405 * SIMPLE64 pointers and start doing CHAIN64 entries after
1406 * that.
1407 */
1408
1409 if (nseg < MPT_NSGL_FIRST(mpt)) {
1410 first_lim = nseg;
1411 } else {
1412 /*
1413 * Leave room for CHAIN element
1414 */
1415 first_lim = MPT_NSGL_FIRST(mpt) - 1;
1416 }
1417
1418 se = (SGE_SIMPLE64 *) sglp;
1419 for (seg = 0; seg < first_lim; seg++, se++, dm_segs++) {
1420 tf = flags;
1421 memset(se, 0, sizeof (*se));
1422 MPI_pSGE_SET_LENGTH(se, dm_segs->ds_len);
1423 se->Address.Low = htole32(dm_segs->ds_addr & 0xffffffff);
1424 if (sizeof(bus_addr_t) > 4) {
1425 addr = ((uint64_t)dm_segs->ds_addr) >> 32;
1426 /* SAS1078 36GB limitation WAR */
1427 if (mpt->is_1078 && (((uint64_t)dm_segs->ds_addr +
1428 MPI_SGE_LENGTH(se->FlagsLength)) >> 32) == 9) {
1429 addr |= (1U << 31);
1430 tf |= MPI_SGE_FLAGS_LOCAL_ADDRESS;
1431 }
1432 se->Address.High = htole32(addr);
1433 }
1434 if (seg == first_lim - 1) {
1435 tf |= MPI_SGE_FLAGS_LAST_ELEMENT;
1436 }
1437 if (seg == nseg - 1) {
1438 tf |= MPI_SGE_FLAGS_END_OF_LIST |
1439 MPI_SGE_FLAGS_END_OF_BUFFER;
1440 }
1441 MPI_pSGE_SET_FLAGS(se, tf);
1442 se->FlagsLength = htole32(se->FlagsLength);
1443 }
1444
1445 if (seg == nseg) {
1446 goto out;
1447 }
1448
1449 /*
1450 * Tell the IOC where to find the first chain element.
1451 */
1452 hdrp->ChainOffset = ((char *)se - (char *)hdrp) >> 2;
1453 nxt_off = MPT_RQSL(mpt);
1454 trq = req;
1455
1456 /*
1457 * Make up the rest of the data segments out of a chain element
1458 * (contained in the current request frame) which points to
1459 * SIMPLE64 elements in the next request frame, possibly ending
1460 * with *another* chain element (if there's more).
1461 */
1462 while (seg < nseg) {
1463 /*
1464 * Point to the chain descriptor. Note that the chain
1465 * descriptor is at the end of the *previous* list (whether
1466 * chain or simple).
1467 */
1468 ce = (SGE_CHAIN64 *) se;
1469
1470 /*
1471 * Before we change our current pointer, make sure we won't
1472 * overflow the request area with this frame. Note that we
1473 * test against 'greater than' here as it's okay in this case
1474 * to have next offset be just outside the request area.
1475 */
1476 if ((nxt_off + MPT_RQSL(mpt)) > MPT_REQUEST_AREA) {
1477 nxt_off = MPT_REQUEST_AREA;
1478 goto next_chain;
1479 }
1480
1481 /*
1482 * Set our SGE element pointer to the beginning of the chain
1483 * list and update our next chain list offset.
1484 */
1485 se = (SGE_SIMPLE64 *) &mpt_off[nxt_off];
1486 cur_off = nxt_off;
1487 nxt_off += MPT_RQSL(mpt);
1488
1489 /*
1490 * Now initialize the chain descriptor.
1491 */
1492 memset(ce, 0, sizeof (*ce));
1493
1494 /*
1495 * Get the physical address of the chain list.
1496 */
1497 chain_list_addr = trq->req_pbuf;
1498 chain_list_addr += cur_off;
1499 if (sizeof (bus_addr_t) > 4) {
1500 ce->Address.High =
1501 htole32(((uint64_t)chain_list_addr) >> 32);
1502 }
1503 ce->Address.Low = htole32(chain_list_addr & 0xffffffff);
1504 ce->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT |
1505 MPI_SGE_FLAGS_64_BIT_ADDRESSING;
1506
1507 /*
1508 * If we have more than a frame's worth of segments left,
1509 * set up the chain list to have the last element be another
1510 * chain descriptor.
1511 */
1512 if ((nseg - seg) > MPT_NSGL(mpt)) {
1513 this_seg_lim = seg + MPT_NSGL(mpt) - 1;
1514 /*
1515 * The length of the chain is the length in bytes of the
1516 * number of segments plus the next chain element.
1517 *
1518 * The next chain descriptor offset is the length,
1519 * in words, of the number of segments.
1520 */
1521 ce->Length = (this_seg_lim - seg) *
1522 sizeof (SGE_SIMPLE64);
1523 ce->NextChainOffset = ce->Length >> 2;
1524 ce->Length += sizeof (SGE_CHAIN64);
1525 } else {
1526 this_seg_lim = nseg;
1527 ce->Length = (this_seg_lim - seg) *
1528 sizeof (SGE_SIMPLE64);
1529 }
1530 ce->Length = htole16(ce->Length);
1531
1532 /*
1533 * Fill in the chain list SGE elements with our segment data.
1534 *
1535 * If we're the last element in this chain list, set the last
1536 * element flag. If we're the completely last element period,
1537 * set the end of list and end of buffer flags.
1538 */
1539 while (seg < this_seg_lim) {
1540 tf = flags;
1541 memset(se, 0, sizeof (*se));
1542 MPI_pSGE_SET_LENGTH(se, dm_segs->ds_len);
1543 se->Address.Low = htole32(dm_segs->ds_addr &
1544 0xffffffff);
1545 if (sizeof (bus_addr_t) > 4) {
1546 addr = ((uint64_t)dm_segs->ds_addr) >> 32;
1547 /* SAS1078 36GB limitation WAR */
1548 if (mpt->is_1078 &&
1549 (((uint64_t)dm_segs->ds_addr +
1550 MPI_SGE_LENGTH(se->FlagsLength)) >>
1551 32) == 9) {
1552 addr |= (1U << 31);
1553 tf |= MPI_SGE_FLAGS_LOCAL_ADDRESS;
1554 }
1555 se->Address.High = htole32(addr);
1556 }
1557 if (seg == this_seg_lim - 1) {
1558 tf |= MPI_SGE_FLAGS_LAST_ELEMENT;
1559 }
1560 if (seg == nseg - 1) {
1561 tf |= MPI_SGE_FLAGS_END_OF_LIST |
1562 MPI_SGE_FLAGS_END_OF_BUFFER;
1563 }
1564 MPI_pSGE_SET_FLAGS(se, tf);
1565 se->FlagsLength = htole32(se->FlagsLength);
1566 se++;
1567 seg++;
1568 dm_segs++;
1569 }
1570
1571 next_chain:
1572 /*
1573 * If we have more segments to do and we've used up all of
1574 * the space in a request area, go allocate another one
1575 * and chain to that.
1576 */
1577 if (seg < nseg && nxt_off >= MPT_REQUEST_AREA) {
1578 request_t *nrq;
1579
1580 nrq = mpt_get_request(mpt, FALSE);
1581
1582 if (nrq == NULL) {
1583 error = ENOMEM;
1584 goto bad;
1585 }
1586
1587 /*
1588 * Append the new request area on the tail of our list.
1589 */
1590 if ((trq = req->chain) == NULL) {
1591 req->chain = nrq;
1592 } else {
1593 while (trq->chain != NULL) {
1594 trq = trq->chain;
1595 }
1596 trq->chain = nrq;
1597 }
1598 trq = nrq;
1599 mpt_off = trq->req_vbuf;
1600 if (mpt->verbose >= MPT_PRT_DEBUG) {
1601 memset(mpt_off, 0xff, MPT_REQUEST_AREA);
1602 }
1603 nxt_off = 0;
1604 }
1605 }
1606 out:
1607
1608 /*
1609 * Last time we need to check if this CCB needs to be aborted.
1610 */
1611 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_INPROG) {
1612 if (hdrp->Function == MPI_FUNCTION_TARGET_ASSIST) {
1613 request_t *cmd_req =
1614 MPT_TAG_2_REQ(mpt, ccb->csio.tag_id);
1615 MPT_TGT_STATE(mpt, cmd_req)->state = TGT_STATE_IN_CAM;
1616 MPT_TGT_STATE(mpt, cmd_req)->ccb = NULL;
1617 MPT_TGT_STATE(mpt, cmd_req)->req = NULL;
1618 }
1619 mpt_prt(mpt,
1620 "mpt_execute_req_a64: I/O cancelled (status 0x%x)\n",
1621 ccb->ccb_h.status & CAM_STATUS_MASK);
1622 if (nseg) {
1623 bus_dmamap_unload(mpt->buffer_dmat, req->dmap);
1624 }
1625 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
1626 KASSERT(ccb->ccb_h.status, ("zero ccb sts at %d", __LINE__));
1627 xpt_done(ccb);
1628 mpt_free_request(mpt, req);
1629 return;
1630 }
1631
1632 ccb->ccb_h.status |= CAM_SIM_QUEUED;
1633 if (ccb->ccb_h.timeout != CAM_TIME_INFINITY) {
1634 mpt_req_timeout(req, SBT_1MS * ccb->ccb_h.timeout,
1635 mpt_timeout, ccb);
1636 }
1637 if (mpt->verbose > MPT_PRT_DEBUG) {
1638 int nc = 0;
1639 mpt_print_request(req->req_vbuf);
1640 for (trq = req->chain; trq; trq = trq->chain) {
1641 printf(" Additional Chain Area %d\n", nc++);
1642 mpt_dump_sgl(trq->req_vbuf, 0);
1643 }
1644 }
1645
1646 if (hdrp->Function == MPI_FUNCTION_TARGET_ASSIST) {
1647 request_t *cmd_req = MPT_TAG_2_REQ(mpt, ccb->csio.tag_id);
1648 mpt_tgt_state_t *tgt = MPT_TGT_STATE(mpt, cmd_req);
1649 #ifdef WE_TRUST_AUTO_GOOD_STATUS
1650 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) &&
1651 csio->scsi_status == SCSI_STATUS_OK && tgt->resid == 0) {
1652 tgt->state = TGT_STATE_MOVING_DATA_AND_STATUS;
1653 } else {
1654 tgt->state = TGT_STATE_MOVING_DATA;
1655 }
1656 #else
1657 tgt->state = TGT_STATE_MOVING_DATA;
1658 #endif
1659 }
1660 mpt_send_cmd(mpt, req);
1661 }
1662
1663 static void
mpt_execute_req(void * arg,bus_dma_segment_t * dm_segs,int nseg,int error)1664 mpt_execute_req(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
1665 {
1666 request_t *req, *trq;
1667 char *mpt_off;
1668 union ccb *ccb;
1669 struct mpt_softc *mpt;
1670 int seg, first_lim;
1671 uint32_t flags, nxt_off;
1672 void *sglp = NULL;
1673 MSG_REQUEST_HEADER *hdrp;
1674 SGE_SIMPLE32 *se;
1675 SGE_CHAIN32 *ce;
1676 int istgt = 0;
1677
1678 req = (request_t *)arg;
1679 ccb = req->ccb;
1680
1681 mpt = ccb->ccb_h.ccb_mpt_ptr;
1682 req = ccb->ccb_h.ccb_req_ptr;
1683
1684 hdrp = req->req_vbuf;
1685 mpt_off = req->req_vbuf;
1686
1687 if (error == 0) {
1688 switch (hdrp->Function) {
1689 case MPI_FUNCTION_SCSI_IO_REQUEST:
1690 case MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH:
1691 sglp = &((PTR_MSG_SCSI_IO_REQUEST)hdrp)->SGL;
1692 break;
1693 case MPI_FUNCTION_TARGET_ASSIST:
1694 istgt = 1;
1695 sglp = &((PTR_MSG_TARGET_ASSIST_REQUEST)hdrp)->SGL;
1696 break;
1697 default:
1698 mpt_prt(mpt, "bad fct 0x%x in mpt_execute_req\n",
1699 hdrp->Function);
1700 error = EINVAL;
1701 break;
1702 }
1703 }
1704
1705 bad:
1706 if (error != 0) {
1707 if (error != EFBIG && error != ENOMEM) {
1708 mpt_prt(mpt, "mpt_execute_req: err %d\n", error);
1709 }
1710 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG) {
1711 cam_status status;
1712 mpt_freeze_ccb(ccb);
1713 if (error == EFBIG) {
1714 status = CAM_REQ_TOO_BIG;
1715 } else if (error == ENOMEM) {
1716 if (mpt->outofbeer == 0) {
1717 mpt->outofbeer = 1;
1718 xpt_freeze_simq(mpt->sim, 1);
1719 mpt_lprt(mpt, MPT_PRT_DEBUG,
1720 "FREEZEQ\n");
1721 }
1722 status = CAM_REQUEUE_REQ;
1723 } else {
1724 status = CAM_REQ_CMP_ERR;
1725 }
1726 mpt_set_ccb_status(ccb, status);
1727 }
1728 if (hdrp->Function == MPI_FUNCTION_TARGET_ASSIST) {
1729 request_t *cmd_req =
1730 MPT_TAG_2_REQ(mpt, ccb->csio.tag_id);
1731 MPT_TGT_STATE(mpt, cmd_req)->state = TGT_STATE_IN_CAM;
1732 MPT_TGT_STATE(mpt, cmd_req)->ccb = NULL;
1733 MPT_TGT_STATE(mpt, cmd_req)->req = NULL;
1734 }
1735 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
1736 KASSERT(ccb->ccb_h.status, ("zero ccb sts at %d", __LINE__));
1737 xpt_done(ccb);
1738 mpt_free_request(mpt, req);
1739 return;
1740 }
1741
1742 /*
1743 * No data to transfer?
1744 * Just make a single simple SGL with zero length.
1745 */
1746
1747 if (mpt->verbose >= MPT_PRT_DEBUG) {
1748 int tidx = ((char *)sglp) - mpt_off;
1749 memset(&mpt_off[tidx], 0xff, MPT_REQUEST_AREA - tidx);
1750 }
1751
1752 if (nseg == 0) {
1753 SGE_SIMPLE32 *se1 = (SGE_SIMPLE32 *) sglp;
1754 MPI_pSGE_SET_FLAGS(se1,
1755 (MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER |
1756 MPI_SGE_FLAGS_SIMPLE_ELEMENT | MPI_SGE_FLAGS_END_OF_LIST));
1757 se1->FlagsLength = htole32(se1->FlagsLength);
1758 goto out;
1759 }
1760
1761 flags = MPI_SGE_FLAGS_SIMPLE_ELEMENT;
1762 if (istgt == 0) {
1763 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) {
1764 flags |= MPI_SGE_FLAGS_HOST_TO_IOC;
1765 }
1766 } else {
1767 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
1768 flags |= MPI_SGE_FLAGS_HOST_TO_IOC;
1769 }
1770 }
1771
1772 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
1773 bus_dmasync_op_t op;
1774 if (istgt) {
1775 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
1776 op = BUS_DMASYNC_PREREAD;
1777 } else {
1778 op = BUS_DMASYNC_PREWRITE;
1779 }
1780 } else {
1781 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
1782 op = BUS_DMASYNC_PREWRITE;
1783 } else {
1784 op = BUS_DMASYNC_PREREAD;
1785 }
1786 }
1787 bus_dmamap_sync(mpt->buffer_dmat, req->dmap, op);
1788 }
1789
1790 /*
1791 * Okay, fill in what we can at the end of the command frame.
1792 * If we have up to MPT_NSGL_FIRST, we can fit them all into
1793 * the command frame.
1794 *
1795 * Otherwise, we fill up through MPT_NSGL_FIRST less one
1796 * SIMPLE32 pointers and start doing CHAIN32 entries after
1797 * that.
1798 */
1799
1800 if (nseg < MPT_NSGL_FIRST(mpt)) {
1801 first_lim = nseg;
1802 } else {
1803 /*
1804 * Leave room for CHAIN element
1805 */
1806 first_lim = MPT_NSGL_FIRST(mpt) - 1;
1807 }
1808
1809 se = (SGE_SIMPLE32 *) sglp;
1810 for (seg = 0; seg < first_lim; seg++, se++, dm_segs++) {
1811 uint32_t tf;
1812
1813 memset(se, 0,sizeof (*se));
1814 se->Address = htole32(dm_segs->ds_addr);
1815
1816 MPI_pSGE_SET_LENGTH(se, dm_segs->ds_len);
1817 tf = flags;
1818 if (seg == first_lim - 1) {
1819 tf |= MPI_SGE_FLAGS_LAST_ELEMENT;
1820 }
1821 if (seg == nseg - 1) {
1822 tf |= MPI_SGE_FLAGS_END_OF_LIST |
1823 MPI_SGE_FLAGS_END_OF_BUFFER;
1824 }
1825 MPI_pSGE_SET_FLAGS(se, tf);
1826 se->FlagsLength = htole32(se->FlagsLength);
1827 }
1828
1829 if (seg == nseg) {
1830 goto out;
1831 }
1832
1833 /*
1834 * Tell the IOC where to find the first chain element.
1835 */
1836 hdrp->ChainOffset = ((char *)se - (char *)hdrp) >> 2;
1837 nxt_off = MPT_RQSL(mpt);
1838 trq = req;
1839
1840 /*
1841 * Make up the rest of the data segments out of a chain element
1842 * (contained in the current request frame) which points to
1843 * SIMPLE32 elements in the next request frame, possibly ending
1844 * with *another* chain element (if there's more).
1845 */
1846 while (seg < nseg) {
1847 int this_seg_lim;
1848 uint32_t tf, cur_off;
1849 bus_addr_t chain_list_addr;
1850
1851 /*
1852 * Point to the chain descriptor. Note that the chain
1853 * descriptor is at the end of the *previous* list (whether
1854 * chain or simple).
1855 */
1856 ce = (SGE_CHAIN32 *) se;
1857
1858 /*
1859 * Before we change our current pointer, make sure we won't
1860 * overflow the request area with this frame. Note that we
1861 * test against 'greater than' here as it's okay in this case
1862 * to have next offset be just outside the request area.
1863 */
1864 if ((nxt_off + MPT_RQSL(mpt)) > MPT_REQUEST_AREA) {
1865 nxt_off = MPT_REQUEST_AREA;
1866 goto next_chain;
1867 }
1868
1869 /*
1870 * Set our SGE element pointer to the beginning of the chain
1871 * list and update our next chain list offset.
1872 */
1873 se = (SGE_SIMPLE32 *) &mpt_off[nxt_off];
1874 cur_off = nxt_off;
1875 nxt_off += MPT_RQSL(mpt);
1876
1877 /*
1878 * Now initialize the chain descriptor.
1879 */
1880 memset(ce, 0, sizeof (*ce));
1881
1882 /*
1883 * Get the physical address of the chain list.
1884 */
1885 chain_list_addr = trq->req_pbuf;
1886 chain_list_addr += cur_off;
1887
1888 ce->Address = htole32(chain_list_addr);
1889 ce->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT;
1890
1891 /*
1892 * If we have more than a frame's worth of segments left,
1893 * set up the chain list to have the last element be another
1894 * chain descriptor.
1895 */
1896 if ((nseg - seg) > MPT_NSGL(mpt)) {
1897 this_seg_lim = seg + MPT_NSGL(mpt) - 1;
1898 /*
1899 * The length of the chain is the length in bytes of the
1900 * number of segments plus the next chain element.
1901 *
1902 * The next chain descriptor offset is the length,
1903 * in words, of the number of segments.
1904 */
1905 ce->Length = (this_seg_lim - seg) *
1906 sizeof (SGE_SIMPLE32);
1907 ce->NextChainOffset = ce->Length >> 2;
1908 ce->Length += sizeof (SGE_CHAIN32);
1909 } else {
1910 this_seg_lim = nseg;
1911 ce->Length = (this_seg_lim - seg) *
1912 sizeof (SGE_SIMPLE32);
1913 }
1914 ce->Length = htole16(ce->Length);
1915
1916 /*
1917 * Fill in the chain list SGE elements with our segment data.
1918 *
1919 * If we're the last element in this chain list, set the last
1920 * element flag. If we're the completely last element period,
1921 * set the end of list and end of buffer flags.
1922 */
1923 while (seg < this_seg_lim) {
1924 memset(se, 0, sizeof (*se));
1925 se->Address = htole32(dm_segs->ds_addr);
1926
1927 MPI_pSGE_SET_LENGTH(se, dm_segs->ds_len);
1928 tf = flags;
1929 if (seg == this_seg_lim - 1) {
1930 tf |= MPI_SGE_FLAGS_LAST_ELEMENT;
1931 }
1932 if (seg == nseg - 1) {
1933 tf |= MPI_SGE_FLAGS_END_OF_LIST |
1934 MPI_SGE_FLAGS_END_OF_BUFFER;
1935 }
1936 MPI_pSGE_SET_FLAGS(se, tf);
1937 se->FlagsLength = htole32(se->FlagsLength);
1938 se++;
1939 seg++;
1940 dm_segs++;
1941 }
1942
1943 next_chain:
1944 /*
1945 * If we have more segments to do and we've used up all of
1946 * the space in a request area, go allocate another one
1947 * and chain to that.
1948 */
1949 if (seg < nseg && nxt_off >= MPT_REQUEST_AREA) {
1950 request_t *nrq;
1951
1952 nrq = mpt_get_request(mpt, FALSE);
1953
1954 if (nrq == NULL) {
1955 error = ENOMEM;
1956 goto bad;
1957 }
1958
1959 /*
1960 * Append the new request area on the tail of our list.
1961 */
1962 if ((trq = req->chain) == NULL) {
1963 req->chain = nrq;
1964 } else {
1965 while (trq->chain != NULL) {
1966 trq = trq->chain;
1967 }
1968 trq->chain = nrq;
1969 }
1970 trq = nrq;
1971 mpt_off = trq->req_vbuf;
1972 if (mpt->verbose >= MPT_PRT_DEBUG) {
1973 memset(mpt_off, 0xff, MPT_REQUEST_AREA);
1974 }
1975 nxt_off = 0;
1976 }
1977 }
1978 out:
1979
1980 /*
1981 * Last time we need to check if this CCB needs to be aborted.
1982 */
1983 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_INPROG) {
1984 if (hdrp->Function == MPI_FUNCTION_TARGET_ASSIST) {
1985 request_t *cmd_req =
1986 MPT_TAG_2_REQ(mpt, ccb->csio.tag_id);
1987 MPT_TGT_STATE(mpt, cmd_req)->state = TGT_STATE_IN_CAM;
1988 MPT_TGT_STATE(mpt, cmd_req)->ccb = NULL;
1989 MPT_TGT_STATE(mpt, cmd_req)->req = NULL;
1990 }
1991 mpt_prt(mpt,
1992 "mpt_execute_req: I/O cancelled (status 0x%x)\n",
1993 ccb->ccb_h.status & CAM_STATUS_MASK);
1994 if (nseg) {
1995 bus_dmamap_unload(mpt->buffer_dmat, req->dmap);
1996 }
1997 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
1998 KASSERT(ccb->ccb_h.status, ("zero ccb sts at %d", __LINE__));
1999 xpt_done(ccb);
2000 mpt_free_request(mpt, req);
2001 return;
2002 }
2003
2004 ccb->ccb_h.status |= CAM_SIM_QUEUED;
2005 if (ccb->ccb_h.timeout != CAM_TIME_INFINITY) {
2006 mpt_req_timeout(req, SBT_1MS * ccb->ccb_h.timeout,
2007 mpt_timeout, ccb);
2008 }
2009 if (mpt->verbose > MPT_PRT_DEBUG) {
2010 int nc = 0;
2011 mpt_print_request(req->req_vbuf);
2012 for (trq = req->chain; trq; trq = trq->chain) {
2013 printf(" Additional Chain Area %d\n", nc++);
2014 mpt_dump_sgl(trq->req_vbuf, 0);
2015 }
2016 }
2017
2018 if (hdrp->Function == MPI_FUNCTION_TARGET_ASSIST) {
2019 request_t *cmd_req = MPT_TAG_2_REQ(mpt, ccb->csio.tag_id);
2020 mpt_tgt_state_t *tgt = MPT_TGT_STATE(mpt, cmd_req);
2021 #ifdef WE_TRUST_AUTO_GOOD_STATUS
2022 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) &&
2023 csio->scsi_status == SCSI_STATUS_OK && tgt->resid == 0) {
2024 tgt->state = TGT_STATE_MOVING_DATA_AND_STATUS;
2025 } else {
2026 tgt->state = TGT_STATE_MOVING_DATA;
2027 }
2028 #else
2029 tgt->state = TGT_STATE_MOVING_DATA;
2030 #endif
2031 }
2032 mpt_send_cmd(mpt, req);
2033 }
2034
2035 static void
mpt_start(struct cam_sim * sim,union ccb * ccb)2036 mpt_start(struct cam_sim *sim, union ccb *ccb)
2037 {
2038 request_t *req;
2039 struct mpt_softc *mpt;
2040 MSG_SCSI_IO_REQUEST *mpt_req;
2041 struct ccb_scsiio *csio = &ccb->csio;
2042 struct ccb_hdr *ccbh = &ccb->ccb_h;
2043 bus_dmamap_callback_t *cb;
2044 target_id_t tgt;
2045 int raid_passthru;
2046 int error;
2047
2048 /* Get the pointer for the physical addapter */
2049 mpt = ccb->ccb_h.ccb_mpt_ptr;
2050 raid_passthru = (sim == mpt->phydisk_sim);
2051
2052 if ((req = mpt_get_request(mpt, FALSE)) == NULL) {
2053 if (mpt->outofbeer == 0) {
2054 mpt->outofbeer = 1;
2055 xpt_freeze_simq(mpt->sim, 1);
2056 mpt_lprt(mpt, MPT_PRT_DEBUG, "FREEZEQ\n");
2057 }
2058 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
2059 mpt_set_ccb_status(ccb, CAM_REQUEUE_REQ);
2060 xpt_done(ccb);
2061 return;
2062 }
2063 #ifdef INVARIANTS
2064 mpt_req_not_spcl(mpt, req, "mpt_start", __LINE__);
2065 #endif
2066
2067 if (sizeof (bus_addr_t) > 4) {
2068 cb = mpt_execute_req_a64;
2069 } else {
2070 cb = mpt_execute_req;
2071 }
2072
2073 /*
2074 * Link the ccb and the request structure so we can find
2075 * the other knowing either the request or the ccb
2076 */
2077 req->ccb = ccb;
2078 ccb->ccb_h.ccb_req_ptr = req;
2079
2080 /* Now we build the command for the IOC */
2081 mpt_req = req->req_vbuf;
2082 memset(mpt_req, 0, sizeof (MSG_SCSI_IO_REQUEST));
2083
2084 mpt_req->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
2085 if (raid_passthru) {
2086 mpt_req->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
2087 if (mpt_map_physdisk(mpt, ccb, &tgt) != 0) {
2088 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
2089 mpt_set_ccb_status(ccb, CAM_DEV_NOT_THERE);
2090 xpt_done(ccb);
2091 return;
2092 }
2093 mpt_req->Bus = 0; /* we never set bus here */
2094 } else {
2095 tgt = ccb->ccb_h.target_id;
2096 mpt_req->Bus = 0; /* XXX */
2097
2098 }
2099 mpt_req->SenseBufferLength =
2100 (csio->sense_len < MPT_SENSE_SIZE) ?
2101 csio->sense_len : MPT_SENSE_SIZE;
2102
2103 /*
2104 * We use the message context to find the request structure when we
2105 * Get the command completion interrupt from the IOC.
2106 */
2107 mpt_req->MsgContext = htole32(req->index | scsi_io_handler_id);
2108
2109 /* Which physical device to do the I/O on */
2110 mpt_req->TargetID = tgt;
2111
2112 be64enc(mpt_req->LUN, CAM_EXTLUN_BYTE_SWIZZLE(ccb->ccb_h.target_lun));
2113
2114 /* Set the direction of the transfer */
2115 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
2116 mpt_req->Control = MPI_SCSIIO_CONTROL_READ;
2117 } else if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) {
2118 mpt_req->Control = MPI_SCSIIO_CONTROL_WRITE;
2119 } else {
2120 mpt_req->Control = MPI_SCSIIO_CONTROL_NODATATRANSFER;
2121 }
2122
2123 if ((ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) != 0) {
2124 switch(ccb->csio.tag_action) {
2125 case MSG_HEAD_OF_Q_TAG:
2126 mpt_req->Control |= MPI_SCSIIO_CONTROL_HEADOFQ;
2127 break;
2128 case MSG_ACA_TASK:
2129 mpt_req->Control |= MPI_SCSIIO_CONTROL_ACAQ;
2130 break;
2131 case MSG_ORDERED_Q_TAG:
2132 mpt_req->Control |= MPI_SCSIIO_CONTROL_ORDEREDQ;
2133 break;
2134 case MSG_SIMPLE_Q_TAG:
2135 default:
2136 mpt_req->Control |= MPI_SCSIIO_CONTROL_SIMPLEQ;
2137 break;
2138 }
2139 } else {
2140 if (mpt->is_fc || mpt->is_sas) {
2141 mpt_req->Control |= MPI_SCSIIO_CONTROL_SIMPLEQ;
2142 } else {
2143 /* XXX No such thing for a target doing packetized. */
2144 mpt_req->Control |= MPI_SCSIIO_CONTROL_UNTAGGED;
2145 }
2146 }
2147
2148 if (mpt->is_spi) {
2149 if (ccb->ccb_h.flags & CAM_DIS_DISCONNECT) {
2150 mpt_req->Control |= MPI_SCSIIO_CONTROL_NO_DISCONNECT;
2151 }
2152 }
2153 mpt_req->Control = htole32(mpt_req->Control);
2154
2155 /* Copy the scsi command block into place */
2156 if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) {
2157 bcopy(csio->cdb_io.cdb_ptr, mpt_req->CDB, csio->cdb_len);
2158 } else {
2159 bcopy(csio->cdb_io.cdb_bytes, mpt_req->CDB, csio->cdb_len);
2160 }
2161
2162 mpt_req->CDBLength = csio->cdb_len;
2163 mpt_req->DataLength = htole32(csio->dxfer_len);
2164 mpt_req->SenseBufferLowAddr = htole32(req->sense_pbuf);
2165
2166 /*
2167 * Do a *short* print here if we're set to MPT_PRT_DEBUG
2168 */
2169 if (mpt->verbose == MPT_PRT_DEBUG) {
2170 U32 df;
2171 mpt_prt(mpt, "mpt_start: %s op 0x%x ",
2172 (mpt_req->Function == MPI_FUNCTION_SCSI_IO_REQUEST)?
2173 "SCSI_IO_REQUEST" : "SCSI_IO_PASSTHRU", mpt_req->CDB[0]);
2174 df = mpt_req->Control & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK;
2175 if (df != MPI_SCSIIO_CONTROL_NODATATRANSFER) {
2176 mpt_prtc(mpt, "(%s %u byte%s ",
2177 (df == MPI_SCSIIO_CONTROL_READ)?
2178 "read" : "write", csio->dxfer_len,
2179 (csio->dxfer_len == 1)? ")" : "s)");
2180 }
2181 mpt_prtc(mpt, "tgt %u lun %jx req %p:%u\n", tgt,
2182 (uintmax_t)ccb->ccb_h.target_lun, req, req->serno);
2183 }
2184
2185 error = bus_dmamap_load_ccb(mpt->buffer_dmat, req->dmap, ccb, cb,
2186 req, 0);
2187 if (error == EINPROGRESS) {
2188 /*
2189 * So as to maintain ordering, freeze the controller queue
2190 * until our mapping is returned.
2191 */
2192 xpt_freeze_simq(mpt->sim, 1);
2193 ccbh->status |= CAM_RELEASE_SIMQ;
2194 }
2195 }
2196
2197 static int
mpt_bus_reset(struct mpt_softc * mpt,target_id_t tgt,lun_id_t lun,int sleep_ok)2198 mpt_bus_reset(struct mpt_softc *mpt, target_id_t tgt, lun_id_t lun,
2199 int sleep_ok)
2200 {
2201 int error;
2202 uint16_t status;
2203 uint8_t response;
2204
2205 error = mpt_scsi_send_tmf(mpt,
2206 (tgt != CAM_TARGET_WILDCARD || lun != CAM_LUN_WILDCARD) ?
2207 MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET :
2208 MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
2209 mpt->is_fc ? MPI_SCSITASKMGMT_MSGFLAGS_LIP_RESET_OPTION : 0,
2210 0, /* XXX How do I get the channel ID? */
2211 tgt != CAM_TARGET_WILDCARD ? tgt : 0,
2212 lun != CAM_LUN_WILDCARD ? lun : 0,
2213 0, sleep_ok);
2214
2215 if (error != 0) {
2216 /*
2217 * mpt_scsi_send_tmf hard resets on failure, so no
2218 * need to do so here.
2219 */
2220 mpt_prt(mpt,
2221 "mpt_bus_reset: mpt_scsi_send_tmf returned %d\n", error);
2222 return (EIO);
2223 }
2224
2225 /* Wait for bus reset to be processed by the IOC. */
2226 error = mpt_wait_req(mpt, mpt->tmf_req, REQ_STATE_DONE,
2227 REQ_STATE_DONE, sleep_ok, 5000);
2228
2229 status = le16toh(mpt->tmf_req->IOCStatus);
2230 response = mpt->tmf_req->ResponseCode;
2231 mpt->tmf_req->state = REQ_STATE_FREE;
2232
2233 if (error) {
2234 mpt_prt(mpt, "mpt_bus_reset: Reset timed-out. "
2235 "Resetting controller.\n");
2236 mpt_reset(mpt, TRUE);
2237 return (ETIMEDOUT);
2238 }
2239
2240 if ((status & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
2241 mpt_prt(mpt, "mpt_bus_reset: TMF IOC Status 0x%x. "
2242 "Resetting controller.\n", status);
2243 mpt_reset(mpt, TRUE);
2244 return (EIO);
2245 }
2246
2247 if (response != MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED &&
2248 response != MPI_SCSITASKMGMT_RSP_TM_COMPLETE) {
2249 mpt_prt(mpt, "mpt_bus_reset: TMF Response 0x%x. "
2250 "Resetting controller.\n", response);
2251 mpt_reset(mpt, TRUE);
2252 return (EIO);
2253 }
2254 return (0);
2255 }
2256
2257 static int
mpt_fc_reset_link(struct mpt_softc * mpt,int dowait)2258 mpt_fc_reset_link(struct mpt_softc *mpt, int dowait)
2259 {
2260 int r = 0;
2261 request_t *req;
2262 PTR_MSG_FC_PRIMITIVE_SEND_REQUEST fc;
2263
2264 req = mpt_get_request(mpt, FALSE);
2265 if (req == NULL) {
2266 return (ENOMEM);
2267 }
2268 fc = req->req_vbuf;
2269 memset(fc, 0, sizeof(*fc));
2270 fc->SendFlags = MPI_FC_PRIM_SEND_FLAGS_RESET_LINK;
2271 fc->Function = MPI_FUNCTION_FC_PRIMITIVE_SEND;
2272 fc->MsgContext = htole32(req->index | fc_els_handler_id);
2273 mpt_send_cmd(mpt, req);
2274 if (dowait) {
2275 r = mpt_wait_req(mpt, req, REQ_STATE_DONE,
2276 REQ_STATE_DONE, FALSE, 60 * 1000);
2277 if (r == 0) {
2278 mpt_free_request(mpt, req);
2279 }
2280 }
2281 return (r);
2282 }
2283
2284 static int
mpt_cam_event(struct mpt_softc * mpt,request_t * req,MSG_EVENT_NOTIFY_REPLY * msg)2285 mpt_cam_event(struct mpt_softc *mpt, request_t *req,
2286 MSG_EVENT_NOTIFY_REPLY *msg)
2287 {
2288 uint32_t data0, data1;
2289
2290 data0 = le32toh(msg->Data[0]);
2291 data1 = le32toh(msg->Data[1]);
2292 switch(msg->Event & 0xFF) {
2293 case MPI_EVENT_UNIT_ATTENTION:
2294 mpt_prt(mpt, "UNIT ATTENTION: Bus: 0x%02x TargetID: 0x%02x\n",
2295 (data0 >> 8) & 0xff, data0 & 0xff);
2296 break;
2297
2298 case MPI_EVENT_IOC_BUS_RESET:
2299 /* We generated a bus reset */
2300 mpt_prt(mpt, "IOC Generated Bus Reset Port: %d\n",
2301 (data0 >> 8) & 0xff);
2302 xpt_async(AC_BUS_RESET, mpt->path, NULL);
2303 break;
2304
2305 case MPI_EVENT_EXT_BUS_RESET:
2306 /* Someone else generated a bus reset */
2307 mpt_prt(mpt, "External Bus Reset Detected\n");
2308 /*
2309 * These replies don't return EventData like the MPI
2310 * spec says they do
2311 */
2312 xpt_async(AC_BUS_RESET, mpt->path, NULL);
2313 break;
2314
2315 case MPI_EVENT_RESCAN:
2316 {
2317 union ccb *ccb;
2318 uint32_t pathid;
2319 /*
2320 * In general this means a device has been added to the loop.
2321 */
2322 mpt_prt(mpt, "Rescan Port: %d\n", (data0 >> 8) & 0xff);
2323 if (mpt->ready == 0) {
2324 break;
2325 }
2326 if (mpt->phydisk_sim) {
2327 pathid = cam_sim_path(mpt->phydisk_sim);
2328 } else {
2329 pathid = cam_sim_path(mpt->sim);
2330 }
2331 /*
2332 * Allocate a CCB, create a wildcard path for this bus,
2333 * and schedule a rescan.
2334 */
2335 ccb = xpt_alloc_ccb_nowait();
2336 if (ccb == NULL) {
2337 mpt_prt(mpt, "unable to alloc CCB for rescan\n");
2338 break;
2339 }
2340
2341 if (xpt_create_path(&ccb->ccb_h.path, NULL, pathid,
2342 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
2343 mpt_prt(mpt, "unable to create path for rescan\n");
2344 xpt_free_ccb(ccb);
2345 break;
2346 }
2347 xpt_rescan(ccb);
2348 break;
2349 }
2350
2351 case MPI_EVENT_LINK_STATUS_CHANGE:
2352 mpt_prt(mpt, "Port %d: LinkState: %s\n",
2353 (data1 >> 8) & 0xff,
2354 ((data0 & 0xff) == 0)? "Failed" : "Active");
2355 break;
2356
2357 case MPI_EVENT_LOOP_STATE_CHANGE:
2358 switch ((data0 >> 16) & 0xff) {
2359 case 0x01:
2360 mpt_prt(mpt,
2361 "Port 0x%x: FC LinkEvent: LIP(%02x,%02x) "
2362 "(Loop Initialization)\n",
2363 (data1 >> 8) & 0xff,
2364 (data0 >> 8) & 0xff,
2365 (data0 ) & 0xff);
2366 switch ((data0 >> 8) & 0xff) {
2367 case 0xF7:
2368 if ((data0 & 0xff) == 0xF7) {
2369 mpt_prt(mpt, "Device needs AL_PA\n");
2370 } else {
2371 mpt_prt(mpt, "Device %02x doesn't like "
2372 "FC performance\n",
2373 data0 & 0xFF);
2374 }
2375 break;
2376 case 0xF8:
2377 if ((data0 & 0xff) == 0xF7) {
2378 mpt_prt(mpt, "Device had loop failure "
2379 "at its receiver prior to acquiring"
2380 " AL_PA\n");
2381 } else {
2382 mpt_prt(mpt, "Device %02x detected loop"
2383 " failure at its receiver\n",
2384 data0 & 0xFF);
2385 }
2386 break;
2387 default:
2388 mpt_prt(mpt, "Device %02x requests that device "
2389 "%02x reset itself\n",
2390 data0 & 0xFF,
2391 (data0 >> 8) & 0xFF);
2392 break;
2393 }
2394 break;
2395 case 0x02:
2396 mpt_prt(mpt, "Port 0x%x: FC LinkEvent: "
2397 "LPE(%02x,%02x) (Loop Port Enable)\n",
2398 (data1 >> 8) & 0xff, /* Port */
2399 (data0 >> 8) & 0xff, /* Character 3 */
2400 (data0 ) & 0xff /* Character 4 */);
2401 break;
2402 case 0x03:
2403 mpt_prt(mpt, "Port 0x%x: FC LinkEvent: "
2404 "LPB(%02x,%02x) (Loop Port Bypass)\n",
2405 (data1 >> 8) & 0xff, /* Port */
2406 (data0 >> 8) & 0xff, /* Character 3 */
2407 (data0 ) & 0xff /* Character 4 */);
2408 break;
2409 default:
2410 mpt_prt(mpt, "Port 0x%x: FC LinkEvent: Unknown "
2411 "FC event (%02x %02x %02x)\n",
2412 (data1 >> 8) & 0xff, /* Port */
2413 (data0 >> 16) & 0xff, /* Event */
2414 (data0 >> 8) & 0xff, /* Character 3 */
2415 (data0 ) & 0xff /* Character 4 */);
2416 }
2417 break;
2418
2419 case MPI_EVENT_LOGOUT:
2420 mpt_prt(mpt, "FC Logout Port: %d N_PortID: %02x\n",
2421 (data1 >> 8) & 0xff, data0);
2422 break;
2423 case MPI_EVENT_QUEUE_FULL:
2424 {
2425 struct cam_sim *sim;
2426 struct cam_path *tmppath;
2427 struct ccb_relsim crs;
2428 PTR_EVENT_DATA_QUEUE_FULL pqf;
2429 lun_id_t lun_id;
2430
2431 pqf = (PTR_EVENT_DATA_QUEUE_FULL)msg->Data;
2432 pqf->CurrentDepth = le16toh(pqf->CurrentDepth);
2433 if (bootverbose) {
2434 mpt_prt(mpt, "QUEUE FULL EVENT: Bus 0x%02x Target 0x%02x "
2435 "Depth %d\n",
2436 pqf->Bus, pqf->TargetID, pqf->CurrentDepth);
2437 }
2438 if (mpt->phydisk_sim && mpt_is_raid_member(mpt,
2439 pqf->TargetID) != 0) {
2440 sim = mpt->phydisk_sim;
2441 } else {
2442 sim = mpt->sim;
2443 }
2444 for (lun_id = 0; lun_id < MPT_MAX_LUNS; lun_id++) {
2445 if (xpt_create_path(&tmppath, NULL, cam_sim_path(sim),
2446 pqf->TargetID, lun_id) != CAM_REQ_CMP) {
2447 mpt_prt(mpt, "unable to create a path to send "
2448 "XPT_REL_SIMQ");
2449 break;
2450 }
2451 xpt_setup_ccb(&crs.ccb_h, tmppath, 5);
2452 crs.ccb_h.func_code = XPT_REL_SIMQ;
2453 crs.ccb_h.flags = CAM_DEV_QFREEZE;
2454 crs.release_flags = RELSIM_ADJUST_OPENINGS;
2455 crs.openings = pqf->CurrentDepth - 1;
2456 xpt_action((union ccb *)&crs);
2457 if (crs.ccb_h.status != CAM_REQ_CMP) {
2458 mpt_prt(mpt, "XPT_REL_SIMQ failed\n");
2459 }
2460 xpt_free_path(tmppath);
2461 }
2462 break;
2463 }
2464 case MPI_EVENT_IR_RESYNC_UPDATE:
2465 mpt_prt(mpt, "IR resync update %d completed\n",
2466 (data0 >> 16) & 0xff);
2467 break;
2468 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
2469 {
2470 union ccb *ccb;
2471 struct cam_sim *sim;
2472 struct cam_path *tmppath;
2473 PTR_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE psdsc;
2474
2475 psdsc = (PTR_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE)msg->Data;
2476 if (mpt->phydisk_sim && mpt_is_raid_member(mpt,
2477 psdsc->TargetID) != 0)
2478 sim = mpt->phydisk_sim;
2479 else
2480 sim = mpt->sim;
2481 switch(psdsc->ReasonCode) {
2482 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
2483 ccb = xpt_alloc_ccb_nowait();
2484 if (ccb == NULL) {
2485 mpt_prt(mpt,
2486 "unable to alloc CCB for rescan\n");
2487 break;
2488 }
2489 if (xpt_create_path(&ccb->ccb_h.path, NULL,
2490 cam_sim_path(sim), psdsc->TargetID,
2491 CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
2492 mpt_prt(mpt,
2493 "unable to create path for rescan\n");
2494 xpt_free_ccb(ccb);
2495 break;
2496 }
2497 xpt_rescan(ccb);
2498 break;
2499 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
2500 if (xpt_create_path(&tmppath, NULL, cam_sim_path(sim),
2501 psdsc->TargetID, CAM_LUN_WILDCARD) !=
2502 CAM_REQ_CMP) {
2503 mpt_prt(mpt,
2504 "unable to create path for async event");
2505 break;
2506 }
2507 xpt_async(AC_LOST_DEVICE, tmppath, NULL);
2508 xpt_free_path(tmppath);
2509 break;
2510 case MPI_EVENT_SAS_DEV_STAT_RC_CMPL_INTERNAL_DEV_RESET:
2511 case MPI_EVENT_SAS_DEV_STAT_RC_CMPL_TASK_ABORT_INTERNAL:
2512 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
2513 break;
2514 default:
2515 mpt_lprt(mpt, MPT_PRT_WARN,
2516 "SAS device status change: Bus: 0x%02x TargetID: "
2517 "0x%02x ReasonCode: 0x%02x\n", psdsc->Bus,
2518 psdsc->TargetID, psdsc->ReasonCode);
2519 break;
2520 }
2521 break;
2522 }
2523 case MPI_EVENT_SAS_DISCOVERY_ERROR:
2524 {
2525 PTR_EVENT_DATA_DISCOVERY_ERROR pde;
2526
2527 pde = (PTR_EVENT_DATA_DISCOVERY_ERROR)msg->Data;
2528 pde->DiscoveryStatus = le32toh(pde->DiscoveryStatus);
2529 mpt_lprt(mpt, MPT_PRT_WARN,
2530 "SAS discovery error: Port: 0x%02x Status: 0x%08x\n",
2531 pde->Port, pde->DiscoveryStatus);
2532 break;
2533 }
2534 case MPI_EVENT_EVENT_CHANGE:
2535 case MPI_EVENT_INTEGRATED_RAID:
2536 case MPI_EVENT_IR2:
2537 case MPI_EVENT_LOG_ENTRY_ADDED:
2538 case MPI_EVENT_SAS_DISCOVERY:
2539 case MPI_EVENT_SAS_PHY_LINK_STATUS:
2540 case MPI_EVENT_SAS_SES:
2541 break;
2542 default:
2543 mpt_lprt(mpt, MPT_PRT_WARN, "mpt_cam_event: 0x%x\n",
2544 msg->Event & 0xFF);
2545 return (0);
2546 }
2547 return (1);
2548 }
2549
2550 /*
2551 * Reply path for all SCSI I/O requests, called from our
2552 * interrupt handler by extracting our handler index from
2553 * the MsgContext field of the reply from the IOC.
2554 *
2555 * This routine is optimized for the common case of a
2556 * completion without error. All exception handling is
2557 * offloaded to non-inlined helper routines to minimize
2558 * cache footprint.
2559 */
2560 static int
mpt_scsi_reply_handler(struct mpt_softc * mpt,request_t * req,uint32_t reply_desc,MSG_DEFAULT_REPLY * reply_frame)2561 mpt_scsi_reply_handler(struct mpt_softc *mpt, request_t *req,
2562 uint32_t reply_desc, MSG_DEFAULT_REPLY *reply_frame)
2563 {
2564 MSG_SCSI_IO_REQUEST *scsi_req;
2565 union ccb *ccb;
2566
2567 if (req->state == REQ_STATE_FREE) {
2568 mpt_prt(mpt, "mpt_scsi_reply_handler: req already free\n");
2569 return (TRUE);
2570 }
2571
2572 scsi_req = (MSG_SCSI_IO_REQUEST *)req->req_vbuf;
2573 ccb = req->ccb;
2574 if (ccb == NULL) {
2575 mpt_prt(mpt, "mpt_scsi_reply_handler: req %p:%u with no ccb\n",
2576 req, req->serno);
2577 return (TRUE);
2578 }
2579
2580 mpt_req_untimeout(req, mpt_timeout, ccb);
2581 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
2582
2583 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
2584 bus_dmasync_op_t op;
2585
2586 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
2587 op = BUS_DMASYNC_POSTREAD;
2588 else
2589 op = BUS_DMASYNC_POSTWRITE;
2590 bus_dmamap_sync(mpt->buffer_dmat, req->dmap, op);
2591 bus_dmamap_unload(mpt->buffer_dmat, req->dmap);
2592 }
2593
2594 if (reply_frame == NULL) {
2595 /*
2596 * Context only reply, completion without error status.
2597 */
2598 ccb->csio.resid = 0;
2599 mpt_set_ccb_status(ccb, CAM_REQ_CMP);
2600 ccb->csio.scsi_status = SCSI_STATUS_OK;
2601 } else {
2602 mpt_scsi_reply_frame_handler(mpt, req, reply_frame);
2603 }
2604
2605 if (mpt->outofbeer) {
2606 ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
2607 mpt->outofbeer = 0;
2608 mpt_lprt(mpt, MPT_PRT_DEBUG, "THAWQ\n");
2609 }
2610 if (scsi_req->CDB[0] == INQUIRY && (scsi_req->CDB[1] & SI_EVPD) == 0) {
2611 struct scsi_inquiry_data *iq =
2612 (struct scsi_inquiry_data *)ccb->csio.data_ptr;
2613 if (scsi_req->Function ==
2614 MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) {
2615 /*
2616 * Fake out the device type so that only the
2617 * pass-thru device will attach.
2618 */
2619 iq->device &= ~0x1F;
2620 iq->device |= T_NODEVICE;
2621 }
2622 }
2623 if (mpt->verbose == MPT_PRT_DEBUG) {
2624 mpt_prt(mpt, "mpt_scsi_reply_handler: %p:%u complete\n",
2625 req, req->serno);
2626 }
2627 KASSERT(ccb->ccb_h.status, ("zero ccb sts at %d", __LINE__));
2628 xpt_done(ccb);
2629 if ((req->state & REQ_STATE_TIMEDOUT) == 0) {
2630 TAILQ_REMOVE(&mpt->request_pending_list, req, links);
2631 } else {
2632 mpt_prt(mpt, "completing timedout/aborted req %p:%u\n",
2633 req, req->serno);
2634 TAILQ_REMOVE(&mpt->request_timeout_list, req, links);
2635 }
2636 KASSERT((req->state & REQ_STATE_NEED_WAKEUP) == 0,
2637 ("CCB req needed wakeup"));
2638 #ifdef INVARIANTS
2639 mpt_req_not_spcl(mpt, req, "mpt_scsi_reply_handler", __LINE__);
2640 #endif
2641 mpt_free_request(mpt, req);
2642 return (TRUE);
2643 }
2644
2645 static int
mpt_scsi_tmf_reply_handler(struct mpt_softc * mpt,request_t * req,uint32_t reply_desc,MSG_DEFAULT_REPLY * reply_frame)2646 mpt_scsi_tmf_reply_handler(struct mpt_softc *mpt, request_t *req,
2647 uint32_t reply_desc, MSG_DEFAULT_REPLY *reply_frame)
2648 {
2649 MSG_SCSI_TASK_MGMT_REPLY *tmf_reply;
2650
2651 KASSERT(req == mpt->tmf_req, ("TMF Reply not using mpt->tmf_req"));
2652 #ifdef INVARIANTS
2653 mpt_req_not_spcl(mpt, req, "mpt_scsi_tmf_reply_handler", __LINE__);
2654 #endif
2655 tmf_reply = (MSG_SCSI_TASK_MGMT_REPLY *)reply_frame;
2656 /* Record IOC Status and Response Code of TMF for any waiters. */
2657 req->IOCStatus = le16toh(tmf_reply->IOCStatus);
2658 req->ResponseCode = tmf_reply->ResponseCode;
2659
2660 mpt_lprt(mpt, MPT_PRT_DEBUG, "TMF complete: req %p:%u status 0x%x\n",
2661 req, req->serno, le16toh(tmf_reply->IOCStatus));
2662 TAILQ_REMOVE(&mpt->request_pending_list, req, links);
2663 if ((req->state & REQ_STATE_NEED_WAKEUP) != 0) {
2664 req->state |= REQ_STATE_DONE;
2665 wakeup(req);
2666 } else {
2667 mpt->tmf_req->state = REQ_STATE_FREE;
2668 }
2669 return (TRUE);
2670 }
2671
2672 /*
2673 * XXX: Move to definitions file
2674 */
2675 #define ELS 0x22
2676 #define FC4LS 0x32
2677 #define ABTS 0x81
2678 #define BA_ACC 0x84
2679
2680 #define LS_RJT 0x01
2681 #define LS_ACC 0x02
2682 #define PLOGI 0x03
2683 #define LOGO 0x05
2684 #define SRR 0x14
2685 #define PRLI 0x20
2686 #define PRLO 0x21
2687 #define ADISC 0x52
2688 #define RSCN 0x61
2689
2690 static void
mpt_fc_els_send_response(struct mpt_softc * mpt,request_t * req,PTR_MSG_LINK_SERVICE_BUFFER_POST_REPLY rp,U8 length)2691 mpt_fc_els_send_response(struct mpt_softc *mpt, request_t *req,
2692 PTR_MSG_LINK_SERVICE_BUFFER_POST_REPLY rp, U8 length)
2693 {
2694 uint32_t fl;
2695 MSG_LINK_SERVICE_RSP_REQUEST tmp;
2696 PTR_MSG_LINK_SERVICE_RSP_REQUEST rsp;
2697
2698 /*
2699 * We are going to reuse the ELS request to send this response back.
2700 */
2701 rsp = &tmp;
2702 memset(rsp, 0, sizeof(*rsp));
2703
2704 #ifdef USE_IMMEDIATE_LINK_DATA
2705 /*
2706 * Apparently the IMMEDIATE stuff doesn't seem to work.
2707 */
2708 rsp->RspFlags = LINK_SERVICE_RSP_FLAGS_IMMEDIATE;
2709 #endif
2710 rsp->RspLength = length;
2711 rsp->Function = MPI_FUNCTION_FC_LINK_SRVC_RSP;
2712 rsp->MsgContext = htole32(req->index | fc_els_handler_id);
2713
2714 /*
2715 * Copy over information from the original reply frame to
2716 * it's correct place in the response.
2717 */
2718 memcpy((U8 *)rsp + 0x0c, (U8 *)rp + 0x1c, 24);
2719
2720 /*
2721 * And now copy back the temporary area to the original frame.
2722 */
2723 memcpy(req->req_vbuf, rsp, sizeof (MSG_LINK_SERVICE_RSP_REQUEST));
2724 rsp = req->req_vbuf;
2725
2726 #ifdef USE_IMMEDIATE_LINK_DATA
2727 memcpy((U8 *)&rsp->SGL, &((U8 *)req->req_vbuf)[MPT_RQSL(mpt)], length);
2728 #else
2729 {
2730 PTR_SGE_SIMPLE32 se = (PTR_SGE_SIMPLE32) &rsp->SGL;
2731 bus_addr_t paddr = req->req_pbuf;
2732 paddr += MPT_RQSL(mpt);
2733
2734 fl =
2735 MPI_SGE_FLAGS_HOST_TO_IOC |
2736 MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2737 MPI_SGE_FLAGS_LAST_ELEMENT |
2738 MPI_SGE_FLAGS_END_OF_LIST |
2739 MPI_SGE_FLAGS_END_OF_BUFFER;
2740 fl <<= MPI_SGE_FLAGS_SHIFT;
2741 fl |= (length);
2742 se->FlagsLength = htole32(fl);
2743 se->Address = htole32((uint32_t) paddr);
2744 }
2745 #endif
2746
2747 /*
2748 * Send it on...
2749 */
2750 mpt_send_cmd(mpt, req);
2751 }
2752
2753 static int
mpt_fc_els_reply_handler(struct mpt_softc * mpt,request_t * req,uint32_t reply_desc,MSG_DEFAULT_REPLY * reply_frame)2754 mpt_fc_els_reply_handler(struct mpt_softc *mpt, request_t *req,
2755 uint32_t reply_desc, MSG_DEFAULT_REPLY *reply_frame)
2756 {
2757 PTR_MSG_LINK_SERVICE_BUFFER_POST_REPLY rp =
2758 (PTR_MSG_LINK_SERVICE_BUFFER_POST_REPLY) reply_frame;
2759 U8 rctl;
2760 U8 type;
2761 U8 cmd;
2762 U16 status = le16toh(reply_frame->IOCStatus);
2763 U32 *elsbuf;
2764 int ioindex;
2765 int do_refresh = TRUE;
2766
2767 #ifdef INVARIANTS
2768 KASSERT(mpt_req_on_free_list(mpt, req) == 0,
2769 ("fc_els_reply_handler: req %p:%u for function %x on freelist!",
2770 req, req->serno, rp->Function));
2771 if (rp->Function != MPI_FUNCTION_FC_PRIMITIVE_SEND) {
2772 mpt_req_spcl(mpt, req, "fc_els_reply_handler", __LINE__);
2773 } else {
2774 mpt_req_not_spcl(mpt, req, "fc_els_reply_handler", __LINE__);
2775 }
2776 #endif
2777 mpt_lprt(mpt, MPT_PRT_DEBUG,
2778 "FC_ELS Complete: req %p:%u, reply %p function %x\n",
2779 req, req->serno, reply_frame, reply_frame->Function);
2780
2781 if (status != MPI_IOCSTATUS_SUCCESS) {
2782 mpt_prt(mpt, "ELS REPLY STATUS 0x%x for Function %x\n",
2783 status, reply_frame->Function);
2784 if (status == MPI_IOCSTATUS_INVALID_STATE) {
2785 /*
2786 * XXX: to get around shutdown issue
2787 */
2788 mpt->disabled = 1;
2789 return (TRUE);
2790 }
2791 return (TRUE);
2792 }
2793
2794 /*
2795 * If the function of a link service response, we recycle the
2796 * response to be a refresh for a new link service request.
2797 *
2798 * The request pointer is bogus in this case and we have to fetch
2799 * it based upon the TransactionContext.
2800 */
2801 if (rp->Function == MPI_FUNCTION_FC_LINK_SRVC_RSP) {
2802 /* Freddie Uncle Charlie Katie */
2803 /* We don't get the IOINDEX as part of the Link Svc Rsp */
2804 for (ioindex = 0; ioindex < mpt->els_cmds_allocated; ioindex++)
2805 if (mpt->els_cmd_ptrs[ioindex] == req) {
2806 break;
2807 }
2808
2809 KASSERT(ioindex < mpt->els_cmds_allocated,
2810 ("can't find my mommie!"));
2811
2812 /* remove from active list as we're going to re-post it */
2813 TAILQ_REMOVE(&mpt->request_pending_list, req, links);
2814 req->state &= ~REQ_STATE_QUEUED;
2815 req->state |= REQ_STATE_DONE;
2816 mpt_fc_post_els(mpt, req, ioindex);
2817 return (TRUE);
2818 }
2819
2820 if (rp->Function == MPI_FUNCTION_FC_PRIMITIVE_SEND) {
2821 /* remove from active list as we're done */
2822 TAILQ_REMOVE(&mpt->request_pending_list, req, links);
2823 req->state &= ~REQ_STATE_QUEUED;
2824 req->state |= REQ_STATE_DONE;
2825 if (req->state & REQ_STATE_TIMEDOUT) {
2826 mpt_lprt(mpt, MPT_PRT_DEBUG,
2827 "Sync Primitive Send Completed After Timeout\n");
2828 mpt_free_request(mpt, req);
2829 } else if ((req->state & REQ_STATE_NEED_WAKEUP) == 0) {
2830 mpt_lprt(mpt, MPT_PRT_DEBUG,
2831 "Async Primitive Send Complete\n");
2832 mpt_free_request(mpt, req);
2833 } else {
2834 mpt_lprt(mpt, MPT_PRT_DEBUG,
2835 "Sync Primitive Send Complete- Waking Waiter\n");
2836 wakeup(req);
2837 }
2838 return (TRUE);
2839 }
2840
2841 if (rp->Function != MPI_FUNCTION_FC_LINK_SRVC_BUF_POST) {
2842 mpt_prt(mpt, "unexpected ELS_REPLY: Function 0x%x Flags %x "
2843 "Length %d Message Flags %x\n", rp->Function, rp->Flags,
2844 rp->MsgLength, rp->MsgFlags);
2845 return (TRUE);
2846 }
2847
2848 if (rp->MsgLength <= 5) {
2849 /*
2850 * This is just a ack of an original ELS buffer post
2851 */
2852 mpt_lprt(mpt, MPT_PRT_DEBUG,
2853 "RECV'd ACK of FC_ELS buf post %p:%u\n", req, req->serno);
2854 return (TRUE);
2855 }
2856
2857 rctl = (le32toh(rp->Rctl_Did) & MPI_FC_RCTL_MASK) >> MPI_FC_RCTL_SHIFT;
2858 type = (le32toh(rp->Type_Fctl) & MPI_FC_TYPE_MASK) >> MPI_FC_TYPE_SHIFT;
2859
2860 elsbuf = &((U32 *)req->req_vbuf)[MPT_RQSL(mpt)/sizeof (U32)];
2861 cmd = be32toh(elsbuf[0]) >> 24;
2862
2863 if (rp->Flags & MPI_LS_BUF_POST_REPLY_FLAG_NO_RSP_NEEDED) {
2864 mpt_lprt(mpt, MPT_PRT_ALWAYS, "ELS_REPLY: response unneeded\n");
2865 return (TRUE);
2866 }
2867
2868 ioindex = le32toh(rp->TransactionContext);
2869 req = mpt->els_cmd_ptrs[ioindex];
2870
2871 if (rctl == ELS && type == 1) {
2872 switch (cmd) {
2873 case PRLI:
2874 /*
2875 * Send back a PRLI ACC
2876 */
2877 mpt_prt(mpt, "PRLI from 0x%08x%08x\n",
2878 le32toh(rp->Wwn.PortNameHigh),
2879 le32toh(rp->Wwn.PortNameLow));
2880 elsbuf[0] = htobe32(0x02100014);
2881 elsbuf[1] |= htobe32(0x00000100);
2882 elsbuf[4] = htobe32(0x00000002);
2883 if (mpt->role & MPT_ROLE_TARGET)
2884 elsbuf[4] |= htobe32(0x00000010);
2885 if (mpt->role & MPT_ROLE_INITIATOR)
2886 elsbuf[4] |= htobe32(0x00000020);
2887 /* remove from active list as we're done */
2888 TAILQ_REMOVE(&mpt->request_pending_list, req, links);
2889 req->state &= ~REQ_STATE_QUEUED;
2890 req->state |= REQ_STATE_DONE;
2891 mpt_fc_els_send_response(mpt, req, rp, 20);
2892 do_refresh = FALSE;
2893 break;
2894 case PRLO:
2895 memset(elsbuf, 0, 5 * (sizeof (U32)));
2896 elsbuf[0] = htobe32(0x02100014);
2897 elsbuf[1] = htobe32(0x08000100);
2898 mpt_prt(mpt, "PRLO from 0x%08x%08x\n",
2899 le32toh(rp->Wwn.PortNameHigh),
2900 le32toh(rp->Wwn.PortNameLow));
2901 /* remove from active list as we're done */
2902 TAILQ_REMOVE(&mpt->request_pending_list, req, links);
2903 req->state &= ~REQ_STATE_QUEUED;
2904 req->state |= REQ_STATE_DONE;
2905 mpt_fc_els_send_response(mpt, req, rp, 20);
2906 do_refresh = FALSE;
2907 break;
2908 default:
2909 mpt_prt(mpt, "ELS TYPE 1 COMMAND: %x\n", cmd);
2910 break;
2911 }
2912 } else if (rctl == ABTS && type == 0) {
2913 uint16_t rx_id = le16toh(rp->Rxid);
2914 uint16_t ox_id = le16toh(rp->Oxid);
2915 mpt_tgt_state_t *tgt;
2916 request_t *tgt_req = NULL;
2917 union ccb *ccb;
2918 uint32_t ct_id;
2919
2920 mpt_prt(mpt,
2921 "ELS: ABTS OX_ID 0x%x RX_ID 0x%x from 0x%08x%08x\n",
2922 ox_id, rx_id, le32toh(rp->Wwn.PortNameHigh),
2923 le32toh(rp->Wwn.PortNameLow));
2924 if (rx_id >= mpt->mpt_max_tgtcmds) {
2925 mpt_prt(mpt, "Bad RX_ID 0x%x\n", rx_id);
2926 } else if (mpt->tgt_cmd_ptrs == NULL) {
2927 mpt_prt(mpt, "No TGT CMD PTRS\n");
2928 } else {
2929 tgt_req = mpt->tgt_cmd_ptrs[rx_id];
2930 }
2931 if (tgt_req == NULL) {
2932 mpt_prt(mpt, "no back pointer for RX_ID 0x%x\n", rx_id);
2933 goto skip;
2934 }
2935 tgt = MPT_TGT_STATE(mpt, tgt_req);
2936
2937 /* Check to make sure we have the correct command. */
2938 ct_id = GET_IO_INDEX(tgt->reply_desc);
2939 if (ct_id != rx_id) {
2940 mpt_lprt(mpt, MPT_PRT_ERROR, "ABORT Mismatch: "
2941 "RX_ID received=0x%x, in cmd=0x%x\n", rx_id, ct_id);
2942 goto skip;
2943 }
2944 if (tgt->itag != ox_id) {
2945 mpt_lprt(mpt, MPT_PRT_ERROR, "ABORT Mismatch: "
2946 "OX_ID received=0x%x, in cmd=0x%x\n", ox_id, tgt->itag);
2947 goto skip;
2948 }
2949
2950 if ((ccb = tgt->ccb) != NULL) {
2951 mpt_prt(mpt, "CCB (%p): lun %jx flags %x status %x\n",
2952 ccb, (uintmax_t)ccb->ccb_h.target_lun,
2953 ccb->ccb_h.flags, ccb->ccb_h.status);
2954 }
2955 mpt_prt(mpt, "target state 0x%x resid %u xfrd %u rpwrd "
2956 "%x nxfers %x\n", tgt->state, tgt->resid,
2957 tgt->bytes_xfered, tgt->reply_desc, tgt->nxfers);
2958 if (mpt_abort_target_cmd(mpt, tgt_req))
2959 mpt_prt(mpt, "unable to start TargetAbort\n");
2960
2961 skip:
2962 memset(elsbuf, 0, 5 * (sizeof (U32)));
2963 elsbuf[0] = htobe32(0);
2964 elsbuf[1] = htobe32((ox_id << 16) | rx_id);
2965 elsbuf[2] = htobe32(0x000ffff);
2966 /*
2967 * Dork with the reply frame so that the response to it
2968 * will be correct.
2969 */
2970 rp->Rctl_Did += ((BA_ACC - ABTS) << MPI_FC_RCTL_SHIFT);
2971 /* remove from active list as we're done */
2972 TAILQ_REMOVE(&mpt->request_pending_list, req, links);
2973 req->state &= ~REQ_STATE_QUEUED;
2974 req->state |= REQ_STATE_DONE;
2975 mpt_fc_els_send_response(mpt, req, rp, 12);
2976 do_refresh = FALSE;
2977 } else {
2978 mpt_prt(mpt, "ELS: RCTL %x TYPE %x CMD %x\n", rctl, type, cmd);
2979 }
2980 if (do_refresh == TRUE) {
2981 /* remove from active list as we're done */
2982 TAILQ_REMOVE(&mpt->request_pending_list, req, links);
2983 req->state &= ~REQ_STATE_QUEUED;
2984 req->state |= REQ_STATE_DONE;
2985 mpt_fc_post_els(mpt, req, ioindex);
2986 }
2987 return (TRUE);
2988 }
2989
2990 /*
2991 * Clean up all SCSI Initiator personality state in response
2992 * to a controller reset.
2993 */
2994 static void
mpt_cam_ioc_reset(struct mpt_softc * mpt,int type)2995 mpt_cam_ioc_reset(struct mpt_softc *mpt, int type)
2996 {
2997
2998 /*
2999 * The pending list is already run down by
3000 * the generic handler. Perform the same
3001 * operation on the timed out request list.
3002 */
3003 mpt_complete_request_chain(mpt, &mpt->request_timeout_list,
3004 MPI_IOCSTATUS_INVALID_STATE);
3005
3006 /*
3007 * XXX: We need to repost ELS and Target Command Buffers?
3008 */
3009
3010 /*
3011 * Inform the XPT that a bus reset has occurred.
3012 */
3013 xpt_async(AC_BUS_RESET, mpt->path, NULL);
3014 }
3015
3016 /*
3017 * Parse additional completion information in the reply
3018 * frame for SCSI I/O requests.
3019 */
3020 static int
mpt_scsi_reply_frame_handler(struct mpt_softc * mpt,request_t * req,MSG_DEFAULT_REPLY * reply_frame)3021 mpt_scsi_reply_frame_handler(struct mpt_softc *mpt, request_t *req,
3022 MSG_DEFAULT_REPLY *reply_frame)
3023 {
3024 union ccb *ccb;
3025 MSG_SCSI_IO_REPLY *scsi_io_reply;
3026 u_int ioc_status;
3027 u_int sstate;
3028
3029 MPT_DUMP_REPLY_FRAME(mpt, reply_frame);
3030 KASSERT(reply_frame->Function == MPI_FUNCTION_SCSI_IO_REQUEST
3031 || reply_frame->Function == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH,
3032 ("MPT SCSI I/O Handler called with incorrect reply type"));
3033 KASSERT((reply_frame->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) == 0,
3034 ("MPT SCSI I/O Handler called with continuation reply"));
3035
3036 scsi_io_reply = (MSG_SCSI_IO_REPLY *)reply_frame;
3037 ioc_status = le16toh(scsi_io_reply->IOCStatus);
3038 ioc_status &= MPI_IOCSTATUS_MASK;
3039 sstate = scsi_io_reply->SCSIState;
3040
3041 ccb = req->ccb;
3042 ccb->csio.resid =
3043 ccb->csio.dxfer_len - le32toh(scsi_io_reply->TransferCount);
3044
3045 if ((sstate & MPI_SCSI_STATE_AUTOSENSE_VALID) != 0
3046 && (ccb->ccb_h.flags & (CAM_SENSE_PHYS | CAM_SENSE_PTR)) == 0) {
3047 uint32_t sense_returned;
3048
3049 ccb->ccb_h.status |= CAM_AUTOSNS_VALID;
3050
3051 sense_returned = le32toh(scsi_io_reply->SenseCount);
3052 if (sense_returned < ccb->csio.sense_len)
3053 ccb->csio.sense_resid = ccb->csio.sense_len -
3054 sense_returned;
3055 else
3056 ccb->csio.sense_resid = 0;
3057
3058 bzero(&ccb->csio.sense_data, sizeof(ccb->csio.sense_data));
3059 bcopy(req->sense_vbuf, &ccb->csio.sense_data,
3060 min(ccb->csio.sense_len, sense_returned));
3061 }
3062
3063 if ((sstate & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) != 0) {
3064 /*
3065 * Tag messages rejected, but non-tagged retry
3066 * was successful.
3067 XXXX
3068 mpt_set_tags(mpt, devinfo, MPT_QUEUE_NONE);
3069 */
3070 }
3071
3072 switch(ioc_status) {
3073 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:
3074 /*
3075 * XXX
3076 * Linux driver indicates that a zero
3077 * transfer length with this error code
3078 * indicates a CRC error.
3079 *
3080 * No need to swap the bytes for checking
3081 * against zero.
3082 */
3083 if (scsi_io_reply->TransferCount == 0) {
3084 mpt_set_ccb_status(ccb, CAM_UNCOR_PARITY);
3085 break;
3086 }
3087 /* FALLTHROUGH */
3088 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:
3089 case MPI_IOCSTATUS_SUCCESS:
3090 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:
3091 if ((sstate & MPI_SCSI_STATE_NO_SCSI_STATUS) != 0) {
3092 /*
3093 * Status was never returned for this transaction.
3094 */
3095 mpt_set_ccb_status(ccb, CAM_UNEXP_BUSFREE);
3096 } else if (scsi_io_reply->SCSIStatus != SCSI_STATUS_OK) {
3097 ccb->csio.scsi_status = scsi_io_reply->SCSIStatus;
3098 mpt_set_ccb_status(ccb, CAM_SCSI_STATUS_ERROR);
3099 if ((sstate & MPI_SCSI_STATE_AUTOSENSE_FAILED) != 0)
3100 mpt_set_ccb_status(ccb, CAM_AUTOSENSE_FAIL);
3101 } else if ((sstate & MPI_SCSI_STATE_RESPONSE_INFO_VALID) != 0) {
3102 /* XXX Handle SPI-Packet and FCP-2 response info. */
3103 mpt_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
3104 } else
3105 mpt_set_ccb_status(ccb, CAM_REQ_CMP);
3106 break;
3107 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN:
3108 mpt_set_ccb_status(ccb, CAM_DATA_RUN_ERR);
3109 break;
3110 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:
3111 mpt_set_ccb_status(ccb, CAM_UNCOR_PARITY);
3112 break;
3113 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
3114 /*
3115 * Since selection timeouts and "device really not
3116 * there" are grouped into this error code, report
3117 * selection timeout. Selection timeouts are
3118 * typically retried before giving up on the device
3119 * whereas "device not there" errors are considered
3120 * unretryable.
3121 */
3122 mpt_set_ccb_status(ccb, CAM_SEL_TIMEOUT);
3123 break;
3124 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:
3125 mpt_set_ccb_status(ccb, CAM_SEQUENCE_FAIL);
3126 break;
3127 case MPI_IOCSTATUS_SCSI_INVALID_BUS:
3128 mpt_set_ccb_status(ccb, CAM_PATH_INVALID);
3129 break;
3130 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID:
3131 mpt_set_ccb_status(ccb, CAM_TID_INVALID);
3132 break;
3133 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED:
3134 ccb->ccb_h.status = CAM_UA_TERMIO;
3135 break;
3136 case MPI_IOCSTATUS_INVALID_STATE:
3137 /*
3138 * The IOC has been reset. Emulate a bus reset.
3139 */
3140 /* FALLTHROUGH */
3141 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:
3142 ccb->ccb_h.status = CAM_SCSI_BUS_RESET;
3143 break;
3144 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:
3145 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:
3146 /*
3147 * Don't clobber any timeout status that has
3148 * already been set for this transaction. We
3149 * want the SCSI layer to be able to differentiate
3150 * between the command we aborted due to timeout
3151 * and any innocent bystanders.
3152 */
3153 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_INPROG)
3154 break;
3155 mpt_set_ccb_status(ccb, CAM_REQ_TERMIO);
3156 break;
3157
3158 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES:
3159 mpt_set_ccb_status(ccb, CAM_RESRC_UNAVAIL);
3160 break;
3161 case MPI_IOCSTATUS_BUSY:
3162 mpt_set_ccb_status(ccb, CAM_BUSY);
3163 break;
3164 case MPI_IOCSTATUS_INVALID_FUNCTION:
3165 case MPI_IOCSTATUS_INVALID_SGL:
3166 case MPI_IOCSTATUS_INTERNAL_ERROR:
3167 case MPI_IOCSTATUS_INVALID_FIELD:
3168 default:
3169 /* XXX
3170 * Some of the above may need to kick
3171 * of a recovery action!!!!
3172 */
3173 ccb->ccb_h.status = CAM_UNREC_HBA_ERROR;
3174 break;
3175 }
3176
3177 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3178 mpt_freeze_ccb(ccb);
3179 }
3180
3181 return (TRUE);
3182 }
3183
3184 static void
mpt_action(struct cam_sim * sim,union ccb * ccb)3185 mpt_action(struct cam_sim *sim, union ccb *ccb)
3186 {
3187 struct mpt_softc *mpt;
3188 struct ccb_trans_settings *cts;
3189 target_id_t tgt;
3190 lun_id_t lun;
3191 int raid_passthru;
3192
3193 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("mpt_action\n"));
3194
3195 mpt = (struct mpt_softc *)cam_sim_softc(sim);
3196 raid_passthru = (sim == mpt->phydisk_sim);
3197 MPT_LOCK_ASSERT(mpt);
3198
3199 tgt = ccb->ccb_h.target_id;
3200 lun = ccb->ccb_h.target_lun;
3201 if (raid_passthru &&
3202 ccb->ccb_h.func_code != XPT_PATH_INQ &&
3203 ccb->ccb_h.func_code != XPT_RESET_BUS &&
3204 ccb->ccb_h.func_code != XPT_RESET_DEV) {
3205 if (mpt_map_physdisk(mpt, ccb, &tgt) != 0) {
3206 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
3207 mpt_set_ccb_status(ccb, CAM_DEV_NOT_THERE);
3208 xpt_done(ccb);
3209 return;
3210 }
3211 }
3212 ccb->ccb_h.ccb_mpt_ptr = mpt;
3213
3214 switch (ccb->ccb_h.func_code) {
3215 case XPT_SCSI_IO: /* Execute the requested I/O operation */
3216 /*
3217 * Do a couple of preliminary checks...
3218 */
3219 if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) {
3220 if ((ccb->ccb_h.flags & CAM_CDB_PHYS) != 0) {
3221 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
3222 mpt_set_ccb_status(ccb, CAM_REQ_INVALID);
3223 break;
3224 }
3225 }
3226 /* Max supported CDB length is 16 bytes */
3227 /* XXX Unless we implement the new 32byte message type */
3228 if (ccb->csio.cdb_len >
3229 sizeof (((PTR_MSG_SCSI_IO_REQUEST)0)->CDB)) {
3230 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
3231 mpt_set_ccb_status(ccb, CAM_REQ_INVALID);
3232 break;
3233 }
3234 #ifdef MPT_TEST_MULTIPATH
3235 if (mpt->failure_id == ccb->ccb_h.target_id) {
3236 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
3237 mpt_set_ccb_status(ccb, CAM_SEL_TIMEOUT);
3238 break;
3239 }
3240 #endif
3241 ccb->csio.scsi_status = SCSI_STATUS_OK;
3242 mpt_start(sim, ccb);
3243 return;
3244
3245 case XPT_RESET_BUS:
3246 if (raid_passthru) {
3247 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
3248 mpt_set_ccb_status(ccb, CAM_REQ_CMP);
3249 break;
3250 }
3251 case XPT_RESET_DEV:
3252 if (ccb->ccb_h.func_code == XPT_RESET_BUS) {
3253 if (bootverbose) {
3254 xpt_print(ccb->ccb_h.path, "reset bus\n");
3255 }
3256 } else {
3257 xpt_print(ccb->ccb_h.path, "reset device\n");
3258 }
3259 (void) mpt_bus_reset(mpt, tgt, lun, FALSE);
3260
3261 /*
3262 * mpt_bus_reset is always successful in that it
3263 * will fall back to a hard reset should a bus
3264 * reset attempt fail.
3265 */
3266 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
3267 mpt_set_ccb_status(ccb, CAM_REQ_CMP);
3268 break;
3269
3270 case XPT_ABORT:
3271 {
3272 union ccb *accb = ccb->cab.abort_ccb;
3273 switch (accb->ccb_h.func_code) {
3274 case XPT_ACCEPT_TARGET_IO:
3275 case XPT_IMMEDIATE_NOTIFY:
3276 ccb->ccb_h.status = mpt_abort_target_ccb(mpt, ccb);
3277 break;
3278 case XPT_CONT_TARGET_IO:
3279 mpt_prt(mpt, "cannot abort active CTIOs yet\n");
3280 ccb->ccb_h.status = CAM_UA_ABORT;
3281 break;
3282 case XPT_SCSI_IO:
3283 ccb->ccb_h.status = CAM_UA_ABORT;
3284 break;
3285 default:
3286 ccb->ccb_h.status = CAM_REQ_INVALID;
3287 break;
3288 }
3289 break;
3290 }
3291
3292 #define IS_CURRENT_SETTINGS(c) ((c)->type == CTS_TYPE_CURRENT_SETTINGS)
3293
3294 #define DP_DISC_ENABLE 0x1
3295 #define DP_DISC_DISABL 0x2
3296 #define DP_DISC (DP_DISC_ENABLE|DP_DISC_DISABL)
3297
3298 #define DP_TQING_ENABLE 0x4
3299 #define DP_TQING_DISABL 0x8
3300 #define DP_TQING (DP_TQING_ENABLE|DP_TQING_DISABL)
3301
3302 #define DP_WIDE 0x10
3303 #define DP_NARROW 0x20
3304 #define DP_WIDTH (DP_WIDE|DP_NARROW)
3305
3306 #define DP_SYNC 0x40
3307
3308 case XPT_SET_TRAN_SETTINGS: /* Nexus Settings */
3309 {
3310 struct ccb_trans_settings_scsi *scsi;
3311 struct ccb_trans_settings_spi *spi;
3312 uint8_t dval;
3313 u_int period;
3314 u_int offset;
3315 int i, j;
3316
3317 cts = &ccb->cts;
3318
3319 if (mpt->is_fc || mpt->is_sas) {
3320 mpt_set_ccb_status(ccb, CAM_REQ_CMP);
3321 break;
3322 }
3323
3324 scsi = &cts->proto_specific.scsi;
3325 spi = &cts->xport_specific.spi;
3326
3327 /*
3328 * We can be called just to valid transport and proto versions
3329 */
3330 if (scsi->valid == 0 && spi->valid == 0) {
3331 mpt_set_ccb_status(ccb, CAM_REQ_CMP);
3332 break;
3333 }
3334
3335 /*
3336 * Skip attempting settings on RAID volume disks.
3337 * Other devices on the bus get the normal treatment.
3338 */
3339 if (mpt->phydisk_sim && raid_passthru == 0 &&
3340 mpt_is_raid_volume(mpt, tgt) != 0) {
3341 mpt_lprt(mpt, MPT_PRT_NEGOTIATION,
3342 "no transfer settings for RAID vols\n");
3343 mpt_set_ccb_status(ccb, CAM_REQ_CMP);
3344 break;
3345 }
3346
3347 i = mpt->mpt_port_page2.PortSettings &
3348 MPI_SCSIPORTPAGE2_PORT_MASK_NEGO_MASTER_SETTINGS;
3349 j = mpt->mpt_port_page2.PortFlags &
3350 MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
3351 if (i == MPI_SCSIPORTPAGE2_PORT_ALL_MASTER_SETTINGS &&
3352 j == MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV) {
3353 mpt_lprt(mpt, MPT_PRT_ALWAYS,
3354 "honoring BIOS transfer negotiations\n");
3355 mpt_set_ccb_status(ccb, CAM_REQ_CMP);
3356 break;
3357 }
3358
3359 dval = 0;
3360 period = 0;
3361 offset = 0;
3362
3363 if ((spi->valid & CTS_SPI_VALID_DISC) != 0) {
3364 dval |= ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0) ?
3365 DP_DISC_ENABLE : DP_DISC_DISABL;
3366 }
3367
3368 if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) {
3369 dval |= ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) ?
3370 DP_TQING_ENABLE : DP_TQING_DISABL;
3371 }
3372
3373 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
3374 dval |= (spi->bus_width == MSG_EXT_WDTR_BUS_16_BIT) ?
3375 DP_WIDE : DP_NARROW;
3376 }
3377
3378 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
3379 dval |= DP_SYNC;
3380 offset = spi->sync_offset;
3381 } else {
3382 PTR_CONFIG_PAGE_SCSI_DEVICE_1 ptr =
3383 &mpt->mpt_dev_page1[tgt];
3384 offset = ptr->RequestedParameters;
3385 offset &= MPI_SCSIDEVPAGE1_RP_MAX_SYNC_OFFSET_MASK;
3386 offset >>= MPI_SCSIDEVPAGE1_RP_SHIFT_MAX_SYNC_OFFSET;
3387 }
3388 if (spi->valid & CTS_SPI_VALID_SYNC_RATE) {
3389 dval |= DP_SYNC;
3390 period = spi->sync_period;
3391 } else {
3392 PTR_CONFIG_PAGE_SCSI_DEVICE_1 ptr =
3393 &mpt->mpt_dev_page1[tgt];
3394 period = ptr->RequestedParameters;
3395 period &= MPI_SCSIDEVPAGE1_RP_MIN_SYNC_PERIOD_MASK;
3396 period >>= MPI_SCSIDEVPAGE1_RP_SHIFT_MIN_SYNC_PERIOD;
3397 }
3398
3399 if (dval & DP_DISC_ENABLE) {
3400 mpt->mpt_disc_enable |= (1 << tgt);
3401 } else if (dval & DP_DISC_DISABL) {
3402 mpt->mpt_disc_enable &= ~(1 << tgt);
3403 }
3404 if (dval & DP_TQING_ENABLE) {
3405 mpt->mpt_tag_enable |= (1 << tgt);
3406 } else if (dval & DP_TQING_DISABL) {
3407 mpt->mpt_tag_enable &= ~(1 << tgt);
3408 }
3409 if (dval & DP_WIDTH) {
3410 mpt_setwidth(mpt, tgt, 1);
3411 }
3412 if (dval & DP_SYNC) {
3413 mpt_setsync(mpt, tgt, period, offset);
3414 }
3415 if (dval == 0) {
3416 mpt_set_ccb_status(ccb, CAM_REQ_CMP);
3417 break;
3418 }
3419 mpt_lprt(mpt, MPT_PRT_NEGOTIATION,
3420 "set [%d]: 0x%x period 0x%x offset %d\n",
3421 tgt, dval, period, offset);
3422 if (mpt_update_spi_config(mpt, tgt)) {
3423 mpt_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
3424 } else {
3425 mpt_set_ccb_status(ccb, CAM_REQ_CMP);
3426 }
3427 break;
3428 }
3429 case XPT_GET_TRAN_SETTINGS:
3430 {
3431 struct ccb_trans_settings_scsi *scsi;
3432 cts = &ccb->cts;
3433 cts->protocol = PROTO_SCSI;
3434 if (mpt->is_fc) {
3435 struct ccb_trans_settings_fc *fc =
3436 &cts->xport_specific.fc;
3437 cts->protocol_version = SCSI_REV_SPC;
3438 cts->transport = XPORT_FC;
3439 cts->transport_version = 0;
3440 if (mpt->mpt_fcport_speed != 0) {
3441 fc->valid = CTS_FC_VALID_SPEED;
3442 fc->bitrate = 100000 * mpt->mpt_fcport_speed;
3443 }
3444 } else if (mpt->is_sas) {
3445 struct ccb_trans_settings_sas *sas =
3446 &cts->xport_specific.sas;
3447 cts->protocol_version = SCSI_REV_SPC2;
3448 cts->transport = XPORT_SAS;
3449 cts->transport_version = 0;
3450 sas->valid = CTS_SAS_VALID_SPEED;
3451 sas->bitrate = 300000;
3452 } else {
3453 cts->protocol_version = SCSI_REV_2;
3454 cts->transport = XPORT_SPI;
3455 cts->transport_version = 2;
3456 if (mpt_get_spi_settings(mpt, cts) != 0) {
3457 mpt_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
3458 break;
3459 }
3460 }
3461 scsi = &cts->proto_specific.scsi;
3462 scsi->valid = CTS_SCSI_VALID_TQ;
3463 scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
3464 mpt_set_ccb_status(ccb, CAM_REQ_CMP);
3465 break;
3466 }
3467 case XPT_CALC_GEOMETRY:
3468 {
3469 struct ccb_calc_geometry *ccg;
3470
3471 ccg = &ccb->ccg;
3472 if (ccg->block_size == 0) {
3473 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
3474 mpt_set_ccb_status(ccb, CAM_REQ_INVALID);
3475 break;
3476 }
3477 cam_calc_geometry(ccg, /* extended */ 1);
3478 KASSERT(ccb->ccb_h.status, ("zero ccb sts at %d", __LINE__));
3479 break;
3480 }
3481 case XPT_GET_SIM_KNOB:
3482 {
3483 struct ccb_sim_knob *kp = &ccb->knob;
3484
3485 if (mpt->is_fc) {
3486 kp->xport_specific.fc.wwnn = mpt->scinfo.fc.wwnn;
3487 kp->xport_specific.fc.wwpn = mpt->scinfo.fc.wwpn;
3488 switch (mpt->role) {
3489 case MPT_ROLE_NONE:
3490 kp->xport_specific.fc.role = KNOB_ROLE_NONE;
3491 break;
3492 case MPT_ROLE_INITIATOR:
3493 kp->xport_specific.fc.role = KNOB_ROLE_INITIATOR;
3494 break;
3495 case MPT_ROLE_TARGET:
3496 kp->xport_specific.fc.role = KNOB_ROLE_TARGET;
3497 break;
3498 case MPT_ROLE_BOTH:
3499 kp->xport_specific.fc.role = KNOB_ROLE_BOTH;
3500 break;
3501 }
3502 kp->xport_specific.fc.valid =
3503 KNOB_VALID_ADDRESS | KNOB_VALID_ROLE;
3504 ccb->ccb_h.status = CAM_REQ_CMP;
3505 } else {
3506 ccb->ccb_h.status = CAM_REQ_INVALID;
3507 }
3508 xpt_done(ccb);
3509 break;
3510 }
3511 case XPT_PATH_INQ: /* Path routing inquiry */
3512 {
3513 struct ccb_pathinq *cpi = &ccb->cpi;
3514
3515 cpi->version_num = 1;
3516 cpi->target_sprt = 0;
3517 cpi->hba_eng_cnt = 0;
3518 cpi->max_target = mpt->port_facts[0].MaxDevices - 1;
3519 cpi->maxio = (mpt->max_cam_seg_cnt - 1) * PAGE_SIZE;
3520 /*
3521 * FC cards report MAX_DEVICES of 512, but
3522 * the MSG_SCSI_IO_REQUEST target id field
3523 * is only 8 bits. Until we fix the driver
3524 * to support 'channels' for bus overflow,
3525 * just limit it.
3526 */
3527 if (cpi->max_target > 255) {
3528 cpi->max_target = 255;
3529 }
3530
3531 /*
3532 * VMware ESX reports > 16 devices and then dies when we probe.
3533 */
3534 if (mpt->is_spi && cpi->max_target > 15) {
3535 cpi->max_target = 15;
3536 }
3537 if (mpt->is_spi)
3538 cpi->max_lun = 7;
3539 else
3540 cpi->max_lun = MPT_MAX_LUNS;
3541 cpi->initiator_id = mpt->mpt_ini_id;
3542 cpi->bus_id = cam_sim_bus(sim);
3543
3544 /*
3545 * The base speed is the speed of the underlying connection.
3546 */
3547 cpi->protocol = PROTO_SCSI;
3548 if (mpt->is_fc) {
3549 cpi->hba_misc = PIM_NOBUSRESET | PIM_UNMAPPED |
3550 PIM_EXTLUNS;
3551 cpi->base_transfer_speed = 100000;
3552 cpi->hba_inquiry = PI_TAG_ABLE;
3553 cpi->transport = XPORT_FC;
3554 cpi->transport_version = 0;
3555 cpi->protocol_version = SCSI_REV_SPC;
3556 cpi->xport_specific.fc.wwnn = mpt->scinfo.fc.wwnn;
3557 cpi->xport_specific.fc.wwpn = mpt->scinfo.fc.wwpn;
3558 cpi->xport_specific.fc.port = mpt->scinfo.fc.portid;
3559 cpi->xport_specific.fc.bitrate =
3560 100000 * mpt->mpt_fcport_speed;
3561 } else if (mpt->is_sas) {
3562 cpi->hba_misc = PIM_NOBUSRESET | PIM_UNMAPPED |
3563 PIM_EXTLUNS;
3564 cpi->base_transfer_speed = 300000;
3565 cpi->hba_inquiry = PI_TAG_ABLE;
3566 cpi->transport = XPORT_SAS;
3567 cpi->transport_version = 0;
3568 cpi->protocol_version = SCSI_REV_SPC2;
3569 } else {
3570 cpi->hba_misc = PIM_SEQSCAN | PIM_UNMAPPED |
3571 PIM_EXTLUNS;
3572 cpi->base_transfer_speed = 3300;
3573 cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16;
3574 cpi->transport = XPORT_SPI;
3575 cpi->transport_version = 2;
3576 cpi->protocol_version = SCSI_REV_2;
3577 }
3578
3579 /*
3580 * We give our fake RAID passhtru bus a width that is MaxVolumes
3581 * wide and restrict it to one lun.
3582 */
3583 if (raid_passthru) {
3584 cpi->max_target = mpt->ioc_page2->MaxPhysDisks - 1;
3585 cpi->initiator_id = cpi->max_target + 1;
3586 cpi->max_lun = 0;
3587 }
3588
3589 if ((mpt->role & MPT_ROLE_INITIATOR) == 0) {
3590 cpi->hba_misc |= PIM_NOINITIATOR;
3591 }
3592 if (mpt->is_fc && (mpt->role & MPT_ROLE_TARGET)) {
3593 cpi->target_sprt =
3594 PIT_PROCESSOR | PIT_DISCONNECT | PIT_TERM_IO;
3595 } else {
3596 cpi->target_sprt = 0;
3597 }
3598 strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
3599 strlcpy(cpi->hba_vid, "LSI", HBA_IDLEN);
3600 strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
3601 cpi->unit_number = cam_sim_unit(sim);
3602 cpi->ccb_h.status = CAM_REQ_CMP;
3603 break;
3604 }
3605 case XPT_EN_LUN: /* Enable LUN as a target */
3606 {
3607 int result;
3608
3609 if (ccb->cel.enable)
3610 result = mpt_enable_lun(mpt,
3611 ccb->ccb_h.target_id, ccb->ccb_h.target_lun);
3612 else
3613 result = mpt_disable_lun(mpt,
3614 ccb->ccb_h.target_id, ccb->ccb_h.target_lun);
3615 if (result == 0) {
3616 mpt_set_ccb_status(ccb, CAM_REQ_CMP);
3617 } else {
3618 mpt_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
3619 }
3620 break;
3621 }
3622 case XPT_IMMEDIATE_NOTIFY: /* Add Immediate Notify Resource */
3623 case XPT_ACCEPT_TARGET_IO: /* Add Accept Target IO Resource */
3624 {
3625 tgt_resource_t *trtp;
3626 lun_id_t lun = ccb->ccb_h.target_lun;
3627 ccb->ccb_h.sim_priv.entries[0].field = 0;
3628 ccb->ccb_h.sim_priv.entries[1].ptr = mpt;
3629
3630 if (lun == CAM_LUN_WILDCARD) {
3631 if (ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) {
3632 mpt_set_ccb_status(ccb, CAM_REQ_INVALID);
3633 break;
3634 }
3635 trtp = &mpt->trt_wildcard;
3636 } else if (lun >= MPT_MAX_LUNS) {
3637 mpt_set_ccb_status(ccb, CAM_REQ_INVALID);
3638 break;
3639 } else {
3640 trtp = &mpt->trt[lun];
3641 }
3642 if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) {
3643 mpt_lprt(mpt, MPT_PRT_DEBUG1,
3644 "Put FREE ATIO %p lun %jx\n", ccb, (uintmax_t)lun);
3645 STAILQ_INSERT_TAIL(&trtp->atios, &ccb->ccb_h,
3646 sim_links.stqe);
3647 } else {
3648 mpt_lprt(mpt, MPT_PRT_DEBUG1,
3649 "Put FREE INOT lun %jx\n", (uintmax_t)lun);
3650 STAILQ_INSERT_TAIL(&trtp->inots, &ccb->ccb_h,
3651 sim_links.stqe);
3652 }
3653 mpt_set_ccb_status(ccb, CAM_REQ_INPROG);
3654 return;
3655 }
3656 case XPT_NOTIFY_ACKNOWLEDGE: /* Task management request done. */
3657 {
3658 request_t *req = MPT_TAG_2_REQ(mpt, ccb->cna2.tag_id);
3659
3660 mpt_lprt(mpt, MPT_PRT_DEBUG, "Got Notify ACK\n");
3661 mpt_scsi_tgt_status(mpt, NULL, req, 0, NULL, 0);
3662 mpt_set_ccb_status(ccb, CAM_REQ_CMP);
3663 break;
3664 }
3665 case XPT_CONT_TARGET_IO:
3666 mpt_target_start_io(mpt, ccb);
3667 return;
3668
3669 default:
3670 ccb->ccb_h.status = CAM_REQ_INVALID;
3671 break;
3672 }
3673 xpt_done(ccb);
3674 }
3675
3676 static int
mpt_get_spi_settings(struct mpt_softc * mpt,struct ccb_trans_settings * cts)3677 mpt_get_spi_settings(struct mpt_softc *mpt, struct ccb_trans_settings *cts)
3678 {
3679 struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi;
3680 struct ccb_trans_settings_spi *spi = &cts->xport_specific.spi;
3681 target_id_t tgt;
3682 uint32_t dval, pval, oval;
3683 int rv;
3684
3685 if (IS_CURRENT_SETTINGS(cts) == 0) {
3686 tgt = cts->ccb_h.target_id;
3687 } else if (xpt_path_sim(cts->ccb_h.path) == mpt->phydisk_sim) {
3688 if (mpt_map_physdisk(mpt, (union ccb *)cts, &tgt)) {
3689 return (-1);
3690 }
3691 } else {
3692 tgt = cts->ccb_h.target_id;
3693 }
3694
3695 /*
3696 * We aren't looking at Port Page 2 BIOS settings here-
3697 * sometimes these have been known to be bogus XXX.
3698 *
3699 * For user settings, we pick the max from port page 0
3700 *
3701 * For current settings we read the current settings out from
3702 * device page 0 for that target.
3703 */
3704 if (IS_CURRENT_SETTINGS(cts)) {
3705 CONFIG_PAGE_SCSI_DEVICE_0 tmp;
3706 dval = 0;
3707
3708 tmp = mpt->mpt_dev_page0[tgt];
3709 rv = mpt_read_cur_cfg_page(mpt, tgt, &tmp.Header,
3710 sizeof(tmp), FALSE, 5000);
3711 if (rv) {
3712 mpt_prt(mpt, "can't get tgt %d config page 0\n", tgt);
3713 return (rv);
3714 }
3715 mpt2host_config_page_scsi_device_0(&tmp);
3716
3717 mpt_lprt(mpt, MPT_PRT_DEBUG,
3718 "mpt_get_spi_settings[%d]: current NP %x Info %x\n", tgt,
3719 tmp.NegotiatedParameters, tmp.Information);
3720 dval |= (tmp.NegotiatedParameters & MPI_SCSIDEVPAGE0_NP_WIDE) ?
3721 DP_WIDE : DP_NARROW;
3722 dval |= (mpt->mpt_disc_enable & (1 << tgt)) ?
3723 DP_DISC_ENABLE : DP_DISC_DISABL;
3724 dval |= (mpt->mpt_tag_enable & (1 << tgt)) ?
3725 DP_TQING_ENABLE : DP_TQING_DISABL;
3726 oval = tmp.NegotiatedParameters;
3727 oval &= MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK;
3728 oval >>= MPI_SCSIDEVPAGE0_NP_SHIFT_SYNC_OFFSET;
3729 pval = tmp.NegotiatedParameters;
3730 pval &= MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK;
3731 pval >>= MPI_SCSIDEVPAGE0_NP_SHIFT_SYNC_PERIOD;
3732 mpt->mpt_dev_page0[tgt] = tmp;
3733 } else {
3734 dval = DP_WIDE|DP_DISC_ENABLE|DP_TQING_ENABLE|DP_SYNC;
3735 oval = mpt->mpt_port_page0.Capabilities;
3736 oval = MPI_SCSIPORTPAGE0_CAP_GET_MAX_SYNC_OFFSET(oval);
3737 pval = mpt->mpt_port_page0.Capabilities;
3738 pval = MPI_SCSIPORTPAGE0_CAP_GET_MIN_SYNC_PERIOD(pval);
3739 }
3740
3741 spi->valid = 0;
3742 scsi->valid = 0;
3743 spi->flags = 0;
3744 scsi->flags = 0;
3745 spi->sync_offset = oval;
3746 spi->sync_period = pval;
3747 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
3748 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
3749 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
3750 if (dval & DP_WIDE) {
3751 spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
3752 } else {
3753 spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
3754 }
3755 if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) {
3756 scsi->valid = CTS_SCSI_VALID_TQ;
3757 if (dval & DP_TQING_ENABLE) {
3758 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
3759 }
3760 spi->valid |= CTS_SPI_VALID_DISC;
3761 if (dval & DP_DISC_ENABLE) {
3762 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
3763 }
3764 }
3765
3766 mpt_lprt(mpt, MPT_PRT_NEGOTIATION,
3767 "mpt_get_spi_settings[%d]: %s flags 0x%x per 0x%x off=%d\n", tgt,
3768 IS_CURRENT_SETTINGS(cts) ? "ACTIVE" : "NVRAM ", dval, pval, oval);
3769 return (0);
3770 }
3771
3772 static void
mpt_setwidth(struct mpt_softc * mpt,int tgt,int onoff)3773 mpt_setwidth(struct mpt_softc *mpt, int tgt, int onoff)
3774 {
3775 PTR_CONFIG_PAGE_SCSI_DEVICE_1 ptr;
3776
3777 ptr = &mpt->mpt_dev_page1[tgt];
3778 if (onoff) {
3779 ptr->RequestedParameters |= MPI_SCSIDEVPAGE1_RP_WIDE;
3780 } else {
3781 ptr->RequestedParameters &= ~MPI_SCSIDEVPAGE1_RP_WIDE;
3782 }
3783 }
3784
3785 static void
mpt_setsync(struct mpt_softc * mpt,int tgt,int period,int offset)3786 mpt_setsync(struct mpt_softc *mpt, int tgt, int period, int offset)
3787 {
3788 PTR_CONFIG_PAGE_SCSI_DEVICE_1 ptr;
3789
3790 ptr = &mpt->mpt_dev_page1[tgt];
3791 ptr->RequestedParameters &= ~MPI_SCSIDEVPAGE1_RP_MIN_SYNC_PERIOD_MASK;
3792 ptr->RequestedParameters &= ~MPI_SCSIDEVPAGE1_RP_MAX_SYNC_OFFSET_MASK;
3793 ptr->RequestedParameters &= ~MPI_SCSIDEVPAGE1_RP_DT;
3794 ptr->RequestedParameters &= ~MPI_SCSIDEVPAGE1_RP_QAS;
3795 ptr->RequestedParameters &= ~MPI_SCSIDEVPAGE1_RP_IU;
3796 if (period == 0) {
3797 return;
3798 }
3799 ptr->RequestedParameters |=
3800 period << MPI_SCSIDEVPAGE1_RP_SHIFT_MIN_SYNC_PERIOD;
3801 ptr->RequestedParameters |=
3802 offset << MPI_SCSIDEVPAGE1_RP_SHIFT_MAX_SYNC_OFFSET;
3803 if (period < 0xa) {
3804 ptr->RequestedParameters |= MPI_SCSIDEVPAGE1_RP_DT;
3805 }
3806 if (period < 0x9) {
3807 ptr->RequestedParameters |= MPI_SCSIDEVPAGE1_RP_QAS;
3808 ptr->RequestedParameters |= MPI_SCSIDEVPAGE1_RP_IU;
3809 }
3810 }
3811
3812 static int
mpt_update_spi_config(struct mpt_softc * mpt,int tgt)3813 mpt_update_spi_config(struct mpt_softc *mpt, int tgt)
3814 {
3815 CONFIG_PAGE_SCSI_DEVICE_1 tmp;
3816 int rv;
3817
3818 mpt_lprt(mpt, MPT_PRT_NEGOTIATION,
3819 "mpt_update_spi_config[%d].page1: Requested Params 0x%08x\n",
3820 tgt, mpt->mpt_dev_page1[tgt].RequestedParameters);
3821 tmp = mpt->mpt_dev_page1[tgt];
3822 host2mpt_config_page_scsi_device_1(&tmp);
3823 rv = mpt_write_cur_cfg_page(mpt, tgt,
3824 &tmp.Header, sizeof(tmp), FALSE, 5000);
3825 if (rv) {
3826 mpt_prt(mpt, "mpt_update_spi_config: write cur page failed\n");
3827 return (-1);
3828 }
3829 return (0);
3830 }
3831
3832 /****************************** Timeout Recovery ******************************/
3833 static int
mpt_spawn_recovery_thread(struct mpt_softc * mpt)3834 mpt_spawn_recovery_thread(struct mpt_softc *mpt)
3835 {
3836 int error;
3837
3838 error = kproc_create(mpt_recovery_thread, mpt,
3839 &mpt->recovery_thread, /*flags*/0,
3840 /*altstack*/0, "mpt_recovery%d", mpt->unit);
3841 return (error);
3842 }
3843
3844 static void
mpt_terminate_recovery_thread(struct mpt_softc * mpt)3845 mpt_terminate_recovery_thread(struct mpt_softc *mpt)
3846 {
3847
3848 if (mpt->recovery_thread == NULL) {
3849 return;
3850 }
3851 mpt->shutdwn_recovery = 1;
3852 wakeup(mpt);
3853 /*
3854 * Sleep on a slightly different location
3855 * for this interlock just for added safety.
3856 */
3857 mpt_sleep(mpt, &mpt->recovery_thread, PUSER, "thtrm", 0);
3858 }
3859
3860 static void
mpt_recovery_thread(void * arg)3861 mpt_recovery_thread(void *arg)
3862 {
3863 struct mpt_softc *mpt;
3864
3865 mpt = (struct mpt_softc *)arg;
3866 MPT_LOCK(mpt);
3867 for (;;) {
3868 if (TAILQ_EMPTY(&mpt->request_timeout_list) != 0) {
3869 if (mpt->shutdwn_recovery == 0) {
3870 mpt_sleep(mpt, mpt, PUSER, "idle", 0);
3871 }
3872 }
3873 if (mpt->shutdwn_recovery != 0) {
3874 break;
3875 }
3876 mpt_recover_commands(mpt);
3877 }
3878 mpt->recovery_thread = NULL;
3879 wakeup(&mpt->recovery_thread);
3880 MPT_UNLOCK(mpt);
3881 kproc_exit(0);
3882 }
3883
3884 static int
mpt_scsi_send_tmf(struct mpt_softc * mpt,u_int type,u_int flags,u_int channel,target_id_t target,lun_id_t lun,u_int abort_ctx,int sleep_ok)3885 mpt_scsi_send_tmf(struct mpt_softc *mpt, u_int type, u_int flags,
3886 u_int channel, target_id_t target, lun_id_t lun, u_int abort_ctx,
3887 int sleep_ok)
3888 {
3889 MSG_SCSI_TASK_MGMT *tmf_req;
3890 int error;
3891
3892 /*
3893 * Wait for any current TMF request to complete.
3894 * We're only allowed to issue one TMF at a time.
3895 */
3896 error = mpt_wait_req(mpt, mpt->tmf_req, REQ_STATE_FREE, REQ_STATE_FREE,
3897 sleep_ok, MPT_TMF_MAX_TIMEOUT);
3898 if (error != 0) {
3899 mpt_reset(mpt, TRUE);
3900 return (ETIMEDOUT);
3901 }
3902
3903 mpt_assign_serno(mpt, mpt->tmf_req);
3904 mpt->tmf_req->state = REQ_STATE_ALLOCATED|REQ_STATE_QUEUED;
3905
3906 tmf_req = (MSG_SCSI_TASK_MGMT *)mpt->tmf_req->req_vbuf;
3907 memset(tmf_req, 0, sizeof(*tmf_req));
3908 tmf_req->TargetID = target;
3909 tmf_req->Bus = channel;
3910 tmf_req->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
3911 tmf_req->TaskType = type;
3912 tmf_req->MsgFlags = flags;
3913 tmf_req->MsgContext =
3914 htole32(mpt->tmf_req->index | scsi_tmf_handler_id);
3915 be64enc(tmf_req->LUN, CAM_EXTLUN_BYTE_SWIZZLE(lun));
3916 tmf_req->TaskMsgContext = abort_ctx;
3917
3918 mpt_lprt(mpt, MPT_PRT_DEBUG,
3919 "Issuing TMF %p:%u with MsgContext of 0x%x\n", mpt->tmf_req,
3920 mpt->tmf_req->serno, tmf_req->MsgContext);
3921 if (mpt->verbose > MPT_PRT_DEBUG) {
3922 mpt_print_request(tmf_req);
3923 }
3924
3925 KASSERT(mpt_req_on_pending_list(mpt, mpt->tmf_req) == 0,
3926 ("mpt_scsi_send_tmf: tmf_req already on pending list"));
3927 TAILQ_INSERT_HEAD(&mpt->request_pending_list, mpt->tmf_req, links);
3928 error = mpt_send_handshake_cmd(mpt, sizeof(*tmf_req), tmf_req);
3929 if (error != MPT_OK) {
3930 TAILQ_REMOVE(&mpt->request_pending_list, mpt->tmf_req, links);
3931 mpt->tmf_req->state = REQ_STATE_FREE;
3932 mpt_reset(mpt, TRUE);
3933 }
3934 return (error);
3935 }
3936
3937 /*
3938 * When a command times out, it is placed on the requeust_timeout_list
3939 * and we wake our recovery thread. The MPT-Fusion architecture supports
3940 * only a single TMF operation at a time, so we serially abort/bdr, etc,
3941 * the timedout transactions. The next TMF is issued either by the
3942 * completion handler of the current TMF waking our recovery thread,
3943 * or the TMF timeout handler causing a hard reset sequence.
3944 */
3945 static void
mpt_recover_commands(struct mpt_softc * mpt)3946 mpt_recover_commands(struct mpt_softc *mpt)
3947 {
3948 request_t *req;
3949 union ccb *ccb;
3950 int error;
3951
3952 if (TAILQ_EMPTY(&mpt->request_timeout_list) != 0) {
3953 /*
3954 * No work to do- leave.
3955 */
3956 mpt_prt(mpt, "mpt_recover_commands: no requests.\n");
3957 return;
3958 }
3959
3960 /*
3961 * Flush any commands whose completion coincides with their timeout.
3962 */
3963 mpt_intr(mpt);
3964
3965 if (TAILQ_EMPTY(&mpt->request_timeout_list) != 0) {
3966 /*
3967 * The timedout commands have already
3968 * completed. This typically means
3969 * that either the timeout value was on
3970 * the hairy edge of what the device
3971 * requires or - more likely - interrupts
3972 * are not happening.
3973 */
3974 mpt_prt(mpt, "Timedout requests already complete. "
3975 "Interrupts may not be functioning.\n");
3976 mpt_enable_ints(mpt);
3977 return;
3978 }
3979
3980 /*
3981 * We have no visibility into the current state of the
3982 * controller, so attempt to abort the commands in the
3983 * order they timed-out. For initiator commands, we
3984 * depend on the reply handler pulling requests off
3985 * the timeout list.
3986 */
3987 while ((req = TAILQ_FIRST(&mpt->request_timeout_list)) != NULL) {
3988 uint16_t status;
3989 uint8_t response;
3990 MSG_REQUEST_HEADER *hdrp = req->req_vbuf;
3991
3992 mpt_prt(mpt, "attempting to abort req %p:%u function %x\n",
3993 req, req->serno, hdrp->Function);
3994 ccb = req->ccb;
3995 if (ccb == NULL) {
3996 mpt_prt(mpt, "null ccb in timed out request. "
3997 "Resetting Controller.\n");
3998 mpt_reset(mpt, TRUE);
3999 continue;
4000 }
4001 mpt_set_ccb_status(ccb, CAM_CMD_TIMEOUT);
4002
4003 /*
4004 * Check to see if this is not an initiator command and
4005 * deal with it differently if it is.
4006 */
4007 switch (hdrp->Function) {
4008 case MPI_FUNCTION_SCSI_IO_REQUEST:
4009 case MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH:
4010 break;
4011 default:
4012 /*
4013 * XXX: FIX ME: need to abort target assists...
4014 */
4015 mpt_prt(mpt, "just putting it back on the pend q\n");
4016 TAILQ_REMOVE(&mpt->request_timeout_list, req, links);
4017 TAILQ_INSERT_HEAD(&mpt->request_pending_list, req,
4018 links);
4019 continue;
4020 }
4021
4022 error = mpt_scsi_send_tmf(mpt,
4023 MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
4024 0, 0, ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
4025 htole32(req->index | scsi_io_handler_id), TRUE);
4026
4027 if (error != 0) {
4028 /*
4029 * mpt_scsi_send_tmf hard resets on failure, so no
4030 * need to do so here. Our queue should be emptied
4031 * by the hard reset.
4032 */
4033 continue;
4034 }
4035
4036 error = mpt_wait_req(mpt, mpt->tmf_req, REQ_STATE_DONE,
4037 REQ_STATE_DONE, TRUE, 500);
4038
4039 status = le16toh(mpt->tmf_req->IOCStatus);
4040 response = mpt->tmf_req->ResponseCode;
4041 mpt->tmf_req->state = REQ_STATE_FREE;
4042
4043 if (error != 0) {
4044 /*
4045 * If we've errored out,, reset the controller.
4046 */
4047 mpt_prt(mpt, "mpt_recover_commands: abort timed-out. "
4048 "Resetting controller\n");
4049 mpt_reset(mpt, TRUE);
4050 continue;
4051 }
4052
4053 if ((status & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4054 mpt_prt(mpt, "mpt_recover_commands: IOC Status 0x%x. "
4055 "Resetting controller.\n", status);
4056 mpt_reset(mpt, TRUE);
4057 continue;
4058 }
4059
4060 if (response != MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED &&
4061 response != MPI_SCSITASKMGMT_RSP_TM_COMPLETE) {
4062 mpt_prt(mpt, "mpt_recover_commands: TMF Response 0x%x. "
4063 "Resetting controller.\n", response);
4064 mpt_reset(mpt, TRUE);
4065 continue;
4066 }
4067 mpt_prt(mpt, "abort of req %p:%u completed\n", req, req->serno);
4068 }
4069 }
4070
4071 /************************ Target Mode Support ****************************/
4072 static void
mpt_fc_post_els(struct mpt_softc * mpt,request_t * req,int ioindex)4073 mpt_fc_post_els(struct mpt_softc *mpt, request_t *req, int ioindex)
4074 {
4075 MSG_LINK_SERVICE_BUFFER_POST_REQUEST *fc;
4076 PTR_SGE_TRANSACTION32 tep;
4077 PTR_SGE_SIMPLE32 se;
4078 bus_addr_t paddr;
4079 uint32_t fl;
4080
4081 paddr = req->req_pbuf;
4082 paddr += MPT_RQSL(mpt);
4083
4084 fc = req->req_vbuf;
4085 memset(fc, 0, MPT_REQUEST_AREA);
4086 fc->BufferCount = 1;
4087 fc->Function = MPI_FUNCTION_FC_LINK_SRVC_BUF_POST;
4088 fc->MsgContext = htole32(req->index | fc_els_handler_id);
4089
4090 /*
4091 * Okay, set up ELS buffer pointers. ELS buffer pointers
4092 * consist of a TE SGL element (with details length of zero)
4093 * followed by a SIMPLE SGL element which holds the address
4094 * of the buffer.
4095 */
4096
4097 tep = (PTR_SGE_TRANSACTION32) &fc->SGL;
4098
4099 tep->ContextSize = 4;
4100 tep->Flags = 0;
4101 tep->TransactionContext[0] = htole32(ioindex);
4102
4103 se = (PTR_SGE_SIMPLE32) &tep->TransactionDetails[0];
4104 fl =
4105 MPI_SGE_FLAGS_HOST_TO_IOC |
4106 MPI_SGE_FLAGS_SIMPLE_ELEMENT |
4107 MPI_SGE_FLAGS_LAST_ELEMENT |
4108 MPI_SGE_FLAGS_END_OF_LIST |
4109 MPI_SGE_FLAGS_END_OF_BUFFER;
4110 fl <<= MPI_SGE_FLAGS_SHIFT;
4111 fl |= (MPT_NRFM(mpt) - MPT_RQSL(mpt));
4112 se->FlagsLength = htole32(fl);
4113 se->Address = htole32((uint32_t) paddr);
4114 mpt_lprt(mpt, MPT_PRT_DEBUG,
4115 "add ELS index %d ioindex %d for %p:%u\n",
4116 req->index, ioindex, req, req->serno);
4117 KASSERT(((req->state & REQ_STATE_LOCKED) != 0),
4118 ("mpt_fc_post_els: request not locked"));
4119 mpt_send_cmd(mpt, req);
4120 }
4121
4122 static void
mpt_post_target_command(struct mpt_softc * mpt,request_t * req,int ioindex)4123 mpt_post_target_command(struct mpt_softc *mpt, request_t *req, int ioindex)
4124 {
4125 PTR_MSG_TARGET_CMD_BUFFER_POST_REQUEST fc;
4126 PTR_CMD_BUFFER_DESCRIPTOR cb;
4127 bus_addr_t paddr;
4128
4129 paddr = req->req_pbuf;
4130 paddr += MPT_RQSL(mpt);
4131 memset(req->req_vbuf, 0, MPT_REQUEST_AREA);
4132 MPT_TGT_STATE(mpt, req)->state = TGT_STATE_LOADING;
4133
4134 fc = req->req_vbuf;
4135 fc->BufferCount = 1;
4136 fc->Function = MPI_FUNCTION_TARGET_CMD_BUFFER_POST;
4137 fc->BufferLength = MIN(MPT_REQUEST_AREA - MPT_RQSL(mpt), UINT8_MAX);
4138 fc->MsgContext = htole32(req->index | mpt->scsi_tgt_handler_id);
4139
4140 cb = &fc->Buffer[0];
4141 cb->IoIndex = htole16(ioindex);
4142 cb->u.PhysicalAddress32 = htole32((U32) paddr);
4143
4144 mpt_check_doorbell(mpt);
4145 mpt_send_cmd(mpt, req);
4146 }
4147
4148 static int
mpt_add_els_buffers(struct mpt_softc * mpt)4149 mpt_add_els_buffers(struct mpt_softc *mpt)
4150 {
4151 int i;
4152
4153 if (mpt->is_fc == 0) {
4154 return (TRUE);
4155 }
4156
4157 if (mpt->els_cmds_allocated) {
4158 return (TRUE);
4159 }
4160
4161 mpt->els_cmd_ptrs = malloc(MPT_MAX_ELS * sizeof (request_t *),
4162 M_DEVBUF, M_NOWAIT | M_ZERO);
4163
4164 if (mpt->els_cmd_ptrs == NULL) {
4165 return (FALSE);
4166 }
4167
4168 /*
4169 * Feed the chip some ELS buffer resources
4170 */
4171 for (i = 0; i < MPT_MAX_ELS; i++) {
4172 request_t *req = mpt_get_request(mpt, FALSE);
4173 if (req == NULL) {
4174 break;
4175 }
4176 req->state |= REQ_STATE_LOCKED;
4177 mpt->els_cmd_ptrs[i] = req;
4178 mpt_fc_post_els(mpt, req, i);
4179 }
4180
4181 if (i == 0) {
4182 mpt_prt(mpt, "unable to add ELS buffer resources\n");
4183 free(mpt->els_cmd_ptrs, M_DEVBUF);
4184 mpt->els_cmd_ptrs = NULL;
4185 return (FALSE);
4186 }
4187 if (i != MPT_MAX_ELS) {
4188 mpt_lprt(mpt, MPT_PRT_INFO,
4189 "only added %d of %d ELS buffers\n", i, MPT_MAX_ELS);
4190 }
4191 mpt->els_cmds_allocated = i;
4192 return(TRUE);
4193 }
4194
4195 static int
mpt_add_target_commands(struct mpt_softc * mpt)4196 mpt_add_target_commands(struct mpt_softc *mpt)
4197 {
4198 int i, max;
4199
4200 if (mpt->tgt_cmd_ptrs) {
4201 return (TRUE);
4202 }
4203
4204 max = MPT_MAX_REQUESTS(mpt) >> 1;
4205 if (max > mpt->mpt_max_tgtcmds) {
4206 max = mpt->mpt_max_tgtcmds;
4207 }
4208 mpt->tgt_cmd_ptrs =
4209 malloc(max * sizeof (request_t *), M_DEVBUF, M_NOWAIT | M_ZERO);
4210 if (mpt->tgt_cmd_ptrs == NULL) {
4211 mpt_prt(mpt,
4212 "mpt_add_target_commands: could not allocate cmd ptrs\n");
4213 return (FALSE);
4214 }
4215
4216 for (i = 0; i < max; i++) {
4217 request_t *req;
4218
4219 req = mpt_get_request(mpt, FALSE);
4220 if (req == NULL) {
4221 break;
4222 }
4223 req->state |= REQ_STATE_LOCKED;
4224 mpt->tgt_cmd_ptrs[i] = req;
4225 mpt_post_target_command(mpt, req, i);
4226 }
4227
4228 if (i == 0) {
4229 mpt_lprt(mpt, MPT_PRT_ERROR, "could not add any target bufs\n");
4230 free(mpt->tgt_cmd_ptrs, M_DEVBUF);
4231 mpt->tgt_cmd_ptrs = NULL;
4232 return (FALSE);
4233 }
4234
4235 mpt->tgt_cmds_allocated = i;
4236
4237 if (i < max) {
4238 mpt_lprt(mpt, MPT_PRT_INFO,
4239 "added %d of %d target bufs\n", i, max);
4240 }
4241 return (i);
4242 }
4243
4244 static int
mpt_enable_lun(struct mpt_softc * mpt,target_id_t tgt,lun_id_t lun)4245 mpt_enable_lun(struct mpt_softc *mpt, target_id_t tgt, lun_id_t lun)
4246 {
4247
4248 if (tgt == CAM_TARGET_WILDCARD && lun == CAM_LUN_WILDCARD) {
4249 mpt->twildcard = 1;
4250 } else if (lun >= MPT_MAX_LUNS) {
4251 return (EINVAL);
4252 } else if (tgt != CAM_TARGET_WILDCARD && tgt != 0) {
4253 return (EINVAL);
4254 }
4255 if (mpt->tenabled == 0) {
4256 if (mpt->is_fc) {
4257 (void) mpt_fc_reset_link(mpt, 0);
4258 }
4259 mpt->tenabled = 1;
4260 }
4261 if (lun == CAM_LUN_WILDCARD) {
4262 mpt->trt_wildcard.enabled = 1;
4263 } else {
4264 mpt->trt[lun].enabled = 1;
4265 }
4266 return (0);
4267 }
4268
4269 static int
mpt_disable_lun(struct mpt_softc * mpt,target_id_t tgt,lun_id_t lun)4270 mpt_disable_lun(struct mpt_softc *mpt, target_id_t tgt, lun_id_t lun)
4271 {
4272 int i;
4273
4274 if (tgt == CAM_TARGET_WILDCARD && lun == CAM_LUN_WILDCARD) {
4275 mpt->twildcard = 0;
4276 } else if (lun >= MPT_MAX_LUNS) {
4277 return (EINVAL);
4278 } else if (tgt != CAM_TARGET_WILDCARD && tgt != 0) {
4279 return (EINVAL);
4280 }
4281 if (lun == CAM_LUN_WILDCARD) {
4282 mpt->trt_wildcard.enabled = 0;
4283 } else {
4284 mpt->trt[lun].enabled = 0;
4285 }
4286 for (i = 0; i < MPT_MAX_LUNS; i++) {
4287 if (mpt->trt[i].enabled) {
4288 break;
4289 }
4290 }
4291 if (i == MPT_MAX_LUNS && mpt->twildcard == 0) {
4292 if (mpt->is_fc) {
4293 (void) mpt_fc_reset_link(mpt, 0);
4294 }
4295 mpt->tenabled = 0;
4296 }
4297 return (0);
4298 }
4299
4300 /*
4301 * Called with MPT lock held
4302 */
4303 static void
mpt_target_start_io(struct mpt_softc * mpt,union ccb * ccb)4304 mpt_target_start_io(struct mpt_softc *mpt, union ccb *ccb)
4305 {
4306 struct ccb_scsiio *csio = &ccb->csio;
4307 request_t *cmd_req = MPT_TAG_2_REQ(mpt, csio->tag_id);
4308 mpt_tgt_state_t *tgt = MPT_TGT_STATE(mpt, cmd_req);
4309
4310 switch (tgt->state) {
4311 case TGT_STATE_IN_CAM:
4312 break;
4313 case TGT_STATE_MOVING_DATA:
4314 mpt_set_ccb_status(ccb, CAM_REQUEUE_REQ);
4315 xpt_freeze_simq(mpt->sim, 1);
4316 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
4317 tgt->ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
4318 xpt_done(ccb);
4319 return;
4320 default:
4321 mpt_prt(mpt, "ccb %p flags 0x%x tag 0x%08x had bad request "
4322 "starting I/O\n", ccb, csio->ccb_h.flags, csio->tag_id);
4323 mpt_tgt_dump_req_state(mpt, cmd_req);
4324 mpt_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
4325 xpt_done(ccb);
4326 return;
4327 }
4328
4329 if (csio->dxfer_len) {
4330 bus_dmamap_callback_t *cb;
4331 PTR_MSG_TARGET_ASSIST_REQUEST ta;
4332 request_t *req;
4333 int error;
4334
4335 KASSERT((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE,
4336 ("dxfer_len %u but direction is NONE", csio->dxfer_len));
4337
4338 if ((req = mpt_get_request(mpt, FALSE)) == NULL) {
4339 if (mpt->outofbeer == 0) {
4340 mpt->outofbeer = 1;
4341 xpt_freeze_simq(mpt->sim, 1);
4342 mpt_lprt(mpt, MPT_PRT_DEBUG, "FREEZEQ\n");
4343 }
4344 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
4345 mpt_set_ccb_status(ccb, CAM_REQUEUE_REQ);
4346 xpt_done(ccb);
4347 return;
4348 }
4349 ccb->ccb_h.status = CAM_SIM_QUEUED | CAM_REQ_INPROG;
4350 if (sizeof (bus_addr_t) > 4) {
4351 cb = mpt_execute_req_a64;
4352 } else {
4353 cb = mpt_execute_req;
4354 }
4355
4356 req->ccb = ccb;
4357 ccb->ccb_h.ccb_req_ptr = req;
4358
4359 /*
4360 * Record the currently active ccb and the
4361 * request for it in our target state area.
4362 */
4363 tgt->ccb = ccb;
4364 tgt->req = req;
4365
4366 memset(req->req_vbuf, 0, MPT_RQSL(mpt));
4367 ta = req->req_vbuf;
4368
4369 if (mpt->is_sas) {
4370 PTR_MPI_TARGET_SSP_CMD_BUFFER ssp =
4371 cmd_req->req_vbuf;
4372 ta->QueueTag = ssp->InitiatorTag;
4373 } else if (mpt->is_spi) {
4374 PTR_MPI_TARGET_SCSI_SPI_CMD_BUFFER sp =
4375 cmd_req->req_vbuf;
4376 ta->QueueTag = sp->Tag;
4377 }
4378 ta->Function = MPI_FUNCTION_TARGET_ASSIST;
4379 ta->MsgContext = htole32(req->index | mpt->scsi_tgt_handler_id);
4380 ta->ReplyWord = htole32(tgt->reply_desc);
4381 be64enc(ta->LUN, CAM_EXTLUN_BYTE_SWIZZLE(csio->ccb_h.target_lun));
4382
4383 ta->RelativeOffset = tgt->bytes_xfered;
4384 ta->DataLength = ccb->csio.dxfer_len;
4385 if (ta->DataLength > tgt->resid) {
4386 ta->DataLength = tgt->resid;
4387 }
4388
4389 /*
4390 * XXX Should be done after data transfer completes?
4391 */
4392 csio->resid = csio->dxfer_len - ta->DataLength;
4393 tgt->resid -= csio->dxfer_len;
4394 tgt->bytes_xfered += csio->dxfer_len;
4395
4396 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
4397 ta->TargetAssistFlags |=
4398 TARGET_ASSIST_FLAGS_DATA_DIRECTION;
4399 }
4400
4401 #ifdef WE_TRUST_AUTO_GOOD_STATUS
4402 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) &&
4403 csio->scsi_status == SCSI_STATUS_OK && tgt->resid == 0) {
4404 ta->TargetAssistFlags |=
4405 TARGET_ASSIST_FLAGS_AUTO_STATUS;
4406 }
4407 #endif
4408 tgt->state = TGT_STATE_SETTING_UP_FOR_DATA;
4409
4410 mpt_lprt(mpt, MPT_PRT_DEBUG,
4411 "DATA_CCB %p tag %x %u bytes %u resid flg %x req %p:%u "
4412 "nxtstate=%d\n", csio, csio->tag_id, csio->dxfer_len,
4413 tgt->resid, ccb->ccb_h.flags, req, req->serno, tgt->state);
4414
4415 error = bus_dmamap_load_ccb(mpt->buffer_dmat, req->dmap, ccb,
4416 cb, req, 0);
4417 if (error == EINPROGRESS) {
4418 xpt_freeze_simq(mpt->sim, 1);
4419 ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
4420 }
4421 } else {
4422 /*
4423 * XXX: I don't know why this seems to happen, but
4424 * XXX: completing the CCB seems to make things happy.
4425 * XXX: This seems to happen if the initiator requests
4426 * XXX: enough data that we have to do multiple CTIOs.
4427 */
4428 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) == 0) {
4429 mpt_lprt(mpt, MPT_PRT_DEBUG,
4430 "Meaningless STATUS CCB (%p): flags %x status %x "
4431 "resid %d bytes_xfered %u\n", ccb, ccb->ccb_h.flags,
4432 ccb->ccb_h.status, tgt->resid, tgt->bytes_xfered);
4433 mpt_set_ccb_status(ccb, CAM_REQ_CMP);
4434 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
4435 xpt_done(ccb);
4436 return;
4437 }
4438 mpt_scsi_tgt_status(mpt, ccb, cmd_req, csio->scsi_status,
4439 (void *)&csio->sense_data,
4440 (ccb->ccb_h.flags & CAM_SEND_SENSE) ?
4441 csio->sense_len : 0);
4442 }
4443 }
4444
4445 static void
mpt_scsi_tgt_local(struct mpt_softc * mpt,request_t * cmd_req,lun_id_t lun,int send,uint8_t * data,size_t length)4446 mpt_scsi_tgt_local(struct mpt_softc *mpt, request_t *cmd_req,
4447 lun_id_t lun, int send, uint8_t *data, size_t length)
4448 {
4449 mpt_tgt_state_t *tgt;
4450 PTR_MSG_TARGET_ASSIST_REQUEST ta;
4451 SGE_SIMPLE32 *se;
4452 uint32_t flags;
4453 uint8_t *dptr;
4454 bus_addr_t pptr;
4455 request_t *req;
4456
4457 /*
4458 * We enter with resid set to the data load for the command.
4459 */
4460 tgt = MPT_TGT_STATE(mpt, cmd_req);
4461 if (length == 0 || tgt->resid == 0) {
4462 tgt->resid = 0;
4463 mpt_scsi_tgt_status(mpt, NULL, cmd_req, 0, NULL, 0);
4464 return;
4465 }
4466
4467 if ((req = mpt_get_request(mpt, FALSE)) == NULL) {
4468 mpt_prt(mpt, "out of resources- dropping local response\n");
4469 return;
4470 }
4471 tgt->is_local = 1;
4472
4473 memset(req->req_vbuf, 0, MPT_RQSL(mpt));
4474 ta = req->req_vbuf;
4475
4476 if (mpt->is_sas) {
4477 PTR_MPI_TARGET_SSP_CMD_BUFFER ssp = cmd_req->req_vbuf;
4478 ta->QueueTag = ssp->InitiatorTag;
4479 } else if (mpt->is_spi) {
4480 PTR_MPI_TARGET_SCSI_SPI_CMD_BUFFER sp = cmd_req->req_vbuf;
4481 ta->QueueTag = sp->Tag;
4482 }
4483 ta->Function = MPI_FUNCTION_TARGET_ASSIST;
4484 ta->MsgContext = htole32(req->index | mpt->scsi_tgt_handler_id);
4485 ta->ReplyWord = htole32(tgt->reply_desc);
4486 be64enc(ta->LUN, CAM_EXTLUN_BYTE_SWIZZLE(lun));
4487 ta->RelativeOffset = 0;
4488 ta->DataLength = length;
4489
4490 dptr = req->req_vbuf;
4491 dptr += MPT_RQSL(mpt);
4492 pptr = req->req_pbuf;
4493 pptr += MPT_RQSL(mpt);
4494 memcpy(dptr, data, min(length, MPT_RQSL(mpt)));
4495
4496 se = (SGE_SIMPLE32 *) &ta->SGL[0];
4497 memset(se, 0,sizeof (*se));
4498
4499 flags = MPI_SGE_FLAGS_SIMPLE_ELEMENT;
4500 if (send) {
4501 ta->TargetAssistFlags |= TARGET_ASSIST_FLAGS_DATA_DIRECTION;
4502 flags |= MPI_SGE_FLAGS_HOST_TO_IOC;
4503 }
4504 se->Address = pptr;
4505 MPI_pSGE_SET_LENGTH(se, length);
4506 flags |= MPI_SGE_FLAGS_LAST_ELEMENT;
4507 flags |= MPI_SGE_FLAGS_END_OF_LIST | MPI_SGE_FLAGS_END_OF_BUFFER;
4508 MPI_pSGE_SET_FLAGS(se, flags);
4509
4510 tgt->ccb = NULL;
4511 tgt->req = req;
4512 tgt->resid -= length;
4513 tgt->bytes_xfered = length;
4514 #ifdef WE_TRUST_AUTO_GOOD_STATUS
4515 tgt->state = TGT_STATE_MOVING_DATA_AND_STATUS;
4516 #else
4517 tgt->state = TGT_STATE_MOVING_DATA;
4518 #endif
4519 mpt_send_cmd(mpt, req);
4520 }
4521
4522 /*
4523 * Abort queued up CCBs
4524 */
4525 static cam_status
mpt_abort_target_ccb(struct mpt_softc * mpt,union ccb * ccb)4526 mpt_abort_target_ccb(struct mpt_softc *mpt, union ccb *ccb)
4527 {
4528 struct mpt_hdr_stailq *lp;
4529 struct ccb_hdr *srch;
4530 union ccb *accb = ccb->cab.abort_ccb;
4531 tgt_resource_t *trtp;
4532 mpt_tgt_state_t *tgt;
4533 request_t *req;
4534 uint32_t tag;
4535
4536 mpt_lprt(mpt, MPT_PRT_DEBUG, "aborting ccb %p\n", accb);
4537 if (ccb->ccb_h.target_lun == CAM_LUN_WILDCARD)
4538 trtp = &mpt->trt_wildcard;
4539 else
4540 trtp = &mpt->trt[ccb->ccb_h.target_lun];
4541 if (accb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) {
4542 lp = &trtp->atios;
4543 tag = accb->atio.tag_id;
4544 } else {
4545 lp = &trtp->inots;
4546 tag = accb->cin1.tag_id;
4547 }
4548
4549 /* Search the CCB among queued. */
4550 STAILQ_FOREACH(srch, lp, sim_links.stqe) {
4551 if (srch != &accb->ccb_h)
4552 continue;
4553 STAILQ_REMOVE(lp, srch, ccb_hdr, sim_links.stqe);
4554 accb->ccb_h.status = CAM_REQ_ABORTED;
4555 xpt_done(accb);
4556 return (CAM_REQ_CMP);
4557 }
4558
4559 /* Search the CCB among running. */
4560 req = MPT_TAG_2_REQ(mpt, tag);
4561 tgt = MPT_TGT_STATE(mpt, req);
4562 if (tgt->tag_id == tag) {
4563 mpt_abort_target_cmd(mpt, req);
4564 return (CAM_REQ_CMP);
4565 }
4566
4567 return (CAM_UA_ABORT);
4568 }
4569
4570 /*
4571 * Ask the MPT to abort the current target command
4572 */
4573 static int
mpt_abort_target_cmd(struct mpt_softc * mpt,request_t * cmd_req)4574 mpt_abort_target_cmd(struct mpt_softc *mpt, request_t *cmd_req)
4575 {
4576 int error;
4577 request_t *req;
4578 PTR_MSG_TARGET_MODE_ABORT abtp;
4579
4580 req = mpt_get_request(mpt, FALSE);
4581 if (req == NULL) {
4582 return (-1);
4583 }
4584 abtp = req->req_vbuf;
4585 memset(abtp, 0, sizeof (*abtp));
4586
4587 abtp->MsgContext = htole32(req->index | mpt->scsi_tgt_handler_id);
4588 abtp->AbortType = TARGET_MODE_ABORT_TYPE_EXACT_IO;
4589 abtp->Function = MPI_FUNCTION_TARGET_MODE_ABORT;
4590 abtp->ReplyWord = htole32(MPT_TGT_STATE(mpt, cmd_req)->reply_desc);
4591 error = 0;
4592 if (mpt->is_fc || mpt->is_sas) {
4593 mpt_send_cmd(mpt, req);
4594 } else {
4595 error = mpt_send_handshake_cmd(mpt, sizeof(*req), req);
4596 }
4597 return (error);
4598 }
4599
4600 /*
4601 * WE_TRUST_AUTO_GOOD_STATUS- I've found that setting
4602 * TARGET_STATUS_SEND_FLAGS_AUTO_GOOD_STATUS leads the
4603 * FC929 to set bogus FC_RSP fields (nonzero residuals
4604 * but w/o RESID fields set). This causes QLogic initiators
4605 * to think maybe that a frame was lost.
4606 *
4607 * WE_CAN_USE_AUTO_REPOST- we can't use AUTO_REPOST because
4608 * we use allocated requests to do TARGET_ASSIST and we
4609 * need to know when to release them.
4610 */
4611
4612 static void
mpt_scsi_tgt_status(struct mpt_softc * mpt,union ccb * ccb,request_t * cmd_req,uint8_t status,uint8_t const * sense_data,u_int sense_len)4613 mpt_scsi_tgt_status(struct mpt_softc *mpt, union ccb *ccb, request_t *cmd_req,
4614 uint8_t status, uint8_t const *sense_data, u_int sense_len)
4615 {
4616 uint8_t *cmd_vbuf;
4617 mpt_tgt_state_t *tgt;
4618 PTR_MSG_TARGET_STATUS_SEND_REQUEST tp;
4619 request_t *req;
4620 bus_addr_t paddr;
4621 int resplen = 0;
4622 uint32_t fl;
4623
4624 cmd_vbuf = cmd_req->req_vbuf;
4625 cmd_vbuf += MPT_RQSL(mpt);
4626 tgt = MPT_TGT_STATE(mpt, cmd_req);
4627
4628 if ((req = mpt_get_request(mpt, FALSE)) == NULL) {
4629 if (mpt->outofbeer == 0) {
4630 mpt->outofbeer = 1;
4631 xpt_freeze_simq(mpt->sim, 1);
4632 mpt_lprt(mpt, MPT_PRT_DEBUG, "FREEZEQ\n");
4633 }
4634 if (ccb) {
4635 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
4636 mpt_set_ccb_status(ccb, CAM_REQUEUE_REQ);
4637 xpt_done(ccb);
4638 } else {
4639 mpt_prt(mpt,
4640 "could not allocate status request- dropping\n");
4641 }
4642 return;
4643 }
4644 req->ccb = ccb;
4645 if (ccb) {
4646 ccb->ccb_h.ccb_mpt_ptr = mpt;
4647 ccb->ccb_h.ccb_req_ptr = req;
4648 }
4649
4650 /*
4651 * Record the currently active ccb, if any, and the
4652 * request for it in our target state area.
4653 */
4654 tgt->ccb = ccb;
4655 tgt->req = req;
4656 tgt->state = TGT_STATE_SENDING_STATUS;
4657
4658 tp = req->req_vbuf;
4659 paddr = req->req_pbuf;
4660 paddr += MPT_RQSL(mpt);
4661
4662 memset(tp, 0, sizeof (*tp));
4663 tp->StatusCode = status;
4664 tp->Function = MPI_FUNCTION_TARGET_STATUS_SEND;
4665 if (mpt->is_fc) {
4666 PTR_MPI_TARGET_FCP_CMD_BUFFER fc =
4667 (PTR_MPI_TARGET_FCP_CMD_BUFFER) cmd_vbuf;
4668 uint8_t *sts_vbuf;
4669 uint32_t *rsp;
4670
4671 sts_vbuf = req->req_vbuf;
4672 sts_vbuf += MPT_RQSL(mpt);
4673 rsp = (uint32_t *) sts_vbuf;
4674 memcpy(tp->LUN, fc->FcpLun, sizeof (tp->LUN));
4675
4676 /*
4677 * The MPI_TARGET_FCP_RSP_BUFFER define is unfortunate.
4678 * It has to be big-endian in memory and is organized
4679 * in 32 bit words, which are much easier to deal with
4680 * as words which are swizzled as needed.
4681 *
4682 * All we're filling here is the FC_RSP payload.
4683 * We may just have the chip synthesize it if
4684 * we have no residual and an OK status.
4685 *
4686 */
4687 memset(rsp, 0, sizeof (MPI_TARGET_FCP_RSP_BUFFER));
4688
4689 rsp[2] = htobe32(status);
4690 #define MIN_FCP_RESPONSE_SIZE 24
4691 #ifndef WE_TRUST_AUTO_GOOD_STATUS
4692 resplen = MIN_FCP_RESPONSE_SIZE;
4693 #endif
4694 if (tgt->resid < 0) {
4695 rsp[2] |= htobe32(0x400); /* XXXX NEED MNEMONIC!!!! */
4696 rsp[3] = htobe32(-tgt->resid);
4697 resplen = MIN_FCP_RESPONSE_SIZE;
4698 } else if (tgt->resid > 0) {
4699 rsp[2] |= htobe32(0x800); /* XXXX NEED MNEMONIC!!!! */
4700 rsp[3] = htobe32(tgt->resid);
4701 resplen = MIN_FCP_RESPONSE_SIZE;
4702 }
4703 if (sense_len > 0) {
4704 rsp[2] |= htobe32(0x200); /* XXXX NEED MNEMONIC!!!! */
4705 rsp[4] = htobe32(sense_len);
4706 memcpy(&rsp[6], sense_data, sense_len);
4707 resplen = MIN_FCP_RESPONSE_SIZE + sense_len;
4708 }
4709 } else if (mpt->is_sas) {
4710 PTR_MPI_TARGET_SSP_CMD_BUFFER ssp =
4711 (PTR_MPI_TARGET_SSP_CMD_BUFFER) cmd_vbuf;
4712 memcpy(tp->LUN, ssp->LogicalUnitNumber, sizeof (tp->LUN));
4713 } else {
4714 PTR_MPI_TARGET_SCSI_SPI_CMD_BUFFER sp =
4715 (PTR_MPI_TARGET_SCSI_SPI_CMD_BUFFER) cmd_vbuf;
4716 tp->QueueTag = htole16(sp->Tag);
4717 memcpy(tp->LUN, sp->LogicalUnitNumber, sizeof (tp->LUN));
4718 }
4719
4720 tp->ReplyWord = htole32(tgt->reply_desc);
4721 tp->MsgContext = htole32(req->index | mpt->scsi_tgt_handler_id);
4722
4723 #ifdef WE_CAN_USE_AUTO_REPOST
4724 tp->MsgFlags = TARGET_STATUS_SEND_FLAGS_REPOST_CMD_BUFFER;
4725 #endif
4726 if (status == SCSI_STATUS_OK && resplen == 0) {
4727 tp->MsgFlags |= TARGET_STATUS_SEND_FLAGS_AUTO_GOOD_STATUS;
4728 } else {
4729 tp->StatusDataSGE.u.Address32 = htole32((uint32_t) paddr);
4730 fl = MPI_SGE_FLAGS_HOST_TO_IOC |
4731 MPI_SGE_FLAGS_SIMPLE_ELEMENT |
4732 MPI_SGE_FLAGS_LAST_ELEMENT |
4733 MPI_SGE_FLAGS_END_OF_LIST |
4734 MPI_SGE_FLAGS_END_OF_BUFFER;
4735 fl <<= MPI_SGE_FLAGS_SHIFT;
4736 fl |= resplen;
4737 tp->StatusDataSGE.FlagsLength = htole32(fl);
4738 }
4739
4740 mpt_lprt(mpt, MPT_PRT_DEBUG,
4741 "STATUS_CCB %p (with%s sense) tag %x req %p:%u resid %u\n",
4742 ccb, sense_len > 0 ? "" : "out", tgt->tag_id,
4743 req, req->serno, tgt->resid);
4744 if (mpt->verbose > MPT_PRT_DEBUG)
4745 mpt_print_request(req->req_vbuf);
4746 if (ccb) {
4747 ccb->ccb_h.status = CAM_SIM_QUEUED | CAM_REQ_INPROG;
4748 mpt_req_timeout(req, SBT_1S * 60, mpt_timeout, ccb);
4749 }
4750 mpt_send_cmd(mpt, req);
4751 }
4752
4753 static void
mpt_scsi_tgt_tsk_mgmt(struct mpt_softc * mpt,request_t * req,mpt_task_mgmt_t fc,tgt_resource_t * trtp,int init_id)4754 mpt_scsi_tgt_tsk_mgmt(struct mpt_softc *mpt, request_t *req, mpt_task_mgmt_t fc,
4755 tgt_resource_t *trtp, int init_id)
4756 {
4757 struct ccb_immediate_notify *inot;
4758 mpt_tgt_state_t *tgt;
4759
4760 tgt = MPT_TGT_STATE(mpt, req);
4761 inot = (struct ccb_immediate_notify *) STAILQ_FIRST(&trtp->inots);
4762 if (inot == NULL) {
4763 mpt_lprt(mpt, MPT_PRT_WARN, "no INOTSs- sending back BSY\n");
4764 mpt_scsi_tgt_status(mpt, NULL, req, SCSI_STATUS_BUSY, NULL, 0);
4765 return;
4766 }
4767 STAILQ_REMOVE_HEAD(&trtp->inots, sim_links.stqe);
4768 mpt_lprt(mpt, MPT_PRT_DEBUG1,
4769 "Get FREE INOT %p lun %jx\n", inot,
4770 (uintmax_t)inot->ccb_h.target_lun);
4771
4772 inot->initiator_id = init_id; /* XXX */
4773 inot->tag_id = tgt->tag_id;
4774 inot->seq_id = 0;
4775 /*
4776 * This is a somewhat grotesque attempt to map from task management
4777 * to old style SCSI messages. God help us all.
4778 */
4779 switch (fc) {
4780 case MPT_QUERY_TASK_SET:
4781 inot->arg = MSG_QUERY_TASK_SET;
4782 break;
4783 case MPT_ABORT_TASK_SET:
4784 inot->arg = MSG_ABORT_TASK_SET;
4785 break;
4786 case MPT_CLEAR_TASK_SET:
4787 inot->arg = MSG_CLEAR_TASK_SET;
4788 break;
4789 case MPT_QUERY_ASYNC_EVENT:
4790 inot->arg = MSG_QUERY_ASYNC_EVENT;
4791 break;
4792 case MPT_LOGICAL_UNIT_RESET:
4793 inot->arg = MSG_LOGICAL_UNIT_RESET;
4794 break;
4795 case MPT_TARGET_RESET:
4796 inot->arg = MSG_TARGET_RESET;
4797 break;
4798 case MPT_CLEAR_ACA:
4799 inot->arg = MSG_CLEAR_ACA;
4800 break;
4801 default:
4802 inot->arg = MSG_NOOP;
4803 break;
4804 }
4805 tgt->ccb = (union ccb *) inot;
4806 inot->ccb_h.status = CAM_MESSAGE_RECV;
4807 xpt_done((union ccb *)inot);
4808 }
4809
4810 static void
mpt_scsi_tgt_atio(struct mpt_softc * mpt,request_t * req,uint32_t reply_desc)4811 mpt_scsi_tgt_atio(struct mpt_softc *mpt, request_t *req, uint32_t reply_desc)
4812 {
4813 static uint8_t null_iqd[SHORT_INQUIRY_LENGTH] = {
4814 0x7f, 0x00, 0x02, 0x02, 0x20, 0x00, 0x00, 0x32,
4815 'F', 'R', 'E', 'E', 'B', 'S', 'D', ' ',
4816 'L', 'S', 'I', '-', 'L', 'O', 'G', 'I',
4817 'C', ' ', 'N', 'U', 'L', 'D', 'E', 'V',
4818 '0', '0', '0', '1'
4819 };
4820 struct ccb_accept_tio *atiop;
4821 lun_id_t lun;
4822 int tag_action = 0;
4823 mpt_tgt_state_t *tgt;
4824 tgt_resource_t *trtp = NULL;
4825 U8 *lunptr;
4826 U8 *vbuf;
4827 U16 ioindex;
4828 mpt_task_mgmt_t fct = MPT_NIL_TMT_VALUE;
4829 uint8_t *cdbp;
4830
4831 /*
4832 * Stash info for the current command where we can get at it later.
4833 */
4834 vbuf = req->req_vbuf;
4835 vbuf += MPT_RQSL(mpt);
4836 if (mpt->verbose >= MPT_PRT_DEBUG) {
4837 mpt_dump_data(mpt, "mpt_scsi_tgt_atio response", vbuf,
4838 max(sizeof (MPI_TARGET_FCP_CMD_BUFFER),
4839 max(sizeof (MPI_TARGET_SSP_CMD_BUFFER),
4840 sizeof (MPI_TARGET_SCSI_SPI_CMD_BUFFER))));
4841 }
4842
4843 /*
4844 * Get our state pointer set up.
4845 */
4846 tgt = MPT_TGT_STATE(mpt, req);
4847 if (tgt->state != TGT_STATE_LOADED) {
4848 mpt_tgt_dump_req_state(mpt, req);
4849 panic("bad target state in mpt_scsi_tgt_atio");
4850 }
4851 memset(tgt, 0, sizeof (mpt_tgt_state_t));
4852 tgt->state = TGT_STATE_IN_CAM;
4853 tgt->reply_desc = reply_desc;
4854 ioindex = GET_IO_INDEX(reply_desc);
4855
4856 /*
4857 * The tag we construct here allows us to find the
4858 * original request that the command came in with.
4859 *
4860 * This way we don't have to depend on anything but the
4861 * tag to find things when CCBs show back up from CAM.
4862 */
4863 tgt->tag_id = MPT_MAKE_TAGID(mpt, req, ioindex);
4864
4865 if (mpt->is_fc) {
4866 PTR_MPI_TARGET_FCP_CMD_BUFFER fc;
4867 fc = (PTR_MPI_TARGET_FCP_CMD_BUFFER) vbuf;
4868 if (fc->FcpCntl[2]) {
4869 /*
4870 * Task Management Request
4871 */
4872 switch (fc->FcpCntl[2]) {
4873 case 0x1:
4874 fct = MPT_QUERY_TASK_SET;
4875 break;
4876 case 0x2:
4877 fct = MPT_ABORT_TASK_SET;
4878 break;
4879 case 0x4:
4880 fct = MPT_CLEAR_TASK_SET;
4881 break;
4882 case 0x8:
4883 fct = MPT_QUERY_ASYNC_EVENT;
4884 break;
4885 case 0x10:
4886 fct = MPT_LOGICAL_UNIT_RESET;
4887 break;
4888 case 0x20:
4889 fct = MPT_TARGET_RESET;
4890 break;
4891 case 0x40:
4892 fct = MPT_CLEAR_ACA;
4893 break;
4894 default:
4895 mpt_prt(mpt, "CORRUPTED TASK MGMT BITS: 0x%x\n",
4896 fc->FcpCntl[2]);
4897 mpt_scsi_tgt_status(mpt, NULL, req,
4898 SCSI_STATUS_OK, NULL, 0);
4899 return;
4900 }
4901 } else {
4902 switch (fc->FcpCntl[1]) {
4903 case 0:
4904 tag_action = MSG_SIMPLE_Q_TAG;
4905 break;
4906 case 1:
4907 tag_action = MSG_HEAD_OF_Q_TAG;
4908 break;
4909 case 2:
4910 tag_action = MSG_ORDERED_Q_TAG;
4911 break;
4912 default:
4913 /*
4914 * Bah. Ignore Untagged Queing and ACA
4915 */
4916 tag_action = MSG_SIMPLE_Q_TAG;
4917 break;
4918 }
4919 }
4920 tgt->resid = be32toh(fc->FcpDl);
4921 cdbp = fc->FcpCdb;
4922 lunptr = fc->FcpLun;
4923 tgt->itag = fc->OptionalOxid;
4924 } else if (mpt->is_sas) {
4925 PTR_MPI_TARGET_SSP_CMD_BUFFER ssp;
4926 ssp = (PTR_MPI_TARGET_SSP_CMD_BUFFER) vbuf;
4927 cdbp = ssp->CDB;
4928 lunptr = ssp->LogicalUnitNumber;
4929 tgt->itag = ssp->InitiatorTag;
4930 } else {
4931 PTR_MPI_TARGET_SCSI_SPI_CMD_BUFFER sp;
4932 sp = (PTR_MPI_TARGET_SCSI_SPI_CMD_BUFFER) vbuf;
4933 cdbp = sp->CDB;
4934 lunptr = sp->LogicalUnitNumber;
4935 tgt->itag = sp->Tag;
4936 }
4937
4938 lun = CAM_EXTLUN_BYTE_SWIZZLE(be64dec(lunptr));
4939
4940 /*
4941 * Deal with non-enabled or bad luns here.
4942 */
4943 if (lun >= MPT_MAX_LUNS || mpt->tenabled == 0 ||
4944 mpt->trt[lun].enabled == 0) {
4945 if (mpt->twildcard) {
4946 trtp = &mpt->trt_wildcard;
4947 } else if (fct == MPT_NIL_TMT_VALUE) {
4948 /*
4949 * In this case, we haven't got an upstream listener
4950 * for either a specific lun or wildcard luns. We
4951 * have to make some sensible response. For regular
4952 * inquiry, just return some NOT HERE inquiry data.
4953 * For VPD inquiry, report illegal field in cdb.
4954 * For REQUEST SENSE, just return NO SENSE data.
4955 * REPORT LUNS gets illegal command.
4956 * All other commands get 'no such device'.
4957 */
4958 uint8_t sense[MPT_SENSE_SIZE];
4959 size_t len;
4960
4961 memset(sense, 0, sizeof(sense));
4962 sense[0] = 0xf0;
4963 sense[2] = 0x5;
4964 sense[7] = 0x8;
4965
4966 switch (cdbp[0]) {
4967 case INQUIRY:
4968 {
4969 if (cdbp[1] != 0) {
4970 sense[12] = 0x26;
4971 sense[13] = 0x01;
4972 break;
4973 }
4974 len = min(tgt->resid, cdbp[4]);
4975 len = min(len, sizeof (null_iqd));
4976 mpt_lprt(mpt, MPT_PRT_DEBUG,
4977 "local inquiry %ld bytes\n", (long) len);
4978 mpt_scsi_tgt_local(mpt, req, lun, 1,
4979 null_iqd, len);
4980 return;
4981 }
4982 case REQUEST_SENSE:
4983 {
4984 sense[2] = 0x0;
4985 len = min(tgt->resid, cdbp[4]);
4986 len = min(len, sizeof (sense));
4987 mpt_lprt(mpt, MPT_PRT_DEBUG,
4988 "local reqsense %ld bytes\n", (long) len);
4989 mpt_scsi_tgt_local(mpt, req, lun, 1,
4990 sense, len);
4991 return;
4992 }
4993 case REPORT_LUNS:
4994 mpt_lprt(mpt, MPT_PRT_DEBUG, "REPORT LUNS\n");
4995 sense[12] = 0x26;
4996 return;
4997 default:
4998 mpt_lprt(mpt, MPT_PRT_DEBUG,
4999 "CMD 0x%x to unmanaged lun %jx\n",
5000 cdbp[0], (uintmax_t)lun);
5001 sense[12] = 0x25;
5002 break;
5003 }
5004 mpt_scsi_tgt_status(mpt, NULL, req,
5005 SCSI_STATUS_CHECK_COND, sense, sizeof(sense));
5006 return;
5007 }
5008 /* otherwise, leave trtp NULL */
5009 } else {
5010 trtp = &mpt->trt[lun];
5011 }
5012
5013 /*
5014 * Deal with any task management
5015 */
5016 if (fct != MPT_NIL_TMT_VALUE) {
5017 if (trtp == NULL) {
5018 mpt_prt(mpt, "task mgmt function %x but no listener\n",
5019 fct);
5020 mpt_scsi_tgt_status(mpt, NULL, req,
5021 SCSI_STATUS_OK, NULL, 0);
5022 } else {
5023 mpt_scsi_tgt_tsk_mgmt(mpt, req, fct, trtp,
5024 GET_INITIATOR_INDEX(reply_desc));
5025 }
5026 return;
5027 }
5028
5029 atiop = (struct ccb_accept_tio *) STAILQ_FIRST(&trtp->atios);
5030 if (atiop == NULL) {
5031 mpt_lprt(mpt, MPT_PRT_WARN,
5032 "no ATIOs for lun %jx- sending back %s\n", (uintmax_t)lun,
5033 mpt->tenabled? "QUEUE FULL" : "BUSY");
5034 mpt_scsi_tgt_status(mpt, NULL, req,
5035 mpt->tenabled? SCSI_STATUS_QUEUE_FULL : SCSI_STATUS_BUSY,
5036 NULL, 0);
5037 return;
5038 }
5039 STAILQ_REMOVE_HEAD(&trtp->atios, sim_links.stqe);
5040 mpt_lprt(mpt, MPT_PRT_DEBUG1,
5041 "Get FREE ATIO %p lun %jx\n", atiop,
5042 (uintmax_t)atiop->ccb_h.target_lun);
5043 atiop->ccb_h.ccb_mpt_ptr = mpt;
5044 atiop->ccb_h.status = CAM_CDB_RECVD;
5045 atiop->ccb_h.target_lun = lun;
5046 atiop->sense_len = 0;
5047 atiop->tag_id = tgt->tag_id;
5048 atiop->init_id = GET_INITIATOR_INDEX(reply_desc);
5049 atiop->cdb_len = 16;
5050 memcpy(atiop->cdb_io.cdb_bytes, cdbp, atiop->cdb_len);
5051 if (tag_action) {
5052 atiop->tag_action = tag_action;
5053 atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID;
5054 }
5055 if (mpt->verbose >= MPT_PRT_DEBUG) {
5056 int i;
5057 mpt_prt(mpt, "START_CCB %p for lun %jx CDB=<", atiop,
5058 (uintmax_t)atiop->ccb_h.target_lun);
5059 for (i = 0; i < atiop->cdb_len; i++) {
5060 mpt_prtc(mpt, "%02x%c", cdbp[i] & 0xff,
5061 (i == (atiop->cdb_len - 1))? '>' : ' ');
5062 }
5063 mpt_prtc(mpt, " itag %x tag %x rdesc %x dl=%u\n",
5064 tgt->itag, tgt->tag_id, tgt->reply_desc, tgt->resid);
5065 }
5066
5067 xpt_done((union ccb *)atiop);
5068 }
5069
5070 static void
mpt_tgt_dump_tgt_state(struct mpt_softc * mpt,request_t * req)5071 mpt_tgt_dump_tgt_state(struct mpt_softc *mpt, request_t *req)
5072 {
5073 mpt_tgt_state_t *tgt = MPT_TGT_STATE(mpt, req);
5074
5075 mpt_prt(mpt, "req %p:%u tgt:rdesc 0x%x resid %u xfrd %u ccb %p treq %p "
5076 "nx %d tag 0x%08x itag 0x%04x state=%d\n", req, req->serno,
5077 tgt->reply_desc, tgt->resid, tgt->bytes_xfered, tgt->ccb,
5078 tgt->req, tgt->nxfers, tgt->tag_id, tgt->itag, tgt->state);
5079 }
5080
5081 static void
mpt_tgt_dump_req_state(struct mpt_softc * mpt,request_t * req)5082 mpt_tgt_dump_req_state(struct mpt_softc *mpt, request_t *req)
5083 {
5084
5085 mpt_prt(mpt, "req %p:%u index %u (%x) state %x\n", req, req->serno,
5086 req->index, req->index, req->state);
5087 mpt_tgt_dump_tgt_state(mpt, req);
5088 }
5089
5090 static int
mpt_scsi_tgt_reply_handler(struct mpt_softc * mpt,request_t * req,uint32_t reply_desc,MSG_DEFAULT_REPLY * reply_frame)5091 mpt_scsi_tgt_reply_handler(struct mpt_softc *mpt, request_t *req,
5092 uint32_t reply_desc, MSG_DEFAULT_REPLY *reply_frame)
5093 {
5094 int dbg;
5095 union ccb *ccb;
5096 U16 status;
5097
5098 if (reply_frame == NULL) {
5099 /*
5100 * Figure out what the state of the command is.
5101 */
5102 mpt_tgt_state_t *tgt = MPT_TGT_STATE(mpt, req);
5103
5104 #ifdef INVARIANTS
5105 mpt_req_spcl(mpt, req, "turbo scsi_tgt_reply", __LINE__);
5106 if (tgt->req) {
5107 mpt_req_not_spcl(mpt, tgt->req,
5108 "turbo scsi_tgt_reply associated req", __LINE__);
5109 }
5110 #endif
5111 switch(tgt->state) {
5112 case TGT_STATE_LOADED:
5113 /*
5114 * This is a new command starting.
5115 */
5116 mpt_scsi_tgt_atio(mpt, req, reply_desc);
5117 break;
5118 case TGT_STATE_MOVING_DATA:
5119 {
5120 ccb = tgt->ccb;
5121 if (tgt->req == NULL) {
5122 panic("mpt: turbo target reply with null "
5123 "associated request moving data");
5124 /* NOTREACHED */
5125 }
5126 if (ccb == NULL) {
5127 if (tgt->is_local == 0) {
5128 panic("mpt: turbo target reply with "
5129 "null associated ccb moving data");
5130 /* NOTREACHED */
5131 }
5132 mpt_lprt(mpt, MPT_PRT_DEBUG,
5133 "TARGET_ASSIST local done\n");
5134 TAILQ_REMOVE(&mpt->request_pending_list,
5135 tgt->req, links);
5136 mpt_free_request(mpt, tgt->req);
5137 tgt->req = NULL;
5138 mpt_scsi_tgt_status(mpt, NULL, req,
5139 0, NULL, 0);
5140 return (TRUE);
5141 }
5142 tgt->ccb = NULL;
5143 tgt->nxfers++;
5144 mpt_req_untimeout(tgt->req, mpt_timeout, ccb);
5145 mpt_lprt(mpt, MPT_PRT_DEBUG,
5146 "TARGET_ASSIST %p (req %p:%u) done tag 0x%x\n",
5147 ccb, tgt->req, tgt->req->serno, ccb->csio.tag_id);
5148 /*
5149 * Free the Target Assist Request
5150 */
5151 KASSERT(tgt->req->ccb == ccb,
5152 ("tgt->req %p:%u tgt->req->ccb %p", tgt->req,
5153 tgt->req->serno, tgt->req->ccb));
5154 TAILQ_REMOVE(&mpt->request_pending_list,
5155 tgt->req, links);
5156 mpt_free_request(mpt, tgt->req);
5157 tgt->req = NULL;
5158
5159 /*
5160 * Do we need to send status now? That is, are
5161 * we done with all our data transfers?
5162 */
5163 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) == 0) {
5164 mpt_set_ccb_status(ccb, CAM_REQ_CMP);
5165 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
5166 KASSERT(ccb->ccb_h.status,
5167 ("zero ccb sts at %d", __LINE__));
5168 tgt->state = TGT_STATE_IN_CAM;
5169 if (mpt->outofbeer) {
5170 ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
5171 mpt->outofbeer = 0;
5172 mpt_lprt(mpt, MPT_PRT_DEBUG, "THAWQ\n");
5173 }
5174 xpt_done(ccb);
5175 break;
5176 }
5177 /*
5178 * Otherwise, send status (and sense)
5179 */
5180 mpt_scsi_tgt_status(mpt, ccb, req,
5181 ccb->csio.scsi_status,
5182 (void *)&ccb->csio.sense_data,
5183 (ccb->ccb_h.flags & CAM_SEND_SENSE) ?
5184 ccb->csio.sense_len : 0);
5185 break;
5186 }
5187 case TGT_STATE_SENDING_STATUS:
5188 case TGT_STATE_MOVING_DATA_AND_STATUS:
5189 {
5190 int ioindex;
5191 ccb = tgt->ccb;
5192
5193 if (tgt->req == NULL) {
5194 panic("mpt: turbo target reply with null "
5195 "associated request sending status");
5196 /* NOTREACHED */
5197 }
5198
5199 if (ccb) {
5200 tgt->ccb = NULL;
5201 if (tgt->state ==
5202 TGT_STATE_MOVING_DATA_AND_STATUS) {
5203 tgt->nxfers++;
5204 }
5205 mpt_req_untimeout(tgt->req, mpt_timeout, ccb);
5206 if (ccb->ccb_h.flags & CAM_SEND_SENSE) {
5207 ccb->ccb_h.status |= CAM_SENT_SENSE;
5208 }
5209 mpt_lprt(mpt, MPT_PRT_DEBUG,
5210 "TARGET_STATUS tag %x sts %x flgs %x req "
5211 "%p\n", ccb->csio.tag_id, ccb->ccb_h.status,
5212 ccb->ccb_h.flags, tgt->req);
5213 /*
5214 * Free the Target Send Status Request
5215 */
5216 KASSERT(tgt->req->ccb == ccb,
5217 ("tgt->req %p:%u tgt->req->ccb %p",
5218 tgt->req, tgt->req->serno, tgt->req->ccb));
5219 /*
5220 * Notify CAM that we're done
5221 */
5222 mpt_set_ccb_status(ccb, CAM_REQ_CMP);
5223 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
5224 KASSERT(ccb->ccb_h.status,
5225 ("ZERO ccb sts at %d", __LINE__));
5226 tgt->ccb = NULL;
5227 } else {
5228 mpt_lprt(mpt, MPT_PRT_DEBUG,
5229 "TARGET_STATUS non-CAM for req %p:%u\n",
5230 tgt->req, tgt->req->serno);
5231 }
5232 TAILQ_REMOVE(&mpt->request_pending_list,
5233 tgt->req, links);
5234 mpt_free_request(mpt, tgt->req);
5235 tgt->req = NULL;
5236
5237 /*
5238 * And re-post the Command Buffer.
5239 * This will reset the state.
5240 */
5241 ioindex = GET_IO_INDEX(reply_desc);
5242 TAILQ_REMOVE(&mpt->request_pending_list, req, links);
5243 tgt->is_local = 0;
5244 mpt_post_target_command(mpt, req, ioindex);
5245
5246 /*
5247 * And post a done for anyone who cares
5248 */
5249 if (ccb) {
5250 if (mpt->outofbeer) {
5251 ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
5252 mpt->outofbeer = 0;
5253 mpt_lprt(mpt, MPT_PRT_DEBUG, "THAWQ\n");
5254 }
5255 xpt_done(ccb);
5256 }
5257 break;
5258 }
5259 case TGT_STATE_NIL: /* XXX This Never Happens XXX */
5260 tgt->state = TGT_STATE_LOADED;
5261 break;
5262 default:
5263 mpt_prt(mpt, "Unknown Target State 0x%x in Context "
5264 "Reply Function\n", tgt->state);
5265 }
5266 return (TRUE);
5267 }
5268
5269 status = le16toh(reply_frame->IOCStatus);
5270 if (status != MPI_IOCSTATUS_SUCCESS) {
5271 dbg = MPT_PRT_ERROR;
5272 } else {
5273 dbg = MPT_PRT_DEBUG1;
5274 }
5275
5276 mpt_lprt(mpt, dbg,
5277 "SCSI_TGT REPLY: req=%p:%u reply=%p func=%x IOCstatus 0x%x\n",
5278 req, req->serno, reply_frame, reply_frame->Function, status);
5279
5280 switch (reply_frame->Function) {
5281 case MPI_FUNCTION_TARGET_CMD_BUFFER_POST:
5282 {
5283 mpt_tgt_state_t *tgt;
5284 #ifdef INVARIANTS
5285 mpt_req_spcl(mpt, req, "tgt reply BUFFER POST", __LINE__);
5286 #endif
5287 if (status != MPI_IOCSTATUS_SUCCESS) {
5288 /*
5289 * XXX What to do?
5290 */
5291 break;
5292 }
5293 tgt = MPT_TGT_STATE(mpt, req);
5294 KASSERT(tgt->state == TGT_STATE_LOADING,
5295 ("bad state 0x%x on reply to buffer post", tgt->state));
5296 mpt_assign_serno(mpt, req);
5297 tgt->state = TGT_STATE_LOADED;
5298 break;
5299 }
5300 case MPI_FUNCTION_TARGET_ASSIST:
5301 #ifdef INVARIANTS
5302 mpt_req_not_spcl(mpt, req, "tgt reply TARGET ASSIST", __LINE__);
5303 #endif
5304 mpt_prt(mpt, "target assist completion\n");
5305 TAILQ_REMOVE(&mpt->request_pending_list, req, links);
5306 mpt_free_request(mpt, req);
5307 break;
5308 case MPI_FUNCTION_TARGET_STATUS_SEND:
5309 #ifdef INVARIANTS
5310 mpt_req_not_spcl(mpt, req, "tgt reply STATUS SEND", __LINE__);
5311 #endif
5312 mpt_prt(mpt, "status send completion\n");
5313 TAILQ_REMOVE(&mpt->request_pending_list, req, links);
5314 mpt_free_request(mpt, req);
5315 break;
5316 case MPI_FUNCTION_TARGET_MODE_ABORT:
5317 {
5318 PTR_MSG_TARGET_MODE_ABORT_REPLY abtrp =
5319 (PTR_MSG_TARGET_MODE_ABORT_REPLY) reply_frame;
5320 PTR_MSG_TARGET_MODE_ABORT abtp =
5321 (PTR_MSG_TARGET_MODE_ABORT) req->req_vbuf;
5322 uint32_t cc = GET_IO_INDEX(le32toh(abtp->ReplyWord));
5323 #ifdef INVARIANTS
5324 mpt_req_not_spcl(mpt, req, "tgt reply TMODE ABORT", __LINE__);
5325 #endif
5326 mpt_prt(mpt, "ABORT RX_ID 0x%x Complete; status 0x%x cnt %u\n",
5327 cc, le16toh(abtrp->IOCStatus), le32toh(abtrp->AbortCount));
5328 TAILQ_REMOVE(&mpt->request_pending_list, req, links);
5329 mpt_free_request(mpt, req);
5330 break;
5331 }
5332 default:
5333 mpt_prt(mpt, "Unknown Target Address Reply Function code: "
5334 "0x%x\n", reply_frame->Function);
5335 break;
5336 }
5337 return (TRUE);
5338 }
5339