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 --- |