isp.c (4102f2f6efdc92f25fe4fa37dfe5a03872f66fd9) isp.c (5f5aafe1fcdeb8cd06e03569f45f947d3a75b040)
1/* $FreeBSD$ */
2/*
3 * Machine and OS Independent (well, as best as possible)
4 * code for the Qlogic ISP SCSI adapters.
5 *
1/* $FreeBSD$ */
2/*
3 * Machine and OS Independent (well, as best as possible)
4 * code for the Qlogic ISP SCSI adapters.
5 *
6 * Copyright (c) 1997, 1998, 1999, 2000 by Matthew Jacob
6 * Copyright (c) 1997, 1998, 1999, 2000, 2001 by Matthew Jacob
7 * Feral Software
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice immediately at the beginning of the file, without modification,

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

103/*
104 * Local function prototypes.
105 */
106static int isp_parse_async __P((struct ispsoftc *, int));
107static int isp_handle_other_response
108__P((struct ispsoftc *, ispstatusreq_t *, u_int16_t *));
109static void isp_parse_status
110__P((struct ispsoftc *, ispstatusreq_t *, XS_T *));
7 * Feral Software
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice immediately at the beginning of the file, without modification,

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

103/*
104 * Local function prototypes.
105 */
106static int isp_parse_async __P((struct ispsoftc *, int));
107static int isp_handle_other_response
108__P((struct ispsoftc *, ispstatusreq_t *, u_int16_t *));
109static void isp_parse_status
110__P((struct ispsoftc *, ispstatusreq_t *, XS_T *));
111static void isp_fastpost_complete __P((struct ispsoftc *, u_int32_t));
111static void isp_fastpost_complete __P((struct ispsoftc *, u_int16_t));
112static void isp_scsi_init __P((struct ispsoftc *));
113static void isp_scsi_channel_init __P((struct ispsoftc *, int));
114static void isp_fibre_init __P((struct ispsoftc *));
115static void isp_mark_getpdb_all __P((struct ispsoftc *));
116static int isp_getmap __P((struct ispsoftc *, fcpos_map_t *));
117static int isp_getpdb __P((struct ispsoftc *, int, isp_pdb_t *));
118static u_int64_t isp_get_portname __P((struct ispsoftc *, int, int));
119static int isp_fclink_test __P((struct ispsoftc *, int));

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

928 * Set (possibly new) Initiator ID.
929 */
930 mbs.param[0] = MBOX_SET_INIT_SCSI_ID;
931 mbs.param[1] = (channel << 7) | sdp->isp_initiator_id;
932 isp_mboxcmd(isp, &mbs, MBLOGALL);
933 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
934 return;
935 }
112static void isp_scsi_init __P((struct ispsoftc *));
113static void isp_scsi_channel_init __P((struct ispsoftc *, int));
114static void isp_fibre_init __P((struct ispsoftc *));
115static void isp_mark_getpdb_all __P((struct ispsoftc *));
116static int isp_getmap __P((struct ispsoftc *, fcpos_map_t *));
117static int isp_getpdb __P((struct ispsoftc *, int, isp_pdb_t *));
118static u_int64_t isp_get_portname __P((struct ispsoftc *, int, int));
119static int isp_fclink_test __P((struct ispsoftc *, int));

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

928 * Set (possibly new) Initiator ID.
929 */
930 mbs.param[0] = MBOX_SET_INIT_SCSI_ID;
931 mbs.param[1] = (channel << 7) | sdp->isp_initiator_id;
932 isp_mboxcmd(isp, &mbs, MBLOGALL);
933 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
934 return;
935 }
936 isp_prt(isp, ISP_LOGINFO, "Initiator ID is %d", sdp->isp_initiator_id);
936 isp_prt(isp, ISP_LOGINFO, "Initiator ID is %d on Channel %d",
937 sdp->isp_initiator_id, channel);
937
938
939 /*
940 * Set current per-target parameters to a safe minimum.
941 */
942 for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
943 int lun;
944 u_int16_t sdf;

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

2240 * Start a command. Locking is assumed done in the caller.
2241 */
2242
2243int
2244isp_start(xs)
2245 XS_T *xs;
2246{
2247 struct ispsoftc *isp;
938
939
940 /*
941 * Set current per-target parameters to a safe minimum.
942 */
943 for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
944 int lun;
945 u_int16_t sdf;

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

2241 * Start a command. Locking is assumed done in the caller.
2242 */
2243
2244int
2245isp_start(xs)
2246 XS_T *xs;
2247{
2248 struct ispsoftc *isp;
2248 u_int16_t iptr, optr;
2249 u_int16_t iptr, optr, handle;
2249 union {
2250 ispreq_t *_reqp;
2251 ispreqt2_t *_t2reqp;
2252 } _u;
2253#define reqp _u._reqp
2254#define t2reqp _u._t2reqp
2255#define UZSIZE max(sizeof (ispreq_t), sizeof (ispreqt2_t))
2256 int target, i;

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

2295 /*
2296 * Check to see whether we have good firmware state still or
2297 * need to refresh our port database for this target.
2298 */
2299 target = XS_TGT(xs);
2300 if (IS_FC(isp)) {
2301 fcparam *fcp = isp->isp_param;
2302 struct lportdb *lp;
2250 union {
2251 ispreq_t *_reqp;
2252 ispreqt2_t *_t2reqp;
2253 } _u;
2254#define reqp _u._reqp
2255#define t2reqp _u._t2reqp
2256#define UZSIZE max(sizeof (ispreq_t), sizeof (ispreqt2_t))
2257 int target, i;

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

2296 /*
2297 * Check to see whether we have good firmware state still or
2298 * need to refresh our port database for this target.
2299 */
2300 target = XS_TGT(xs);
2301 if (IS_FC(isp)) {
2302 fcparam *fcp = isp->isp_param;
2303 struct lportdb *lp;
2304#ifdef HANDLE_LOOPSTATE_IN_OUTER_LAYERS
2305 if (fcp->isp_fwstate != FW_READY ||
2306 fcp->isp_loopstate != LOOP_READY) {
2307 return (CMD_RQLATER);
2308 }
2309
2303 /*
2310 /*
2311 * If we're not on a Fabric, we can't have a target
2312 * above FL_PORT_ID-1.
2313 *
2314 * If we're on a fabric and *not* connected as an F-port,
2315 * we can't have a target less than FC_SNS_ID+1. This
2316 * keeps us from having to sort out the difference between
2317 * local public loop devices and those which we might get
2318 * from a switch's database.
2319 */
2320 if (fcp->isp_onfabric == 0) {
2321 if (target >= FL_PORT_ID) {
2322 XS_SETERR(xs, HBA_SELTIMEOUT);
2323 return (CMD_COMPLETE);
2324 }
2325 } else {
2326 if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
2327 XS_SETERR(xs, HBA_SELTIMEOUT);
2328 return (CMD_COMPLETE);
2329 }
2330 if (fcp->isp_topo != TOPO_F_PORT &&
2331 target < FL_PORT_ID) {
2332 XS_SETERR(xs, HBA_SELTIMEOUT);
2333 return (CMD_COMPLETE);
2334 }
2335 }
2336#else
2337 /*
2304 * Check for f/w being in ready state. If the f/w
2305 * isn't in ready state, then we don't know our
2306 * loop ID and the f/w hasn't completed logging
2307 * into all targets on the loop. If this is the
2308 * case, then bounce the command. We pretend this is
2309 * a SELECTION TIMEOUT error if we've never gone to
2310 * FW_READY state at all- in this case we may not
2311 * be hooked to a loop at all and we shouldn't hang

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

2411 return (CMD_RQLATER);
2412 }
2413 }
2414
2415 /*
2416 * XXX: Here's were we would cancel any loop_dead flag
2417 * XXX: also cancel in dead_loop timeout that's running
2418 */
2338 * Check for f/w being in ready state. If the f/w
2339 * isn't in ready state, then we don't know our
2340 * loop ID and the f/w hasn't completed logging
2341 * into all targets on the loop. If this is the
2342 * case, then bounce the command. We pretend this is
2343 * a SELECTION TIMEOUT error if we've never gone to
2344 * FW_READY state at all- in this case we may not
2345 * be hooked to a loop at all and we shouldn't hang

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

2445 return (CMD_RQLATER);
2446 }
2447 }
2448
2449 /*
2450 * XXX: Here's were we would cancel any loop_dead flag
2451 * XXX: also cancel in dead_loop timeout that's running
2452 */
2453#endif
2419
2420 /*
2421 * Now check whether we should even think about pursuing this.
2422 */
2423 lp = &fcp->portdb[target];
2424 if (lp->valid == 0) {
2425 XS_SETERR(xs, HBA_SELTIMEOUT);
2426 return (CMD_COMPLETE);

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

2542
2543 /*
2544 * Always give a bit more leeway to commands after a bus reset.
2545 * XXX: DOES NOT DISTINGUISH WHICH PORT MAY HAVE BEEN SYNCED
2546 */
2547 if (isp->isp_sendmarker && reqp->req_time < 5) {
2548 reqp->req_time = 5;
2549 }
2454
2455 /*
2456 * Now check whether we should even think about pursuing this.
2457 */
2458 lp = &fcp->portdb[target];
2459 if (lp->valid == 0) {
2460 XS_SETERR(xs, HBA_SELTIMEOUT);
2461 return (CMD_COMPLETE);

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

2577
2578 /*
2579 * Always give a bit more leeway to commands after a bus reset.
2580 * XXX: DOES NOT DISTINGUISH WHICH PORT MAY HAVE BEEN SYNCED
2581 */
2582 if (isp->isp_sendmarker && reqp->req_time < 5) {
2583 reqp->req_time = 5;
2584 }
2550 if (isp_save_xs(isp, xs, &reqp->req_handle)) {
2585 if (isp_save_xs(isp, xs, &handle)) {
2551 isp_prt(isp, ISP_LOGDEBUG1, "out of xflist pointers");
2552 XS_SETERR(xs, HBA_BOTCH);
2553 return (CMD_EAGAIN);
2554 }
2586 isp_prt(isp, ISP_LOGDEBUG1, "out of xflist pointers");
2587 XS_SETERR(xs, HBA_BOTCH);
2588 return (CMD_EAGAIN);
2589 }
2590 reqp->req_handle = handle;
2555 /*
2556 * Set up DMA and/or do any bus swizzling of the request entry
2557 * so that the Qlogic F/W understands what is being asked of it.
2558 */
2559 i = ISP_DMASETUP(isp, xs, reqp, &iptr, optr);
2560 if (i != CMD_QUEUED) {
2591 /*
2592 * Set up DMA and/or do any bus swizzling of the request entry
2593 * so that the Qlogic F/W understands what is being asked of it.
2594 */
2595 i = ISP_DMASETUP(isp, xs, reqp, &iptr, optr);
2596 if (i != CMD_QUEUED) {
2561 isp_destroy_handle(isp, reqp->req_handle);
2597 isp_destroy_handle(isp, handle);
2562 /*
2563 * dmasetup sets actual error in packet, and
2564 * return what we were given to return.
2565 */
2566 return (i);
2567 }
2568 XS_SETERR(xs, HBA_NOERROR);
2569 isp_prt(isp, ISP_LOGDEBUG2,

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

2588isp_control(isp, ctl, arg)
2589 struct ispsoftc *isp;
2590 ispctl_t ctl;
2591 void *arg;
2592{
2593 XS_T *xs;
2594 mbreg_t mbs;
2595 int bus, tgt;
2598 /*
2599 * dmasetup sets actual error in packet, and
2600 * return what we were given to return.
2601 */
2602 return (i);
2603 }
2604 XS_SETERR(xs, HBA_NOERROR);
2605 isp_prt(isp, ISP_LOGDEBUG2,

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

2624isp_control(isp, ctl, arg)
2625 struct ispsoftc *isp;
2626 ispctl_t ctl;
2627 void *arg;
2628{
2629 XS_T *xs;
2630 mbreg_t mbs;
2631 int bus, tgt;
2596 u_int32_t handle;
2632 u_int16_t handle;
2597
2598 switch (ctl) {
2599 default:
2600 isp_prt(isp, ISP_LOGERR, "Unknown Control Opcode 0x%x", ctl);
2601 break;
2602
2603 case ISPCTL_RESET_BUS:
2604 /*

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

2661 mbs.param[6] = XS_LUN(xs);
2662 } else {
2663 mbs.param[1] = tgt << 8 | XS_LUN(xs);
2664 }
2665 } else {
2666 mbs.param[1] =
2667 (bus << 15) | (XS_TGT(xs) << 8) | XS_LUN(xs);
2668 }
2633
2634 switch (ctl) {
2635 default:
2636 isp_prt(isp, ISP_LOGERR, "Unknown Control Opcode 0x%x", ctl);
2637 break;
2638
2639 case ISPCTL_RESET_BUS:
2640 /*

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

2697 mbs.param[6] = XS_LUN(xs);
2698 } else {
2699 mbs.param[1] = tgt << 8 | XS_LUN(xs);
2700 }
2701 } else {
2702 mbs.param[1] =
2703 (bus << 15) | (XS_TGT(xs) << 8) | XS_LUN(xs);
2704 }
2669 mbs.param[3] = handle >> 16;
2670 mbs.param[2] = handle & 0xffff;
2705 mbs.param[3] = 0;
2706 mbs.param[2] = handle;
2671 isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_ERROR);
2672 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
2673 return (0);
2674 }
2675 /*
2676 * XXX: Look for command in the REQUEST QUEUE. That is,
2677 * XXX: It hasen't been picked up by firmware yet.
2678 */

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

2845 }
2846 MBOX_NOTIFY_COMPLETE(isp);
2847 } else {
2848 isp_prt(isp, ISP_LOGWARN,
2849 "Mbox Command Async (0x%x) with no waiters",
2850 mbox);
2851 }
2852 } else {
2707 isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_ERROR);
2708 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
2709 return (0);
2710 }
2711 /*
2712 * XXX: Look for command in the REQUEST QUEUE. That is,
2713 * XXX: It hasen't been picked up by firmware yet.
2714 */

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

2881 }
2882 MBOX_NOTIFY_COMPLETE(isp);
2883 } else {
2884 isp_prt(isp, ISP_LOGWARN,
2885 "Mbox Command Async (0x%x) with no waiters",
2886 mbox);
2887 }
2888 } else {
2853 u_int32_t fhandle = isp_parse_async(isp, (int) mbox);
2889 int fhandle = isp_parse_async(isp, (int) mbox);
2854 isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
2855 if (fhandle > 0) {
2890 isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
2891 if (fhandle > 0) {
2856 isp_fastpost_complete(isp, fhandle);
2892 isp_fastpost_complete(isp, (u_int16_t) fhandle);
2857 }
2858 }
2859 if (IS_FC(isp) || isp->isp_state != ISP_RUNSTATE) {
2860 ISP_WRITE(isp, BIU_SEMA, 0);
2861 ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
2862 return (1);
2863 }
2864 }

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

3157 */
3158
3159static int
3160isp_parse_async(isp, mbox)
3161 struct ispsoftc *isp;
3162 int mbox;
3163{
3164 int bus;
2893 }
2894 }
2895 if (IS_FC(isp) || isp->isp_state != ISP_RUNSTATE) {
2896 ISP_WRITE(isp, BIU_SEMA, 0);
2897 ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
2898 return (1);
2899 }
2900 }

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

3193 */
3194
3195static int
3196isp_parse_async(isp, mbox)
3197 struct ispsoftc *isp;
3198 int mbox;
3199{
3200 int bus;
3165 u_int32_t fast_post_handle = 0;
3201 u_int16_t fast_post_handle = 0;
3166
3167 if (IS_DUALBUS(isp)) {
3168 bus = ISP_READ(isp, OUTMAILBOX6);
3169 } else {
3170 bus = 0;
3171 }
3172
3173 switch (mbox) {

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

3273 /*
3274 * XXX: Set up to renegotiate again!
3275 */
3276 /* Can only be for a 1080... */
3277 isp->isp_sendmarker |= (1 << bus);
3278 break;
3279
3280 case ASYNC_CMD_CMPLT:
3202
3203 if (IS_DUALBUS(isp)) {
3204 bus = ISP_READ(isp, OUTMAILBOX6);
3205 } else {
3206 bus = 0;
3207 }
3208
3209 switch (mbox) {

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

3309 /*
3310 * XXX: Set up to renegotiate again!
3311 */
3312 /* Can only be for a 1080... */
3313 isp->isp_sendmarker |= (1 << bus);
3314 break;
3315
3316 case ASYNC_CMD_CMPLT:
3281 fast_post_handle = (ISP_READ(isp, OUTMAILBOX2) << 16) |
3282 ISP_READ(isp, OUTMAILBOX1);
3317 fast_post_handle = ISP_READ(isp, OUTMAILBOX1);
3283 isp_prt(isp, ISP_LOGDEBUG3, "fast post completion of %u",
3284 fast_post_handle);
3285 break;
3286
3287 case ASYNC_CTIO_DONE:
3288#ifdef ISP_TARGET_MODE
3289 /*
3290 * Bus gets overloaded with the handle. Dual bus

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

3798 if (XS_NOERR(xs)) {
3799 XS_SETERR(xs, HBA_BOTCH);
3800 }
3801}
3802
3803static void
3804isp_fastpost_complete(isp, fph)
3805 struct ispsoftc *isp;
3318 isp_prt(isp, ISP_LOGDEBUG3, "fast post completion of %u",
3319 fast_post_handle);
3320 break;
3321
3322 case ASYNC_CTIO_DONE:
3323#ifdef ISP_TARGET_MODE
3324 /*
3325 * Bus gets overloaded with the handle. Dual bus

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

3833 if (XS_NOERR(xs)) {
3834 XS_SETERR(xs, HBA_BOTCH);
3835 }
3836}
3837
3838static void
3839isp_fastpost_complete(isp, fph)
3840 struct ispsoftc *isp;
3806 u_int32_t fph;
3841 u_int16_t fph;
3807{
3808 XS_T *xs;
3809
3842{
3843 XS_T *xs;
3844
3810 if (fph < 1) {
3845 if (fph == 0) {
3811 return;
3812 }
3813 xs = isp_find_xs(isp, fph);
3814 if (xs == NULL) {
3815 isp_prt(isp, ISP_LOGWARN,
3816 "Command for fast post handle 0x%x not found", fph);
3817 return;
3818 }

--- 1549 unchanged lines hidden ---
3846 return;
3847 }
3848 xs = isp_find_xs(isp, fph);
3849 if (xs == NULL) {
3850 isp_prt(isp, ISP_LOGWARN,
3851 "Command for fast post handle 0x%x not found", fph);
3852 return;
3853 }

--- 1549 unchanged lines hidden ---