Deleted Added
full compact
mpt.c (156796) mpt.c (157117)
1/*-
2 * Generic routines for LSI Fusion adapters.
3 * FreeBSD Version.
4 *
5 * Copyright (c) 2000, 2001 by Greg Ansley
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 78 unchanged lines hidden (view full) ---

87 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
88 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
89 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
90 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF THE COPYRIGHT
91 * OWNER OR CONTRIBUTOR IS ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92 */
93
94#include <sys/cdefs.h>
1/*-
2 * Generic routines for LSI Fusion adapters.
3 * FreeBSD Version.
4 *
5 * Copyright (c) 2000, 2001 by Greg Ansley
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 78 unchanged lines hidden (view full) ---

87 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
88 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
89 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
90 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF THE COPYRIGHT
91 * OWNER OR CONTRIBUTOR IS ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92 */
93
94#include <sys/cdefs.h>
95__FBSDID("$FreeBSD: head/sys/dev/mpt/mpt.c 156796 2006-03-17 04:52:27Z mjacob $");
95__FBSDID("$FreeBSD: head/sys/dev/mpt/mpt.c 157117 2006-03-25 07:08:27Z mjacob $");
96
97#include <dev/mpt/mpt.h>
98#include <dev/mpt/mpt_cam.h> /* XXX For static handler registration */
99#include <dev/mpt/mpt_raid.h> /* XXX For static handler registration */
100
101#include <dev/mpt/mpilib/mpi.h>
102#include <dev/mpt/mpilib/mpi_ioc.h>
96
97#include <dev/mpt/mpt.h>
98#include <dev/mpt/mpt_cam.h> /* XXX For static handler registration */
99#include <dev/mpt/mpt_raid.h> /* XXX For static handler registration */
100
101#include <dev/mpt/mpilib/mpi.h>
102#include <dev/mpt/mpilib/mpi_ioc.h>
103#include <dev/mpt/mpilib/mpi_fc.h>
104#include <dev/mpt/mpilib/mpi_targ.h>
103
104#include <sys/sysctl.h>
105
106#define MPT_MAX_TRYS 3
107#define MPT_MAX_WAIT 300000
108
109static int maxwait_ack = 0;
110static int maxwait_int = 0;

--- 7 unchanged lines hidden (view full) ---

118static mpt_reply_handler_t mpt_handshake_reply_handler;
119static mpt_reply_handler_t mpt_event_reply_handler;
120static void mpt_send_event_ack(struct mpt_softc *mpt, request_t *ack_req,
121 MSG_EVENT_NOTIFY_REPLY *msg, uint32_t context);
122static int mpt_send_event_request(struct mpt_softc *mpt, int onoff);
123static int mpt_soft_reset(struct mpt_softc *mpt);
124static void mpt_hard_reset(struct mpt_softc *mpt);
125static int mpt_configure_ioc(struct mpt_softc *mpt);
105
106#include <sys/sysctl.h>
107
108#define MPT_MAX_TRYS 3
109#define MPT_MAX_WAIT 300000
110
111static int maxwait_ack = 0;
112static int maxwait_int = 0;

--- 7 unchanged lines hidden (view full) ---

120static mpt_reply_handler_t mpt_handshake_reply_handler;
121static mpt_reply_handler_t mpt_event_reply_handler;
122static void mpt_send_event_ack(struct mpt_softc *mpt, request_t *ack_req,
123 MSG_EVENT_NOTIFY_REPLY *msg, uint32_t context);
124static int mpt_send_event_request(struct mpt_softc *mpt, int onoff);
125static int mpt_soft_reset(struct mpt_softc *mpt);
126static void mpt_hard_reset(struct mpt_softc *mpt);
127static int mpt_configure_ioc(struct mpt_softc *mpt);
126static int mpt_enable_ioc(struct mpt_softc *mpt);
128static int mpt_enable_ioc(struct mpt_softc *mpt, int);
127
128/************************* Personality Module Support *************************/
129/*
130 * We include one extra entry that is guaranteed to be NULL
131 * to simplify our itterator.
132 */
133static struct mpt_personality *mpt_personalities[MPT_MAX_PERSONALITIES + 1];
134static __inline struct mpt_personality*

--- 10 unchanged lines hidden (view full) ---

145 while (start_at < MPT_MAX_PERSONALITIES
146 && (mpt->mpt_pers_mask & (0x1 << start_at)) == 0) {
147 start_at++;
148 }
149 return (mpt_personalities[start_at]);
150}
151
152/*
129
130/************************* Personality Module Support *************************/
131/*
132 * We include one extra entry that is guaranteed to be NULL
133 * to simplify our itterator.
134 */
135static struct mpt_personality *mpt_personalities[MPT_MAX_PERSONALITIES + 1];
136static __inline struct mpt_personality*

--- 10 unchanged lines hidden (view full) ---

147 while (start_at < MPT_MAX_PERSONALITIES
148 && (mpt->mpt_pers_mask & (0x1 << start_at)) == 0) {
149 start_at++;
150 }
151 return (mpt_personalities[start_at]);
152}
153
154/*
153 * Used infrequenstly, so no need to optimize like a forward
155 * Used infrequently, so no need to optimize like a forward
154 * traversal where we use the MAX+1 is guaranteed to be NULL
155 * trick.
156 */
157static __inline struct mpt_personality *
158mpt_pers_find_reverse(struct mpt_softc *mpt, u_int start_at)
159{
160 while (start_at < MPT_MAX_PERSONALITIES
161 && (mpt->mpt_pers_mask & (0x1 << start_at)) == 0) {

--- 12 unchanged lines hidden (view full) ---

174#define MPT_PERS_FOREACH_REVERSE(mpt, pers) \
175 for (pers = mpt_pers_find_reverse(mpt, MPT_MAX_PERSONALITIES-1);\
176 pers != NULL; \
177 pers = mpt_pers_find_reverse(mpt, /*start_at*/pers->id-1))
178
179static mpt_load_handler_t mpt_stdload;
180static mpt_probe_handler_t mpt_stdprobe;
181static mpt_attach_handler_t mpt_stdattach;
156 * traversal where we use the MAX+1 is guaranteed to be NULL
157 * trick.
158 */
159static __inline struct mpt_personality *
160mpt_pers_find_reverse(struct mpt_softc *mpt, u_int start_at)
161{
162 while (start_at < MPT_MAX_PERSONALITIES
163 && (mpt->mpt_pers_mask & (0x1 << start_at)) == 0) {

--- 12 unchanged lines hidden (view full) ---

176#define MPT_PERS_FOREACH_REVERSE(mpt, pers) \
177 for (pers = mpt_pers_find_reverse(mpt, MPT_MAX_PERSONALITIES-1);\
178 pers != NULL; \
179 pers = mpt_pers_find_reverse(mpt, /*start_at*/pers->id-1))
180
181static mpt_load_handler_t mpt_stdload;
182static mpt_probe_handler_t mpt_stdprobe;
183static mpt_attach_handler_t mpt_stdattach;
184static mpt_enable_handler_t mpt_stdenable;
182static mpt_event_handler_t mpt_stdevent;
183static mpt_reset_handler_t mpt_stdreset;
184static mpt_shutdown_handler_t mpt_stdshutdown;
185static mpt_detach_handler_t mpt_stddetach;
186static mpt_unload_handler_t mpt_stdunload;
187static struct mpt_personality mpt_default_personality =
188{
189 .load = mpt_stdload,
190 .probe = mpt_stdprobe,
191 .attach = mpt_stdattach,
185static mpt_event_handler_t mpt_stdevent;
186static mpt_reset_handler_t mpt_stdreset;
187static mpt_shutdown_handler_t mpt_stdshutdown;
188static mpt_detach_handler_t mpt_stddetach;
189static mpt_unload_handler_t mpt_stdunload;
190static struct mpt_personality mpt_default_personality =
191{
192 .load = mpt_stdload,
193 .probe = mpt_stdprobe,
194 .attach = mpt_stdattach,
195 .enable = mpt_stdenable,
192 .event = mpt_stdevent,
193 .reset = mpt_stdreset,
194 .shutdown = mpt_stdshutdown,
195 .detach = mpt_stddetach,
196 .unload = mpt_stdunload
197};
198
199static mpt_load_handler_t mpt_core_load;
200static mpt_attach_handler_t mpt_core_attach;
196 .event = mpt_stdevent,
197 .reset = mpt_stdreset,
198 .shutdown = mpt_stdshutdown,
199 .detach = mpt_stddetach,
200 .unload = mpt_stdunload
201};
202
203static mpt_load_handler_t mpt_core_load;
204static mpt_attach_handler_t mpt_core_attach;
205static mpt_enable_handler_t mpt_core_enable;
201static mpt_reset_handler_t mpt_core_ioc_reset;
202static mpt_event_handler_t mpt_core_event;
203static mpt_shutdown_handler_t mpt_core_shutdown;
204static mpt_shutdown_handler_t mpt_core_detach;
205static mpt_unload_handler_t mpt_core_unload;
206static struct mpt_personality mpt_core_personality =
207{
208 .name = "mpt_core",
209 .load = mpt_core_load,
210 .attach = mpt_core_attach,
206static mpt_reset_handler_t mpt_core_ioc_reset;
207static mpt_event_handler_t mpt_core_event;
208static mpt_shutdown_handler_t mpt_core_shutdown;
209static mpt_shutdown_handler_t mpt_core_detach;
210static mpt_unload_handler_t mpt_core_unload;
211static struct mpt_personality mpt_core_personality =
212{
213 .name = "mpt_core",
214 .load = mpt_core_load,
215 .attach = mpt_core_attach,
216 .enable = mpt_core_enable,
211 .event = mpt_core_event,
212 .reset = mpt_core_ioc_reset,
213 .shutdown = mpt_core_shutdown,
214 .detach = mpt_core_detach,
215 .unload = mpt_core_unload,
216};
217
218/*
219 * Manual declaration so that DECLARE_MPT_PERSONALITY doesn't need
220 * ordering information. We want the core to always register FIRST.
221 * other modules are set to SI_ORDER_SECOND.
222 */
223static moduledata_t mpt_core_mod = {
224 "mpt_core", mpt_modevent, &mpt_core_personality
225};
226DECLARE_MODULE(mpt_core, mpt_core_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
227MODULE_VERSION(mpt_core, 1);
228
217 .event = mpt_core_event,
218 .reset = mpt_core_ioc_reset,
219 .shutdown = mpt_core_shutdown,
220 .detach = mpt_core_detach,
221 .unload = mpt_core_unload,
222};
223
224/*
225 * Manual declaration so that DECLARE_MPT_PERSONALITY doesn't need
226 * ordering information. We want the core to always register FIRST.
227 * other modules are set to SI_ORDER_SECOND.
228 */
229static moduledata_t mpt_core_mod = {
230 "mpt_core", mpt_modevent, &mpt_core_personality
231};
232DECLARE_MODULE(mpt_core, mpt_core_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
233MODULE_VERSION(mpt_core, 1);
234
229#define MPT_PERS_ATACHED(pers, mpt) \
230 ((mpt)->pers_mask & (0x1 << pers->id))
235#define MPT_PERS_ATTACHED(pers, mpt) ((mpt)->mpt_pers_mask & (0x1 << pers->id))
231
232
233int
234mpt_modevent(module_t mod, int type, void *data)
235{
236 struct mpt_personality *pers;
237 int error;
238

--- 30 unchanged lines hidden (view full) ---

269
270 error = (pers->load(pers));
271 if (error != 0)
272 mpt_personalities[i] = NULL;
273 break;
274 }
275 case MOD_SHUTDOWN:
276 break;
236
237
238int
239mpt_modevent(module_t mod, int type, void *data)
240{
241 struct mpt_personality *pers;
242 int error;
243

--- 30 unchanged lines hidden (view full) ---

274
275 error = (pers->load(pers));
276 if (error != 0)
277 mpt_personalities[i] = NULL;
278 break;
279 }
280 case MOD_SHUTDOWN:
281 break;
282#if __FreeBSD_version >= 500000
277 case MOD_QUIESCE:
278 break;
283 case MOD_QUIESCE:
284 break;
285#endif
279 case MOD_UNLOAD:
280 error = pers->unload(pers);
281 mpt_personalities[pers->id] = NULL;
282 break;
283 default:
284 error = EINVAL;
285 break;
286 }

--- 17 unchanged lines hidden (view full) ---

304int
305mpt_stdattach(struct mpt_softc *mpt)
306{
307 /* Attach is always successfull. */
308 return (0);
309}
310
311int
286 case MOD_UNLOAD:
287 error = pers->unload(pers);
288 mpt_personalities[pers->id] = NULL;
289 break;
290 default:
291 error = EINVAL;
292 break;
293 }

--- 17 unchanged lines hidden (view full) ---

311int
312mpt_stdattach(struct mpt_softc *mpt)
313{
314 /* Attach is always successfull. */
315 return (0);
316}
317
318int
319mpt_stdenable(struct mpt_softc *mpt)
320{
321 /* Enable is always successfull. */
322 return (0);
323}
324
325int
312mpt_stdevent(struct mpt_softc *mpt, request_t *req, MSG_EVENT_NOTIFY_REPLY *msg)
313{
314 mpt_lprt(mpt, MPT_PRT_DEBUG, "mpt_stdevent: 0x%x\n", msg->Event & 0xFF);
315 /* Event was not for us. */
316 return (0);
317}
318
319void

--- 60 unchanged lines hidden (view full) ---

380 * Fill from the front in the hope that
381 * all registered handlers consume only a
382 * single cache line.
383 *
384 * We don't break on the first empty slot so
385 * that the full table is checked to see if
386 * this handler was previously registered.
387 */
326mpt_stdevent(struct mpt_softc *mpt, request_t *req, MSG_EVENT_NOTIFY_REPLY *msg)
327{
328 mpt_lprt(mpt, MPT_PRT_DEBUG, "mpt_stdevent: 0x%x\n", msg->Event & 0xFF);
329 /* Event was not for us. */
330 return (0);
331}
332
333void

--- 60 unchanged lines hidden (view full) ---

394 * Fill from the front in the hope that
395 * all registered handlers consume only a
396 * single cache line.
397 *
398 * We don't break on the first empty slot so
399 * that the full table is checked to see if
400 * this handler was previously registered.
401 */
388 if (free_cbi == MPT_HANDLER_ID_NONE
389 && (mpt_reply_handlers[cbi]
402 if (free_cbi == MPT_HANDLER_ID_NONE &&
403 (mpt_reply_handlers[cbi]
390 == mpt_default_reply_handler))
391 free_cbi = cbi;
392 }
404 == mpt_default_reply_handler))
405 free_cbi = cbi;
406 }
393 if (free_cbi == MPT_HANDLER_ID_NONE)
407 if (free_cbi == MPT_HANDLER_ID_NONE) {
394 return (ENOMEM);
408 return (ENOMEM);
409 }
395 mpt_reply_handlers[free_cbi] = handler.reply_handler;
396 *phandler_id = MPT_CBI_TO_HID(free_cbi);
397 break;
398 }
399 default:
400 mpt_prt(mpt, "mpt_register_handler unknown type %d\n", type);
401 return (EINVAL);
402 }

--- 21 unchanged lines hidden (view full) ---

424 mpt_prt(mpt, "mpt_deregister_handler unknown type %d\n", type);
425 return (EINVAL);
426 }
427 return (0);
428}
429
430static int
431mpt_default_reply_handler(struct mpt_softc *mpt, request_t *req,
410 mpt_reply_handlers[free_cbi] = handler.reply_handler;
411 *phandler_id = MPT_CBI_TO_HID(free_cbi);
412 break;
413 }
414 default:
415 mpt_prt(mpt, "mpt_register_handler unknown type %d\n", type);
416 return (EINVAL);
417 }

--- 21 unchanged lines hidden (view full) ---

439 mpt_prt(mpt, "mpt_deregister_handler unknown type %d\n", type);
440 return (EINVAL);
441 }
442 return (0);
443}
444
445static int
446mpt_default_reply_handler(struct mpt_softc *mpt, request_t *req,
432 MSG_DEFAULT_REPLY *reply_frame)
447 uint32_t reply_desc, MSG_DEFAULT_REPLY *reply_frame)
433{
448{
434 mpt_prt(mpt, "XXXX Default Handler Called. Req %p, Frame %p\n",
435 req, reply_frame);
449 mpt_prt(mpt,
450 "Default Handler Called: req=%p:%u reply_descriptor=%x frame=%p\n",
451 req, req->serno, reply_desc, reply_frame);
436
437 if (reply_frame != NULL)
438 mpt_dump_reply_frame(mpt, reply_frame);
439
452
453 if (reply_frame != NULL)
454 mpt_dump_reply_frame(mpt, reply_frame);
455
440 mpt_prt(mpt, "XXXX Reply Frame Ignored\n");
456 mpt_prt(mpt, "Reply Frame Ignored\n");
441
442 return (/*free_reply*/TRUE);
443}
444
445static int
446mpt_config_reply_handler(struct mpt_softc *mpt, request_t *req,
457
458 return (/*free_reply*/TRUE);
459}
460
461static int
462mpt_config_reply_handler(struct mpt_softc *mpt, request_t *req,
447 MSG_DEFAULT_REPLY *reply_frame)
463 uint32_t reply_desc, MSG_DEFAULT_REPLY *reply_frame)
448{
449 if (req != NULL) {
450
451 if (reply_frame != NULL) {
452 MSG_CONFIG *cfgp;
453 MSG_CONFIG_REPLY *reply;
454
455 cfgp = (MSG_CONFIG *)req->req_vbuf;

--- 10 unchanged lines hidden (view full) ---

466 wakeup(req);
467 }
468
469 return (/*free_reply*/TRUE);
470}
471
472static int
473mpt_handshake_reply_handler(struct mpt_softc *mpt, request_t *req,
464{
465 if (req != NULL) {
466
467 if (reply_frame != NULL) {
468 MSG_CONFIG *cfgp;
469 MSG_CONFIG_REPLY *reply;
470
471 cfgp = (MSG_CONFIG *)req->req_vbuf;

--- 10 unchanged lines hidden (view full) ---

482 wakeup(req);
483 }
484
485 return (/*free_reply*/TRUE);
486}
487
488static int
489mpt_handshake_reply_handler(struct mpt_softc *mpt, request_t *req,
474 MSG_DEFAULT_REPLY *reply_frame)
490 uint32_t reply_desc, MSG_DEFAULT_REPLY *reply_frame)
475{
476 /* Nothing to be done. */
477 return (/*free_reply*/TRUE);
478}
479
480static int
481mpt_event_reply_handler(struct mpt_softc *mpt, request_t *req,
491{
492 /* Nothing to be done. */
493 return (/*free_reply*/TRUE);
494}
495
496static int
497mpt_event_reply_handler(struct mpt_softc *mpt, request_t *req,
482 MSG_DEFAULT_REPLY *reply_frame)
498 uint32_t reply_desc, MSG_DEFAULT_REPLY *reply_frame)
483{
484 int free_reply;
485
486 if (reply_frame == NULL) {
499{
500 int free_reply;
501
502 if (reply_frame == NULL) {
487 mpt_prt(mpt, "Event Handler: req %p - Unexpected NULL reply\n");
503 mpt_prt(mpt, "Event Handler: req %p:%u - Unexpected NULL reply\n",
504 req, req->serno);
488 return (/*free_reply*/TRUE);
489 }
490
491 free_reply = TRUE;
492 switch (reply_frame->Function) {
493 case MPI_FUNCTION_EVENT_NOTIFICATION:
494 {
495 MSG_EVENT_NOTIFY_REPLY *msg;

--- 118 unchanged lines hidden (view full) ---

614 mpt_send_cmd(mpt, ack_req);
615}
616
617/***************************** Interrupt Handling *****************************/
618void
619mpt_intr(void *arg)
620{
621 struct mpt_softc *mpt;
505 return (/*free_reply*/TRUE);
506 }
507
508 free_reply = TRUE;
509 switch (reply_frame->Function) {
510 case MPI_FUNCTION_EVENT_NOTIFICATION:
511 {
512 MSG_EVENT_NOTIFY_REPLY *msg;

--- 118 unchanged lines hidden (view full) ---

631 mpt_send_cmd(mpt, ack_req);
632}
633
634/***************************** Interrupt Handling *****************************/
635void
636mpt_intr(void *arg)
637{
638 struct mpt_softc *mpt;
622 uint32_t reply_desc;
639 uint32_t reply_desc;
640 int ntrips = 0;
623
624 mpt = (struct mpt_softc *)arg;
625 while ((reply_desc = mpt_pop_reply_queue(mpt)) != MPT_REPLY_EMPTY) {
626 request_t *req;
627 MSG_DEFAULT_REPLY *reply_frame;
628 uint32_t reply_baddr;
641
642 mpt = (struct mpt_softc *)arg;
643 while ((reply_desc = mpt_pop_reply_queue(mpt)) != MPT_REPLY_EMPTY) {
644 request_t *req;
645 MSG_DEFAULT_REPLY *reply_frame;
646 uint32_t reply_baddr;
647 uint32_t ctxt_idx;
629 u_int cb_index;
630 u_int req_index;
631 int free_rf;
632
633 req = NULL;
634 reply_frame = NULL;
635 reply_baddr = 0;
636 if ((reply_desc & MPI_ADDRESS_REPLY_A_BIT) != 0) {
637 u_int offset;
648 u_int cb_index;
649 u_int req_index;
650 int free_rf;
651
652 req = NULL;
653 reply_frame = NULL;
654 reply_baddr = 0;
655 if ((reply_desc & MPI_ADDRESS_REPLY_A_BIT) != 0) {
656 u_int offset;
638
639 /*
640 * Insure that the reply frame is coherent.
641 */
642 reply_baddr = (reply_desc << 1);
643 offset = reply_baddr - (mpt->reply_phys & 0xFFFFFFFF);
657 /*
658 * Insure that the reply frame is coherent.
659 */
660 reply_baddr = (reply_desc << 1);
661 offset = reply_baddr - (mpt->reply_phys & 0xFFFFFFFF);
644 bus_dmamap_sync_range(mpt->reply_dmat, mpt->reply_dmap,
645 offset, MPT_REPLY_SIZE,
646 BUS_DMASYNC_POSTREAD);
662 bus_dmamap_sync_range(mpt->reply_dmat,
663 mpt->reply_dmap, offset, MPT_REPLY_SIZE,
664 BUS_DMASYNC_POSTREAD);
647 reply_frame = MPT_REPLY_OTOV(mpt, offset);
665 reply_frame = MPT_REPLY_OTOV(mpt, offset);
648 reply_desc = le32toh(reply_frame->MsgContext);
666 ctxt_idx = le32toh(reply_frame->MsgContext);
667 } else {
668 uint32_t type;
669
670 type = MPI_GET_CONTEXT_REPLY_TYPE(reply_desc);
671 ctxt_idx = reply_desc;
672 mpt_lprt(mpt, MPT_PRT_DEBUG1, "Context Reply: 0x%08x\n",
673 reply_desc);
674
675 switch (type) {
676 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
677 ctxt_idx &= MPI_CONTEXT_REPLY_CONTEXT_MASK;
678 break;
679 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
680 ctxt_idx = GET_IO_INDEX(reply_desc);
681 if (mpt->tgt_cmd_ptrs == NULL) {
682 mpt_prt(mpt,
683 "mpt_intr: no target cmd ptrs\n");
684 reply_desc = MPT_REPLY_EMPTY;
685 break;
686 }
687 if (ctxt_idx >= mpt->tgt_cmds_allocated) {
688 mpt_prt(mpt,
689 "mpt_intr: bad tgt cmd ctxt %u\n",
690 ctxt_idx);
691 reply_desc = MPT_REPLY_EMPTY;
692 ntrips = 1000;
693 break;
694 }
695 req = mpt->tgt_cmd_ptrs[ctxt_idx];
696 if (req == NULL) {
697 mpt_prt(mpt, "no request backpointer "
698 "at index %u", ctxt_idx);
699 reply_desc = MPT_REPLY_EMPTY;
700 ntrips = 1000;
701 break;
702 }
703 /*
704 * Reformulate ctxt_idx to be just as if
705 * it were another type of context reply
706 * so the code below will find the request
707 * via indexing into the pool.
708 */
709 ctxt_idx =
710 req->index | mpt->scsi_tgt_handler_id;
711 req = NULL;
712 break;
713 case MPI_CONTEXT_REPLY_TYPE_LAN:
714 mpt_prt(mpt, "LAN CONTEXT REPLY: 0x%08x\n",
715 reply_desc);
716 reply_desc = MPT_REPLY_EMPTY;
717 break;
718 default:
719 mpt_prt(mpt, "Context Reply 0x%08x?\n", type);
720 reply_desc = MPT_REPLY_EMPTY;
721 break;
722 }
723 if (reply_desc == MPT_REPLY_EMPTY) {
724 if (ntrips++ > 1000) {
725 break;
726 }
727 continue;
728 }
649 }
729 }
650 cb_index = MPT_CONTEXT_TO_CBI(reply_desc);
651 req_index = MPT_CONTEXT_TO_REQI(reply_desc);
652 if (req_index < MPT_MAX_REQUESTS(mpt))
730
731 cb_index = MPT_CONTEXT_TO_CBI(ctxt_idx);
732 req_index = MPT_CONTEXT_TO_REQI(ctxt_idx);
733 if (req_index < MPT_MAX_REQUESTS(mpt)) {
653 req = &mpt->request_pool[req_index];
734 req = &mpt->request_pool[req_index];
735 }
654
736
655 free_rf = mpt_reply_handlers[cb_index](mpt, req, reply_frame);
737 free_rf = mpt_reply_handlers[cb_index](mpt, req,
738 reply_desc, reply_frame);
656
657 if (reply_frame != NULL && free_rf)
658 mpt_free_reply(mpt, reply_baddr);
739
740 if (reply_frame != NULL && free_rf)
741 mpt_free_reply(mpt, reply_baddr);
742
743 /*
744 * If we got ourselves disabled, don't get stuck in a loop
745 */
746 if (mpt->disabled) {
747 mpt_disable_ints(mpt);
748 break;
749 }
750 if (ntrips++ > 1000) {
751 break;
752 }
659 }
660}
661
662/******************************* Error Recovery *******************************/
663void
664mpt_complete_request_chain(struct mpt_softc *mpt, struct req_queue *chain,
665 u_int iocstatus)
666{

--- 6 unchanged lines hidden (view full) ---

673 while((req = TAILQ_FIRST(chain)) != NULL) {
674 MSG_REQUEST_HEADER *msg_hdr;
675 u_int cb_index;
676 TAILQ_REMOVE(chain, req, links);
677 msg_hdr = (MSG_REQUEST_HEADER *)req->req_vbuf;
678 ioc_status_frame.Function = msg_hdr->Function;
679 ioc_status_frame.MsgContext = msg_hdr->MsgContext;
680 cb_index = MPT_CONTEXT_TO_CBI(le32toh(msg_hdr->MsgContext));
753 }
754}
755
756/******************************* Error Recovery *******************************/
757void
758mpt_complete_request_chain(struct mpt_softc *mpt, struct req_queue *chain,
759 u_int iocstatus)
760{

--- 6 unchanged lines hidden (view full) ---

767 while((req = TAILQ_FIRST(chain)) != NULL) {
768 MSG_REQUEST_HEADER *msg_hdr;
769 u_int cb_index;
770 TAILQ_REMOVE(chain, req, links);
771 msg_hdr = (MSG_REQUEST_HEADER *)req->req_vbuf;
772 ioc_status_frame.Function = msg_hdr->Function;
773 ioc_status_frame.MsgContext = msg_hdr->MsgContext;
774 cb_index = MPT_CONTEXT_TO_CBI(le32toh(msg_hdr->MsgContext));
681 mpt_reply_handlers[cb_index](mpt, req, &ioc_status_frame);
775 mpt_reply_handlers[cb_index](mpt, req, msg_hdr->MsgContext,
776 &ioc_status_frame);
682 }
683}
684
685/********************************* Diagnostics ********************************/
686/*
687 * Perform a diagnostic dump of a reply frame.
688 */
689void

--- 23 unchanged lines hidden (view full) ---

713/* Busy wait for a door bell to be read by IOC */
714static int
715mpt_wait_db_ack(struct mpt_softc *mpt)
716{
717 int i;
718 for (i=0; i < MPT_MAX_WAIT; i++) {
719 if (!MPT_DB_IS_BUSY(mpt_rd_intr(mpt))) {
720 maxwait_ack = i > maxwait_ack ? i : maxwait_ack;
777 }
778}
779
780/********************************* Diagnostics ********************************/
781/*
782 * Perform a diagnostic dump of a reply frame.
783 */
784void

--- 23 unchanged lines hidden (view full) ---

808/* Busy wait for a door bell to be read by IOC */
809static int
810mpt_wait_db_ack(struct mpt_softc *mpt)
811{
812 int i;
813 for (i=0; i < MPT_MAX_WAIT; i++) {
814 if (!MPT_DB_IS_BUSY(mpt_rd_intr(mpt))) {
815 maxwait_ack = i > maxwait_ack ? i : maxwait_ack;
721 return MPT_OK;
816 return (MPT_OK);
722 }
817 }
723
724 DELAY(1000);
818 DELAY(200);
725 }
819 }
726 return MPT_FAIL;
820 return (MPT_FAIL);
727}
728
729/* Busy wait for a door bell interrupt */
730static int
731mpt_wait_db_int(struct mpt_softc *mpt)
732{
733 int i;
734 for (i=0; i < MPT_MAX_WAIT; i++) {
735 if (MPT_DB_INTR(mpt_rd_intr(mpt))) {
736 maxwait_int = i > maxwait_int ? i : maxwait_int;
737 return MPT_OK;
738 }
739 DELAY(100);
740 }
821}
822
823/* Busy wait for a door bell interrupt */
824static int
825mpt_wait_db_int(struct mpt_softc *mpt)
826{
827 int i;
828 for (i=0; i < MPT_MAX_WAIT; i++) {
829 if (MPT_DB_INTR(mpt_rd_intr(mpt))) {
830 maxwait_int = i > maxwait_int ? i : maxwait_int;
831 return MPT_OK;
832 }
833 DELAY(100);
834 }
741 return MPT_FAIL;
835 return (MPT_FAIL);
742}
743
744/* Wait for IOC to transition to a give state */
745void
746mpt_check_doorbell(struct mpt_softc *mpt)
747{
748 uint32_t db = mpt_rd_db(mpt);
749 if (MPT_STATE(db) != MPT_DB_STATE_RUNNING) {

--- 27 unchanged lines hidden (view full) ---

777static int
778mpt_soft_reset(struct mpt_softc *mpt)
779{
780 mpt_lprt(mpt, MPT_PRT_DEBUG, "soft reset\n");
781
782 /* Have to use hard reset if we are not in Running state */
783 if (MPT_STATE(mpt_rd_db(mpt)) != MPT_DB_STATE_RUNNING) {
784 mpt_prt(mpt, "soft reset failed: device not running\n");
836}
837
838/* Wait for IOC to transition to a give state */
839void
840mpt_check_doorbell(struct mpt_softc *mpt)
841{
842 uint32_t db = mpt_rd_db(mpt);
843 if (MPT_STATE(db) != MPT_DB_STATE_RUNNING) {

--- 27 unchanged lines hidden (view full) ---

871static int
872mpt_soft_reset(struct mpt_softc *mpt)
873{
874 mpt_lprt(mpt, MPT_PRT_DEBUG, "soft reset\n");
875
876 /* Have to use hard reset if we are not in Running state */
877 if (MPT_STATE(mpt_rd_db(mpt)) != MPT_DB_STATE_RUNNING) {
878 mpt_prt(mpt, "soft reset failed: device not running\n");
785 return MPT_FAIL;
879 return (MPT_FAIL);
786 }
787
788 /* If door bell is in use we don't have a chance of getting
789 * a word in since the IOC probably crashed in message
790 * processing. So don't waste our time.
791 */
792 if (MPT_DB_IS_IN_USE(mpt_rd_db(mpt))) {
793 mpt_prt(mpt, "soft reset failed: doorbell wedged\n");
880 }
881
882 /* If door bell is in use we don't have a chance of getting
883 * a word in since the IOC probably crashed in message
884 * processing. So don't waste our time.
885 */
886 if (MPT_DB_IS_IN_USE(mpt_rd_db(mpt))) {
887 mpt_prt(mpt, "soft reset failed: doorbell wedged\n");
794 return MPT_FAIL;
888 return (MPT_FAIL);
795 }
796
797 /* Send the reset request to the IOC */
798 mpt_write(mpt, MPT_OFFSET_DOORBELL,
799 MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET << MPI_DOORBELL_FUNCTION_SHIFT);
800 if (mpt_wait_db_ack(mpt) != MPT_OK) {
801 mpt_prt(mpt, "soft reset failed: ack timeout\n");
889 }
890
891 /* Send the reset request to the IOC */
892 mpt_write(mpt, MPT_OFFSET_DOORBELL,
893 MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET << MPI_DOORBELL_FUNCTION_SHIFT);
894 if (mpt_wait_db_ack(mpt) != MPT_OK) {
895 mpt_prt(mpt, "soft reset failed: ack timeout\n");
802 return MPT_FAIL;
896 return (MPT_FAIL);
803 }
804
805 /* Wait for the IOC to reload and come out of reset state */
806 if (mpt_wait_state(mpt, MPT_DB_STATE_READY) != MPT_OK) {
807 mpt_prt(mpt, "soft reset failed: device did not restart\n");
897 }
898
899 /* Wait for the IOC to reload and come out of reset state */
900 if (mpt_wait_state(mpt, MPT_DB_STATE_READY) != MPT_OK) {
901 mpt_prt(mpt, "soft reset failed: device did not restart\n");
808 return MPT_FAIL;
902 return (MPT_FAIL);
809 }
810
811 return MPT_OK;
812}
813
814static int
815mpt_enable_diag_mode(struct mpt_softc *mpt)
816{

--- 157 unchanged lines hidden (view full) ---

974 * the specified wait condition, it should stop its wait.
975 */
976 mpt->reset_cnt++;
977 MPT_PERS_FOREACH(mpt, pers)
978 pers->reset(mpt, ret);
979 }
980
981 if (reinit != 0) {
903 }
904
905 return MPT_OK;
906}
907
908static int
909mpt_enable_diag_mode(struct mpt_softc *mpt)
910{

--- 157 unchanged lines hidden (view full) ---

1068 * the specified wait condition, it should stop its wait.
1069 */
1070 mpt->reset_cnt++;
1071 MPT_PERS_FOREACH(mpt, pers)
1072 pers->reset(mpt, ret);
1073 }
1074
1075 if (reinit != 0) {
982 ret = mpt_enable_ioc(mpt);
1076 ret = mpt_enable_ioc(mpt, 1);
983 if (ret == MPT_OK) {
984 mpt_enable_ints(mpt);
985 }
986 }
987 if (ret != MPT_OK && retry_cnt++ < 2) {
988 goto again;
989 }
990 return ret;

--- 14 unchanged lines hidden (view full) ---

1005 if ((nxt = req->chain) != NULL) {
1006 req->chain = NULL;
1007 mpt_free_request(mpt, nxt); /* NB: recursion */
1008 }
1009 req->serno = 0;
1010 req->ccb = NULL;
1011 req->state = REQ_STATE_FREE;
1012 if (LIST_EMPTY(&mpt->ack_frames)) {
1077 if (ret == MPT_OK) {
1078 mpt_enable_ints(mpt);
1079 }
1080 }
1081 if (ret != MPT_OK && retry_cnt++ < 2) {
1082 goto again;
1083 }
1084 return ret;

--- 14 unchanged lines hidden (view full) ---

1099 if ((nxt = req->chain) != NULL) {
1100 req->chain = NULL;
1101 mpt_free_request(mpt, nxt); /* NB: recursion */
1102 }
1103 req->serno = 0;
1104 req->ccb = NULL;
1105 req->state = REQ_STATE_FREE;
1106 if (LIST_EMPTY(&mpt->ack_frames)) {
1013 TAILQ_INSERT_HEAD(&mpt->request_free_list, req, links);
1107 /*
1108 * Insert free ones at the tail
1109 */
1110 TAILQ_INSERT_TAIL(&mpt->request_free_list, req, links);
1014 if (mpt->getreqwaiter != 0) {
1015 mpt->getreqwaiter = 0;
1016 wakeup(&mpt->request_free_list);
1017 }
1018 return;
1019 }
1020
1021 /*

--- 16 unchanged lines hidden (view full) ---

1038retry:
1039 req = TAILQ_FIRST(&mpt->request_free_list);
1040 if (req != NULL) {
1041 KASSERT(req == &mpt->request_pool[req->index],
1042 ("mpt_get_request: corrupted request free list\n"));
1043 TAILQ_REMOVE(&mpt->request_free_list, req, links);
1044 req->state = REQ_STATE_ALLOCATED;
1045 req->chain = NULL;
1111 if (mpt->getreqwaiter != 0) {
1112 mpt->getreqwaiter = 0;
1113 wakeup(&mpt->request_free_list);
1114 }
1115 return;
1116 }
1117
1118 /*

--- 16 unchanged lines hidden (view full) ---

1135retry:
1136 req = TAILQ_FIRST(&mpt->request_free_list);
1137 if (req != NULL) {
1138 KASSERT(req == &mpt->request_pool[req->index],
1139 ("mpt_get_request: corrupted request free list\n"));
1140 TAILQ_REMOVE(&mpt->request_free_list, req, links);
1141 req->state = REQ_STATE_ALLOCATED;
1142 req->chain = NULL;
1046 if ((req->serno = ++(mpt->cmd_serno)) == 0) {
1047 req->serno = ++(mpt->cmd_serno);
1048 }
1143 req->serno = mpt->sequence++;
1049 } else if (sleep_ok != 0) {
1050 mpt->getreqwaiter = 1;
1051 mpt_sleep(mpt, &mpt->request_free_list, PUSER, "mptgreq", 0);
1052 goto retry;
1053 }
1054 return req;
1055}
1056
1057/* Pass the command to the IOC */
1058void
1059mpt_send_cmd(struct mpt_softc *mpt, request_t *req)
1060{
1061 uint32_t *pReq;
1062
1063 pReq = req->req_vbuf;
1064 if (mpt->verbose > MPT_PRT_TRACE) {
1065 int offset;
1144 } else if (sleep_ok != 0) {
1145 mpt->getreqwaiter = 1;
1146 mpt_sleep(mpt, &mpt->request_free_list, PUSER, "mptgreq", 0);
1147 goto retry;
1148 }
1149 return req;
1150}
1151
1152/* Pass the command to the IOC */
1153void
1154mpt_send_cmd(struct mpt_softc *mpt, request_t *req)
1155{
1156 uint32_t *pReq;
1157
1158 pReq = req->req_vbuf;
1159 if (mpt->verbose > MPT_PRT_TRACE) {
1160 int offset;
1066 mpt_prt(mpt, "Send Request %d (0x%x):",
1067 req->index, req->req_pbuf);
1161#if __FreeBSD_version >= 500000
1162 mpt_prt(mpt, "Send Request %d (%jx):",
1163 req->index, (uintmax_t) req->req_pbuf);
1164#else
1165 mpt_prt(mpt, "Send Request %d (%llx):",
1166 req->index, (unsigned long long) req->req_pbuf);
1167#endif
1068 for (offset = 0; offset < mpt->request_frame_size; offset++) {
1069 if ((offset & 0x7) == 0) {
1070 mpt_prtc(mpt, "\n");
1071 mpt_prt(mpt, " ");
1072 }
1073 mpt_prtc(mpt, " %08x", pReq[offset]);
1074 }
1075 mpt_prtc(mpt, "\n");

--- 27 unchanged lines hidden (view full) ---

1103 int timeout;
1104 u_int saved_cnt;
1105
1106 /*
1107 * timeout is in ms. 0 indicates infinite wait.
1108 * Convert to ticks or 500us units depending on
1109 * our sleep mode.
1110 */
1168 for (offset = 0; offset < mpt->request_frame_size; offset++) {
1169 if ((offset & 0x7) == 0) {
1170 mpt_prtc(mpt, "\n");
1171 mpt_prt(mpt, " ");
1172 }
1173 mpt_prtc(mpt, " %08x", pReq[offset]);
1174 }
1175 mpt_prtc(mpt, "\n");

--- 27 unchanged lines hidden (view full) ---

1203 int timeout;
1204 u_int saved_cnt;
1205
1206 /*
1207 * timeout is in ms. 0 indicates infinite wait.
1208 * Convert to ticks or 500us units depending on
1209 * our sleep mode.
1210 */
1111 if (sleep_ok != 0)
1211 if (sleep_ok != 0) {
1112 timeout = (time_ms * hz) / 1000;
1212 timeout = (time_ms * hz) / 1000;
1113 else
1213 } else {
1114 timeout = time_ms * 2;
1214 timeout = time_ms * 2;
1215 }
1115 req->state |= REQ_STATE_NEED_WAKEUP;
1116 mask &= ~REQ_STATE_NEED_WAKEUP;
1117 saved_cnt = mpt->reset_cnt;
1216 req->state |= REQ_STATE_NEED_WAKEUP;
1217 mask &= ~REQ_STATE_NEED_WAKEUP;
1218 saved_cnt = mpt->reset_cnt;
1118 while ((req->state & mask) != state
1119 && mpt->reset_cnt == saved_cnt) {
1120
1219 while ((req->state & mask) != state && mpt->reset_cnt == saved_cnt) {
1121 if (sleep_ok != 0) {
1122 error = mpt_sleep(mpt, req, PUSER, "mptreq", timeout);
1123 if (error == EWOULDBLOCK) {
1124 timeout = 0;
1125 break;
1126 }
1127 } else {
1128 if (time_ms != 0 && --timeout == 0) {
1220 if (sleep_ok != 0) {
1221 error = mpt_sleep(mpt, req, PUSER, "mptreq", timeout);
1222 if (error == EWOULDBLOCK) {
1223 timeout = 0;
1224 break;
1225 }
1226 } else {
1227 if (time_ms != 0 && --timeout == 0) {
1129 mpt_prt(mpt, "mpt_wait_req timed out\n");
1130 break;
1131 }
1132 DELAY(500);
1133 mpt_intr(mpt);
1134 }
1135 }
1136 req->state &= ~REQ_STATE_NEED_WAKEUP;
1228 break;
1229 }
1230 DELAY(500);
1231 mpt_intr(mpt);
1232 }
1233 }
1234 req->state &= ~REQ_STATE_NEED_WAKEUP;
1137 if (mpt->reset_cnt != saved_cnt)
1235 if (mpt->reset_cnt != saved_cnt) {
1138 return (EIO);
1236 return (EIO);
1139 if (time_ms && timeout <= 0)
1237 }
1238 if (time_ms && timeout <= 0) {
1239 MSG_REQUEST_HEADER *msg_hdr = req->req_vbuf;
1240 mpt_prt(mpt, "mpt_wait_req(%x) timed out\n", msg_hdr->Function);
1140 return (ETIMEDOUT);
1241 return (ETIMEDOUT);
1242 }
1141 return (0);
1142}
1143
1144/*
1145 * Send a command to the IOC via the handshake register.
1146 *
1147 * Only done at initialization time and for certain unusual
1148 * commands such as device/bus reset as specified by LSI.

--- 282 unchanged lines hidden (view full) ---

1431 req->IOCStatus);
1432 error = EIO;
1433 break;
1434 }
1435 mpt_free_request(mpt, req);
1436 return (error);
1437}
1438
1243 return (0);
1244}
1245
1246/*
1247 * Send a command to the IOC via the handshake register.
1248 *
1249 * Only done at initialization time and for certain unusual
1250 * commands such as device/bus reset as specified by LSI.

--- 282 unchanged lines hidden (view full) ---

1533 req->IOCStatus);
1534 error = EIO;
1535 break;
1536 }
1537 mpt_free_request(mpt, req);
1538 return (error);
1539}
1540
1439#define CFG_DATA_OFF 128
1440
1441int
1442mpt_read_cfg_page(struct mpt_softc *mpt, int Action, uint32_t PageAddress,
1443 CONFIG_PAGE_HEADER *hdr, size_t len, int sleep_ok,
1444 int timeout_ms)
1445{
1446 request_t *req;
1447 int error;
1448
1449 req = mpt_get_request(mpt, sleep_ok);
1450 if (req == NULL) {
1451 mpt_prt(mpt, "mpt_read_cfg_page: Get request failed!\n");
1452 return (-1);
1453 }
1454
1455 error = mpt_issue_cfg_req(mpt, req, Action, hdr->PageVersion,
1456 hdr->PageLength, hdr->PageNumber,
1457 hdr->PageType & MPI_CONFIG_PAGETYPE_MASK,
1541int
1542mpt_read_cfg_page(struct mpt_softc *mpt, int Action, uint32_t PageAddress,
1543 CONFIG_PAGE_HEADER *hdr, size_t len, int sleep_ok,
1544 int timeout_ms)
1545{
1546 request_t *req;
1547 int error;
1548
1549 req = mpt_get_request(mpt, sleep_ok);
1550 if (req == NULL) {
1551 mpt_prt(mpt, "mpt_read_cfg_page: Get request failed!\n");
1552 return (-1);
1553 }
1554
1555 error = mpt_issue_cfg_req(mpt, req, Action, hdr->PageVersion,
1556 hdr->PageLength, hdr->PageNumber,
1557 hdr->PageType & MPI_CONFIG_PAGETYPE_MASK,
1458 PageAddress, req->req_pbuf + CFG_DATA_OFF,
1558 PageAddress, req->req_pbuf + MPT_RQSL(mpt),
1459 len, sleep_ok, timeout_ms);
1460 if (error != 0) {
1461 mpt_prt(mpt, "read_cfg_page(%d) timed out\n", Action);
1462 return (-1);
1463 }
1464
1465 if ((req->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
1466 mpt_prt(mpt, "mpt_read_cfg_page: Config Info Status %x\n",
1467 req->IOCStatus);
1468 mpt_free_request(mpt, req);
1469 return (-1);
1470 }
1471 bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap,
1472 BUS_DMASYNC_POSTREAD);
1559 len, sleep_ok, timeout_ms);
1560 if (error != 0) {
1561 mpt_prt(mpt, "read_cfg_page(%d) timed out\n", Action);
1562 return (-1);
1563 }
1564
1565 if ((req->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
1566 mpt_prt(mpt, "mpt_read_cfg_page: Config Info Status %x\n",
1567 req->IOCStatus);
1568 mpt_free_request(mpt, req);
1569 return (-1);
1570 }
1571 bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap,
1572 BUS_DMASYNC_POSTREAD);
1473 memcpy(hdr, ((uint8_t *)req->req_vbuf)+CFG_DATA_OFF, len);
1573 memcpy(hdr, ((uint8_t *)req->req_vbuf)+MPT_RQSL(mpt), len);
1474 mpt_free_request(mpt, req);
1475 return (0);
1476}
1477
1478int
1479mpt_write_cfg_page(struct mpt_softc *mpt, int Action, uint32_t PageAddress,
1480 CONFIG_PAGE_HEADER *hdr, size_t len, int sleep_ok,
1481 int timeout_ms)

--- 10 unchanged lines hidden (view full) ---

1492 return (-1);
1493 }
1494 hdr->PageType &= MPI_CONFIG_PAGETYPE_MASK,
1495
1496 req = mpt_get_request(mpt, sleep_ok);
1497 if (req == NULL)
1498 return (-1);
1499
1574 mpt_free_request(mpt, req);
1575 return (0);
1576}
1577
1578int
1579mpt_write_cfg_page(struct mpt_softc *mpt, int Action, uint32_t PageAddress,
1580 CONFIG_PAGE_HEADER *hdr, size_t len, int sleep_ok,
1581 int timeout_ms)

--- 10 unchanged lines hidden (view full) ---

1592 return (-1);
1593 }
1594 hdr->PageType &= MPI_CONFIG_PAGETYPE_MASK,
1595
1596 req = mpt_get_request(mpt, sleep_ok);
1597 if (req == NULL)
1598 return (-1);
1599
1500 memcpy(((caddr_t)req->req_vbuf)+CFG_DATA_OFF, hdr, len);
1600 memcpy(((caddr_t)req->req_vbuf)+MPT_RQSL(mpt), hdr, len);
1501 /* Restore stripped out attributes */
1502 hdr->PageType |= hdr_attr;
1503
1504 error = mpt_issue_cfg_req(mpt, req, Action, hdr->PageVersion,
1505 hdr->PageLength, hdr->PageNumber,
1506 hdr->PageType & MPI_CONFIG_PAGETYPE_MASK,
1601 /* Restore stripped out attributes */
1602 hdr->PageType |= hdr_attr;
1603
1604 error = mpt_issue_cfg_req(mpt, req, Action, hdr->PageVersion,
1605 hdr->PageLength, hdr->PageNumber,
1606 hdr->PageType & MPI_CONFIG_PAGETYPE_MASK,
1507 PageAddress, req->req_pbuf + CFG_DATA_OFF,
1607 PageAddress, req->req_pbuf + MPT_RQSL(mpt),
1508 len, sleep_ok, timeout_ms);
1509 if (error != 0) {
1510 mpt_prt(mpt, "mpt_write_cfg_page timed out\n");
1511 return (-1);
1512 }
1513
1514 if ((req->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
1515 mpt_prt(mpt, "mpt_write_cfg_page: Config Info Status %x\n",

--- 153 unchanged lines hidden (view full) ---

1669 }
1670
1671 mpt_raid_wakeup(mpt);
1672
1673 return (0);
1674}
1675
1676/*
1608 len, sleep_ok, timeout_ms);
1609 if (error != 0) {
1610 mpt_prt(mpt, "mpt_write_cfg_page timed out\n");
1611 return (-1);
1612 }
1613
1614 if ((req->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
1615 mpt_prt(mpt, "mpt_write_cfg_page: Config Info Status %x\n",

--- 153 unchanged lines hidden (view full) ---

1769 }
1770
1771 mpt_raid_wakeup(mpt);
1772
1773 return (0);
1774}
1775
1776/*
1677 * Read SCSI configuration information
1678 */
1679static int
1680mpt_read_config_info_spi(struct mpt_softc *mpt)
1681{
1682 int rv, i;
1683
1684 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 0,
1685 0, &mpt->mpt_port_page0.Header,
1686 /*sleep_ok*/FALSE, /*timeout_ms*/5000);
1687 if (rv)
1688 return (-1);
1689 mpt_lprt(mpt, MPT_PRT_DEBUG,
1690 "SPI Port Page 0 Header: %x %x %x %x\n",
1691 mpt->mpt_port_page0.Header.PageVersion,
1692 mpt->mpt_port_page0.Header.PageLength,
1693 mpt->mpt_port_page0.Header.PageNumber,
1694 mpt->mpt_port_page0.Header.PageType);
1695
1696 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 1,
1697 0, &mpt->mpt_port_page1.Header,
1698 /*sleep_ok*/FALSE, /*timeout_ms*/5000);
1699 if (rv)
1700 return (-1);
1701
1702 mpt_lprt(mpt, MPT_PRT_DEBUG, "SPI Port Page 1 Header: %x %x %x %x\n",
1703 mpt->mpt_port_page1.Header.PageVersion,
1704 mpt->mpt_port_page1.Header.PageLength,
1705 mpt->mpt_port_page1.Header.PageNumber,
1706 mpt->mpt_port_page1.Header.PageType);
1707
1708 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 2,
1709 /*PageAddress*/0, &mpt->mpt_port_page2.Header,
1710 /*sleep_ok*/FALSE, /*timeout_ms*/5000);
1711 if (rv)
1712 return (-1);
1713
1714 mpt_lprt(mpt, MPT_PRT_DEBUG,
1715 "SPI Port Page 2 Header: %x %x %x %x\n",
1716 mpt->mpt_port_page1.Header.PageVersion,
1717 mpt->mpt_port_page1.Header.PageLength,
1718 mpt->mpt_port_page1.Header.PageNumber,
1719 mpt->mpt_port_page1.Header.PageType);
1720
1721 for (i = 0; i < 16; i++) {
1722 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_DEVICE,
1723 0, i, &mpt->mpt_dev_page0[i].Header,
1724 /*sleep_ok*/FALSE, /*timeout_ms*/5000);
1725 if (rv)
1726 return (-1);
1727
1728 mpt_lprt(mpt, MPT_PRT_DEBUG,
1729 "SPI Target %d Device Page 0 Header: %x %x %x %x\n",
1730 i, mpt->mpt_dev_page0[i].Header.PageVersion,
1731 mpt->mpt_dev_page0[i].Header.PageLength,
1732 mpt->mpt_dev_page0[i].Header.PageNumber,
1733 mpt->mpt_dev_page0[i].Header.PageType);
1734
1735 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_DEVICE,
1736 1, i, &mpt->mpt_dev_page1[i].Header,
1737 /*sleep_ok*/FALSE, /*timeout_ms*/5000);
1738 if (rv)
1739 return (-1);
1740
1741 mpt_lprt(mpt, MPT_PRT_DEBUG,
1742 "SPI Target %d Device Page 1 Header: %x %x %x %x\n",
1743 i, mpt->mpt_dev_page1[i].Header.PageVersion,
1744 mpt->mpt_dev_page1[i].Header.PageLength,
1745 mpt->mpt_dev_page1[i].Header.PageNumber,
1746 mpt->mpt_dev_page1[i].Header.PageType);
1747 }
1748
1749 /*
1750 * At this point, we don't *have* to fail. As long as we have
1751 * valid config header information, we can (barely) lurch
1752 * along.
1753 */
1754
1755 rv = mpt_read_cur_cfg_page(mpt, /*PageAddress*/0,
1756 &mpt->mpt_port_page0.Header,
1757 sizeof(mpt->mpt_port_page0),
1758 /*sleep_ok*/FALSE, /*timeout_ms*/5000);
1759 if (rv) {
1760 mpt_prt(mpt, "failed to read SPI Port Page 0\n");
1761 } else {
1762 mpt_lprt(mpt, MPT_PRT_DEBUG,
1763 "SPI Port Page 0: Capabilities %x PhysicalInterface %x\n",
1764 mpt->mpt_port_page0.Capabilities,
1765 mpt->mpt_port_page0.PhysicalInterface);
1766 }
1767
1768 rv = mpt_read_cur_cfg_page(mpt, /*PageAddress*/0,
1769 &mpt->mpt_port_page1.Header,
1770 sizeof(mpt->mpt_port_page1),
1771 /*sleep_ok*/FALSE, /*timeout_ms*/5000);
1772 if (rv) {
1773 mpt_prt(mpt, "failed to read SPI Port Page 1\n");
1774 } else {
1775 mpt_lprt(mpt, MPT_PRT_DEBUG,
1776 "SPI Port Page 1: Configuration %x OnBusTimerValue %x\n",
1777 mpt->mpt_port_page1.Configuration,
1778 mpt->mpt_port_page1.OnBusTimerValue);
1779 }
1780
1781 rv = mpt_read_cur_cfg_page(mpt, /*PageAddress*/0,
1782 &mpt->mpt_port_page2.Header,
1783 sizeof(mpt->mpt_port_page2),
1784 /*sleep_ok*/FALSE, /*timeout_ms*/5000);
1785 if (rv) {
1786 mpt_prt(mpt, "failed to read SPI Port Page 2\n");
1787 } else {
1788 mpt_lprt(mpt, MPT_PRT_DEBUG,
1789 "SPI Port Page 2: Flags %x Settings %x\n",
1790 mpt->mpt_port_page2.PortFlags,
1791 mpt->mpt_port_page2.PortSettings);
1792 for (i = 0; i < 16; i++) {
1793 mpt_lprt(mpt, MPT_PRT_DEBUG,
1794 "SPI Port Page 2 Tgt %d: timo %x SF %x Flags %x\n",
1795 i, mpt->mpt_port_page2.DeviceSettings[i].Timeout,
1796 mpt->mpt_port_page2.DeviceSettings[i].SyncFactor,
1797 mpt->mpt_port_page2.DeviceSettings[i].DeviceFlags);
1798 }
1799 }
1800
1801 for (i = 0; i < 16; i++) {
1802 rv = mpt_read_cur_cfg_page(mpt, /*PageAddress*/i,
1803 &mpt->mpt_dev_page0[i].Header,
1804 sizeof(*mpt->mpt_dev_page0),
1805 /*sleep_ok*/FALSE,
1806 /*timeout_ms*/5000);
1807 if (rv) {
1808 mpt_prt(mpt,
1809 "cannot read SPI Tgt %d Device Page 0\n", i);
1810 continue;
1811 }
1812 mpt_lprt(mpt, MPT_PRT_DEBUG,
1813 "SPI Tgt %d Page 0: NParms %x Information %x",
1814 i, mpt->mpt_dev_page0[i].NegotiatedParameters,
1815 mpt->mpt_dev_page0[i].Information);
1816
1817 rv = mpt_read_cur_cfg_page(mpt, /*PageAddress*/i,
1818 &mpt->mpt_dev_page1[i].Header,
1819 sizeof(*mpt->mpt_dev_page1),
1820 /*sleep_ok*/FALSE,
1821 /*timeout_ms*/5000);
1822 if (rv) {
1823 mpt_prt(mpt,
1824 "cannot read SPI Tgt %d Device Page 1\n", i);
1825 continue;
1826 }
1827 mpt_lprt(mpt, MPT_PRT_DEBUG,
1828 "SPI Tgt %d Page 1: RParms %x Configuration %x\n",
1829 i, mpt->mpt_dev_page1[i].RequestedParameters,
1830 mpt->mpt_dev_page1[i].Configuration);
1831 }
1832 return (0);
1833}
1834
1835/*
1836 * Validate SPI configuration information.
1837 *
1838 * In particular, validate SPI Port Page 1.
1839 */
1840static int
1841mpt_set_initial_config_spi(struct mpt_softc *mpt)
1842{
1843 int i, pp1val = ((1 << mpt->mpt_ini_id) << 16) | mpt->mpt_ini_id;
1844 int error;
1845
1846 mpt->mpt_disc_enable = 0xff;
1847 mpt->mpt_tag_enable = 0;
1848
1849 if (mpt->mpt_port_page1.Configuration != pp1val) {
1850 CONFIG_PAGE_SCSI_PORT_1 tmp;
1851
1852 mpt_prt(mpt,
1853 "SPI Port Page 1 Config value bad (%x)- should be %x\n",
1854 mpt->mpt_port_page1.Configuration, pp1val);
1855 tmp = mpt->mpt_port_page1;
1856 tmp.Configuration = pp1val;
1857 error = mpt_write_cur_cfg_page(mpt, /*PageAddress*/0,
1858 &tmp.Header, sizeof(tmp),
1859 /*sleep_ok*/FALSE,
1860 /*timeout_ms*/5000);
1861 if (error)
1862 return (-1);
1863 error = mpt_read_cur_cfg_page(mpt, /*PageAddress*/0,
1864 &tmp.Header, sizeof(tmp),
1865 /*sleep_ok*/FALSE,
1866 /*timeout_ms*/5000);
1867 if (error)
1868 return (-1);
1869 if (tmp.Configuration != pp1val) {
1870 mpt_prt(mpt,
1871 "failed to reset SPI Port Page 1 Config value\n");
1872 return (-1);
1873 }
1874 mpt->mpt_port_page1 = tmp;
1875 }
1876
1877 for (i = 0; i < 16; i++) {
1878 CONFIG_PAGE_SCSI_DEVICE_1 tmp;
1879 tmp = mpt->mpt_dev_page1[i];
1880 tmp.RequestedParameters = 0;
1881 tmp.Configuration = 0;
1882 mpt_lprt(mpt, MPT_PRT_DEBUG,
1883 "Set Tgt %d SPI DevicePage 1 values to %x 0 %x\n",
1884 i, tmp.RequestedParameters, tmp.Configuration);
1885 error = mpt_write_cur_cfg_page(mpt, /*PageAddress*/i,
1886 &tmp.Header, sizeof(tmp),
1887 /*sleep_ok*/FALSE,
1888 /*timeout_ms*/5000);
1889 if (error)
1890 return (-1);
1891 error = mpt_read_cur_cfg_page(mpt, /*PageAddress*/i,
1892 &tmp.Header, sizeof(tmp),
1893 /*sleep_ok*/FALSE,
1894 /*timeout_ms*/5000);
1895 if (error)
1896 return (-1);
1897 mpt->mpt_dev_page1[i] = tmp;
1898 mpt_lprt(mpt, MPT_PRT_DEBUG,
1899 "SPI Tgt %d Page 1: RParm %x Configuration %x\n", i,
1900 mpt->mpt_dev_page1[i].RequestedParameters,
1901 mpt->mpt_dev_page1[i].Configuration);
1902 }
1903 return (0);
1904}
1905
1906/*
1907 * Enable IOC port
1908 */
1909static int
1910mpt_send_port_enable(struct mpt_softc *mpt, int port)
1911{
1912 request_t *req;
1913 MSG_PORT_ENABLE *enable_req;
1914 int error;
1915
1916 req = mpt_get_request(mpt, /*sleep_ok*/FALSE);
1917 if (req == NULL)
1918 return (-1);
1919
1920 enable_req = req->req_vbuf;
1777 * Enable IOC port
1778 */
1779static int
1780mpt_send_port_enable(struct mpt_softc *mpt, int port)
1781{
1782 request_t *req;
1783 MSG_PORT_ENABLE *enable_req;
1784 int error;
1785
1786 req = mpt_get_request(mpt, /*sleep_ok*/FALSE);
1787 if (req == NULL)
1788 return (-1);
1789
1790 enable_req = req->req_vbuf;
1921 bzero(enable_req, sizeof *enable_req);
1791 bzero(enable_req, MPT_RQSL(mpt));
1922
1923 enable_req->Function = MPI_FUNCTION_PORT_ENABLE;
1924 enable_req->MsgContext = htole32(req->index | MPT_REPLY_HANDLER_CONFIG);
1925 enable_req->PortNumber = port;
1926
1927 mpt_check_doorbell(mpt);
1928 mpt_lprt(mpt, MPT_PRT_DEBUG, "enabling port %d\n", port);
1929
1930 mpt_send_cmd(mpt, req);
1931 error = mpt_wait_req(mpt, req, REQ_STATE_DONE, REQ_STATE_DONE,
1932 /*sleep_ok*/FALSE,
1933 /*time_ms*/(mpt->is_sas || mpt->is_fc)? 30000 : 3000);
1934 if (error != 0) {
1792
1793 enable_req->Function = MPI_FUNCTION_PORT_ENABLE;
1794 enable_req->MsgContext = htole32(req->index | MPT_REPLY_HANDLER_CONFIG);
1795 enable_req->PortNumber = port;
1796
1797 mpt_check_doorbell(mpt);
1798 mpt_lprt(mpt, MPT_PRT_DEBUG, "enabling port %d\n", port);
1799
1800 mpt_send_cmd(mpt, req);
1801 error = mpt_wait_req(mpt, req, REQ_STATE_DONE, REQ_STATE_DONE,
1802 /*sleep_ok*/FALSE,
1803 /*time_ms*/(mpt->is_sas || mpt->is_fc)? 30000 : 3000);
1804 if (error != 0) {
1935 mpt_prt(mpt, "port enable timed out\n");
1805 mpt_prt(mpt, "port %d enable timed out\n", port);
1936 return (-1);
1937 }
1938 mpt_free_request(mpt, req);
1806 return (-1);
1807 }
1808 mpt_free_request(mpt, req);
1809 mpt_lprt(mpt, MPT_PRT_DEBUG, "enabled port %d\n", port);
1939 return (0);
1940}
1941
1942/*
1943 * Enable/Disable asynchronous event reporting.
1944 *
1945 * NB: this is the first command we send via shared memory
1946 * instead of the handshake register.

--- 40 unchanged lines hidden (view full) ---

1987 /* Mask all interrupts */
1988 mpt_write(mpt, MPT_OFFSET_INTR_MASK,
1989 MPT_INTR_REPLY_MASK | MPT_INTR_DB_MASK);
1990}
1991
1992static void
1993mpt_sysctl_attach(struct mpt_softc *mpt)
1994{
1810 return (0);
1811}
1812
1813/*
1814 * Enable/Disable asynchronous event reporting.
1815 *
1816 * NB: this is the first command we send via shared memory
1817 * instead of the handshake register.

--- 40 unchanged lines hidden (view full) ---

1858 /* Mask all interrupts */
1859 mpt_write(mpt, MPT_OFFSET_INTR_MASK,
1860 MPT_INTR_REPLY_MASK | MPT_INTR_DB_MASK);
1861}
1862
1863static void
1864mpt_sysctl_attach(struct mpt_softc *mpt)
1865{
1866#if __FreeBSD_version >= 500000
1995 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(mpt->dev);
1996 struct sysctl_oid *tree = device_get_sysctl_tree(mpt->dev);
1997
1998 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
1999 "debug", CTLFLAG_RW, &mpt->verbose, 0,
2000 "Debugging/Verbose level");
1867 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(mpt->dev);
1868 struct sysctl_oid *tree = device_get_sysctl_tree(mpt->dev);
1869
1870 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
1871 "debug", CTLFLAG_RW, &mpt->verbose, 0,
1872 "Debugging/Verbose level");
1873#endif
2001}
2002
2003int
2004mpt_attach(struct mpt_softc *mpt)
2005{
1874}
1875
1876int
1877mpt_attach(struct mpt_softc *mpt)
1878{
1879 struct mpt_personality *pers;
2006 int i;
1880 int i;
1881 int error;
2007
2008 for (i = 0; i < MPT_MAX_PERSONALITIES; i++) {
1882
1883 for (i = 0; i < MPT_MAX_PERSONALITIES; i++) {
2009 struct mpt_personality *pers;
2010 int error;
2011
2012 pers = mpt_personalities[i];
1884 pers = mpt_personalities[i];
2013 if (pers == NULL)
1885 if (pers == NULL) {
2014 continue;
1886 continue;
2015
1887 }
2016 if (pers->probe(mpt) == 0) {
2017 error = pers->attach(mpt);
2018 if (error != 0) {
2019 mpt_detach(mpt);
2020 return (error);
2021 }
2022 mpt->mpt_pers_mask |= (0x1 << pers->id);
2023 pers->use_count++;
2024 }
2025 }
2026
1888 if (pers->probe(mpt) == 0) {
1889 error = pers->attach(mpt);
1890 if (error != 0) {
1891 mpt_detach(mpt);
1892 return (error);
1893 }
1894 mpt->mpt_pers_mask |= (0x1 << pers->id);
1895 pers->use_count++;
1896 }
1897 }
1898
1899 /*
1900 * Now that we've attached everything, do the enable function
1901 * for all of the personalities. This allows the personalities
1902 * to do setups that are appropriate for them prior to enabling
1903 * any ports.
1904 */
1905 for (i = 0; i < MPT_MAX_PERSONALITIES; i++) {
1906 pers = mpt_personalities[i];
1907 if (pers != NULL && MPT_PERS_ATTACHED(pers, mpt) != 0) {
1908 error = pers->enable(mpt);
1909 if (error != 0) {
1910 mpt_prt(mpt, "personality %s attached but would"
1911 " not enable (%d)\n", pers->name, error);
1912 mpt_detach(mpt);
1913 return (error);
1914 }
1915 }
1916 }
2027 return (0);
2028}
2029
2030int
2031mpt_shutdown(struct mpt_softc *mpt)
2032{
2033 struct mpt_personality *pers;
2034
1917 return (0);
1918}
1919
1920int
1921mpt_shutdown(struct mpt_softc *mpt)
1922{
1923 struct mpt_personality *pers;
1924
2035 MPT_PERS_FOREACH_REVERSE(mpt, pers)
1925 MPT_PERS_FOREACH_REVERSE(mpt, pers) {
2036 pers->shutdown(mpt);
1926 pers->shutdown(mpt);
2037
2038 mpt_reset(mpt, /*reinit*/FALSE);
1927 }
2039 return (0);
2040}
2041
2042int
2043mpt_detach(struct mpt_softc *mpt)
2044{
2045 struct mpt_personality *pers;
2046

--- 10 unchanged lines hidden (view full) ---

2057mpt_core_load(struct mpt_personality *pers)
2058{
2059 int i;
2060
2061 /*
2062 * Setup core handlers and insert the default handler
2063 * into all "empty slots".
2064 */
1928 return (0);
1929}
1930
1931int
1932mpt_detach(struct mpt_softc *mpt)
1933{
1934 struct mpt_personality *pers;
1935

--- 10 unchanged lines hidden (view full) ---

1946mpt_core_load(struct mpt_personality *pers)
1947{
1948 int i;
1949
1950 /*
1951 * Setup core handlers and insert the default handler
1952 * into all "empty slots".
1953 */
2065 for (i = 0; i < MPT_NUM_REPLY_HANDLERS; i++)
1954 for (i = 0; i < MPT_NUM_REPLY_HANDLERS; i++) {
2066 mpt_reply_handlers[i] = mpt_default_reply_handler;
1955 mpt_reply_handlers[i] = mpt_default_reply_handler;
1956 }
2067
2068 mpt_reply_handlers[MPT_CBI(MPT_REPLY_HANDLER_EVENTS)] =
2069 mpt_event_reply_handler;
2070 mpt_reply_handlers[MPT_CBI(MPT_REPLY_HANDLER_CONFIG)] =
2071 mpt_config_reply_handler;
2072 mpt_reply_handlers[MPT_CBI(MPT_REPLY_HANDLER_HANDSHAKE)] =
2073 mpt_handshake_reply_handler;
1957
1958 mpt_reply_handlers[MPT_CBI(MPT_REPLY_HANDLER_EVENTS)] =
1959 mpt_event_reply_handler;
1960 mpt_reply_handlers[MPT_CBI(MPT_REPLY_HANDLER_CONFIG)] =
1961 mpt_config_reply_handler;
1962 mpt_reply_handlers[MPT_CBI(MPT_REPLY_HANDLER_HANDSHAKE)] =
1963 mpt_handshake_reply_handler;
2074
2075 return (0);
2076}
2077
2078/*
2079 * Initialize per-instance driver data and perform
2080 * initial controller configuration.
2081 */
2082int
2083mpt_core_attach(struct mpt_softc *mpt)
2084{
2085 int val;
2086 int error;
2087
1964 return (0);
1965}
1966
1967/*
1968 * Initialize per-instance driver data and perform
1969 * initial controller configuration.
1970 */
1971int
1972mpt_core_attach(struct mpt_softc *mpt)
1973{
1974 int val;
1975 int error;
1976
1977
2088 LIST_INIT(&mpt->ack_frames);
2089
2090 /* Put all request buffers on the free list */
2091 TAILQ_INIT(&mpt->request_pending_list);
2092 TAILQ_INIT(&mpt->request_free_list);
1978 LIST_INIT(&mpt->ack_frames);
1979
1980 /* Put all request buffers on the free list */
1981 TAILQ_INIT(&mpt->request_pending_list);
1982 TAILQ_INIT(&mpt->request_free_list);
2093 for (val = 0; val < MPT_MAX_REQUESTS(mpt); val++)
1983 for (val = 0; val < MPT_MAX_REQUESTS(mpt); val++) {
2094 mpt_free_request(mpt, &mpt->request_pool[val]);
1984 mpt_free_request(mpt, &mpt->request_pool[val]);
1985 }
2095
1986
1987 for (val = 0; val < MPT_MAX_LUNS; val++) {
1988 STAILQ_INIT(&mpt->trt[val].atios);
1989 STAILQ_INIT(&mpt->trt[val].inots);
1990 }
1991 STAILQ_INIT(&mpt->trt_wildcard.atios);
1992 STAILQ_INIT(&mpt->trt_wildcard.inots);
1993
1994 mpt->scsi_tgt_handler_id = MPT_HANDLER_ID_NONE;
1995
2096 mpt_sysctl_attach(mpt);
2097
2098 mpt_lprt(mpt, MPT_PRT_DEBUG, "doorbell req = %s\n",
1996 mpt_sysctl_attach(mpt);
1997
1998 mpt_lprt(mpt, MPT_PRT_DEBUG, "doorbell req = %s\n",
2099 mpt_ioc_diag(mpt_read(mpt, MPT_OFFSET_DOORBELL)));
1999 mpt_ioc_diag(mpt_read(mpt, MPT_OFFSET_DOORBELL)));
2100
2101 error = mpt_configure_ioc(mpt);
2102
2103 return (error);
2104}
2105
2000
2001 error = mpt_configure_ioc(mpt);
2002
2003 return (error);
2004}
2005
2006int
2007mpt_core_enable(struct mpt_softc *mpt)
2008{
2009 /*
2010 * We enter with the IOC enabled, but async events
2011 * not enabled, ports not enabled and interrupts
2012 * not enabled.
2013 */
2014
2015 /*
2016 * Enable asynchronous event reporting- all personalities
2017 * have attached so that they should be able to now field
2018 * async events.
2019 */
2020 mpt_send_event_request(mpt, 1);
2021
2022 /*
2023 * Catch any pending interrupts
2024 *
2025 * This seems to be crucial- otherwise
2026 * the portenable below times out.
2027 */
2028 mpt_intr(mpt);
2029
2030 /*
2031 * Enable Interrupts
2032 */
2033 mpt_enable_ints(mpt);
2034
2035 /*
2036 * Catch any pending interrupts
2037 *
2038 * This seems to be crucial- otherwise
2039 * the portenable below times out.
2040 */
2041 mpt_intr(mpt);
2042
2043 /*
2044 * Enable the port- but only if we are not MPT_ROLE_NONE.
2045 */
2046 if (mpt_send_port_enable(mpt, 0) != MPT_OK) {
2047 mpt_prt(mpt, "failed to enable port 0\n");
2048 return (ENXIO);
2049 }
2050 return (0);
2051}
2052
2106void
2107mpt_core_shutdown(struct mpt_softc *mpt)
2108{
2053void
2054mpt_core_shutdown(struct mpt_softc *mpt)
2055{
2056 mpt_disable_ints(mpt);
2109}
2110
2111void
2112mpt_core_detach(struct mpt_softc *mpt)
2113{
2057}
2058
2059void
2060mpt_core_detach(struct mpt_softc *mpt)
2061{
2062 mpt_disable_ints(mpt);
2114}
2115
2116int
2117mpt_core_unload(struct mpt_personality *pers)
2118{
2119 /* Unload is always successfull. */
2120 return (0);
2121}

--- 135 unchanged lines hidden (view full) ---

2257 * No need to reset if the IOC is already in the READY state.
2258 *
2259 * Force reset if initialization failed previously.
2260 * Note that a hard_reset of the second channel of a '929
2261 * will stop operation of the first channel. Hopefully, if the
2262 * first channel is ok, the second will not require a hard
2263 * reset.
2264 */
2063}
2064
2065int
2066mpt_core_unload(struct mpt_personality *pers)
2067{
2068 /* Unload is always successfull. */
2069 return (0);
2070}

--- 135 unchanged lines hidden (view full) ---

2206 * No need to reset if the IOC is already in the READY state.
2207 *
2208 * Force reset if initialization failed previously.
2209 * Note that a hard_reset of the second channel of a '929
2210 * will stop operation of the first channel. Hopefully, if the
2211 * first channel is ok, the second will not require a hard
2212 * reset.
2213 */
2265 if (needreset || (mpt_rd_db(mpt) & MPT_DB_STATE_MASK) !=
2214 if (needreset || MPT_STATE(mpt_rd_db(mpt)) !=
2266 MPT_DB_STATE_READY) {
2215 MPT_DB_STATE_READY) {
2267 if (mpt_reset(mpt, /*reinit*/FALSE) != MPT_OK)
2216 if (mpt_reset(mpt, FALSE) != MPT_OK) {
2268 continue;
2217 continue;
2218 }
2269 }
2270 needreset = 0;
2271
2272 if (mpt_get_iocfacts(mpt, &facts) != MPT_OK) {
2273 mpt_prt(mpt, "mpt_get_iocfacts failed\n");
2274 needreset = 1;
2275 continue;
2276 }

--- 126 unchanged lines hidden (view full) ---

2403 mpt->mpt_proto_flags = pfp.ProtocolFlags;
2404 if (pfp.PortType != MPI_PORTFACTS_PORTTYPE_SCSI &&
2405 pfp.PortType != MPI_PORTFACTS_PORTTYPE_SAS &&
2406 pfp.PortType != MPI_PORTFACTS_PORTTYPE_FC) {
2407 mpt_prt(mpt, "Unsupported Port Type (%x)\n",
2408 pfp.PortType);
2409 return (ENXIO);
2410 }
2219 }
2220 needreset = 0;
2221
2222 if (mpt_get_iocfacts(mpt, &facts) != MPT_OK) {
2223 mpt_prt(mpt, "mpt_get_iocfacts failed\n");
2224 needreset = 1;
2225 continue;
2226 }

--- 126 unchanged lines hidden (view full) ---

2353 mpt->mpt_proto_flags = pfp.ProtocolFlags;
2354 if (pfp.PortType != MPI_PORTFACTS_PORTTYPE_SCSI &&
2355 pfp.PortType != MPI_PORTFACTS_PORTTYPE_SAS &&
2356 pfp.PortType != MPI_PORTFACTS_PORTTYPE_FC) {
2357 mpt_prt(mpt, "Unsupported Port Type (%x)\n",
2358 pfp.PortType);
2359 return (ENXIO);
2360 }
2411 if (!(pfp.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR)) {
2412 mpt_prt(mpt, "initiator role unsupported\n");
2413 return (ENXIO);
2414 }
2361 mpt->mpt_max_tgtcmds = le16toh(pfp.MaxPostedCmdBuffers);
2362
2415 if (pfp.PortType == MPI_PORTFACTS_PORTTYPE_FC) {
2416 mpt->is_fc = 1;
2417 mpt->is_sas = 0;
2418 } else if (pfp.PortType == MPI_PORTFACTS_PORTTYPE_SAS) {
2419 mpt->is_fc = 0;
2420 mpt->is_sas = 1;
2421 } else {
2422 mpt->is_fc = 0;
2423 mpt->is_sas = 0;
2424 }
2425 mpt->mpt_ini_id = pfp.PortSCSIID;
2426 mpt->mpt_max_devices = pfp.MaxDevices;
2427
2363 if (pfp.PortType == MPI_PORTFACTS_PORTTYPE_FC) {
2364 mpt->is_fc = 1;
2365 mpt->is_sas = 0;
2366 } else if (pfp.PortType == MPI_PORTFACTS_PORTTYPE_SAS) {
2367 mpt->is_fc = 0;
2368 mpt->is_sas = 1;
2369 } else {
2370 mpt->is_fc = 0;
2371 mpt->is_sas = 0;
2372 }
2373 mpt->mpt_ini_id = pfp.PortSCSIID;
2374 mpt->mpt_max_devices = pfp.MaxDevices;
2375
2428 if (mpt_enable_ioc(mpt) != 0) {
2429 mpt_prt(mpt, "Unable to initialize IOC\n");
2376 /*
2377 * Match our expected role with what this port supports.
2378 *
2379 * We only do this to meet expectations. That is, if the
2380 * user has specified they want initiator role, and we
2381 * don't support it, that's an error we return back upstream.
2382 */
2383
2384 mpt->cap = MPT_ROLE_NONE;
2385 if (pfp.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2386 mpt->cap |= MPT_ROLE_INITIATOR;
2387 }
2388 if (pfp.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2389 mpt->cap |= MPT_ROLE_TARGET;
2390 }
2391 if (mpt->cap == MPT_ROLE_NONE) {
2392 mpt_prt(mpt, "port does not support either target or "
2393 "initiator role\n");
2430 return (ENXIO);
2431 }
2432
2394 return (ENXIO);
2395 }
2396
2397 if ((mpt->role & MPT_ROLE_INITIATOR) &&
2398 (mpt->cap & MPT_ROLE_INITIATOR) == 0) {
2399 mpt_prt(mpt, "port does not support initiator role\n");
2400 return (ENXIO);
2401 }
2402
2403 if ((mpt->role & MPT_ROLE_TARGET) &&
2404 (mpt->cap & MPT_ROLE_TARGET) == 0) {
2405 mpt_prt(mpt, "port does not support target role\n");
2406 return (ENXIO);
2407 }
2408
2409 if (mpt_enable_ioc(mpt, 0) != MPT_OK) {
2410 mpt_prt(mpt, "unable to initialize IOC\n");
2411 return (ENXIO);
2412 }
2413
2433 /*
2414 /*
2434 * Read and set up initial configuration information
2435 * (IOC and SPI only for now)
2436 *
2437 * XXX Should figure out what "personalities" are
2438 * available and defer all initialization junk to
2439 * them.
2415 * Read IOC configuration information.
2440 */
2441 mpt_read_config_info_ioc(mpt);
2442
2416 */
2417 mpt_read_config_info_ioc(mpt);
2418
2443 if (mpt->is_fc == 0 && mpt->is_sas == 0) {
2444 if (mpt_read_config_info_spi(mpt)) {
2445 return (EIO);
2446 }
2447 if (mpt_set_initial_config_spi(mpt)) {
2448 return (EIO);
2449 }
2450 }
2451
2452 /* Everything worked */
2453 break;
2454 }
2455
2456 if (try >= MPT_MAX_TRYS) {
2457 mpt_prt(mpt, "failed to initialize IOC");
2458 return (EIO);
2459 }
2460
2419 /* Everything worked */
2420 break;
2421 }
2422
2423 if (try >= MPT_MAX_TRYS) {
2424 mpt_prt(mpt, "failed to initialize IOC");
2425 return (EIO);
2426 }
2427
2461 mpt_lprt(mpt, MPT_PRT_DEBUG, "enabling interrupts\n");
2462
2463 mpt_enable_ints(mpt);
2464 return (0);
2465}
2466
2467static int
2428 return (0);
2429}
2430
2431static int
2468mpt_enable_ioc(struct mpt_softc *mpt)
2432mpt_enable_ioc(struct mpt_softc *mpt, int portenable)
2469{
2470 uint32_t pptr;
2471 int val;
2472
2473 if (mpt_send_ioc_init(mpt, MPI_WHOINIT_HOST_DRIVER) != MPT_OK) {
2474 mpt_prt(mpt, "mpt_send_ioc_init failed\n");
2475 return (EIO);
2476 }

--- 14 unchanged lines hidden (view full) ---

2491 for (val = 0, pptr = mpt->reply_phys;
2492 (pptr + MPT_REPLY_SIZE) < (mpt->reply_phys + PAGE_SIZE);
2493 pptr += MPT_REPLY_SIZE) {
2494 mpt_free_reply(mpt, pptr);
2495 if (++val == mpt->mpt_global_credits - 1)
2496 break;
2497 }
2498
2433{
2434 uint32_t pptr;
2435 int val;
2436
2437 if (mpt_send_ioc_init(mpt, MPI_WHOINIT_HOST_DRIVER) != MPT_OK) {
2438 mpt_prt(mpt, "mpt_send_ioc_init failed\n");
2439 return (EIO);
2440 }

--- 14 unchanged lines hidden (view full) ---

2455 for (val = 0, pptr = mpt->reply_phys;
2456 (pptr + MPT_REPLY_SIZE) < (mpt->reply_phys + PAGE_SIZE);
2457 pptr += MPT_REPLY_SIZE) {
2458 mpt_free_reply(mpt, pptr);
2459 if (++val == mpt->mpt_global_credits - 1)
2460 break;
2461 }
2462
2499 /*
2500 * Enable asynchronous event reporting
2501 */
2502 mpt_send_event_request(mpt, 1);
2503
2504 /*
2463
2464 /*
2505 * Enable the port
2465 * Enable the port if asked
2506 */
2466 */
2507 if (mpt_send_port_enable(mpt, 0) != MPT_OK) {
2508 mpt_prt(mpt, "failed to enable port 0\n");
2509 return (ENXIO);
2510 }
2511 mpt_lprt(mpt, MPT_PRT_DEBUG, "enabled port 0\n");
2467 if (portenable) {
2468 /*
2469 * Enable asynchronous event reporting
2470 */
2471 mpt_send_event_request(mpt, 1);
2512
2472
2513
2473 if (mpt_send_port_enable(mpt, 0) != MPT_OK) {
2474 mpt_prt(mpt, "failed to enable port 0\n");
2475 return (ENXIO);
2476 }
2477 }
2514 return (MPT_OK);
2515}
2478 return (MPT_OK);
2479}