isp.c (161790) | isp.c (163899) |
---|---|
1/*- 2 * Copyright (c) 1997-2006 by Matthew Jacob 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 28 unchanged lines hidden (view full) --- 37/* 38 * Include header file appropriate for platform we're building on. 39 */ 40#ifdef __NetBSD__ 41#include <dev/ic/isp_netbsd.h> 42#endif 43#ifdef __FreeBSD__ 44#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1997-2006 by Matthew Jacob 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 28 unchanged lines hidden (view full) --- 37/* 38 * Include header file appropriate for platform we're building on. 39 */ 40#ifdef __NetBSD__ 41#include <dev/ic/isp_netbsd.h> 42#endif 43#ifdef __FreeBSD__ 44#include <sys/cdefs.h> |
45__FBSDID("$FreeBSD: head/sys/dev/isp/isp.c 161790 2006-09-01 04:18:17Z mjacob $"); | 45__FBSDID("$FreeBSD: head/sys/dev/isp/isp.c 163899 2006-11-02 03:21:32Z mjacob $"); |
46#include <dev/isp/isp_freebsd.h> 47#endif 48#ifdef __OpenBSD__ 49#include <dev/ic/isp_openbsd.h> 50#endif 51#ifdef __linux__ 52#include "isp_linux.h" 53#endif --- 5 unchanged lines hidden (view full) --- 59 * General defines 60 */ 61 62#define MBOX_DELAY_COUNT 1000000 / 100 63 64/* 65 * Local static data 66 */ | 46#include <dev/isp/isp_freebsd.h> 47#endif 48#ifdef __OpenBSD__ 49#include <dev/ic/isp_openbsd.h> 50#endif 51#ifdef __linux__ 52#include "isp_linux.h" 53#endif --- 5 unchanged lines hidden (view full) --- 59 * General defines 60 */ 61 62#define MBOX_DELAY_COUNT 1000000 / 100 63 64/* 65 * Local static data 66 */ |
67static const char portshift[] = 68 "Target %d Loop ID 0x%x (Port 0x%x) => Loop 0x%x (Port 0x%x)"; 69static const char portdup[] = 70 "Target %d duplicates Target %d- killing off both"; 71static const char retained[] = 72 "Retaining Loop ID 0x%x for Target %d (Port 0x%x)"; 73static const char lretained[] = 74 "Retained login of Target %d (Loop ID 0x%x) Port 0x%x"; 75static const char plogout[] = 76 "Logging out Target %d at Loop ID 0x%x (Port 0x%x)"; 77static const char plogierr[] = 78 "Command Error in PLOGI for Port 0x%x (0x%x)"; 79static const char nopdb[] = 80 "Could not get PDB for Device @ Port 0x%x"; 81static const char pdbmfail1[] = 82 "PDB Loop ID info for Device @ Port 0x%x does not match up (0x%x)"; 83static const char pdbmfail2[] = 84 "PDB Port info for Device @ Port 0x%x does not match up (0x%x)"; 85static const char ldumped[] = 86 "Target %d (Loop ID 0x%x) Port 0x%x dumped after login info mismatch"; | 67static const char fconf[] = 68 "PortDB[%d] changed:\n current =(0x%x@0x%06x 0x%08x%08x 0x%08x%08x)\n" 69 " database=(0x%x@0x%06x 0x%08x%08x 0x%08x%08x)"; |
87static const char notresp[] = 88 "Not RESPONSE in RESPONSE Queue (type 0x%x) @ idx %d (next %d) nlooked %d"; 89static const char xact1[] = 90 "HBA attempted queued transaction with disconnect not set for %d.%d.%d"; 91static const char xact2[] = 92 "HBA attempted queued transaction to target routine %d on target %d bus %d"; 93static const char xact3[] = 94 "HBA attempted queued cmd for %d.%d.%d when queueing disabled"; 95static const char pskip[] = 96 "SCSI phase skipped for target %d.%d.%d"; 97static const char topology[] = | 70static const char notresp[] = 71 "Not RESPONSE in RESPONSE Queue (type 0x%x) @ idx %d (next %d) nlooked %d"; 72static const char xact1[] = 73 "HBA attempted queued transaction with disconnect not set for %d.%d.%d"; 74static const char xact2[] = 75 "HBA attempted queued transaction to target routine %d on target %d bus %d"; 76static const char xact3[] = 77 "HBA attempted queued cmd for %d.%d.%d when queueing disabled"; 78static const char pskip[] = 79 "SCSI phase skipped for target %d.%d.%d"; 80static const char topology[] = |
98 "Loop ID %d, Port ID 0x%x, Loop State 0x%x, Topology '%s'"; 99static const char swrej[] = 100 "Fabric Nameserver rejected %s (Reason=0x%x Expl=0x%x) for Port ID 0x%x"; | 81 "HBA PortID 0x%06x N-Port Handle %d, Connection Topology '%s'"; 82static const char ourwwn[] = 83 "HBA WWNN 0x%08x%08x HBA WWPN 0x%08x%08x"; |
101static const char finmsg[] = 102 "%d.%d.%d: FIN dl%d resid %d STS 0x%x SKEY %c XS_ERR=0x%x"; 103static const char sc0[] = 104 "%s CHAN %d FTHRSH %d IID %d RESETD %d RETRYC %d RETRYD %d ASD 0x%x"; 105static const char sc1[] = 106 "%s RAAN 0x%x DLAN 0x%x DDMAB 0x%x CDMAB 0x%x SELTIME %d MQD %d"; 107static const char sc2[] = "%s CHAN %d TGT %d FLAGS 0x%x 0x%x/0x%x"; 108static const char sc3[] = "Generated"; 109static const char sc4[] = "NVRAM"; 110static const char bun[] = 111 "bad underrun for %d.%d (count %d, resid %d, status %s)"; 112 113/* 114 * Local function prototypes. 115 */ 116static int isp_parse_async(ispsoftc_t *, uint16_t); 117static int isp_handle_other_response(ispsoftc_t *, int, isphdr_t *, | 84static const char finmsg[] = 85 "%d.%d.%d: FIN dl%d resid %d STS 0x%x SKEY %c XS_ERR=0x%x"; 86static const char sc0[] = 87 "%s CHAN %d FTHRSH %d IID %d RESETD %d RETRYC %d RETRYD %d ASD 0x%x"; 88static const char sc1[] = 89 "%s RAAN 0x%x DLAN 0x%x DDMAB 0x%x CDMAB 0x%x SELTIME %d MQD %d"; 90static const char sc2[] = "%s CHAN %d TGT %d FLAGS 0x%x 0x%x/0x%x"; 91static const char sc3[] = "Generated"; 92static const char sc4[] = "NVRAM"; 93static const char bun[] = 94 "bad underrun for %d.%d (count %d, resid %d, status %s)"; 95 96/* 97 * Local function prototypes. 98 */ 99static int isp_parse_async(ispsoftc_t *, uint16_t); 100static int isp_handle_other_response(ispsoftc_t *, int, isphdr_t *, |
118 uint16_t *); | 101 uint32_t *); |
119static void | 102static void |
120isp_parse_status(ispsoftc_t *, ispstatusreq_t *, XS_T *); | 103isp_parse_status(ispsoftc_t *, ispstatusreq_t *, XS_T *, long *); 104static void 105isp_parse_status_24xx(ispsoftc_t *, isp24xx_statusreq_t *, XS_T *, long *); |
121static void isp_fastpost_complete(ispsoftc_t *, uint16_t); 122static int isp_mbox_continue(ispsoftc_t *); 123static void isp_scsi_init(ispsoftc_t *); 124static void isp_scsi_channel_init(ispsoftc_t *, int); 125static void isp_fibre_init(ispsoftc_t *); | 106static void isp_fastpost_complete(ispsoftc_t *, uint16_t); 107static int isp_mbox_continue(ispsoftc_t *); 108static void isp_scsi_init(ispsoftc_t *); 109static void isp_scsi_channel_init(ispsoftc_t *, int); 110static void isp_fibre_init(ispsoftc_t *); |
126static void isp_mark_getpdb_all(ispsoftc_t *); 127static int isp_getmap(ispsoftc_t *, fcpos_map_t *); 128static int isp_getpdb(ispsoftc_t *, int, isp_pdb_t *); | 111static void isp_fibre_init_2400(ispsoftc_t *); 112static void isp_dump_portdb(ispsoftc_t *); 113static void isp_mark_portdb(ispsoftc_t *, int); 114static void isp_plogx_24xx(ispsoftc_t *, uint16_t, uint32_t, int *); 115static int isp_port_login(ispsoftc_t *, uint16_t, uint32_t); 116static void isp_port_logout(ispsoftc_t *, uint16_t, uint32_t); 117static int isp_getpdb(ispsoftc_t *, uint16_t, isp_pdb_t *, int); |
129static uint64_t isp_get_portname(ispsoftc_t *, int, int); 130static int isp_fclink_test(ispsoftc_t *, int); 131static const char *isp2100_fw_statename(int); 132static int isp_pdb_sync(ispsoftc_t *); 133static int isp_scan_loop(ispsoftc_t *); | 118static uint64_t isp_get_portname(ispsoftc_t *, int, int); 119static int isp_fclink_test(ispsoftc_t *, int); 120static const char *isp2100_fw_statename(int); 121static int isp_pdb_sync(ispsoftc_t *); 122static int isp_scan_loop(ispsoftc_t *); |
134static int isp_fabric_mbox_cmd(ispsoftc_t *, mbreg_t *); 135static int isp_scan_fabric(ispsoftc_t *, int); 136static void isp_register_fc4_type(ispsoftc_t *); | 123static int isp_gid_ft_sns(ispsoftc_t *); 124static int isp_gid_ft_ct_passthru(ispsoftc_t *); 125static int isp_scan_fabric(ispsoftc_t *); 126static int isp_login_device(ispsoftc_t *, uint32_t, isp_pdb_t *, uint16_t *); 127static int isp_register_fc4_type(ispsoftc_t *); 128static int isp_register_fc4_type_24xx(ispsoftc_t *); 129static uint16_t isp_nxt_handle(ispsoftc_t *, uint16_t); |
137static void isp_fw_state(ispsoftc_t *); 138static void isp_mboxcmd_qnw(ispsoftc_t *, mbreg_t *, int); | 130static void isp_fw_state(ispsoftc_t *); 131static void isp_mboxcmd_qnw(ispsoftc_t *, mbreg_t *, int); |
139static void isp_mboxcmd(ispsoftc_t *, mbreg_t *, int); | 132static void isp_mboxcmd(ispsoftc_t *, mbreg_t *); |
140 141static void isp_update(ispsoftc_t *); 142static void isp_update_bus(ispsoftc_t *, int); 143static void isp_setdfltparm(ispsoftc_t *, int); 144static int isp_read_nvram(ispsoftc_t *); | 133 134static void isp_update(ispsoftc_t *); 135static void isp_update_bus(ispsoftc_t *, int); 136static void isp_setdfltparm(ispsoftc_t *, int); 137static int isp_read_nvram(ispsoftc_t *); |
138static int isp_read_nvram_2400(ispsoftc_t *); |
|
145static void isp_rdnvram_word(ispsoftc_t *, int, uint16_t *); | 139static void isp_rdnvram_word(ispsoftc_t *, int, uint16_t *); |
140static void isp_rd_2400_nvram(ispsoftc_t *, uint32_t, uint32_t *); |
|
146static void isp_parse_nvram_1020(ispsoftc_t *, uint8_t *); 147static void isp_parse_nvram_1080(ispsoftc_t *, int, uint8_t *); 148static void isp_parse_nvram_12160(ispsoftc_t *, int, uint8_t *); | 141static void isp_parse_nvram_1020(ispsoftc_t *, uint8_t *); 142static void isp_parse_nvram_1080(ispsoftc_t *, int, uint8_t *); 143static void isp_parse_nvram_12160(ispsoftc_t *, int, uint8_t *); |
144static void isp_fix_nvram_wwns(ispsoftc_t *); |
|
149static void isp_parse_nvram_2100(ispsoftc_t *, uint8_t *); | 145static void isp_parse_nvram_2100(ispsoftc_t *, uint8_t *); |
146static void isp_parse_nvram_2400(ispsoftc_t *, uint8_t *); |
|
150 151/* 152 * Reset Hardware. 153 * 154 * Hit the chip over the head, download new f/w if available and set it running. 155 * 156 * Locking done elsewhere. 157 */ 158 159void 160isp_reset(ispsoftc_t *isp) 161{ 162 mbreg_t mbs; | 147 148/* 149 * Reset Hardware. 150 * 151 * Hit the chip over the head, download new f/w if available and set it running. 152 * 153 * Locking done elsewhere. 154 */ 155 156void 157isp_reset(ispsoftc_t *isp) 158{ 159 mbreg_t mbs; |
163 uint32_t code_org; | 160 uint32_t code_org, val; |
164 int loops, i, dodnld = 1; | 161 int loops, i, dodnld = 1; |
165 char *btype = "????"; | 162 static const char *btype = "????"; 163 static const char dcrc[] = "Downloaded RISC Code Checksum Failure"; |
166 167 isp->isp_state = ISP_NILSTATE; 168 169 /* 170 * Basic types (SCSI, FibreChannel and PCI or SBus) 171 * have been set in the MD code. We figure out more 172 * here. Possibly more refined types based upon PCI 173 * identification. Chip revision has been gathered. --- 23 unchanged lines hidden (view full) --- 197 * certainly will be running firmware by now. 198 */ 199 if (ISP_READ(isp, OUTMAILBOX1) != 0x4953 || 200 ISP_READ(isp, OUTMAILBOX2) != 0x5020 || 201 ISP_READ(isp, OUTMAILBOX3) != 0x2020) { 202 /* 203 * Just in case it was paused... 204 */ | 164 165 isp->isp_state = ISP_NILSTATE; 166 167 /* 168 * Basic types (SCSI, FibreChannel and PCI or SBus) 169 * have been set in the MD code. We figure out more 170 * here. Possibly more refined types based upon PCI 171 * identification. Chip revision has been gathered. --- 23 unchanged lines hidden (view full) --- 195 * certainly will be running firmware by now. 196 */ 197 if (ISP_READ(isp, OUTMAILBOX1) != 0x4953 || 198 ISP_READ(isp, OUTMAILBOX2) != 0x5020 || 199 ISP_READ(isp, OUTMAILBOX3) != 0x2020) { 200 /* 201 * Just in case it was paused... 202 */ |
205 ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE); | 203 if (IS_24XX(isp)) { 204 ISP_WRITE(isp, BIU2400_HCCR, 205 HCCR_2400_CMD_RELEASE); 206 } else { 207 ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE); 208 } |
206 MEMZERO(&mbs, sizeof (mbs)); 207 mbs.param[0] = MBOX_ABOUT_FIRMWARE; | 209 MEMZERO(&mbs, sizeof (mbs)); 210 mbs.param[0] = MBOX_ABOUT_FIRMWARE; |
208 isp_mboxcmd(isp, &mbs, MBLOGNONE); | 211 mbs.logval = MBLOGNONE; 212 isp_mboxcmd(isp, &mbs); |
209 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { 210 isp->isp_romfw_rev[0] = mbs.param[1]; 211 isp->isp_romfw_rev[1] = mbs.param[2]; 212 isp->isp_romfw_rev[2] = mbs.param[3]; 213 } 214 } 215 isp->isp_touched = 1; 216 } 217 | 213 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { 214 isp->isp_romfw_rev[0] = mbs.param[1]; 215 isp->isp_romfw_rev[1] = mbs.param[2]; 216 isp->isp_romfw_rev[2] = mbs.param[3]; 217 } 218 } 219 isp->isp_touched = 1; 220 } 221 |
218 DISABLE_INTS(isp); | 222 ISP_DISABLE_INTS(isp); |
219 220 /* | 223 224 /* |
225 * Pick an initial maxcmds value which will be used 226 * to allocate xflist pointer space. It may be changed 227 * later by the firmware. 228 */ 229 if (IS_24XX(isp)) { 230 isp->isp_maxcmds = 4096; 231 } else if (IS_2322(isp)) { 232 isp->isp_maxcmds = 2048; 233 } else if (IS_23XX(isp) || IS_2200(isp)) { 234 isp->isp_maxcmds = 1024; 235 } else { 236 isp->isp_maxcmds = 512; 237 } 238 239 /* 240 * Set up DMA for the request and result queues. 241 * 242 * We do this now so we can use the request queue 243 * for a dma 244 */ 245 if (ISP_MBOXDMASETUP(isp) != 0) { 246 isp_prt(isp, ISP_LOGERR, "Cannot setup DMA"); 247 return; 248 } 249 250 251 /* |
|
221 * Set up default request/response queue in-pointer/out-pointer 222 * register indices. 223 */ | 252 * Set up default request/response queue in-pointer/out-pointer 253 * register indices. 254 */ |
224 if (IS_23XX(isp)) { | 255 if (IS_24XX(isp)) { 256 isp->isp_rqstinrp = BIU2400_REQINP; 257 isp->isp_rqstoutrp = BIU2400_REQOUTP; 258 isp->isp_respinrp = BIU2400_RSPINP; 259 isp->isp_respoutrp = BIU2400_RSPOUTP; 260 isp->isp_atioinrp = BIU2400_ATIO_RSPINP; 261 isp->isp_atiooutrp = BIU2400_ATIO_REQINP; 262 } else if (IS_23XX(isp)) { |
225 isp->isp_rqstinrp = BIU_REQINP; 226 isp->isp_rqstoutrp = BIU_REQOUTP; 227 isp->isp_respinrp = BIU_RSPINP; 228 isp->isp_respoutrp = BIU_RSPOUTP; | 263 isp->isp_rqstinrp = BIU_REQINP; 264 isp->isp_rqstoutrp = BIU_REQOUTP; 265 isp->isp_respinrp = BIU_RSPINP; 266 isp->isp_respoutrp = BIU_RSPOUTP; |
229 ISP_WRITE(isp, isp->isp_rqstinrp, 0); 230 ISP_WRITE(isp, isp->isp_rqstoutrp, 0); 231 ISP_WRITE(isp, isp->isp_respinrp, 0); 232 ISP_WRITE(isp, isp->isp_respoutrp, 0); | |
233 } else { 234 isp->isp_rqstinrp = INMAILBOX4; 235 isp->isp_rqstoutrp = OUTMAILBOX4; 236 isp->isp_respinrp = OUTMAILBOX5; 237 isp->isp_respoutrp = INMAILBOX5; 238 } 239 240 /* 241 * Put the board into PAUSE mode (so we can read the SXP registers 242 * or write FPM/FBM registers). 243 */ | 267 } else { 268 isp->isp_rqstinrp = INMAILBOX4; 269 isp->isp_rqstoutrp = OUTMAILBOX4; 270 isp->isp_respinrp = OUTMAILBOX5; 271 isp->isp_respoutrp = INMAILBOX5; 272 } 273 274 /* 275 * Put the board into PAUSE mode (so we can read the SXP registers 276 * or write FPM/FBM registers). 277 */ |
244 ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE); | 278 if (IS_24XX(isp)) { 279 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_HOST_INT); 280 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT); 281 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_PAUSE); 282 } else { 283 ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE); 284 } |
245 246 if (IS_FC(isp)) { 247 switch (isp->isp_type) { 248 case ISP_HA_FC_2100: 249 btype = "2100"; 250 break; 251 case ISP_HA_FC_2200: 252 btype = "2200"; 253 break; 254 case ISP_HA_FC_2300: 255 btype = "2300"; 256 break; 257 case ISP_HA_FC_2312: 258 btype = "2312"; 259 break; 260 case ISP_HA_FC_2322: 261 btype = "2322"; 262 break; | 285 286 if (IS_FC(isp)) { 287 switch (isp->isp_type) { 288 case ISP_HA_FC_2100: 289 btype = "2100"; 290 break; 291 case ISP_HA_FC_2200: 292 btype = "2200"; 293 break; 294 case ISP_HA_FC_2300: 295 btype = "2300"; 296 break; 297 case ISP_HA_FC_2312: 298 btype = "2312"; 299 break; 300 case ISP_HA_FC_2322: 301 btype = "2322"; 302 break; |
263 case ISP_HA_FC_2422: | 303 case ISP_HA_FC_2400: |
264 btype = "2422"; 265 break; 266 default: 267 break; 268 } | 304 btype = "2422"; 305 break; 306 default: 307 break; 308 } |
269 /* 270 * While we're paused, reset the FPM module and FBM fifos. 271 */ 272 ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS); 273 ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET); 274 ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS); 275 ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL); 276 ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS); | 309 310 if (!IS_24XX(isp)) { 311 /* 312 * While we're paused, reset the FPM module and FBM 313 * fifos. 314 */ 315 ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS); 316 ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET); 317 ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS); 318 ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL); 319 ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS); 320 } |
277 } else if (IS_1240(isp)) { 278 sdparam *sdp = isp->isp_param; 279 btype = "1240"; 280 isp->isp_clock = 60; 281 sdp->isp_ultramode = 1; 282 sdp++; 283 sdp->isp_ultramode = 1; 284 /* --- 153 unchanged lines hidden (view full) --- 438 */ 439 isp->isp_intcnt = isp->isp_intbogus = 0; 440 441 /* 442 * Do MD specific pre initialization 443 */ 444 ISP_RESET0(isp); 445 | 321 } else if (IS_1240(isp)) { 322 sdparam *sdp = isp->isp_param; 323 btype = "1240"; 324 isp->isp_clock = 60; 325 sdp->isp_ultramode = 1; 326 sdp++; 327 sdp->isp_ultramode = 1; 328 /* --- 153 unchanged lines hidden (view full) --- 482 */ 483 isp->isp_intcnt = isp->isp_intbogus = 0; 484 485 /* 486 * Do MD specific pre initialization 487 */ 488 ISP_RESET0(isp); 489 |
446again: 447 | |
448 /* 449 * Hit the chip over the head with hammer, 450 * and give the ISP a chance to recover. 451 */ 452 453 if (IS_SCSI(isp)) { 454 ISP_WRITE(isp, BIU_ICR, BIU_ICR_SOFT_RESET); 455 /* --- 5 unchanged lines hidden (view full) --- 461 * Clear data && control DMA engines. 462 */ 463 ISP_WRITE(isp, CDMA_CONTROL, 464 DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT); 465 ISP_WRITE(isp, DDMA_CONTROL, 466 DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT); 467 468 | 490 /* 491 * Hit the chip over the head with hammer, 492 * and give the ISP a chance to recover. 493 */ 494 495 if (IS_SCSI(isp)) { 496 ISP_WRITE(isp, BIU_ICR, BIU_ICR_SOFT_RESET); 497 /* --- 5 unchanged lines hidden (view full) --- 503 * Clear data && control DMA engines. 504 */ 505 ISP_WRITE(isp, CDMA_CONTROL, 506 DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT); 507 ISP_WRITE(isp, DDMA_CONTROL, 508 DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT); 509 510 |
511 } else if (IS_24XX(isp)) { 512 /* 513 * Stop DMA and wait for it to stop. 514 */ 515 ISP_WRITE(isp, BIU2400_CSR, BIU2400_DMA_STOP|(3 << 4)); 516 for (val = loops = 0; loops < 30000; loops++) { 517 USEC_DELAY(10); 518 val = ISP_READ(isp, BIU2400_CSR); 519 if ((val & BIU2400_DMA_ACTIVE) == 0) { 520 break; 521 } 522 } 523 if (val & BIU2400_DMA_ACTIVE) { 524 isp_prt(isp, ISP_LOGERR, "DMA Failed to Stop on Reset"); 525 return; 526 } 527 /* 528 * Hold it in SOFT_RESET and STOP state for 100us. 529 */ 530 ISP_WRITE(isp, BIU2400_CSR, 531 BIU2400_SOFT_RESET|BIU2400_DMA_STOP|(3 << 4)); 532 USEC_DELAY(100); 533 for (loops = 0; loops < 10000; loops++) { 534 USEC_DELAY(5); 535 val = ISP_READ(isp, OUTMAILBOX0); 536 } 537 for (val = loops = 0; loops < 500000; loops ++) { 538 val = ISP_READ(isp, BIU2400_CSR); 539 if ((val & BIU2400_SOFT_RESET) == 0) { 540 break; 541 } 542 } 543 if (val & BIU2400_SOFT_RESET) { 544 isp_prt(isp, ISP_LOGERR, "Failed to come out of reset"); 545 return; 546 } |
|
469 } else { 470 ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET); 471 /* 472 * A slight delay... 473 */ 474 USEC_DELAY(100); 475 476 /* --- 8 unchanged lines hidden (view full) --- 485 } 486 487 /* 488 * Wait for ISP to be ready to go... 489 */ 490 loops = MBOX_DELAY_COUNT; 491 for (;;) { 492 if (IS_SCSI(isp)) { | 547 } else { 548 ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET); 549 /* 550 * A slight delay... 551 */ 552 USEC_DELAY(100); 553 554 /* --- 8 unchanged lines hidden (view full) --- 563 } 564 565 /* 566 * Wait for ISP to be ready to go... 567 */ 568 loops = MBOX_DELAY_COUNT; 569 for (;;) { 570 if (IS_SCSI(isp)) { |
493 if (!(ISP_READ(isp, BIU_ICR) & BIU_ICR_SOFT_RESET)) | 571 if (!(ISP_READ(isp, BIU_ICR) & BIU_ICR_SOFT_RESET)) { |
494 break; | 572 break; |
573 } 574 } else if (IS_24XX(isp)) { 575 if (ISP_READ(isp, OUTMAILBOX0) == 0) { 576 break; 577 } |
|
495 } else { 496 if (!(ISP_READ(isp, BIU2100_CSR) & BIU2100_SOFT_RESET)) 497 break; 498 } 499 USEC_DELAY(100); 500 if (--loops < 0) { 501 ISP_DUMPREGS(isp, "chip reset timed out"); 502 return; 503 } 504 } 505 506 /* 507 * After we've fired this chip up, zero out the conf1 register 508 * for SCSI adapters and other settings for the 2100. 509 */ 510 511 if (IS_SCSI(isp)) { 512 ISP_WRITE(isp, BIU_CONF1, 0); | 578 } else { 579 if (!(ISP_READ(isp, BIU2100_CSR) & BIU2100_SOFT_RESET)) 580 break; 581 } 582 USEC_DELAY(100); 583 if (--loops < 0) { 584 ISP_DUMPREGS(isp, "chip reset timed out"); 585 return; 586 } 587 } 588 589 /* 590 * After we've fired this chip up, zero out the conf1 register 591 * for SCSI adapters and other settings for the 2100. 592 */ 593 594 if (IS_SCSI(isp)) { 595 ISP_WRITE(isp, BIU_CONF1, 0); |
513 } else { | 596 } else if (!IS_24XX(isp)) { |
514 ISP_WRITE(isp, BIU2100_CSR, 0); 515 } 516 517 /* 518 * Reset RISC Processor 519 */ | 597 ISP_WRITE(isp, BIU2100_CSR, 0); 598 } 599 600 /* 601 * Reset RISC Processor 602 */ |
520 ISP_WRITE(isp, HCCR, HCCR_CMD_RESET); 521 USEC_DELAY(100); 522 /* Clear semaphore register (just to be sure) */ 523 ISP_WRITE(isp, BIU_SEMA, 0); | 603 if (IS_24XX(isp)) { 604 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RESET); 605 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RELEASE); 606 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RESET); 607 } else { 608 ISP_WRITE(isp, HCCR, HCCR_CMD_RESET); 609 USEC_DELAY(100); 610 ISP_WRITE(isp, BIU_SEMA, 0); 611 } |
524 | 612 |
613 |
|
525 /* | 614 /* |
526 * Establish some initial burst rate stuff. 527 * (only for the 1XX0 boards). This really should 528 * be done later after fetching from NVRAM. | 615 * Post-RISC Reset stuff. |
529 */ | 616 */ |
530 if (IS_SCSI(isp)) { | 617 if (IS_24XX(isp)) { 618 for (val = loops = 0; loops < 5000000; loops++) { 619 USEC_DELAY(5); 620 val = ISP_READ(isp, OUTMAILBOX0); 621 if (val == 0) { 622 break; 623 } 624 } 625 if (val != 0) { 626 isp_prt(isp, ISP_LOGERR, "reset didn't clear"); 627 return; 628 } 629 } else if (IS_SCSI(isp)) { |
531 uint16_t tmp = isp->isp_mdvec->dv_conf1; 532 /* 533 * Busted FIFO. Turn off all but burst enables. 534 */ 535 if (isp->isp_type == ISP_HA_SCSI_1040A) { 536 tmp &= BIU_BURST_ENABLE; 537 } 538 ISP_SETBITS(isp, BIU_CONF1, tmp); 539 if (tmp & BIU_BURST_ENABLE) { 540 ISP_SETBITS(isp, CDMA_CONF, DMA_ENABLE_BURST); 541 ISP_SETBITS(isp, DDMA_CONF, DMA_ENABLE_BURST); 542 } | 630 uint16_t tmp = isp->isp_mdvec->dv_conf1; 631 /* 632 * Busted FIFO. Turn off all but burst enables. 633 */ 634 if (isp->isp_type == ISP_HA_SCSI_1040A) { 635 tmp &= BIU_BURST_ENABLE; 636 } 637 ISP_SETBITS(isp, BIU_CONF1, tmp); 638 if (tmp & BIU_BURST_ENABLE) { 639 ISP_SETBITS(isp, CDMA_CONF, DMA_ENABLE_BURST); 640 ISP_SETBITS(isp, DDMA_CONF, DMA_ENABLE_BURST); 641 } |
543 ISP_WRITE(isp, RISC_MTR, 0x1212); | 642 if (SDPARAM(isp)->isp_ptisp) { 643 if (SDPARAM(isp)->isp_ultramode) { 644 while (ISP_READ(isp, RISC_MTR) != 0x1313) { 645 ISP_WRITE(isp, RISC_MTR, 0x1313); 646 ISP_WRITE(isp, HCCR, HCCR_CMD_STEP); 647 } 648 } else { 649 ISP_WRITE(isp, RISC_MTR, 0x1212); 650 } 651 /* 652 * PTI specific register 653 */ 654 ISP_WRITE(isp, RISC_EMB, DUAL_BANK); 655 } else { 656 ISP_WRITE(isp, RISC_MTR, 0x1212); 657 } 658 ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE); |
544 } else { 545 ISP_WRITE(isp, RISC_MTR2100, 0x1212); 546 if (IS_2200(isp) || IS_23XX(isp)) { 547 ISP_WRITE(isp, HCCR, HCCR_2X00_DISABLE_PARITY_PAUSE); 548 } | 659 } else { 660 ISP_WRITE(isp, RISC_MTR2100, 0x1212); 661 if (IS_2200(isp) || IS_23XX(isp)) { 662 ISP_WRITE(isp, HCCR, HCCR_2X00_DISABLE_PARITY_PAUSE); 663 } |
664 ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE); |
|
549 } 550 | 665 } 666 |
551 ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE); /* release paused processor */ | 667 ISP_WRITE(isp, isp->isp_rqstinrp, 0); 668 ISP_WRITE(isp, isp->isp_rqstoutrp, 0); 669 ISP_WRITE(isp, isp->isp_respinrp, 0); 670 ISP_WRITE(isp, isp->isp_respoutrp, 0); |
552 | 671 |
672 |
|
553 /* 554 * Do MD specific post initialization 555 */ 556 ISP_RESET1(isp); 557 558 /* 559 * Wait for everything to finish firing up. 560 * 561 * Avoid doing this on the 2312 because you can generate a PCI 562 * parity error (chip breakage). 563 */ | 673 /* 674 * Do MD specific post initialization 675 */ 676 ISP_RESET1(isp); 677 678 /* 679 * Wait for everything to finish firing up. 680 * 681 * Avoid doing this on the 2312 because you can generate a PCI 682 * parity error (chip breakage). 683 */ |
564 if (IS_23XX(isp)) { 565 USEC_DELAY(5); | 684 if (IS_2312(isp)) { 685 USEC_DELAY(100); |
566 } else { 567 loops = MBOX_DELAY_COUNT; 568 while (ISP_READ(isp, OUTMAILBOX0) == MBOX_BUSY) { 569 USEC_DELAY(100); 570 if (--loops < 0) { 571 isp_prt(isp, ISP_LOGERR, 572 "MBOX_BUSY never cleared on reset"); 573 return; --- 7 unchanged lines hidden (view full) --- 581 * kind of firmware running in the card. 582 */ 583 584 /* 585 * Do some sanity checking. 586 */ 587 MEMZERO(&mbs, sizeof (mbs)); 588 mbs.param[0] = MBOX_NO_OP; | 686 } else { 687 loops = MBOX_DELAY_COUNT; 688 while (ISP_READ(isp, OUTMAILBOX0) == MBOX_BUSY) { 689 USEC_DELAY(100); 690 if (--loops < 0) { 691 isp_prt(isp, ISP_LOGERR, 692 "MBOX_BUSY never cleared on reset"); 693 return; --- 7 unchanged lines hidden (view full) --- 701 * kind of firmware running in the card. 702 */ 703 704 /* 705 * Do some sanity checking. 706 */ 707 MEMZERO(&mbs, sizeof (mbs)); 708 mbs.param[0] = MBOX_NO_OP; |
589 isp_mboxcmd(isp, &mbs, MBLOGALL); | 709 mbs.logval = MBLOGALL; 710 isp_mboxcmd(isp, &mbs); |
590 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 591 return; 592 } 593 | 711 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 712 return; 713 } 714 |
594 if (IS_SCSI(isp)) { | 715 if (IS_SCSI(isp) || IS_24XX(isp)) { |
595 MEMZERO(&mbs, sizeof (mbs)); 596 mbs.param[0] = MBOX_MAILBOX_REG_TEST; 597 mbs.param[1] = 0xdead; 598 mbs.param[2] = 0xbeef; 599 mbs.param[3] = 0xffff; 600 mbs.param[4] = 0x1111; 601 mbs.param[5] = 0xa5a5; | 716 MEMZERO(&mbs, sizeof (mbs)); 717 mbs.param[0] = MBOX_MAILBOX_REG_TEST; 718 mbs.param[1] = 0xdead; 719 mbs.param[2] = 0xbeef; 720 mbs.param[3] = 0xffff; 721 mbs.param[4] = 0x1111; 722 mbs.param[5] = 0xa5a5; |
602 isp_mboxcmd(isp, &mbs, MBLOGALL); | 723 mbs.param[6] = 0x0000; 724 mbs.param[7] = 0x0000; 725 mbs.logval = MBLOGALL; 726 isp_mboxcmd(isp, &mbs); |
603 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 604 return; 605 } 606 if (mbs.param[1] != 0xdead || mbs.param[2] != 0xbeef || 607 mbs.param[3] != 0xffff || mbs.param[4] != 0x1111 || 608 mbs.param[5] != 0xa5a5) { 609 isp_prt(isp, ISP_LOGERR, 610 "Register Test Failed (0x%x 0x%x 0x%x 0x%x 0x%x)", --- 13 unchanged lines hidden (view full) --- 624 * whether we have f/w at all and whether a config flag 625 * has disabled our download. 626 */ 627 if ((isp->isp_mdvec->dv_ispfw == NULL) || 628 (isp->isp_confopts & ISP_CFG_NORELOAD)) { 629 dodnld = 0; 630 } 631 | 727 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 728 return; 729 } 730 if (mbs.param[1] != 0xdead || mbs.param[2] != 0xbeef || 731 mbs.param[3] != 0xffff || mbs.param[4] != 0x1111 || 732 mbs.param[5] != 0xa5a5) { 733 isp_prt(isp, ISP_LOGERR, 734 "Register Test Failed (0x%x 0x%x 0x%x 0x%x 0x%x)", --- 13 unchanged lines hidden (view full) --- 748 * whether we have f/w at all and whether a config flag 749 * has disabled our download. 750 */ 751 if ((isp->isp_mdvec->dv_ispfw == NULL) || 752 (isp->isp_confopts & ISP_CFG_NORELOAD)) { 753 dodnld = 0; 754 } 755 |
632 if (IS_23XX(isp)) { | 756 if (IS_24XX(isp)) { 757 code_org = ISP_CODE_ORG_2400; 758 } else if (IS_23XX(isp)) { |
633 code_org = ISP_CODE_ORG_2300; 634 } else { 635 code_org = ISP_CODE_ORG; 636 } | 759 code_org = ISP_CODE_ORG_2300; 760 } else { 761 code_org = ISP_CODE_ORG; 762 } |
637 if (dodnld) { | 763 764 if (dodnld && IS_24XX(isp)) { 765 uint32_t *ptr = isp->isp_mdvec->dv_ispfw; 766 767 /* 768 * NB: Whatever you do do, do *not* issue the VERIFY FIRMWARE 769 * NB: command to the 2400 while loading new firmware. This 770 * NB: causes the new f/w to start and immediately crash back 771 * NB: to the ROM. 772 */ 773 774 /* 775 * Keep loading until we run out of f/w. 776 */ 777 code_org = ptr[2]; /* 1st load address is our start addr */ 778 779 for (;;) { 780 uint32_t la, wi, wl; 781 782 isp_prt(isp, ISP_LOGDEBUG0, 783 "load 0x%x words of code at load address 0x%x", 784 ptr[3], ptr[2]); 785 786 wi = 0; 787 la = ptr[2]; 788 wl = ptr[3]; 789 790 while (wi < ptr[3]) { 791 uint32_t *cp; 792 uint32_t nw; 793 794 nw = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) >> 2; 795 if (nw > wl) { 796 nw = wl; 797 } 798 cp = isp->isp_rquest; 799 for (i = 0; i < nw; i++) { 800 cp[i] = ptr[wi++]; 801 wl--; 802 } 803 MEMORYBARRIER(isp, SYNC_REQUEST, 804 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp))); 805 MEMZERO(&mbs, sizeof (mbs)); 806 mbs.param[0] = MBOX_LOAD_RISC_RAM; 807 mbs.param[1] = la; 808 mbs.param[2] = DMA_WD1(isp->isp_rquest_dma); 809 mbs.param[3] = DMA_WD0(isp->isp_rquest_dma); 810 mbs.param[4] = nw >> 16; 811 mbs.param[5] = nw; 812 mbs.param[6] = DMA_WD3(isp->isp_rquest_dma); 813 mbs.param[7] = DMA_WD2(isp->isp_rquest_dma); 814 mbs.param[8] = la >> 16; 815 mbs.logval = MBLOGALL; 816 isp_mboxcmd(isp, &mbs); 817 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 818 isp_prt(isp, ISP_LOGERR, 819 "F/W Risc Ram Load Failed"); 820 return; 821 } 822 la += nw; 823 } 824 825 if (ptr[1] == 0) { 826 break; 827 } 828 ptr += ptr[3]; 829 } 830 isp->isp_loaded_fw = 1; 831 } else if (dodnld && IS_23XX(isp)) { |
638 uint16_t *ptr = isp->isp_mdvec->dv_ispfw; | 832 uint16_t *ptr = isp->isp_mdvec->dv_ispfw; |
833 uint16_t wi, wl, segno; 834 uint32_t la; |
|
639 | 835 |
836 la = code_org; 837 segno = 0; 838 839 for (;;) { 840 uint32_t nxtaddr; 841 842 isp_prt(isp, ISP_LOGDEBUG0, 843 "load 0x%x words of code at load address 0x%x", 844 ptr[3], la); 845 846 wi = 0; 847 wl = ptr[3]; 848 849 while (wi < ptr[3]) { 850 uint16_t *cp; 851 uint32_t nw; 852 853 nw = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) >> 1; 854 if (nw > wl) { 855 nw = wl; 856 } 857 if (nw > (1 << 15)) { 858 nw = 1 << 15; 859 } 860 cp = isp->isp_rquest; 861 for (i = 0; i < nw; i++) { 862 cp[i] = ptr[wi++]; 863 wl--; 864 } 865 MEMORYBARRIER(isp, SYNC_REQUEST, 866 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp))); 867 MEMZERO(&mbs, sizeof (mbs)); 868 mbs.param[0] = MBOX_LOAD_RISC_RAM; 869 mbs.param[1] = la; 870 mbs.param[2] = DMA_WD1(isp->isp_rquest_dma); 871 mbs.param[3] = DMA_WD0(isp->isp_rquest_dma); 872 mbs.param[4] = nw; 873 mbs.param[6] = DMA_WD3(isp->isp_rquest_dma); 874 mbs.param[7] = DMA_WD2(isp->isp_rquest_dma); 875 mbs.param[8] = la >> 16; 876 mbs.logval = MBLOGALL; 877 isp_mboxcmd(isp, &mbs); 878 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 879 isp_prt(isp, ISP_LOGERR, 880 "F/W Risc Ram Load Failed"); 881 return; 882 } 883 la += nw; 884 } 885 886 if (!IS_2322(isp)) { 887 /* 888 * Verify that it downloaded correctly. 889 */ 890 MEMZERO(&mbs, sizeof (mbs)); 891 mbs.param[0] = MBOX_VERIFY_CHECKSUM; 892 mbs.param[1] = code_org; 893 mbs.logval = MBLOGNONE; 894 isp_mboxcmd(isp, &mbs); 895 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 896 isp_prt(isp, ISP_LOGERR, dcrc); 897 return; 898 } 899 break; 900 } 901 902 if (++segno == 3) { 903 break; 904 } 905 906 /* 907 * If we're a 2322, the firmware actually comes in 908 * three chunks. We loaded the first at the code_org 909 * address. The other two chunks, which follow right 910 * after each other in memory here, get loaded at 911 * addresses specfied at offset 0x9..0xB. 912 */ 913 914 nxtaddr = ptr[3]; 915 ptr = &ptr[nxtaddr]; 916 la = ptr[5] | ((ptr[4] & 0x3f) << 16); 917 } 918 isp->isp_loaded_fw = 1; 919 } else if (dodnld) { 920 uint16_t *ptr = isp->isp_mdvec->dv_ispfw; 921 |
|
640 isp->isp_mbxworkp = &ptr[1]; 641 isp->isp_mbxwrk0 = ptr[3] - 1; 642 isp->isp_mbxwrk1 = code_org + 1; 643 MEMZERO(&mbs, sizeof (mbs)); 644 mbs.param[0] = MBOX_WRITE_RAM_WORD; 645 mbs.param[1] = code_org; 646 mbs.param[2] = ptr[0]; | 922 isp->isp_mbxworkp = &ptr[1]; 923 isp->isp_mbxwrk0 = ptr[3] - 1; 924 isp->isp_mbxwrk1 = code_org + 1; 925 MEMZERO(&mbs, sizeof (mbs)); 926 mbs.param[0] = MBOX_WRITE_RAM_WORD; 927 mbs.param[1] = code_org; 928 mbs.param[2] = ptr[0]; |
647 isp_mboxcmd(isp, &mbs, MBLOGNONE); | 929 mbs.logval = MBLOGNONE; 930 isp_mboxcmd(isp, &mbs); |
648 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 649 isp_prt(isp, ISP_LOGERR, 650 "F/W download failed at word %d", 651 isp->isp_mbxwrk1 - code_org); | 931 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 932 isp_prt(isp, ISP_LOGERR, 933 "F/W download failed at word %d", 934 isp->isp_mbxwrk1 - code_org); |
652 dodnld = 0; 653 goto again; | 935 return; |
654 } | 936 } |
655 | |
656 /* | 937 /* |
657 * If we're a 2322, the firmware actually comes in three chunks. 658 * We loaded the first at the code_org address. The other two 659 * chunks, which follow right after each other in memory here, 660 * get loaded at addresses specfied at offset 0x9..0xB. | 938 * Verify that it downloaded correctly. |
661 */ | 939 */ |
662 if (IS_2322(isp)) { 663 uint32_t nxtaddr; 664 uint32_t offset; 665 666 nxtaddr = ptr[3]; 667 ptr = &ptr[nxtaddr]; 668 offset = ptr[5] | (((uint32_t)(ptr[4] & 0x3f)) << 16); 669 isp->isp_mbxworkp = &ptr[1]; 670 isp->isp_mbxwrk0 = ptr[3] - 1; 671 isp->isp_mbxwrk1 = offset + 1; 672 isp->isp_mbxwrk8 = (offset + 1) >> 16; 673 MEMZERO(&mbs, sizeof (mbs)); 674 mbs.param[0] = MBOX_WRITE_RAM_WORD_EXTENDED; 675 mbs.param[1] = offset; 676 mbs.param[2] = ptr[0]; 677 mbs.param[8] = offset >> 16; 678 isp_mboxcmd(isp, &mbs, MBLOGNONE); 679 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 680 isp_prt(isp, ISP_LOGERR, 681 "Receive Sequencer F/W Load Failed"); 682 return; 683 } 684 685 nxtaddr = ptr[3]; 686 ptr = &ptr[nxtaddr]; 687 offset = ptr[5] | (((uint32_t)(ptr[4] & 0x3f)) << 16); 688 isp->isp_mbxworkp = &ptr[1]; 689 isp->isp_mbxwrk0 = ptr[3] - 1; 690 isp->isp_mbxwrk1 = (offset + 1); 691 isp->isp_mbxwrk8 = (offset + 1) >> 16; 692 MEMZERO(&mbs, sizeof (mbs)); 693 mbs.param[0] = MBOX_WRITE_RAM_WORD_EXTENDED; 694 mbs.param[1] = offset; 695 mbs.param[2] = ptr[0]; 696 mbs.param[8] = offset >> 16; 697 isp_mboxcmd(isp, &mbs, MBLOGNONE); 698 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 699 isp_prt(isp, ISP_LOGERR, 700 "Transmit Sequencer F/W Load Failed"); 701 return; 702 } 703 } else { 704 /* 705 * Verify that it downloaded correctly. 706 */ 707 MEMZERO(&mbs, sizeof (mbs)); 708 mbs.param[0] = MBOX_VERIFY_CHECKSUM; 709 mbs.param[1] = code_org; 710 isp_mboxcmd(isp, &mbs, MBLOGNONE); 711 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 712 isp_prt(isp, ISP_LOGERR, 713 "Downloaded RISC Code Checksum Failure"); 714 return; 715 } 716 | 940 MEMZERO(&mbs, sizeof (mbs)); 941 mbs.param[0] = MBOX_VERIFY_CHECKSUM; 942 mbs.param[1] = code_org; 943 mbs.logval = MBLOGNONE; 944 isp_mboxcmd(isp, &mbs); 945 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 946 isp_prt(isp, ISP_LOGERR, dcrc); 947 return; |
717 } 718 isp->isp_loaded_fw = 1; 719 } else { 720 isp->isp_loaded_fw = 0; 721 isp_prt(isp, ISP_LOGDEBUG2, "skipping f/w download"); 722 } 723 724 /* 725 * Now start it rolling. 726 * 727 * If we didn't actually download f/w, 728 * we still need to (re)start it. 729 */ 730 731 732 MEMZERO(&mbs, sizeof (mbs)); | 948 } 949 isp->isp_loaded_fw = 1; 950 } else { 951 isp->isp_loaded_fw = 0; 952 isp_prt(isp, ISP_LOGDEBUG2, "skipping f/w download"); 953 } 954 955 /* 956 * Now start it rolling. 957 * 958 * If we didn't actually download f/w, 959 * we still need to (re)start it. 960 */ 961 962 963 MEMZERO(&mbs, sizeof (mbs)); |
964 mbs.timeout = 1000000; |
|
733 mbs.param[0] = MBOX_EXEC_FIRMWARE; | 965 mbs.param[0] = MBOX_EXEC_FIRMWARE; |
734 mbs.param[1] = code_org; 735 if (IS_2322(isp) || IS_24XX(isp)) { | 966 if (IS_24XX(isp)) { 967 mbs.param[1] = code_org >> 16; 968 mbs.param[2] = code_org; |
736 if (isp->isp_loaded_fw) { | 969 if (isp->isp_loaded_fw) { |
970 mbs.param[3] = 0; 971 } else { 972 mbs.param[3] = 1; 973 } 974 } else if (IS_2322(isp)) { 975 mbs.param[1] = code_org; 976 if (isp->isp_loaded_fw) { |
|
737 mbs.param[2] = 0; 738 } else { 739 mbs.param[2] = 1; 740 } | 977 mbs.param[2] = 0; 978 } else { 979 mbs.param[2] = 1; 980 } |
981 } else { 982 mbs.param[1] = code_org; |
|
741 } | 983 } |
742 isp_mboxcmd(isp, &mbs, MBLOGNONE); | 984 985 mbs.logval = MBLOGALL; 986 isp_mboxcmd(isp, &mbs); |
743 if (IS_2322(isp) || IS_24XX(isp)) { 744 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { | 987 if (IS_2322(isp) || IS_24XX(isp)) { 988 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { |
745 isp_prt(isp, ISP_LOGERR, "EXEC F/W failed: 0x%x", 746 mbs.param[0]); | |
747 return; 748 } 749 } 750 751 /* | 989 return; 990 } 991 } 992 993 /* |
752 * Give it a chance to start. | 994 * Give it a chance to finish starting up. |
753 */ | 995 */ |
754 USEC_DELAY(500); | 996 USEC_DELAY(250000); |
755 756 if (IS_SCSI(isp)) { 757 /* 758 * Set CLOCK RATE, but only if asked to. 759 */ 760 if (isp->isp_clock) { 761 mbs.param[0] = MBOX_SET_CLOCK_RATE; 762 mbs.param[1] = isp->isp_clock; | 997 998 if (IS_SCSI(isp)) { 999 /* 1000 * Set CLOCK RATE, but only if asked to. 1001 */ 1002 if (isp->isp_clock) { 1003 mbs.param[0] = MBOX_SET_CLOCK_RATE; 1004 mbs.param[1] = isp->isp_clock; |
763 isp_mboxcmd(isp, &mbs, MBLOGALL); | 1005 mbs.logval = MBLOGNONE; 1006 isp_mboxcmd(isp, &mbs); |
764 /* we will try not to care if this fails */ 765 } 766 } 767 768 MEMZERO(&mbs, sizeof (mbs)); 769 mbs.param[0] = MBOX_ABOUT_FIRMWARE; | 1007 /* we will try not to care if this fails */ 1008 } 1009 } 1010 1011 MEMZERO(&mbs, sizeof (mbs)); 1012 mbs.param[0] = MBOX_ABOUT_FIRMWARE; |
770 isp_mboxcmd(isp, &mbs, MBLOGALL); | 1013 mbs.logval = MBLOGALL; 1014 isp_mboxcmd(isp, &mbs); |
771 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 772 return; 773 } 774 | 1015 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1016 return; 1017 } 1018 |
1019 if (IS_24XX(isp) && mbs.param[1] == 0xdead) { 1020 isp_prt(isp, ISP_LOGERR, "f/w didn't *really* start"); 1021 return; 1022 } 1023 |
|
775 /* 776 * The SBus firmware that we are using apparently does not return 777 * major, minor, micro revisions in the mailbox registers, which 778 * is really, really, annoying. 779 */ 780 if (ISP_SBUS_SUPPORTED && isp->isp_bustype == ISP_BT_SBUS) { 781 if (dodnld) { 782#ifdef ISP_TARGET_MODE --- 6 unchanged lines hidden (view full) --- 789 isp->isp_fwrev[2] = 0; 790 } 791 } else { 792 isp->isp_fwrev[0] = mbs.param[1]; 793 isp->isp_fwrev[1] = mbs.param[2]; 794 isp->isp_fwrev[2] = mbs.param[3]; 795 } 796 | 1024 /* 1025 * The SBus firmware that we are using apparently does not return 1026 * major, minor, micro revisions in the mailbox registers, which 1027 * is really, really, annoying. 1028 */ 1029 if (ISP_SBUS_SUPPORTED && isp->isp_bustype == ISP_BT_SBUS) { 1030 if (dodnld) { 1031#ifdef ISP_TARGET_MODE --- 6 unchanged lines hidden (view full) --- 1038 isp->isp_fwrev[2] = 0; 1039 } 1040 } else { 1041 isp->isp_fwrev[0] = mbs.param[1]; 1042 isp->isp_fwrev[1] = mbs.param[2]; 1043 isp->isp_fwrev[2] = mbs.param[3]; 1044 } 1045 |
797 isp_prt(isp, ISP_LOGCONFIG, | 1046 isp_prt(isp, ISP_LOGALL, |
798 "Board Type %s, Chip Revision 0x%x, %s F/W Revision %d.%d.%d", 799 btype, isp->isp_revision, dodnld? "loaded" : "resident", 800 isp->isp_fwrev[0], isp->isp_fwrev[1], isp->isp_fwrev[2]); 801 802 if (IS_FC(isp)) { 803 /* 804 * We do not believe firmware attributes for 2100 code less 805 * than 1.17.0, unless it's the firmware we specifically 806 * are loading. 807 * | 1047 "Board Type %s, Chip Revision 0x%x, %s F/W Revision %d.%d.%d", 1048 btype, isp->isp_revision, dodnld? "loaded" : "resident", 1049 isp->isp_fwrev[0], isp->isp_fwrev[1], isp->isp_fwrev[2]); 1050 1051 if (IS_FC(isp)) { 1052 /* 1053 * We do not believe firmware attributes for 2100 code less 1054 * than 1.17.0, unless it's the firmware we specifically 1055 * are loading. 1056 * |
808 * Note that all 22XX and 23XX f/w is greater than 1.X.0. | 1057 * Note that all 22XX and later f/w is greater than 1.X.0. |
809 */ | 1058 */ |
810 if (!(ISP_FW_NEWER_THAN(isp, 1, 17, 0))) { | 1059 if ((ISP_FW_OLDER_THAN(isp, 1, 17, 1))) { |
811#ifdef USE_SMALLER_2100_FIRMWARE 812 FCPARAM(isp)->isp_fwattr = ISP_FW_ATTR_SCCLUN; 813#else 814 FCPARAM(isp)->isp_fwattr = 0; 815#endif 816 } else { 817 FCPARAM(isp)->isp_fwattr = mbs.param[6]; 818 isp_prt(isp, ISP_LOGDEBUG0, 819 "Firmware Attributes = 0x%x", mbs.param[6]); 820 } | 1060#ifdef USE_SMALLER_2100_FIRMWARE 1061 FCPARAM(isp)->isp_fwattr = ISP_FW_ATTR_SCCLUN; 1062#else 1063 FCPARAM(isp)->isp_fwattr = 0; 1064#endif 1065 } else { 1066 FCPARAM(isp)->isp_fwattr = mbs.param[6]; 1067 isp_prt(isp, ISP_LOGDEBUG0, 1068 "Firmware Attributes = 0x%x", mbs.param[6]); 1069 } |
821 if (IS_2KLOGIN(isp)) { | 1070 FCPARAM(isp)->isp_2klogin = 0; 1071 FCPARAM(isp)->isp_sccfw = 0; 1072 FCPARAM(isp)->isp_tmode = 0; 1073 if (IS_24XX(isp)) { 1074 FCPARAM(isp)->isp_2klogin = 1; 1075 FCPARAM(isp)->isp_sccfw = 1; 1076 FCPARAM(isp)->isp_tmode = 1; 1077 } else { 1078 if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) { 1079 FCPARAM(isp)->isp_sccfw = 1; 1080 } 1081 if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_2KLOGINS) { 1082 FCPARAM(isp)->isp_2klogin = 1; 1083 FCPARAM(isp)->isp_sccfw = 1; 1084 } 1085 if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_TMODE) { 1086 FCPARAM(isp)->isp_tmode = 1; 1087 } 1088 } 1089 if (FCPARAM(isp)->isp_2klogin) { |
822 isp_prt(isp, ISP_LOGCONFIG, "2K Logins Supported"); 823 } 824 } 825 826 if (isp->isp_romfw_rev[0] || isp->isp_romfw_rev[1] || 827 isp->isp_romfw_rev[2]) { 828 isp_prt(isp, ISP_LOGCONFIG, "Last F/W revision was %d.%d.%d", 829 isp->isp_romfw_rev[0], isp->isp_romfw_rev[1], 830 isp->isp_romfw_rev[2]); 831 } 832 | 1090 isp_prt(isp, ISP_LOGCONFIG, "2K Logins Supported"); 1091 } 1092 } 1093 1094 if (isp->isp_romfw_rev[0] || isp->isp_romfw_rev[1] || 1095 isp->isp_romfw_rev[2]) { 1096 isp_prt(isp, ISP_LOGCONFIG, "Last F/W revision was %d.%d.%d", 1097 isp->isp_romfw_rev[0], isp->isp_romfw_rev[1], 1098 isp->isp_romfw_rev[2]); 1099 } 1100 |
833 MEMZERO(&mbs, sizeof (mbs)); 834 mbs.param[0] = MBOX_GET_FIRMWARE_STATUS; 835 isp_mboxcmd(isp, &mbs, MBLOGALL); 836 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 837 return; | 1101 if (!IS_24XX(isp)) { 1102 MEMZERO(&mbs, sizeof (mbs)); 1103 mbs.param[0] = MBOX_GET_FIRMWARE_STATUS; 1104 mbs.logval = MBLOGALL; 1105 isp_mboxcmd(isp, &mbs); 1106 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1107 return; 1108 } 1109 if (isp->isp_maxcmds >= mbs.param[2]) { 1110 isp->isp_maxcmds = mbs.param[2]; 1111 } |
838 } | 1112 } |
839 isp->isp_maxcmds = mbs.param[2]; 840 isp_prt(isp, ISP_LOGINFO, 841 "%d max I/O commands supported", mbs.param[2]); | 1113 isp_prt(isp, ISP_LOGCONFIG, 1114 "%d max I/O command limit set", isp->isp_maxcmds); |
842 isp_fw_state(isp); 843 | 1115 isp_fw_state(isp); 1116 |
844 /* 845 * Set up DMA for the request and result mailboxes. 846 */ 847 if (ISP_MBOXDMASETUP(isp) != 0) { 848 isp_prt(isp, ISP_LOGERR, "Cannot setup DMA"); 849 return; 850 } | |
851 isp->isp_state = ISP_RESETSTATE; 852 853 /* 854 * Okay- now that we have new firmware running, we now (re)set our 855 * notion of how many luns we support. This is somewhat tricky because 856 * if we haven't loaded firmware, we sometimes do not have an easy way 857 * of knowing how many luns we support. 858 * --- 14 unchanged lines hidden (view full) --- 873 isp->isp_maxluns = 32; 874 } else { 875 isp->isp_maxluns = 8; 876 } 877 } else { 878 isp->isp_maxluns = 8; 879 } 880 } else { | 1117 isp->isp_state = ISP_RESETSTATE; 1118 1119 /* 1120 * Okay- now that we have new firmware running, we now (re)set our 1121 * notion of how many luns we support. This is somewhat tricky because 1122 * if we haven't loaded firmware, we sometimes do not have an easy way 1123 * of knowing how many luns we support. 1124 * --- 14 unchanged lines hidden (view full) --- 1139 isp->isp_maxluns = 32; 1140 } else { 1141 isp->isp_maxluns = 8; 1142 } 1143 } else { 1144 isp->isp_maxluns = 8; 1145 } 1146 } else { |
881 if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) { | 1147 if (FCPARAM(isp)->isp_sccfw) { |
882 isp->isp_maxluns = 16384; 883 } else { 884 isp->isp_maxluns = 16; 885 } 886 } 887} 888 889/* --- 7 unchanged lines hidden (view full) --- 897{ 898 /* 899 * Must do this first to get defaults established. 900 */ 901 isp_setdfltparm(isp, 0); 902 if (IS_DUALBUS(isp)) { 903 isp_setdfltparm(isp, 1); 904 } | 1148 isp->isp_maxluns = 16384; 1149 } else { 1150 isp->isp_maxluns = 16; 1151 } 1152 } 1153} 1154 1155/* --- 7 unchanged lines hidden (view full) --- 1163{ 1164 /* 1165 * Must do this first to get defaults established. 1166 */ 1167 isp_setdfltparm(isp, 0); 1168 if (IS_DUALBUS(isp)) { 1169 isp_setdfltparm(isp, 1); 1170 } |
1171 |
|
905 if (IS_FC(isp)) { | 1172 if (IS_FC(isp)) { |
906 isp_fibre_init(isp); | 1173 /* 1174 * Do this *before* initializing the firmware. 1175 */ 1176 isp_mark_portdb(isp, 0); 1177 FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT; 1178 FCPARAM(isp)->isp_loopstate = LOOP_NIL; 1179 1180 if (isp->isp_role != ISP_ROLE_NONE) { 1181 if (IS_24XX(isp)) { 1182 isp_fibre_init_2400(isp); 1183 } else { 1184 isp_fibre_init(isp); 1185 } 1186 } |
907 } else { 908 isp_scsi_init(isp); 909 } 910} 911 912static void 913isp_scsi_init(ispsoftc_t *isp) 914{ --- 27 unchanged lines hidden (view full) --- 942 * You set both channels at the same time. 943 */ 944 MEMZERO(&mbs, sizeof (mbs)); 945 mbs.param[0] = MBOX_SET_RETRY_COUNT; 946 mbs.param[1] = sdp_chan0->isp_retry_count; 947 mbs.param[2] = sdp_chan0->isp_retry_delay; 948 mbs.param[6] = sdp_chan1->isp_retry_count; 949 mbs.param[7] = sdp_chan1->isp_retry_delay; | 1187 } else { 1188 isp_scsi_init(isp); 1189 } 1190} 1191 1192static void 1193isp_scsi_init(ispsoftc_t *isp) 1194{ --- 27 unchanged lines hidden (view full) --- 1222 * You set both channels at the same time. 1223 */ 1224 MEMZERO(&mbs, sizeof (mbs)); 1225 mbs.param[0] = MBOX_SET_RETRY_COUNT; 1226 mbs.param[1] = sdp_chan0->isp_retry_count; 1227 mbs.param[2] = sdp_chan0->isp_retry_delay; 1228 mbs.param[6] = sdp_chan1->isp_retry_count; 1229 mbs.param[7] = sdp_chan1->isp_retry_delay; |
950 951 isp_mboxcmd(isp, &mbs, MBLOGALL); | 1230 mbs.logval = MBLOGALL; 1231 isp_mboxcmd(isp, &mbs); |
952 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 953 return; 954 } 955 956 /* 957 * Set ASYNC DATA SETUP time. This is very important. 958 */ 959 MEMZERO(&mbs, sizeof (mbs)); 960 mbs.param[0] = MBOX_SET_ASYNC_DATA_SETUP_TIME; 961 mbs.param[1] = sdp_chan0->isp_async_data_setup; 962 mbs.param[2] = sdp_chan1->isp_async_data_setup; | 1232 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1233 return; 1234 } 1235 1236 /* 1237 * Set ASYNC DATA SETUP time. This is very important. 1238 */ 1239 MEMZERO(&mbs, sizeof (mbs)); 1240 mbs.param[0] = MBOX_SET_ASYNC_DATA_SETUP_TIME; 1241 mbs.param[1] = sdp_chan0->isp_async_data_setup; 1242 mbs.param[2] = sdp_chan1->isp_async_data_setup; |
963 isp_mboxcmd(isp, &mbs, MBLOGALL); | 1243 mbs.logval = MBLOGALL; 1244 isp_mboxcmd(isp, &mbs); |
964 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 965 return; 966 } 967 968 /* 969 * Set ACTIVE Negation State. 970 */ 971 MEMZERO(&mbs, sizeof (mbs)); 972 mbs.param[0] = MBOX_SET_ACT_NEG_STATE; 973 mbs.param[1] = 974 (sdp_chan0->isp_req_ack_active_neg << 4) | 975 (sdp_chan0->isp_data_line_active_neg << 5); 976 mbs.param[2] = 977 (sdp_chan1->isp_req_ack_active_neg << 4) | 978 (sdp_chan1->isp_data_line_active_neg << 5); | 1245 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1246 return; 1247 } 1248 1249 /* 1250 * Set ACTIVE Negation State. 1251 */ 1252 MEMZERO(&mbs, sizeof (mbs)); 1253 mbs.param[0] = MBOX_SET_ACT_NEG_STATE; 1254 mbs.param[1] = 1255 (sdp_chan0->isp_req_ack_active_neg << 4) | 1256 (sdp_chan0->isp_data_line_active_neg << 5); 1257 mbs.param[2] = 1258 (sdp_chan1->isp_req_ack_active_neg << 4) | 1259 (sdp_chan1->isp_data_line_active_neg << 5); |
979 980 MEMZERO(&mbs, sizeof (mbs)); 981 isp_mboxcmd(isp, &mbs, MBLOGNONE); | 1260 mbs.logval = MBLOGNONE; 1261 isp_mboxcmd(isp, &mbs); |
982 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 983 isp_prt(isp, ISP_LOGERR, 984 "failed to set active negation state (%d,%d), (%d,%d)", 985 sdp_chan0->isp_req_ack_active_neg, 986 sdp_chan0->isp_data_line_active_neg, 987 sdp_chan1->isp_req_ack_active_neg, 988 sdp_chan1->isp_data_line_active_neg); 989 /* 990 * But don't return. 991 */ 992 } 993 994 /* 995 * Set the Tag Aging limit 996 */ 997 MEMZERO(&mbs, sizeof (mbs)); 998 mbs.param[0] = MBOX_SET_TAG_AGE_LIMIT; 999 mbs.param[1] = sdp_chan0->isp_tag_aging; 1000 mbs.param[2] = sdp_chan1->isp_tag_aging; | 1262 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1263 isp_prt(isp, ISP_LOGERR, 1264 "failed to set active negation state (%d,%d), (%d,%d)", 1265 sdp_chan0->isp_req_ack_active_neg, 1266 sdp_chan0->isp_data_line_active_neg, 1267 sdp_chan1->isp_req_ack_active_neg, 1268 sdp_chan1->isp_data_line_active_neg); 1269 /* 1270 * But don't return. 1271 */ 1272 } 1273 1274 /* 1275 * Set the Tag Aging limit 1276 */ 1277 MEMZERO(&mbs, sizeof (mbs)); 1278 mbs.param[0] = MBOX_SET_TAG_AGE_LIMIT; 1279 mbs.param[1] = sdp_chan0->isp_tag_aging; 1280 mbs.param[2] = sdp_chan1->isp_tag_aging; |
1001 isp_mboxcmd(isp, &mbs, MBLOGALL); | 1281 mbs.logval = MBLOGALL; 1282 isp_mboxcmd(isp, &mbs); |
1002 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1003 isp_prt(isp, ISP_LOGERR, "failed to set tag age limit (%d,%d)", 1004 sdp_chan0->isp_tag_aging, sdp_chan1->isp_tag_aging); 1005 return; 1006 } 1007 1008 /* 1009 * Set selection timeout. 1010 */ 1011 MEMZERO(&mbs, sizeof (mbs)); 1012 mbs.param[0] = MBOX_SET_SELECT_TIMEOUT; 1013 mbs.param[1] = sdp_chan0->isp_selection_timeout; 1014 mbs.param[2] = sdp_chan1->isp_selection_timeout; | 1283 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1284 isp_prt(isp, ISP_LOGERR, "failed to set tag age limit (%d,%d)", 1285 sdp_chan0->isp_tag_aging, sdp_chan1->isp_tag_aging); 1286 return; 1287 } 1288 1289 /* 1290 * Set selection timeout. 1291 */ 1292 MEMZERO(&mbs, sizeof (mbs)); 1293 mbs.param[0] = MBOX_SET_SELECT_TIMEOUT; 1294 mbs.param[1] = sdp_chan0->isp_selection_timeout; 1295 mbs.param[2] = sdp_chan1->isp_selection_timeout; |
1015 isp_mboxcmd(isp, &mbs, MBLOGALL); | 1296 mbs.logval = MBLOGALL; 1297 isp_mboxcmd(isp, &mbs); |
1016 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1017 return; 1018 } 1019 1020 /* now do per-channel settings */ 1021 isp_scsi_channel_init(isp, 0); 1022 if (IS_DUALBUS(isp)) 1023 isp_scsi_channel_init(isp, 1); --- 6 unchanged lines hidden (view full) --- 1030 MEMZERO(&mbs, sizeof (mbs)); 1031 mbs.param[0] = MBOX_INIT_RES_QUEUE_A64; 1032 mbs.param[1] = RESULT_QUEUE_LEN(isp); 1033 mbs.param[2] = DMA_WD1(isp->isp_result_dma); 1034 mbs.param[3] = DMA_WD0(isp->isp_result_dma); 1035 mbs.param[4] = 0; 1036 mbs.param[6] = DMA_WD3(isp->isp_result_dma); 1037 mbs.param[7] = DMA_WD2(isp->isp_result_dma); | 1298 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1299 return; 1300 } 1301 1302 /* now do per-channel settings */ 1303 isp_scsi_channel_init(isp, 0); 1304 if (IS_DUALBUS(isp)) 1305 isp_scsi_channel_init(isp, 1); --- 6 unchanged lines hidden (view full) --- 1312 MEMZERO(&mbs, sizeof (mbs)); 1313 mbs.param[0] = MBOX_INIT_RES_QUEUE_A64; 1314 mbs.param[1] = RESULT_QUEUE_LEN(isp); 1315 mbs.param[2] = DMA_WD1(isp->isp_result_dma); 1316 mbs.param[3] = DMA_WD0(isp->isp_result_dma); 1317 mbs.param[4] = 0; 1318 mbs.param[6] = DMA_WD3(isp->isp_result_dma); 1319 mbs.param[7] = DMA_WD2(isp->isp_result_dma); |
1038 isp_mboxcmd(isp, &mbs, MBLOGALL); | 1320 mbs.logval = MBLOGALL; 1321 isp_mboxcmd(isp, &mbs); |
1039 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1040 return; 1041 } 1042 isp->isp_residx = mbs.param[5]; 1043 1044 MEMZERO(&mbs, sizeof (mbs)); 1045 mbs.param[0] = MBOX_INIT_REQ_QUEUE_A64; 1046 mbs.param[1] = RQUEST_QUEUE_LEN(isp); 1047 mbs.param[2] = DMA_WD1(isp->isp_rquest_dma); 1048 mbs.param[3] = DMA_WD0(isp->isp_rquest_dma); 1049 mbs.param[5] = 0; 1050 mbs.param[6] = DMA_WD3(isp->isp_result_dma); 1051 mbs.param[7] = DMA_WD2(isp->isp_result_dma); | 1322 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1323 return; 1324 } 1325 isp->isp_residx = mbs.param[5]; 1326 1327 MEMZERO(&mbs, sizeof (mbs)); 1328 mbs.param[0] = MBOX_INIT_REQ_QUEUE_A64; 1329 mbs.param[1] = RQUEST_QUEUE_LEN(isp); 1330 mbs.param[2] = DMA_WD1(isp->isp_rquest_dma); 1331 mbs.param[3] = DMA_WD0(isp->isp_rquest_dma); 1332 mbs.param[5] = 0; 1333 mbs.param[6] = DMA_WD3(isp->isp_result_dma); 1334 mbs.param[7] = DMA_WD2(isp->isp_result_dma); |
1052 isp_mboxcmd(isp, &mbs, MBLOGALL); | 1335 mbs.logval = MBLOGALL; 1336 isp_mboxcmd(isp, &mbs); |
1053 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1054 return; 1055 } 1056 isp->isp_reqidx = isp->isp_reqodx = mbs.param[4]; 1057 } else { 1058 MEMZERO(&mbs, sizeof (mbs)); 1059 mbs.param[0] = MBOX_INIT_RES_QUEUE; 1060 mbs.param[1] = RESULT_QUEUE_LEN(isp); 1061 mbs.param[2] = DMA_WD1(isp->isp_result_dma); 1062 mbs.param[3] = DMA_WD0(isp->isp_result_dma); 1063 mbs.param[4] = 0; | 1337 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1338 return; 1339 } 1340 isp->isp_reqidx = isp->isp_reqodx = mbs.param[4]; 1341 } else { 1342 MEMZERO(&mbs, sizeof (mbs)); 1343 mbs.param[0] = MBOX_INIT_RES_QUEUE; 1344 mbs.param[1] = RESULT_QUEUE_LEN(isp); 1345 mbs.param[2] = DMA_WD1(isp->isp_result_dma); 1346 mbs.param[3] = DMA_WD0(isp->isp_result_dma); 1347 mbs.param[4] = 0; |
1064 isp_mboxcmd(isp, &mbs, MBLOGALL); | 1348 mbs.logval = MBLOGALL; 1349 isp_mboxcmd(isp, &mbs); |
1065 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1066 return; 1067 } 1068 isp->isp_residx = mbs.param[5]; 1069 1070 MEMZERO(&mbs, sizeof (mbs)); 1071 mbs.param[0] = MBOX_INIT_REQ_QUEUE; 1072 mbs.param[1] = RQUEST_QUEUE_LEN(isp); 1073 mbs.param[2] = DMA_WD1(isp->isp_rquest_dma); 1074 mbs.param[3] = DMA_WD0(isp->isp_rquest_dma); 1075 mbs.param[5] = 0; | 1350 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1351 return; 1352 } 1353 isp->isp_residx = mbs.param[5]; 1354 1355 MEMZERO(&mbs, sizeof (mbs)); 1356 mbs.param[0] = MBOX_INIT_REQ_QUEUE; 1357 mbs.param[1] = RQUEST_QUEUE_LEN(isp); 1358 mbs.param[2] = DMA_WD1(isp->isp_rquest_dma); 1359 mbs.param[3] = DMA_WD0(isp->isp_rquest_dma); 1360 mbs.param[5] = 0; |
1076 isp_mboxcmd(isp, &mbs, MBLOGALL); | 1361 mbs.logval = MBLOGALL; 1362 isp_mboxcmd(isp, &mbs); |
1077 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1078 return; 1079 } 1080 isp->isp_reqidx = isp->isp_reqodx = mbs.param[4]; 1081 } 1082 1083 /* 1084 * Turn on Fast Posting, LVD transitions --- 13 unchanged lines hidden (view full) --- 1098 if (IS_ULTRA2(isp) || IS_1240(isp)) 1099 mbs.param[1] |= FW_FEATURE_RIO_16BIT; 1100#else 1101 if (IS_ULTRA2(isp) || IS_1240(isp)) 1102 mbs.param[1] |= FW_FEATURE_FAST_POST; 1103#endif 1104 if (mbs.param[1] != 0) { 1105 uint16_t sfeat = mbs.param[1]; | 1363 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1364 return; 1365 } 1366 isp->isp_reqidx = isp->isp_reqodx = mbs.param[4]; 1367 } 1368 1369 /* 1370 * Turn on Fast Posting, LVD transitions --- 13 unchanged lines hidden (view full) --- 1384 if (IS_ULTRA2(isp) || IS_1240(isp)) 1385 mbs.param[1] |= FW_FEATURE_RIO_16BIT; 1386#else 1387 if (IS_ULTRA2(isp) || IS_1240(isp)) 1388 mbs.param[1] |= FW_FEATURE_FAST_POST; 1389#endif 1390 if (mbs.param[1] != 0) { 1391 uint16_t sfeat = mbs.param[1]; |
1106 isp_mboxcmd(isp, &mbs, MBLOGALL); | 1392 mbs.logval = MBLOGALL; 1393 isp_mboxcmd(isp, &mbs); |
1107 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { 1108 isp_prt(isp, ISP_LOGINFO, 1109 "Enabled FW features (0x%x)", sfeat); 1110 } 1111 } 1112 1113 /* 1114 * Let the outer layers decide whether to issue a SCSI bus reset. --- 12 unchanged lines hidden (view full) --- 1127 sdp += channel; 1128 1129 /* 1130 * Set (possibly new) Initiator ID. 1131 */ 1132 MEMZERO(&mbs, sizeof (mbs)); 1133 mbs.param[0] = MBOX_SET_INIT_SCSI_ID; 1134 mbs.param[1] = (channel << 7) | sdp->isp_initiator_id; | 1394 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { 1395 isp_prt(isp, ISP_LOGINFO, 1396 "Enabled FW features (0x%x)", sfeat); 1397 } 1398 } 1399 1400 /* 1401 * Let the outer layers decide whether to issue a SCSI bus reset. --- 12 unchanged lines hidden (view full) --- 1414 sdp += channel; 1415 1416 /* 1417 * Set (possibly new) Initiator ID. 1418 */ 1419 MEMZERO(&mbs, sizeof (mbs)); 1420 mbs.param[0] = MBOX_SET_INIT_SCSI_ID; 1421 mbs.param[1] = (channel << 7) | sdp->isp_initiator_id; |
1135 isp_mboxcmd(isp, &mbs, MBLOGALL); | 1422 mbs.logval = MBLOGALL; 1423 isp_mboxcmd(isp, &mbs); |
1136 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1137 return; 1138 } 1139 isp_prt(isp, ISP_LOGINFO, "Initiator ID is %d on Channel %d", 1140 sdp->isp_initiator_id, channel); 1141 1142 1143 /* --- 39 unchanged lines hidden (view full) --- 1183 mbs.param[3] = 1184 (sdp->isp_devparam[tgt].goal_offset << 8) | 1185 (sdp->isp_devparam[tgt].goal_period); 1186 } 1187 isp_prt(isp, ISP_LOGDEBUG0, 1188 "Initial Settings bus%d tgt%d flags 0x%x off 0x%x per 0x%x", 1189 channel, tgt, mbs.param[2], mbs.param[3] >> 8, 1190 mbs.param[3] & 0xff); | 1424 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1425 return; 1426 } 1427 isp_prt(isp, ISP_LOGINFO, "Initiator ID is %d on Channel %d", 1428 sdp->isp_initiator_id, channel); 1429 1430 1431 /* --- 39 unchanged lines hidden (view full) --- 1471 mbs.param[3] = 1472 (sdp->isp_devparam[tgt].goal_offset << 8) | 1473 (sdp->isp_devparam[tgt].goal_period); 1474 } 1475 isp_prt(isp, ISP_LOGDEBUG0, 1476 "Initial Settings bus%d tgt%d flags 0x%x off 0x%x per 0x%x", 1477 channel, tgt, mbs.param[2], mbs.param[3] >> 8, 1478 mbs.param[3] & 0xff); |
1191 isp_mboxcmd(isp, &mbs, MBLOGNONE); | 1479 mbs.logval = MBLOGNONE; 1480 isp_mboxcmd(isp, &mbs); |
1192 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1193 sdf = DPARM_SAFE_DFLT; 1194 MEMZERO(&mbs, sizeof (mbs)); 1195 mbs.param[0] = MBOX_SET_TARGET_PARAMS; 1196 mbs.param[1] = (tgt << 8) | (channel << 15); 1197 mbs.param[2] = sdf; 1198 mbs.param[3] = 0; | 1481 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1482 sdf = DPARM_SAFE_DFLT; 1483 MEMZERO(&mbs, sizeof (mbs)); 1484 mbs.param[0] = MBOX_SET_TARGET_PARAMS; 1485 mbs.param[1] = (tgt << 8) | (channel << 15); 1486 mbs.param[2] = sdf; 1487 mbs.param[3] = 0; |
1199 isp_mboxcmd(isp, &mbs, MBLOGALL); | 1488 mbs.logval = MBLOGALL; 1489 isp_mboxcmd(isp, &mbs); |
1200 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1201 continue; 1202 } 1203 } 1204 1205 /* 1206 * We don't update any information directly from the f/w 1207 * because we need to run at least one command to cause a --- 7 unchanged lines hidden (view full) --- 1215 */ 1216 sdp->isp_devparam[tgt].actv_flags = sdf & ~DPARM_TQING; 1217 for (lun = 0; lun < (int) isp->isp_maxluns; lun++) { 1218 MEMZERO(&mbs, sizeof (mbs)); 1219 mbs.param[0] = MBOX_SET_DEV_QUEUE_PARAMS; 1220 mbs.param[1] = (channel << 15) | (tgt << 8) | lun; 1221 mbs.param[2] = sdp->isp_max_queue_depth; 1222 mbs.param[3] = sdp->isp_devparam[tgt].exc_throttle; | 1490 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1491 continue; 1492 } 1493 } 1494 1495 /* 1496 * We don't update any information directly from the f/w 1497 * because we need to run at least one command to cause a --- 7 unchanged lines hidden (view full) --- 1505 */ 1506 sdp->isp_devparam[tgt].actv_flags = sdf & ~DPARM_TQING; 1507 for (lun = 0; lun < (int) isp->isp_maxluns; lun++) { 1508 MEMZERO(&mbs, sizeof (mbs)); 1509 mbs.param[0] = MBOX_SET_DEV_QUEUE_PARAMS; 1510 mbs.param[1] = (channel << 15) | (tgt << 8) | lun; 1511 mbs.param[2] = sdp->isp_max_queue_depth; 1512 mbs.param[3] = sdp->isp_devparam[tgt].exc_throttle; |
1223 isp_mboxcmd(isp, &mbs, MBLOGALL); | 1513 mbs.logval = MBLOGALL; 1514 isp_mboxcmd(isp, &mbs); |
1224 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1225 break; 1226 } 1227 } 1228 } 1229 for (tgt = 0; tgt < MAX_TARGETS; tgt++) { 1230 if (sdp->isp_devparam[tgt].dev_refresh) { 1231 isp->isp_sendmarker |= (1 << channel); 1232 isp->isp_update |= (1 << channel); 1233 break; 1234 } 1235 } 1236} 1237 1238/* 1239 * Fibre Channel specific initialization. | 1515 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1516 break; 1517 } 1518 } 1519 } 1520 for (tgt = 0; tgt < MAX_TARGETS; tgt++) { 1521 if (sdp->isp_devparam[tgt].dev_refresh) { 1522 isp->isp_sendmarker |= (1 << channel); 1523 isp->isp_update |= (1 << channel); 1524 break; 1525 } 1526 } 1527} 1528 1529/* 1530 * Fibre Channel specific initialization. |
1240 * 1241 * Locks are held before coming here. | |
1242 */ 1243static void 1244isp_fibre_init(ispsoftc_t *isp) 1245{ 1246 fcparam *fcp; 1247 isp_icb_t local, *icbp = &local; 1248 mbreg_t mbs; | 1531 */ 1532static void 1533isp_fibre_init(ispsoftc_t *isp) 1534{ 1535 fcparam *fcp; 1536 isp_icb_t local, *icbp = &local; 1537 mbreg_t mbs; |
1249 int loopid; | |
1250 uint64_t nwwn, pwwn; 1251 1252 fcp = isp->isp_param; 1253 | 1538 uint64_t nwwn, pwwn; 1539 1540 fcp = isp->isp_param; 1541 |
1254 /* 1255 * Do this *before* initializing the firmware. 1256 */ 1257 isp_mark_getpdb_all(isp); 1258 fcp->isp_fwstate = FW_CONFIG_WAIT; 1259 fcp->isp_loopstate = LOOP_NIL; 1260 1261 /* 1262 * If we have no role (neither target nor initiator), return. 1263 */ 1264 if (isp->isp_role == ISP_ROLE_NONE) { 1265 return; 1266 } 1267 1268 loopid = fcp->isp_loopid; | |
1269 MEMZERO(icbp, sizeof (*icbp)); 1270 icbp->icb_version = ICB_VERSION1; | 1542 MEMZERO(icbp, sizeof (*icbp)); 1543 icbp->icb_version = ICB_VERSION1; |
1544 icbp->icb_fwoptions = fcp->isp_fwoptions; |
|
1271 1272 /* 1273 * Firmware Options are either retrieved from NVRAM or 1274 * are patched elsewhere. We check them for sanity here 1275 * and make changes based on board revision, but otherwise 1276 * let others decide policy. 1277 */ 1278 1279 /* 1280 * If this is a 2100 < revision 5, we have to turn off FAIRNESS. 1281 */ | 1545 1546 /* 1547 * Firmware Options are either retrieved from NVRAM or 1548 * are patched elsewhere. We check them for sanity here 1549 * and make changes based on board revision, but otherwise 1550 * let others decide policy. 1551 */ 1552 1553 /* 1554 * If this is a 2100 < revision 5, we have to turn off FAIRNESS. 1555 */ |
1282 if ((isp->isp_type == ISP_HA_FC_2100) && isp->isp_revision < 5) { 1283 fcp->isp_fwoptions &= ~ICBOPT_FAIRNESS; | 1556 if (IS_2100(isp) && isp->isp_revision < 5) { 1557 icbp->icb_fwoptions &= ~ICBOPT_FAIRNESS; |
1284 } 1285 1286 /* 1287 * We have to use FULL LOGIN even though it resets the loop too much 1288 * because otherwise port database entries don't get updated after 1289 * a LIP- this is a known f/w bug for 2100 f/w less than 1.17.0. 1290 */ 1291 if (!ISP_FW_NEWER_THAN(isp, 1, 17, 0)) { | 1558 } 1559 1560 /* 1561 * We have to use FULL LOGIN even though it resets the loop too much 1562 * because otherwise port database entries don't get updated after 1563 * a LIP- this is a known f/w bug for 2100 f/w less than 1.17.0. 1564 */ 1565 if (!ISP_FW_NEWER_THAN(isp, 1, 17, 0)) { |
1292 fcp->isp_fwoptions |= ICBOPT_FULL_LOGIN; | 1566 icbp->icb_fwoptions |= ICBOPT_FULL_LOGIN; |
1293 } 1294 1295 /* 1296 * Insist on Port Database Update Async notifications 1297 */ | 1567 } 1568 1569 /* 1570 * Insist on Port Database Update Async notifications 1571 */ |
1298 fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE; | 1572 icbp->icb_fwoptions |= ICBOPT_PDBCHANGE_AE; |
1299 1300 /* 1301 * Make sure that target role reflects into fwoptions. 1302 */ 1303 if (isp->isp_role & ISP_ROLE_TARGET) { | 1573 1574 /* 1575 * Make sure that target role reflects into fwoptions. 1576 */ 1577 if (isp->isp_role & ISP_ROLE_TARGET) { |
1304 fcp->isp_fwoptions |= ICBOPT_TGT_ENABLE; | 1578 icbp->icb_fwoptions |= ICBOPT_TGT_ENABLE; |
1305 } else { | 1579 } else { |
1306 fcp->isp_fwoptions &= ~ICBOPT_TGT_ENABLE; | 1580 icbp->icb_fwoptions &= ~ICBOPT_TGT_ENABLE; |
1307 } 1308 1309 if (isp->isp_role & ISP_ROLE_INITIATOR) { | 1581 } 1582 1583 if (isp->isp_role & ISP_ROLE_INITIATOR) { |
1310 fcp->isp_fwoptions &= ~ICBOPT_INI_DISABLE; | 1584 icbp->icb_fwoptions &= ~ICBOPT_INI_DISABLE; |
1311 } else { | 1585 } else { |
1312 fcp->isp_fwoptions |= ICBOPT_INI_DISABLE; | 1586 icbp->icb_fwoptions |= ICBOPT_INI_DISABLE; |
1313 } 1314 | 1587 } 1588 |
1315 /* 1316 * Propagate all of this into the ICB structure. 1317 */ 1318 icbp->icb_fwoptions = fcp->isp_fwoptions; | |
1319 icbp->icb_maxfrmlen = fcp->isp_maxfrmlen; 1320 if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN || 1321 icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) { 1322 isp_prt(isp, ISP_LOGERR, 1323 "bad frame length (%d) from NVRAM- using %d", 1324 fcp->isp_maxfrmlen, ICB_DFLT_FRMLEN); 1325 icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN; 1326 } --- 7 unchanged lines hidden (view full) --- 1334 if (icbp->icb_execthrottle < 1) { 1335 isp_prt(isp, ISP_LOGERR, 1336 "bad execution throttle of %d- using 16", 1337 fcp->isp_execthrottle); 1338 icbp->icb_execthrottle = ICB_DFLT_THROTTLE; 1339 } 1340 icbp->icb_retry_delay = fcp->isp_retry_delay; 1341 icbp->icb_retry_count = fcp->isp_retry_count; | 1589 icbp->icb_maxfrmlen = fcp->isp_maxfrmlen; 1590 if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN || 1591 icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) { 1592 isp_prt(isp, ISP_LOGERR, 1593 "bad frame length (%d) from NVRAM- using %d", 1594 fcp->isp_maxfrmlen, ICB_DFLT_FRMLEN); 1595 icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN; 1596 } --- 7 unchanged lines hidden (view full) --- 1604 if (icbp->icb_execthrottle < 1) { 1605 isp_prt(isp, ISP_LOGERR, 1606 "bad execution throttle of %d- using 16", 1607 fcp->isp_execthrottle); 1608 icbp->icb_execthrottle = ICB_DFLT_THROTTLE; 1609 } 1610 icbp->icb_retry_delay = fcp->isp_retry_delay; 1611 icbp->icb_retry_count = fcp->isp_retry_count; |
1342 icbp->icb_hardaddr = loopid; | 1612 icbp->icb_hardaddr = fcp->isp_loopid; |
1343 if (icbp->icb_hardaddr > 125) { 1344 /* 1345 * We end up with these Loop IDs for F-Port topologies 1346 */ 1347 if (icbp->icb_hardaddr != 0xff && icbp->icb_hardaddr != 0x800) { 1348 isp_prt(isp, ISP_LOGERR, 1349 "bad hard address %u- resetting to zero", 1350 icbp->icb_hardaddr); --- 78 unchanged lines hidden (view full) --- 1429 * Turn on generate AE 8013 on all LIP Resets (2) 1430 * Disable LIP F7 switching (8) 1431 */ 1432 MEMZERO(&mbs, sizeof (mbs)); 1433 mbs.param[0] = MBOX_SET_FIRMWARE_OPTIONS; 1434 mbs.param[1] = 0xb; 1435 mbs.param[2] = 0; 1436 mbs.param[3] = 0; | 1613 if (icbp->icb_hardaddr > 125) { 1614 /* 1615 * We end up with these Loop IDs for F-Port topologies 1616 */ 1617 if (icbp->icb_hardaddr != 0xff && icbp->icb_hardaddr != 0x800) { 1618 isp_prt(isp, ISP_LOGERR, 1619 "bad hard address %u- resetting to zero", 1620 icbp->icb_hardaddr); --- 78 unchanged lines hidden (view full) --- 1699 * Turn on generate AE 8013 on all LIP Resets (2) 1700 * Disable LIP F7 switching (8) 1701 */ 1702 MEMZERO(&mbs, sizeof (mbs)); 1703 mbs.param[0] = MBOX_SET_FIRMWARE_OPTIONS; 1704 mbs.param[1] = 0xb; 1705 mbs.param[2] = 0; 1706 mbs.param[3] = 0; |
1437 isp_mboxcmd(isp, &mbs, MBLOGALL); | 1707 mbs.logval = MBLOGALL; 1708 isp_mboxcmd(isp, &mbs); 1709 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1710 return; 1711 } |
1438 } 1439 icbp->icb_logintime = ICB_LOGIN_TOV; 1440 icbp->icb_lunetimeout = ICB_LUN_ENABLE_TOV; 1441 1442 nwwn = ISP_NODEWWN(isp); 1443 pwwn = ISP_PORTWWN(isp); 1444 if (nwwn && pwwn) { 1445 icbp->icb_fwoptions |= ICBOPT_BOTH_WWNS; 1446 MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, nwwn); 1447 MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, pwwn); 1448 isp_prt(isp, ISP_LOGDEBUG1, 1449 "Setting ICB Node 0x%08x%08x Port 0x%08x%08x", 1450 ((uint32_t) (nwwn >> 32)), 1451 ((uint32_t) (nwwn & 0xffffffff)), 1452 ((uint32_t) (pwwn >> 32)), 1453 ((uint32_t) (pwwn & 0xffffffff))); | 1712 } 1713 icbp->icb_logintime = ICB_LOGIN_TOV; 1714 icbp->icb_lunetimeout = ICB_LUN_ENABLE_TOV; 1715 1716 nwwn = ISP_NODEWWN(isp); 1717 pwwn = ISP_PORTWWN(isp); 1718 if (nwwn && pwwn) { 1719 icbp->icb_fwoptions |= ICBOPT_BOTH_WWNS; 1720 MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, nwwn); 1721 MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, pwwn); 1722 isp_prt(isp, ISP_LOGDEBUG1, 1723 "Setting ICB Node 0x%08x%08x Port 0x%08x%08x", 1724 ((uint32_t) (nwwn >> 32)), 1725 ((uint32_t) (nwwn & 0xffffffff)), 1726 ((uint32_t) (pwwn >> 32)), 1727 ((uint32_t) (pwwn & 0xffffffff))); |
1728 } else if (pwwn) { 1729 icbp->icb_fwoptions &= ~ICBOPT_BOTH_WWNS; 1730 MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, pwwn); 1731 isp_prt(isp, ISP_LOGDEBUG1, 1732 "Setting ICB Port 0x%08x%08x", 1733 ((uint32_t) (pwwn >> 32)), 1734 ((uint32_t) (pwwn & 0xffffffff))); |
|
1454 } else { | 1735 } else { |
1455 isp_prt(isp, ISP_LOGDEBUG1, "Not using any WWNs"); 1456 icbp->icb_fwoptions &= ~(ICBOPT_BOTH_WWNS|ICBOPT_FULL_LOGIN); | 1736 isp_prt(isp, ISP_LOGERR, "No valid WWNs to use"); 1737 return; |
1457 } 1458 icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp); 1459 if (icbp->icb_rqstqlen < 1) { 1460 isp_prt(isp, ISP_LOGERR, "bad request queue length"); 1461 } 1462 icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp); 1463 if (icbp->icb_rsltqlen < 1) { 1464 isp_prt(isp, ISP_LOGERR, "bad result queue length"); --- 18 unchanged lines hidden (view full) --- 1483 * Init the firmware 1484 */ 1485 MEMZERO(&mbs, sizeof (mbs)); 1486 mbs.param[0] = MBOX_INIT_FIRMWARE; 1487 mbs.param[2] = DMA_WD1(fcp->isp_scdma); 1488 mbs.param[3] = DMA_WD0(fcp->isp_scdma); 1489 mbs.param[6] = DMA_WD3(fcp->isp_scdma); 1490 mbs.param[7] = DMA_WD2(fcp->isp_scdma); | 1738 } 1739 icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp); 1740 if (icbp->icb_rqstqlen < 1) { 1741 isp_prt(isp, ISP_LOGERR, "bad request queue length"); 1742 } 1743 icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp); 1744 if (icbp->icb_rsltqlen < 1) { 1745 isp_prt(isp, ISP_LOGERR, "bad result queue length"); --- 18 unchanged lines hidden (view full) --- 1764 * Init the firmware 1765 */ 1766 MEMZERO(&mbs, sizeof (mbs)); 1767 mbs.param[0] = MBOX_INIT_FIRMWARE; 1768 mbs.param[2] = DMA_WD1(fcp->isp_scdma); 1769 mbs.param[3] = DMA_WD0(fcp->isp_scdma); 1770 mbs.param[6] = DMA_WD3(fcp->isp_scdma); 1771 mbs.param[7] = DMA_WD2(fcp->isp_scdma); |
1772 mbs.logval = MBLOGALL; 1773 mbs.timeout = 30 * 1000000; |
|
1491 isp_prt(isp, ISP_LOGDEBUG0, "INIT F/W from %p (%08x%08x)", 1492 fcp->isp_scratch, (uint32_t) ((uint64_t)fcp->isp_scdma >> 32), 1493 (uint32_t) fcp->isp_scdma); 1494 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (*icbp)); | 1774 isp_prt(isp, ISP_LOGDEBUG0, "INIT F/W from %p (%08x%08x)", 1775 fcp->isp_scratch, (uint32_t) ((uint64_t)fcp->isp_scdma >> 32), 1776 (uint32_t) fcp->isp_scdma); 1777 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (*icbp)); |
1495 isp_mboxcmd(isp, &mbs, MBLOGALL); | 1778 isp_mboxcmd(isp, &mbs); |
1496 FC_SCRATCH_RELEASE(isp); 1497 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1498 return; 1499 } | 1779 FC_SCRATCH_RELEASE(isp); 1780 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1781 return; 1782 } |
1500 isp->isp_reqidx = isp->isp_reqodx = 0; | 1783 isp->isp_reqidx = 0; 1784 isp->isp_reqodx = 0; |
1501 isp->isp_residx = 0; | 1785 isp->isp_residx = 0; |
1502 isp->isp_sendmarker = 1; | |
1503 1504 /* 1505 * Whatever happens, we're now committed to being here. 1506 */ 1507 isp->isp_state = ISP_INITSTATE; 1508} 1509 | 1786 1787 /* 1788 * Whatever happens, we're now committed to being here. 1789 */ 1790 isp->isp_state = ISP_INITSTATE; 1791} 1792 |
1510/* 1511 * Fibre Channel Support- get the port database for the id. 1512 * 1513 * Locks are held before coming here. Return 0 if success, 1514 * else failure. 1515 */ 1516 1517static int 1518isp_getmap(ispsoftc_t *isp, fcpos_map_t *map) | 1793static void 1794isp_fibre_init_2400(ispsoftc_t *isp) |
1519{ | 1795{ |
1520 fcparam *fcp = (fcparam *) isp->isp_param; | 1796 fcparam *fcp; 1797 isp_icb_2400_t local, *icbp = &local; |
1521 mbreg_t mbs; | 1798 mbreg_t mbs; |
1799 uint64_t nwwn, pwwn; |
|
1522 | 1800 |
1801 fcp = isp->isp_param; 1802 1803 /* 1804 * Turn on LIP F8 async event (1) 1805 */ |
|
1523 MEMZERO(&mbs, sizeof (mbs)); | 1806 MEMZERO(&mbs, sizeof (mbs)); |
1524 mbs.param[0] = MBOX_GET_FC_AL_POSITION_MAP; | 1807 mbs.param[0] = MBOX_SET_FIRMWARE_OPTIONS; 1808 mbs.param[1] = 1; 1809 mbs.logval = MBLOGALL; 1810 isp_mboxcmd(isp, &mbs); 1811 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1812 return; 1813 } 1814 1815 /* 1816 * XXX: This should be applied to icb- not fwoptions 1817 */ 1818 if (isp->isp_role & ISP_ROLE_TARGET) { 1819 fcp->isp_fwoptions |= ICB2400_OPT1_TGT_ENABLE; 1820 } else { 1821 fcp->isp_fwoptions &= ~ICB2400_OPT1_TGT_ENABLE; 1822 } 1823 1824 if (isp->isp_role & ISP_ROLE_INITIATOR) { 1825 fcp->isp_fwoptions &= ~ICB2400_OPT1_INI_DISABLE; 1826 } else { 1827 fcp->isp_fwoptions |= ICB2400_OPT1_INI_DISABLE; 1828 } 1829 1830 MEMZERO(icbp, sizeof (*icbp)); 1831 icbp->icb_version = ICB_VERSION1; 1832 icbp->icb_maxfrmlen = fcp->isp_maxfrmlen; 1833 if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN || 1834 icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) { 1835 isp_prt(isp, ISP_LOGERR, 1836 "bad frame length (%d) from NVRAM- using %d", 1837 fcp->isp_maxfrmlen, ICB_DFLT_FRMLEN); 1838 icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN; 1839 } 1840 1841 icbp->icb_execthrottle = fcp->isp_execthrottle; 1842 if (icbp->icb_execthrottle < 1) { 1843 isp_prt(isp, ISP_LOGERR, 1844 "bad execution throttle of %d- using 16", 1845 fcp->isp_execthrottle); 1846 icbp->icb_execthrottle = ICB_DFLT_THROTTLE; 1847 } 1848 1849 if (isp->isp_role & ISP_ROLE_TARGET) { 1850 /* 1851 * Get current resource count 1852 */ 1853 MEMZERO(&mbs, sizeof (mbs)); 1854 mbs.param[0] = MBOX_GET_RESOURCE_COUNT; 1855 mbs.obits = 0x4cf; 1856 mbs.logval = MBLOGALL; 1857 isp_mboxcmd(isp, &mbs); 1858 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1859 return; 1860 } 1861 icbp->icb_xchgcnt = mbs.param[3]; 1862 } 1863 1864 icbp->icb_fwoptions1 = fcp->isp_fwoptions; 1865 1866 icbp->icb_hardaddr = fcp->isp_loopid; 1867 if (icbp->icb_hardaddr > 125) { 1868 /* 1869 * We end up with these Loop IDs for F-Port topologies 1870 */ 1871 if (icbp->icb_hardaddr != 0xff && icbp->icb_hardaddr != 0x800) { 1872 isp_prt(isp, ISP_LOGERR, 1873 "bad hard address %u- resetting to zero", 1874 icbp->icb_hardaddr); 1875 icbp->icb_hardaddr = 0; 1876 } 1877 } 1878 1879 if (isp->isp_confopts & ISP_CFG_OWNLOOPID) { 1880 icbp->icb_fwoptions1 |= ICB2400_OPT1_HARD_ADDRESS; 1881 } 1882 1883 icbp->icb_fwoptions2 = fcp->isp_xfwoptions; 1884 switch(isp->isp_confopts & ISP_CFG_PORT_PREF) { 1885 case ISP_CFG_NPORT: 1886 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK; 1887 icbp->icb_fwoptions2 |= ICB2400_OPT2_PTP_2_LOOP; 1888 break; 1889 case ISP_CFG_NPORT_ONLY: 1890 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK; 1891 icbp->icb_fwoptions2 |= ICB2400_OPT2_PTP_ONLY; 1892 break; 1893 case ISP_CFG_LPORT_ONLY: 1894 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK; 1895 icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_ONLY; 1896 break; 1897 default: 1898 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK; 1899 icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_2_PTP; 1900 break; 1901 } 1902 1903 switch (icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK) { 1904 case ICB2400_OPT2_ZIO: 1905 case ICB2400_OPT2_ZIO1: 1906 icbp->icb_idelaytimer = 0; 1907 break; 1908 case 0: 1909 break; 1910 default: 1911 isp_prt(isp, ISP_LOGWARN, "bad value %x in fwopt2 timer field", 1912 icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK); 1913 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TIMER_MASK; 1914 break; 1915 } 1916 1917 icbp->icb_fwoptions3 = fcp->isp_zfwoptions; 1918 icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_AUTO; 1919 if (isp->isp_confopts & ISP_CFG_ONEGB) { 1920 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_ONEGB; 1921 } else if (isp->isp_confopts & ISP_CFG_TWOGB) { 1922 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_TWOGB; 1923 } else if (isp->isp_confopts & ISP_CFG_FOURGB) { 1924 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_FOURGB; 1925 } else { 1926 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_AUTO; 1927 } 1928 1929 if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) { 1930 icbp->icb_fwoptions3 |= ICB2400_OPT3_SOFTID; 1931 } 1932 icbp->icb_logintime = ICB_LOGIN_TOV; 1933 1934 nwwn = ISP_NODEWWN(isp); 1935 pwwn = ISP_PORTWWN(isp); 1936 1937 if (nwwn && pwwn) { 1938 icbp->icb_fwoptions1 |= ICB2400_OPT1_BOTH_WWNS; 1939 MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, nwwn); 1940 MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, pwwn); 1941 isp_prt(isp, ISP_LOGDEBUG1, 1942 "Setting ICB Node 0x%08x%08x Port 0x%08x%08x", 1943 ((uint32_t) (nwwn >> 32)), 1944 ((uint32_t) (nwwn & 0xffffffff)), 1945 ((uint32_t) (pwwn >> 32)), 1946 ((uint32_t) (pwwn & 0xffffffff))); 1947 } else if (pwwn) { 1948 icbp->icb_fwoptions1 &= ~ICB2400_OPT1_BOTH_WWNS; 1949 MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, pwwn); 1950 isp_prt(isp, ISP_LOGDEBUG1, 1951 "Setting ICB Port 0x%08x%08x", 1952 ((uint32_t) (pwwn >> 32)), 1953 ((uint32_t) (pwwn & 0xffffffff))); 1954 } else { 1955 isp_prt(isp, ISP_LOGERR, "No valid WWNs to use"); 1956 return; 1957 } 1958 icbp->icb_retry_count = fcp->isp_retry_count; 1959 1960 icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp); 1961 if (icbp->icb_rqstqlen < 8) { 1962 isp_prt(isp, ISP_LOGERR, "bad request queue length %d", 1963 icbp->icb_rqstqlen); 1964 return; 1965 } 1966 icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp); 1967 if (icbp->icb_rsltqlen < 8) { 1968 isp_prt(isp, ISP_LOGERR, "bad result queue length %d", 1969 icbp->icb_rsltqlen); 1970 return; 1971 } 1972 icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_rquest_dma); 1973 icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_rquest_dma); 1974 icbp->icb_rqstaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_rquest_dma); 1975 icbp->icb_rqstaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_rquest_dma); 1976 1977 icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_result_dma); 1978 icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma); 1979 icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma); 1980 icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma); 1981 1982#ifdef ISP_TARGET_MODE 1983 if (isp->isp_role & ISP_ROLE_TARGET) { 1984 icbp->icb_atioqlen = RESULT_QUEUE_LEN(isp); 1985 if (icbp->icb_atioqlen < 8) { 1986 isp_prt(isp, ISP_LOGERR, "bad ATIO queue length %d", 1987 icbp->icb_atioqlen); 1988 return; 1989 } 1990 icbp->icb_atioqaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_atioq_dma); 1991 icbp->icb_atioqaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_atioq_dma); 1992 icbp->icb_atioqaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_atioq_dma); 1993 icbp->icb_atioqaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_atioq_dma); 1994 isp_prt(isp, ISP_LOGDEBUG0, 1995 "isp_fibre_init_2400: atioq %04x%04x%04x%04x", 1996 DMA_WD3(isp->isp_atioq_dma), DMA_WD2(isp->isp_atioq_dma), 1997 DMA_WD1(isp->isp_atioq_dma), DMA_WD0(isp->isp_atioq_dma)); 1998 } 1999#endif 2000 2001 isp_prt(isp, ISP_LOGDEBUG0, 2002 "isp_fibre_init_2400: fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x", 2003 icbp->icb_fwoptions1, icbp->icb_fwoptions2, icbp->icb_fwoptions3); 2004 2005 isp_prt(isp, ISP_LOGDEBUG0, 2006 "isp_fibre_init_2400: rqst %04x%04x%04x%04x rsp %04x%04x%04x%04x", 2007 DMA_WD3(isp->isp_rquest_dma), DMA_WD2(isp->isp_rquest_dma), 2008 DMA_WD1(isp->isp_rquest_dma), DMA_WD0(isp->isp_rquest_dma), 2009 DMA_WD3(isp->isp_result_dma), DMA_WD2(isp->isp_result_dma), 2010 DMA_WD1(isp->isp_result_dma), DMA_WD0(isp->isp_result_dma)); 2011 2012 if (isp->isp_dblev & ISP_LOGDEBUG1) { 2013 isp_print_bytes(isp, "isp_fibre_init_2400", sizeof (*icbp), 2014 icbp); 2015 } 2016 FC_SCRATCH_ACQUIRE(isp); 2017 isp_put_icb_2400(isp, icbp, fcp->isp_scratch); 2018 2019 2020 /* 2021 * Init the firmware 2022 */ 2023 MEMZERO(&mbs, sizeof (mbs)); 2024 mbs.param[0] = MBOX_INIT_FIRMWARE; |
1525 mbs.param[2] = DMA_WD1(fcp->isp_scdma); 1526 mbs.param[3] = DMA_WD0(fcp->isp_scdma); 1527 mbs.param[6] = DMA_WD3(fcp->isp_scdma); 1528 mbs.param[7] = DMA_WD2(fcp->isp_scdma); | 2025 mbs.param[2] = DMA_WD1(fcp->isp_scdma); 2026 mbs.param[3] = DMA_WD0(fcp->isp_scdma); 2027 mbs.param[6] = DMA_WD3(fcp->isp_scdma); 2028 mbs.param[7] = DMA_WD2(fcp->isp_scdma); |
1529 FC_SCRATCH_ACQUIRE(isp); 1530 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (fcpos_map_t)); 1531 isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR); 1532 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { 1533 MEMCPY(map, fcp->isp_scratch, sizeof (fcpos_map_t)); 1534 map->fwmap = mbs.param[1] != 0; 1535 FC_SCRATCH_RELEASE(isp); 1536 return (0); 1537 } | 2029 mbs.logval = MBLOGALL; 2030 mbs.timeout = 30 * 1000000; 2031 isp_prt(isp, ISP_LOGDEBUG0, "INIT F/W from %04x%04x%04x%04x", 2032 DMA_WD3(fcp->isp_scdma), DMA_WD2(fcp->isp_scdma), 2033 DMA_WD1(fcp->isp_scdma), DMA_WD0(fcp->isp_scdma)); 2034 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (*icbp)); 2035 isp_mboxcmd(isp, &mbs); |
1538 FC_SCRATCH_RELEASE(isp); | 2036 FC_SCRATCH_RELEASE(isp); |
1539 return (-1); | 2037 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 2038 return; 2039 } 2040 isp->isp_reqidx = 0; 2041 isp->isp_reqodx = 0; 2042 isp->isp_residx = 0; 2043 2044 /* 2045 * Whatever happens, we're now committed to being here. 2046 */ 2047 isp->isp_state = ISP_INITSTATE; |
1540} 1541 | 2048} 2049 |
2050/* 2051 * Fibre Channel Support- get the port database for the id. 2052 */ |
|
1542static void | 2053static void |
1543isp_mark_getpdb_all(ispsoftc_t *isp) | 2054isp_dump_portdb(ispsoftc_t *isp) |
1544{ 1545 fcparam *fcp = (fcparam *) isp->isp_param; 1546 int i; | 2055{ 2056 fcparam *fcp = (fcparam *) isp->isp_param; 2057 int i; |
2058 |
|
1547 for (i = 0; i < MAX_FC_TARG; i++) { | 2059 for (i = 0; i < MAX_FC_TARG; i++) { |
1548 fcp->portdb[i].valid = fcp->portdb[i].fabric_dev = 0; | 2060 char mb[4]; 2061 const char *dbs[8] = { 2062 "NIL ", 2063 "PROB", 2064 "DEAD", 2065 "CHGD", 2066 "NEW ", 2067 "PVLD", 2068 "????", 2069 "VLD " 2070 }; 2071 const char *roles[4] = { 2072 " UNK", " TGT", " INI", "TINI" 2073 }; 2074 fcportdb_t *lp = &fcp->portdb[i]; 2075 2076 if (lp->state == FC_PORTDB_STATE_NIL) { 2077 continue; 2078 } 2079 if (lp->ini_map_idx) { 2080 SNPRINTF(mb, sizeof (mb), "%3d", 2081 ((int) lp->ini_map_idx) - 1); 2082 } else { 2083 SNPRINTF(mb, sizeof (mb), "---"); 2084 } 2085 isp_prt(isp, ISP_LOGALL, "%d: %s al%d tgt %s %s 0x%06x =>%s" 2086 " 0x%06x; WWNN 0x%08x%08x WWPN 0x%08x%08x", i, 2087 dbs[lp->state], lp->autologin, mb, 2088 roles[lp->roles], lp->portid, 2089 roles[lp->new_roles], lp->new_portid, 2090 (uint32_t) (lp->node_wwn >> 32), 2091 (uint32_t) (lp->node_wwn), 2092 (uint32_t) (lp->port_wwn >> 32), 2093 (uint32_t) (lp->port_wwn)); |
1549 } 1550} 1551 | 2094 } 2095} 2096 |
2097static void 2098isp_mark_portdb(ispsoftc_t *isp, int onprobation) 2099{ 2100 fcparam *fcp = (fcparam *) isp->isp_param; 2101 int i; 2102 2103 for (i = 0; i < MAX_FC_TARG; i++) { 2104 fcp->isp_ini_map[i] = 0; 2105 if (onprobation == 0) { 2106 MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t)); 2107 } else { 2108 switch (fcp->portdb[i].state) { 2109 case FC_PORTDB_STATE_CHANGED: 2110 case FC_PORTDB_STATE_PENDING_VALID: 2111 case FC_PORTDB_STATE_VALID: 2112 case FC_PORTDB_STATE_PROBATIONAL: 2113 fcp->portdb[i].state = 2114 FC_PORTDB_STATE_PROBATIONAL; 2115 break; 2116 case FC_PORTDB_STATE_NIL: 2117 default: 2118 MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t)); 2119 fcp->portdb[i].state = 2120 FC_PORTDB_STATE_NIL; 2121 break; 2122 } 2123 } 2124 } 2125} 2126 2127/* 2128 * Perform an IOCB PLOGI or LOGO via EXECUTE IOCB A64 for 24XX cards 2129 */ 2130static void 2131isp_plogx_24xx(ispsoftc_t *isp, uint16_t handle, uint32_t portid, int *log_ret) 2132{ 2133 mbreg_t mbs; 2134 uint8_t q[QENTRY_LEN]; 2135 isp_plogx_t *plp = (isp_plogx_t *) q; 2136 uint8_t *scp = FCPARAM(isp)->isp_scratch; 2137 uint32_t sst, parm1; 2138 int junk; 2139 2140 MEMZERO(q, QENTRY_LEN); 2141 plp->plogx_header.rqs_entry_count = 1; 2142 plp->plogx_header.rqs_entry_type = RQSTYPE_LOGIN; 2143 plp->plogx_handle = 0xffffffff; 2144 plp->plogx_nphdl = handle; 2145 plp->plogx_portlo = portid; 2146 plp->plogx_rspsz_porthi = (portid >> 16) & 0xff; 2147 if (log_ret) { 2148 plp->plogx_flags = *log_ret; 2149 } else { 2150 log_ret = &junk; 2151 } 2152 2153 if (isp->isp_dblev & ISP_LOGDEBUG1) { 2154 isp_print_bytes(isp, "IOCB LOGX", QENTRY_LEN, plp); 2155 } 2156 /* 2157 * XXX: We're going to assume somebody has acquired SCRATCH for us 2158 */ 2159 isp_put_plogx(isp, plp, (isp_plogx_t *) scp); 2160 2161 2162 MEMZERO(&mbs, sizeof (mbs)); 2163 mbs.param[0] = MBOX_EXEC_COMMAND_IOCB_A64; 2164 mbs.param[1] = QENTRY_LEN; 2165 mbs.param[2] = DMA_WD1(FCPARAM(isp)->isp_scdma); 2166 mbs.param[3] = DMA_WD0(FCPARAM(isp)->isp_scdma); 2167 mbs.param[6] = DMA_WD3(FCPARAM(isp)->isp_scdma); 2168 mbs.param[7] = DMA_WD2(FCPARAM(isp)->isp_scdma); 2169 mbs.logval = MBLOGALL; 2170 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, QENTRY_LEN); 2171 isp_mboxcmd(isp, &mbs); 2172 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 2173 *log_ret = mbs.param[0]; 2174 } 2175 MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN, QENTRY_LEN); 2176 scp += QENTRY_LEN; 2177 isp_get_plogx(isp, (isp_plogx_t *) scp, plp); 2178 if (isp->isp_dblev & ISP_LOGDEBUG1) { 2179 isp_print_bytes(isp, "IOCB LOGX response", QENTRY_LEN, plp); 2180 } 2181 2182 if (plp->plogx_status == PLOGX_STATUS_OK) { 2183 *log_ret = 0; 2184 return; 2185 } else if (plp->plogx_status != PLOGX_STATUS_IOCBERR) { 2186 isp_prt(isp, ISP_LOGWARN, "status 0x%x on port login IOCB", 2187 plp->plogx_status); 2188 *log_ret = -1; 2189 return; 2190 } 2191 2192 sst = plp->plogx_ioparm[0].lo16 | (plp->plogx_ioparm[0].hi16 << 16); 2193 parm1 = plp->plogx_ioparm[1].lo16 | (plp->plogx_ioparm[1].hi16 << 16); 2194 2195 *log_ret = -1; 2196 2197 switch (sst) { 2198 case PLOGX_IOCBERR_NOLINK: 2199 isp_prt(isp, ISP_LOGERR, "PLOGX failed- no link"); 2200 break; 2201 case PLOGX_IOCBERR_NOIOCB: 2202 isp_prt(isp, ISP_LOGERR, "PLOGX failed- no IOCB buffer"); 2203 break; 2204 case PLOGX_IOCBERR_NOXGHG: 2205 isp_prt(isp, ISP_LOGERR, 2206 "PLOGX failed- no Exchange Control Block"); 2207 break; 2208 case PLOGX_IOCBERR_FAILED: 2209 isp_prt(isp, ISP_LOGERR, 2210 "PLOGX(0x%x) of Port 0x%06x failed: reason 0x%x (last LOGIN" 2211 " state 0x%x)", *log_ret, portid, 2212 parm1 & 0xff, (parm1 >> 8) & 0xff); 2213 break; 2214 case PLOGX_IOCBERR_NOFABRIC: 2215 isp_prt(isp, ISP_LOGERR, "PLOGX failed- no fabric"); 2216 break; 2217 case PLOGX_IOCBERR_NOTREADY: 2218 isp_prt(isp, ISP_LOGERR, "PLOGX failed- f/w not ready"); 2219 break; 2220 case PLOGX_IOCBERR_NOLOGIN: 2221 isp_prt(isp, ISP_LOGERR, 2222 "PLOGX failed- not logged in (last LOGIN state 0x%x)", 2223 parm1); 2224 *log_ret = MBOX_NOT_LOGGED_IN; 2225 break; 2226 case PLOGX_IOCBERR_REJECT: 2227 isp_prt(isp, ISP_LOGERR, "PLOGX failed: LS_RJT = 0x%x", parm1); 2228 break; 2229 case PLOGX_IOCBERR_NOPCB: 2230 isp_prt(isp, ISP_LOGERR, "PLOGX failed- no PCB allocated"); 2231 break; 2232 case PLOGX_IOCBERR_EINVAL: 2233 isp_prt(isp, ISP_LOGERR, 2234 "PLOGX failed: invalid parameter at offset 0x%x", parm1); 2235 break; 2236 case PLOGX_IOCBERR_PORTUSED: 2237 isp_prt(isp, ISP_LOGDEBUG0, 2238 "portid 0x%x already logged in with N-port handle 0x%x", 2239 portid, parm1); 2240 *log_ret = MBOX_PORT_ID_USED | (handle << 16); 2241 break; 2242 case PLOGX_IOCBERR_HNDLUSED: 2243 isp_prt(isp, ISP_LOGDEBUG0, 2244 "N-port handle 0x%x already used for portid 0x%x", 2245 handle, parm1); 2246 *log_ret = MBOX_LOOP_ID_USED; 2247 break; 2248 case PLOGX_IOCBERR_NOHANDLE: 2249 isp_prt(isp, ISP_LOGERR, "PLOGX failed- no handle allocated"); 2250 break; 2251 case PLOGX_IOCBERR_NOFLOGI: 2252 isp_prt(isp, ISP_LOGERR, "PLOGX failed- no FLOGI_ACC"); 2253 break; 2254 default: 2255 isp_prt(isp, ISP_LOGERR, "status %x from %s", plp->plogx_status, 2256 (*log_ret)? "PLOGI" : "LOGO"); 2257 *log_ret = -1; 2258 break; 2259 } 2260} 2261 |
|
1552static int | 2262static int |
1553isp_getpdb(ispsoftc_t *isp, int id, isp_pdb_t *pdbp) | 2263isp_port_login(ispsoftc_t *isp, uint16_t handle, uint32_t portid) |
1554{ | 2264{ |
2265 mbreg_t mbs; 2266 2267 MEMZERO(&mbs, sizeof (mbs)); 2268 mbs.param[0] = MBOX_FABRIC_LOGIN; 2269 if (FCPARAM(isp)->isp_2klogin) { 2270 mbs.param[1] = handle; 2271 mbs.ibits = (1 << 10); 2272 } else { 2273 mbs.param[1] = handle << 8; 2274 } 2275 mbs.param[2] = portid >> 16; 2276 mbs.param[3] = portid; 2277 2278 mbs.logval = MBLOGNONE; 2279 isp_mboxcmd(isp, &mbs); 2280 2281 switch (mbs.param[0]) { 2282 case MBOX_PORT_ID_USED: 2283 isp_prt(isp, ISP_LOGDEBUG0, 2284 "isp_port_login: portid 0x%06x already logged in as %u", 2285 portid, mbs.param[1]); 2286 return (MBOX_PORT_ID_USED | (mbs.param[1] << 16)); 2287 break; 2288 2289 case MBOX_LOOP_ID_USED: 2290 isp_prt(isp, ISP_LOGDEBUG0, 2291 "isp_port_login: handle %u in use for port id 0x%02xXXXX", 2292 handle, mbs.param[1] & 0xff); 2293 return (MBOX_LOOP_ID_USED); 2294 2295 case MBOX_COMMAND_COMPLETE: 2296 return (0); 2297 2298 case MBOX_COMMAND_ERROR: 2299 isp_prt(isp, ISP_LOGINFO, 2300 "isp_port_login: error 0x%x in PLOGI to port 0x%06x", 2301 mbs.param[1], portid); 2302 return (MBOX_COMMAND_ERROR); 2303 2304 case MBOX_ALL_IDS_USED: 2305 isp_prt(isp, ISP_LOGINFO, 2306 "isp_port_login: all IDs used for fabric login"); 2307 return (MBOX_ALL_IDS_USED); 2308 2309 default: 2310 isp_prt(isp, ISP_LOGINFO, 2311 "isp_port_login: error 0x%x on port login of 0x%06x@0x%0x", 2312 mbs.param[0], portid, handle); 2313 return (mbs.param[0]); 2314 } 2315} 2316 2317static void 2318isp_port_logout(ispsoftc_t *isp, uint16_t handle, uint32_t portid) 2319{ 2320 mbreg_t mbs; 2321 2322 MEMZERO(&mbs, sizeof (mbs)); 2323 mbs.param[0] = MBOX_FABRIC_LOGOUT; 2324 if (FCPARAM(isp)->isp_2klogin) { 2325 mbs.param[1] = handle; 2326 mbs.ibits = (1 << 10); 2327 } else { 2328 mbs.param[1] = handle << 8; 2329 } 2330 mbs.logval = MBLOGNONE; 2331 isp_mboxcmd(isp, &mbs); 2332} 2333 2334static int 2335isp_getpdb(ispsoftc_t *isp, uint16_t id, isp_pdb_t *pdb, int dolock) 2336{ |
|
1555 fcparam *fcp = (fcparam *) isp->isp_param; 1556 mbreg_t mbs; | 2337 fcparam *fcp = (fcparam *) isp->isp_param; 2338 mbreg_t mbs; |
2339 union { 2340 isp_pdb_21xx_t fred; 2341 isp_pdb_24xx_t bill; 2342 } un; |
|
1557 1558 MEMZERO(&mbs, sizeof (mbs)); 1559 mbs.param[0] = MBOX_GET_PORT_DB; | 2343 2344 MEMZERO(&mbs, sizeof (mbs)); 2345 mbs.param[0] = MBOX_GET_PORT_DB; |
1560 if (IS_2KLOGIN(isp)) { | 2346 if (IS_24XX(isp)) { 2347 mbs.ibits = 0x3ff; |
1561 mbs.param[1] = id; | 2348 mbs.param[1] = id; |
1562 mbs.ibits |= (1 << 10); | 2349 } else if (FCPARAM(isp)->isp_2klogin) { 2350 mbs.param[1] = id; 2351 mbs.ibits = (1 << 10); |
1563 } else { 1564 mbs.param[1] = id << 8; 1565 } 1566 mbs.param[2] = DMA_WD1(fcp->isp_scdma); 1567 mbs.param[3] = DMA_WD0(fcp->isp_scdma); 1568 mbs.param[6] = DMA_WD3(fcp->isp_scdma); 1569 mbs.param[7] = DMA_WD2(fcp->isp_scdma); | 2352 } else { 2353 mbs.param[1] = id << 8; 2354 } 2355 mbs.param[2] = DMA_WD1(fcp->isp_scdma); 2356 mbs.param[3] = DMA_WD0(fcp->isp_scdma); 2357 mbs.param[6] = DMA_WD3(fcp->isp_scdma); 2358 mbs.param[7] = DMA_WD2(fcp->isp_scdma); |
1570 FC_SCRATCH_ACQUIRE(isp); 1571 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (isp_pdb_t)); 1572 isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR); 1573 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { 1574 isp_get_pdb(isp, (isp_pdb_t *)fcp->isp_scratch, pdbp); | 2359 mbs.logval = MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR; 2360 if (dolock) { 2361 FC_SCRATCH_ACQUIRE(isp); 2362 } 2363 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (un)); 2364 isp_mboxcmd(isp, &mbs); 2365 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 2366 if (dolock) { 2367 FC_SCRATCH_RELEASE(isp); 2368 } 2369 return (-1); 2370 } 2371 if (IS_24XX(isp)) { 2372 isp_get_pdb_24xx(isp, fcp->isp_scratch, &un.bill); 2373 pdb->handle = un.bill.pdb_handle; 2374 pdb->s3_role = un.bill.pdb_prli_svc3; 2375 pdb->portid = BITS2WORD_24XX(un.bill.pdb_portid_bits); 2376 MEMCPY(pdb->portname, un.bill.pdb_portname, 8); 2377 MEMCPY(pdb->nodename, un.bill.pdb_nodename, 8); 2378 } else { 2379 isp_get_pdb_21xx(isp, fcp->isp_scratch, &un.fred); 2380 pdb->handle = un.fred.pdb_loopid; 2381 pdb->s3_role = un.fred.pdb_prli_svc3; 2382 pdb->portid = BITS2WORD(un.fred.pdb_portid_bits); 2383 MEMCPY(pdb->portname, un.fred.pdb_portname, 8); 2384 MEMCPY(pdb->nodename, un.fred.pdb_nodename, 8); 2385 } 2386 if (dolock) { |
1575 FC_SCRATCH_RELEASE(isp); | 2387 FC_SCRATCH_RELEASE(isp); |
1576 return (0); | |
1577 } | 2388 } |
1578 FC_SCRATCH_RELEASE(isp); 1579 return (-1); | 2389 return (0); |
1580} 1581 1582static uint64_t 1583isp_get_portname(ispsoftc_t *isp, int loopid, int nodename) 1584{ | 2390} 2391 2392static uint64_t 2393isp_get_portname(ispsoftc_t *isp, int loopid, int nodename) 2394{ |
1585 uint64_t wwn = 0; | 2395 uint64_t wwn = (uint64_t) -1; |
1586 mbreg_t mbs; 1587 1588 MEMZERO(&mbs, sizeof (mbs)); 1589 mbs.param[0] = MBOX_GET_PORT_NAME; | 2396 mbreg_t mbs; 2397 2398 MEMZERO(&mbs, sizeof (mbs)); 2399 mbs.param[0] = MBOX_GET_PORT_NAME; |
1590 if (IS_2KLOGIN(isp)) { | 2400 if (FCPARAM(isp)->isp_2klogin || IS_24XX(isp)) { |
1591 mbs.param[1] = loopid; | 2401 mbs.param[1] = loopid; |
1592 mbs.ibits |= (1 << 10); | 2402 mbs.ibits = (1 << 10); |
1593 if (nodename) { 1594 mbs.param[10] = 1; 1595 } 1596 } else { 1597 mbs.param[1] = loopid << 8; 1598 if (nodename) { 1599 mbs.param[1] |= 1; 1600 } 1601 } | 2403 if (nodename) { 2404 mbs.param[10] = 1; 2405 } 2406 } else { 2407 mbs.param[1] = loopid << 8; 2408 if (nodename) { 2409 mbs.param[1] |= 1; 2410 } 2411 } |
1602 isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR); 1603 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { | 2412 mbs.logval = MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR; 2413 mbs.timeout = 30000; 2414 isp_mboxcmd(isp, &mbs); 2415 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 2416 return (wwn); 2417 } 2418 if (IS_24XX(isp)) { |
1604 wwn = | 2419 wwn = |
2420 (((uint64_t)(mbs.param[2] >> 8)) << 56) | 2421 (((uint64_t)(mbs.param[2] & 0xff)) << 48) | 2422 (((uint64_t)(mbs.param[3] >> 8)) << 40) | 2423 (((uint64_t)(mbs.param[3] & 0xff)) << 32) | 2424 (((uint64_t)(mbs.param[6] >> 8)) << 24) | 2425 (((uint64_t)(mbs.param[6] & 0xff)) << 16) | 2426 (((uint64_t)(mbs.param[7] >> 8)) << 8) | 2427 (((uint64_t)(mbs.param[7] & 0xff))); 2428 } else { 2429 wwn = |
|
1605 (((uint64_t)(mbs.param[2] & 0xff)) << 56) | 1606 (((uint64_t)(mbs.param[2] >> 8)) << 48) | 1607 (((uint64_t)(mbs.param[3] & 0xff)) << 40) | 1608 (((uint64_t)(mbs.param[3] >> 8)) << 32) | 1609 (((uint64_t)(mbs.param[6] & 0xff)) << 24) | 1610 (((uint64_t)(mbs.param[6] >> 8)) << 16) | 1611 (((uint64_t)(mbs.param[7] & 0xff)) << 8) | 1612 (((uint64_t)(mbs.param[7] >> 8))); 1613 } 1614 return (wwn); 1615} 1616 1617/* | 2430 (((uint64_t)(mbs.param[2] & 0xff)) << 56) | 2431 (((uint64_t)(mbs.param[2] >> 8)) << 48) | 2432 (((uint64_t)(mbs.param[3] & 0xff)) << 40) | 2433 (((uint64_t)(mbs.param[3] >> 8)) << 32) | 2434 (((uint64_t)(mbs.param[6] & 0xff)) << 24) | 2435 (((uint64_t)(mbs.param[6] >> 8)) << 16) | 2436 (((uint64_t)(mbs.param[7] & 0xff)) << 8) | 2437 (((uint64_t)(mbs.param[7] >> 8))); 2438 } 2439 return (wwn); 2440} 2441 2442/* |
1618 * Make sure we have good FC link and know our Loop ID. | 2443 * Make sure we have good FC link. |
1619 */ 1620 1621static int 1622isp_fclink_test(ispsoftc_t *isp, int usdelay) 1623{ | 2444 */ 2445 2446static int 2447isp_fclink_test(ispsoftc_t *isp, int usdelay) 2448{ |
1624 static char *toponames[] = { | 2449 static const char *toponames[] = { |
1625 "Private Loop", 1626 "FL Port", 1627 "N-Port to N-Port", 1628 "F Port", 1629 "F Port (no FLOGI_ACC response)" 1630 }; 1631 mbreg_t mbs; 1632 int count, check_for_fabric; 1633 uint8_t lwfs; | 2450 "Private Loop", 2451 "FL Port", 2452 "N-Port to N-Port", 2453 "F Port", 2454 "F Port (no FLOGI_ACC response)" 2455 }; 2456 mbreg_t mbs; 2457 int count, check_for_fabric; 2458 uint8_t lwfs; |
2459 int loopid; |
|
1634 fcparam *fcp; | 2460 fcparam *fcp; |
1635 struct lportdb *lp; | 2461 fcportdb_t *lp; |
1636 isp_pdb_t pdb; 1637 1638 fcp = isp->isp_param; 1639 1640 isp_prt(isp, ISP_LOGDEBUG0, "FC Link Test Entry"); | 2462 isp_pdb_t pdb; 2463 2464 fcp = isp->isp_param; 2465 2466 isp_prt(isp, ISP_LOGDEBUG0, "FC Link Test Entry"); |
2467 isp_mark_portdb(isp, 1); |
|
1641 1642 /* | 2468 2469 /* |
1643 * XXX: Here is where we would start a 'loop dead' timeout 1644 */ 1645 1646 /* | |
1647 * Wait up to N microseconds for F/W to go to a ready state. 1648 */ 1649 lwfs = FW_CONFIG_WAIT; 1650 count = 0; 1651 while (count < usdelay) { 1652 uint64_t enano; 1653 uint32_t wrk; 1654 NANOTIME_T hra, hrb; --- 50 unchanged lines hidden (view full) --- 1705 count += (wrk / 1000); 1706 } 1707 } 1708 1709 /* 1710 * If we haven't gone to 'ready' state, return. 1711 */ 1712 if (fcp->isp_fwstate != FW_READY) { | 2470 * Wait up to N microseconds for F/W to go to a ready state. 2471 */ 2472 lwfs = FW_CONFIG_WAIT; 2473 count = 0; 2474 while (count < usdelay) { 2475 uint64_t enano; 2476 uint32_t wrk; 2477 NANOTIME_T hra, hrb; --- 50 unchanged lines hidden (view full) --- 2528 count += (wrk / 1000); 2529 } 2530 } 2531 2532 /* 2533 * If we haven't gone to 'ready' state, return. 2534 */ 2535 if (fcp->isp_fwstate != FW_READY) { |
2536 isp_prt(isp, ISP_LOGDEBUG0, 2537 "isp_fclink_test: not at FW_READY state"); |
|
1713 return (-1); 1714 } 1715 1716 /* | 2538 return (-1); 2539 } 2540 2541 /* |
1717 * Get our Loop ID (if possible). We really need to have it. | 2542 * Get our Loop ID and Port ID. |
1718 */ 1719 MEMZERO(&mbs, sizeof (mbs)); 1720 mbs.param[0] = MBOX_GET_LOOP_ID; | 2543 */ 2544 MEMZERO(&mbs, sizeof (mbs)); 2545 mbs.param[0] = MBOX_GET_LOOP_ID; |
1721 isp_mboxcmd(isp, &mbs, MBLOGALL); | 2546 mbs.logval = MBLOGALL; 2547 isp_mboxcmd(isp, &mbs); |
1722 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1723 return (-1); 1724 } | 2548 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 2549 return (-1); 2550 } |
1725 if (IS_2KLOGIN(isp)) { | 2551 2552 if (FCPARAM(isp)->isp_2klogin) { |
1726 fcp->isp_loopid = mbs.param[1]; 1727 } else { 1728 fcp->isp_loopid = mbs.param[1] & 0xff; 1729 } | 2553 fcp->isp_loopid = mbs.param[1]; 2554 } else { 2555 fcp->isp_loopid = mbs.param[1] & 0xff; 2556 } |
1730 if (fcp->isp_loopid == 0xffff) { /* happens with 2k login f/w */ 1731 fcp->isp_loopid = MAX_FC_TARG-1; 1732 } else if (fcp->isp_loopid >= MAX_FC_TARG) { 1733 isp_prt(isp, ISP_LOGWARN, "bad initiator loopid (0x%x)", fcp->isp_loopid); 1734 fcp->isp_loopid = MAX_FC_TARG-1; 1735 } 1736 if (IS_2200(isp) || IS_23XX(isp)) { | 2557 2558 if (IS_2100(isp)) { 2559 fcp->isp_topo = TOPO_NL_PORT; 2560 } else { |
1737 int topo = (int) mbs.param[6]; | 2561 int topo = (int) mbs.param[6]; |
1738 if (topo < TOPO_NL_PORT || topo > TOPO_PTP_STUB) | 2562 if (topo < TOPO_NL_PORT || topo > TOPO_PTP_STUB) { |
1739 topo = TOPO_PTP_STUB; | 2563 topo = TOPO_PTP_STUB; |
2564 } |
|
1740 fcp->isp_topo = topo; | 2565 fcp->isp_topo = topo; |
1741 } else { 1742 fcp->isp_topo = TOPO_NL_PORT; | |
1743 } | 2566 } |
1744 /* 1745 * Get the port id. 1746 */ | |
1747 fcp->isp_portid = mbs.param[2] | (mbs.param[3] << 16); 1748 | 2567 fcp->isp_portid = mbs.param[2] | (mbs.param[3] << 16); 2568 |
1749 /* 1750 * Check to see if we're on a fabric by trying to see if we 1751 * can talk to the fabric name server. This can be a bit 1752 * tricky because if we're a 2100, we should check always 1753 * (in case we're connected to a server doing aliasing). 1754 */ 1755 fcp->isp_onfabric = 0; 1756 | |
1757 if (IS_2100(isp)) { 1758 /* 1759 * Don't bother with fabric if we are using really old 1760 * 2100 firmware. It's just not worth it. 1761 */ 1762 if (ISP_FW_NEWER_THAN(isp, 1, 15, 37)) { 1763 check_for_fabric = 1; 1764 } else { 1765 check_for_fabric = 0; 1766 } 1767 } else if (fcp->isp_topo == TOPO_FL_PORT || 1768 fcp->isp_topo == TOPO_F_PORT) { 1769 check_for_fabric = 1; | 2569 if (IS_2100(isp)) { 2570 /* 2571 * Don't bother with fabric if we are using really old 2572 * 2100 firmware. It's just not worth it. 2573 */ 2574 if (ISP_FW_NEWER_THAN(isp, 1, 15, 37)) { 2575 check_for_fabric = 1; 2576 } else { 2577 check_for_fabric = 0; 2578 } 2579 } else if (fcp->isp_topo == TOPO_FL_PORT || 2580 fcp->isp_topo == TOPO_F_PORT) { 2581 check_for_fabric = 1; |
1770 } else | 2582 } else { |
1771 check_for_fabric = 0; | 2583 check_for_fabric = 0; |
2584 } |
|
1772 | 2585 |
1773 if (check_for_fabric && isp_getpdb(isp, FL_PORT_ID, &pdb) == 0) { 1774 int loopid = FL_PORT_ID; | 2586 if (IS_24XX(isp)) { 2587 loopid = NPH_FL_ID; 2588 } else { 2589 loopid = FL_ID; 2590 } 2591 2592 if (check_for_fabric && isp_getpdb(isp, loopid, &pdb, 1) == 0) { |
1775 if (IS_2100(isp)) { 1776 fcp->isp_topo = TOPO_FL_PORT; 1777 } | 2593 if (IS_2100(isp)) { 2594 fcp->isp_topo = TOPO_FL_PORT; 2595 } |
1778 1779 if (BITS2WORD(pdb.pdb_portid_bits) == 0) { | 2596 if (pdb.portid == 0) { |
1780 /* 1781 * Crock. 1782 */ 1783 fcp->isp_topo = TOPO_NL_PORT; 1784 goto not_on_fabric; 1785 } | 2597 /* 2598 * Crock. 2599 */ 2600 fcp->isp_topo = TOPO_NL_PORT; 2601 goto not_on_fabric; 2602 } |
1786 fcp->isp_portid = mbs.param[2] | ((int) mbs.param[3] << 16); | |
1787 1788 /* 1789 * Save the Fabric controller's port database entry. 1790 */ | 2603 2604 /* 2605 * Save the Fabric controller's port database entry. 2606 */ |
1791 lp = &fcp->portdb[loopid]; 1792 lp->node_wwn = 1793 (((uint64_t)pdb.pdb_nodename[0]) << 56) | 1794 (((uint64_t)pdb.pdb_nodename[1]) << 48) | 1795 (((uint64_t)pdb.pdb_nodename[2]) << 40) | 1796 (((uint64_t)pdb.pdb_nodename[3]) << 32) | 1797 (((uint64_t)pdb.pdb_nodename[4]) << 24) | 1798 (((uint64_t)pdb.pdb_nodename[5]) << 16) | 1799 (((uint64_t)pdb.pdb_nodename[6]) << 8) | 1800 (((uint64_t)pdb.pdb_nodename[7])); 1801 lp->port_wwn = 1802 (((uint64_t)pdb.pdb_portname[0]) << 56) | 1803 (((uint64_t)pdb.pdb_portname[1]) << 48) | 1804 (((uint64_t)pdb.pdb_portname[2]) << 40) | 1805 (((uint64_t)pdb.pdb_portname[3]) << 32) | 1806 (((uint64_t)pdb.pdb_portname[4]) << 24) | 1807 (((uint64_t)pdb.pdb_portname[5]) << 16) | 1808 (((uint64_t)pdb.pdb_portname[6]) << 8) | 1809 (((uint64_t)pdb.pdb_portname[7])); 1810 lp->roles = 1811 (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT; 1812 lp->portid = BITS2WORD(pdb.pdb_portid_bits); 1813 lp->loopid = pdb.pdb_loopid; 1814 lp->loggedin = lp->valid = 1; 1815 fcp->isp_onfabric = 1; 1816 (void) isp_async(isp, ISPASYNC_PROMENADE, &loopid); 1817 isp_register_fc4_type(isp); | 2607 lp = &fcp->portdb[FL_ID]; 2608 lp->state = FC_PORTDB_STATE_PENDING_VALID; 2609 MAKE_WWN_FROM_NODE_NAME(lp->node_wwn, pdb.nodename); 2610 MAKE_WWN_FROM_NODE_NAME(lp->port_wwn, pdb.portname); 2611 lp->roles = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT; 2612 lp->portid = pdb.portid; 2613 lp->handle = pdb.handle; 2614 lp->new_portid = lp->portid; 2615 lp->new_roles = lp->roles; 2616 if (IS_24XX(isp)) { 2617 (void) isp_register_fc4_type_24xx(isp); 2618 } else { 2619 (void) isp_register_fc4_type(isp); 2620 } |
1818 } else { 1819not_on_fabric: | 2621 } else { 2622not_on_fabric: |
1820 fcp->isp_onfabric = 0; 1821 fcp->portdb[FL_PORT_ID].valid = 0; | 2623 fcp->portdb[FL_ID].state = FC_PORTDB_STATE_NIL; |
1822 } 1823 1824 fcp->isp_gbspeed = 1; | 2624 } 2625 2626 fcp->isp_gbspeed = 1; |
1825 if (IS_23XX(isp)) { | 2627 if (IS_23XX(isp) || IS_24XX(isp)) { |
1826 MEMZERO(&mbs, sizeof (mbs)); 1827 mbs.param[0] = MBOX_GET_SET_DATA_RATE; 1828 mbs.param[1] = MBGSD_GET_RATE; 1829 /* mbs.param[2] undefined if we're just getting rate */ | 2628 MEMZERO(&mbs, sizeof (mbs)); 2629 mbs.param[0] = MBOX_GET_SET_DATA_RATE; 2630 mbs.param[1] = MBGSD_GET_RATE; 2631 /* mbs.param[2] undefined if we're just getting rate */ |
1830 isp_mboxcmd(isp, &mbs, MBLOGALL); | 2632 mbs.logval = MBLOGALL; 2633 isp_mboxcmd(isp, &mbs); |
1831 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { | 2634 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { |
1832 if (mbs.param[1] == MBGSD_TWOGB) { | 2635 if (mbs.param[1] == MBGSD_FOURGB) { 2636 isp_prt(isp, ISP_LOGINFO, "4Gb link speed/s"); 2637 fcp->isp_gbspeed = 4; 2638 } if (mbs.param[1] == MBGSD_TWOGB) { |
1833 isp_prt(isp, ISP_LOGINFO, "2Gb link speed/s"); 1834 fcp->isp_gbspeed = 2; 1835 } 1836 } 1837 } 1838 | 2639 isp_prt(isp, ISP_LOGINFO, "2Gb link speed/s"); 2640 fcp->isp_gbspeed = 2; 2641 } 2642 } 2643 } 2644 |
1839 isp_prt(isp, ISP_LOGCONFIG, topology, fcp->isp_loopid, 1840 fcp->isp_portid, fcp->isp_loopstate, toponames[fcp->isp_topo]); 1841 | |
1842 /* | 2645 /* |
1843 * Announce ourselves, too. This involves synthesizing an entry. | 2646 * Announce ourselves, too. |
1844 */ | 2647 */ |
1845 if (fcp->isp_iid_set == 0) { 1846 fcp->isp_iid_set = 1; 1847 fcp->isp_iid = fcp->isp_loopid; 1848 lp = &fcp->portdb[fcp->isp_iid]; 1849 } else { 1850 lp = &fcp->portdb[fcp->isp_iid]; 1851 if (fcp->isp_portid != lp->portid || 1852 fcp->isp_loopid != lp->loopid || 1853 fcp->isp_nodewwn != ISP_NODEWWN(isp) || 1854 fcp->isp_portwwn != ISP_PORTWWN(isp)) { 1855 lp->valid = 0; 1856 count = fcp->isp_iid; 1857 (void) isp_async(isp, ISPASYNC_PROMENADE, &count); 1858 } 1859 } 1860 lp->loopid = fcp->isp_loopid; 1861 lp->portid = fcp->isp_portid; 1862 lp->node_wwn = ISP_NODEWWN(isp); 1863 lp->port_wwn = ISP_PORTWWN(isp); 1864 switch (isp->isp_role) { 1865 case ISP_ROLE_NONE: 1866 lp->roles = 0; 1867 break; 1868 case ISP_ROLE_TARGET: 1869 lp->roles = SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT; 1870 break; 1871 case ISP_ROLE_INITIATOR: 1872 lp->roles = SVC3_INI_ROLE >> SVC3_ROLE_SHIFT; 1873 break; 1874 case ISP_ROLE_BOTH: 1875 lp->roles = (SVC3_INI_ROLE|SVC3_TGT_ROLE) >> SVC3_ROLE_SHIFT; 1876 break; 1877 } 1878 lp->loggedin = lp->valid = 1; 1879 count = fcp->isp_iid; 1880 (void) isp_async(isp, ISPASYNC_PROMENADE, &count); | 2648 isp_prt(isp, ISP_LOGCONFIG, topology, fcp->isp_portid, 2649 fcp->isp_loopid, toponames[fcp->isp_topo]); 2650 isp_prt(isp, ISP_LOGCONFIG, ourwwn, 2651 (uint32_t) (ISP_NODEWWN(isp) >> 32), 2652 (uint32_t) ISP_NODEWWN(isp), 2653 (uint32_t) (ISP_PORTWWN(isp) >> 32), 2654 (uint32_t) ISP_PORTWWN(isp)); |
1881 isp_prt(isp, ISP_LOGDEBUG0, "FC Link Test Complete"); 1882 return (0); 1883} 1884 1885static const char * 1886isp2100_fw_statename(int state) 1887{ 1888 switch(state) { --- 5 unchanged lines hidden (view full) --- 1894 case FW_ERROR: return "Error"; 1895 case FW_REINIT: return "Re-Init"; 1896 case FW_NON_PART: return "Nonparticipating"; 1897 default: return "?????"; 1898 } 1899} 1900 1901/* | 2655 isp_prt(isp, ISP_LOGDEBUG0, "FC Link Test Complete"); 2656 return (0); 2657} 2658 2659static const char * 2660isp2100_fw_statename(int state) 2661{ 2662 switch(state) { --- 5 unchanged lines hidden (view full) --- 2668 case FW_ERROR: return "Error"; 2669 case FW_REINIT: return "Re-Init"; 2670 case FW_NON_PART: return "Nonparticipating"; 2671 default: return "?????"; 2672 } 2673} 2674 2675/* |
1902 * Synchronize our soft copy of the port database with what the f/w thinks 1903 * (with a view toward possibly for a specific target....) | 2676 * Complete the synchronization of our Port Database. 2677 * 2678 * At this point, we've scanned the local loop (if any) and the fabric 2679 * and performed fabric logins on all new devices. 2680 * 2681 * Our task here is to go through our port database and remove any entities 2682 * that are still marked probational (issuing PLOGO for ones which we had 2683 * PLOGI'd into) or are dead. 2684 * 2685 * Our task here is to also check policy to decide whether devices which 2686 * have *changed* in some way should still be kept active. For example, 2687 * if a device has just changed PortID, we can either elect to treat it 2688 * as an old device or as a newly arrived device (and notify the outer 2689 * layer appropriately). 2690 * 2691 * We also do initiator map target id assignment here for new initiator 2692 * devices and refresh old ones ot make sure that they point to the corret 2693 * entities. |
1904 */ | 2694 */ |
1905 | |
1906static int 1907isp_pdb_sync(ispsoftc_t *isp) 1908{ | 2695static int 2696isp_pdb_sync(ispsoftc_t *isp) 2697{ |
1909 struct lportdb *lp; | |
1910 fcparam *fcp = isp->isp_param; | 2698 fcparam *fcp = isp->isp_param; |
1911 isp_pdb_t pdb; 1912 int loopid, base, lim; | 2699 fcportdb_t *lp; 2700 uint16_t dbidx; |
1913 | 2701 |
2702 if (fcp->isp_loopstate == LOOP_READY) { 2703 return (0); 2704 } 2705 |
|
1914 /* 1915 * Make sure we're okay for doing this right now. 1916 */ 1917 if (fcp->isp_loopstate != LOOP_PDB_RCVD && 1918 fcp->isp_loopstate != LOOP_FSCAN_DONE && 1919 fcp->isp_loopstate != LOOP_LSCAN_DONE) { | 2706 /* 2707 * Make sure we're okay for doing this right now. 2708 */ 2709 if (fcp->isp_loopstate != LOOP_PDB_RCVD && 2710 fcp->isp_loopstate != LOOP_FSCAN_DONE && 2711 fcp->isp_loopstate != LOOP_LSCAN_DONE) { |
2712 isp_prt(isp, ISP_LOGWARN, "isp_pdb_sync: bad loopstate %d", 2713 fcp->isp_loopstate); |
|
1920 return (-1); 1921 } 1922 | 2714 return (-1); 2715 } 2716 |
1923 if (fcp->isp_topo == TOPO_FL_PORT || fcp->isp_topo == TOPO_NL_PORT || | 2717 if (fcp->isp_topo == TOPO_FL_PORT || 2718 fcp->isp_topo == TOPO_NL_PORT || |
1924 fcp->isp_topo == TOPO_N_PORT) { 1925 if (fcp->isp_loopstate < LOOP_LSCAN_DONE) { 1926 if (isp_scan_loop(isp) != 0) { | 2719 fcp->isp_topo == TOPO_N_PORT) { 2720 if (fcp->isp_loopstate < LOOP_LSCAN_DONE) { 2721 if (isp_scan_loop(isp) != 0) { |
2722 isp_prt(isp, ISP_LOGWARN, 2723 "isp_pdb_sync: isp_scan_loop failed"); |
|
1927 return (-1); 1928 } 1929 } 1930 } | 2724 return (-1); 2725 } 2726 } 2727 } |
1931 fcp->isp_loopstate = LOOP_SYNCING_PDB; | |
1932 | 2728 |
1933 /* 1934 * If we get this far, we've settled our differences with the f/w 1935 * (for local loop device) and we can say that the loop state is ready. 1936 */ 1937 1938 if (fcp->isp_topo == TOPO_NL_PORT) { 1939 fcp->loop_seen_once = 1; 1940 fcp->isp_loopstate = LOOP_READY; 1941 return (0); 1942 } 1943 1944 /* 1945 * Find all Fabric Entities that didn't make it from one scan to the 1946 * next and let the world know they went away. Scan the whole database. 1947 */ 1948 for (lp = &fcp->portdb[0]; lp < &fcp->portdb[MAX_FC_TARG]; lp++) { 1949 if (lp->was_fabric_dev && lp->fabric_dev == 0) { 1950 loopid = lp - fcp->portdb; 1951 lp->valid = 0; /* should already be set */ 1952 (void) isp_async(isp, ISPASYNC_PROMENADE, &loopid); 1953 MEMZERO((void *) lp, sizeof (*lp)); 1954 continue; | 2729 if (fcp->isp_topo == TOPO_F_PORT || fcp->isp_topo == TOPO_FL_PORT) { 2730 if (fcp->isp_loopstate < LOOP_FSCAN_DONE) { 2731 if (isp_scan_fabric(isp) != 0) { 2732 isp_prt(isp, ISP_LOGWARN, 2733 "isp_pdb_sync: isp_scan_fabric failed"); 2734 return (-1); 2735 } |
1955 } | 2736 } |
1956 lp->was_fabric_dev = lp->fabric_dev; | |
1957 } 1958 | 2737 } 2738 |
1959 if (fcp->isp_topo == TOPO_FL_PORT) 1960 base = FC_SNS_ID+1; 1961 else 1962 base = 0; | 2739 fcp->isp_loopstate = LOOP_SYNCING_PDB; |
1963 | 2740 |
1964 if (fcp->isp_topo == TOPO_N_PORT) 1965 lim = 1; 1966 else 1967 lim = MAX_FC_TARG; | 2741 for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) { 2742 lp = &fcp->portdb[dbidx]; |
1968 | 2743 |
1969 /* 1970 * Now log in any fabric devices that the outer layer has 1971 * left for us to see. This seems the most sane policy 1972 * for the moment. 1973 */ 1974 for (lp = &fcp->portdb[base]; lp < &fcp->portdb[lim]; lp++) { 1975 uint32_t portid; 1976 mbreg_t mbs; 1977 1978 loopid = lp - fcp->portdb; 1979 if (loopid >= FL_PORT_ID && loopid <= FC_SNS_ID) { | 2744 if (lp->state == FC_PORTDB_STATE_NIL) { |
1980 continue; 1981 } 1982 | 2745 continue; 2746 } 2747 |
1983 /* 1984 * Anything here? 1985 */ 1986 if (lp->port_wwn == 0) { | 2748 if (lp->state == FC_PORTDB_STATE_VALID) { 2749 if (dbidx != FL_ID) { 2750 isp_prt(isp, 2751 ISP_LOGERR, "portdb idx %d already valid", 2752 dbidx); 2753 } |
1987 continue; 1988 } 1989 | 2754 continue; 2755 } 2756 |
1990 /* 1991 * Don't try to log into yourself. 1992 */ 1993 if ((portid = lp->portid) == fcp->isp_portid) { 1994 continue; 1995 } 1996 1997 1998 /* 1999 * If we'd been logged in- see if we still are and we haven't 2000 * changed. If so, no need to log ourselves out, etc.. 2001 * 2002 * Unfortunately, our charming Qlogic f/w has decided to 2003 * return a valid port database entry for a fabric device 2004 * that has, in fact, gone away. And it hangs trying to 2005 * log it out. 2006 */ 2007 if (lp->loggedin && lp->force_logout == 0 && 2008 isp_getpdb(isp, lp->loopid, &pdb) == 0) { 2009 int nrole; 2010 uint64_t nwwnn, nwwpn; 2011 nwwnn = 2012 (((uint64_t)pdb.pdb_nodename[0]) << 56) | 2013 (((uint64_t)pdb.pdb_nodename[1]) << 48) | 2014 (((uint64_t)pdb.pdb_nodename[2]) << 40) | 2015 (((uint64_t)pdb.pdb_nodename[3]) << 32) | 2016 (((uint64_t)pdb.pdb_nodename[4]) << 24) | 2017 (((uint64_t)pdb.pdb_nodename[5]) << 16) | 2018 (((uint64_t)pdb.pdb_nodename[6]) << 8) | 2019 (((uint64_t)pdb.pdb_nodename[7])); 2020 nwwpn = 2021 (((uint64_t)pdb.pdb_portname[0]) << 56) | 2022 (((uint64_t)pdb.pdb_portname[1]) << 48) | 2023 (((uint64_t)pdb.pdb_portname[2]) << 40) | 2024 (((uint64_t)pdb.pdb_portname[3]) << 32) | 2025 (((uint64_t)pdb.pdb_portname[4]) << 24) | 2026 (((uint64_t)pdb.pdb_portname[5]) << 16) | 2027 (((uint64_t)pdb.pdb_portname[6]) << 8) | 2028 (((uint64_t)pdb.pdb_portname[7])); 2029 nrole = (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> 2030 SVC3_ROLE_SHIFT; 2031 if (pdb.pdb_loopid == lp->loopid && lp->portid == 2032 (uint32_t) BITS2WORD(pdb.pdb_portid_bits) && 2033 nwwnn == lp->node_wwn && nwwpn == lp->port_wwn && 2034 lp->roles == nrole && lp->force_logout == 0) { 2035 lp->loggedin = lp->valid = 1; 2036 isp_prt(isp, ISP_LOGCONFIG, lretained, 2037 (int) (lp - fcp->portdb), 2038 (int) lp->loopid, lp->portid); 2039 continue; | 2757 switch (lp->state) { 2758 case FC_PORTDB_STATE_PROBATIONAL: 2759 case FC_PORTDB_STATE_DEAD: 2760 isp_async(isp, ISPASYNC_DEV_GONE, lp); 2761 if (lp->ini_map_idx) { 2762 fcp->isp_ini_map[lp->ini_map_idx-1] = 0; 2763 lp->ini_map_idx = 0; |
2040 } | 2764 } |
2041 } 2042 2043 if (fcp->isp_fwstate != FW_READY || 2044 fcp->isp_loopstate != LOOP_SYNCING_PDB) { 2045 return (-1); 2046 } 2047 2048 /* 2049 * Force a logout if we were logged in. 2050 */ 2051 if (lp->loggedin) { 2052 if (lp->force_logout || 2053 isp_getpdb(isp, lp->loopid, &pdb) == 0) { 2054 MEMZERO(&mbs, sizeof (mbs)); 2055 mbs.param[0] = MBOX_FABRIC_LOGOUT; 2056 if (IS_2KLOGIN(isp)) { 2057 mbs.param[1] = lp->loopid; 2058 mbs.ibits |= (1 << 10); | 2765 lp->state = FC_PORTDB_STATE_NIL; 2766 if (lp->autologin == 0) { 2767 if (IS_24XX(isp)) { 2768 int action = 2769 PLOGX_FLG_CMD_LOGO | 2770 PLOGX_FLG_IMPLICIT | 2771 PLOGX_FLG_FREE_NPHDL; 2772 FC_SCRATCH_ACQUIRE(isp); 2773 isp_plogx_24xx(isp, lp->handle, 2774 lp->portid, &action); 2775 FC_SCRATCH_RELEASE(isp); |
2059 } else { | 2776 } else { |
2060 mbs.param[1] = lp->loopid << 8; | 2777 isp_port_logout(isp, lp->handle, 2778 lp->portid); |
2061 } | 2779 } |
2062 isp_mboxcmd(isp, &mbs, MBLOGNONE); 2063 isp_prt(isp, ISP_LOGINFO, plogout, 2064 (int) (lp - fcp->portdb), lp->loopid, 2065 lp->portid); 2066 } 2067 lp->force_logout = lp->loggedin = 0; 2068 if (fcp->isp_fwstate != FW_READY || 2069 fcp->isp_loopstate != LOOP_SYNCING_PDB) { 2070 return (-1); 2071 } 2072 } 2073 2074 /* 2075 * And log in.... 2076 */ 2077 loopid = lp - fcp->portdb; 2078 lp->loopid = FL_PORT_ID; 2079 do { 2080 MEMZERO(&mbs, sizeof (mbs)); 2081 mbs.param[0] = MBOX_FABRIC_LOGIN; 2082 if (IS_2KLOGIN(isp)) { 2083 mbs.param[1] = loopid; 2084 mbs.ibits |= (1 << 10); | |
2085 } else { | 2780 } else { |
2086 mbs.param[1] = loopid << 8; | 2781 lp->autologin = 0; |
2087 } | 2782 } |
2088 mbs.param[2] = portid >> 16; 2089 mbs.param[3] = portid & 0xffff; 2090 isp_mboxcmd(isp, &mbs, MBLOGALL & ~(MBOX_LOOP_ID_USED | 2091 MBOX_PORT_ID_USED | MBOX_COMMAND_ERROR)); 2092 if (fcp->isp_fwstate != FW_READY || 2093 fcp->isp_loopstate != LOOP_SYNCING_PDB) { 2094 return (-1); 2095 } 2096 switch (mbs.param[0]) { 2097 case MBOX_LOOP_ID_USED: 2098 /* 2099 * Try the next available loop id. 2100 */ 2101 loopid++; 2102 break; 2103 case MBOX_PORT_ID_USED: 2104 /* 2105 * This port is already logged in. 2106 * Snaffle the loop id it's using if it's 2107 * nonzero, otherwise we're hosed. 2108 */ 2109 if (mbs.param[1] != 0) { 2110 loopid = mbs.param[1]; 2111 if (loopid >= MAX_FC_TARG) { 2112 loopid = MAX_FC_TARG; 2113 break; | 2783 lp->new_roles = 0; 2784 lp->new_portid = 0; 2785 break; 2786 case FC_PORTDB_STATE_NEW: 2787 /* 2788 * If *we* have a new target dole and *it* has a target 2789 * role, assign a new target id to it. 2790 */ 2791 lp->portid = lp->new_portid; 2792 lp->roles = lp->new_roles; 2793 lp->state = FC_PORTDB_STATE_VALID; 2794 if ((isp->isp_role & ISP_ROLE_INITIATOR) && 2795 (lp->roles & (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT))) { 2796 int i, t = dbidx; 2797 for (i = 0; i < MAX_FC_TARG; i++) { 2798 if (i < FL_ID || i > SNS_ID) { 2799 if (fcp->isp_ini_map[t] == 0) { 2800 break; 2801 } |
2114 } | 2802 } |
2115 isp_prt(isp, ISP_LOGINFO, retained, 2116 loopid, (int) (lp - fcp->portdb), 2117 lp->portid); | 2803 if (++t == MAX_FC_TARG) { 2804 t = 0; 2805 } 2806 } 2807 if (i < MAX_FC_TARG) { 2808 fcp->isp_ini_map[t] = dbidx + 1; 2809 lp->ini_map_idx = t + 1; |
2118 } else { | 2810 } else { |
2119 loopid = MAX_FC_TARG; 2120 break; | 2811 isp_prt(isp, ISP_LOGWARN, 2812 "out of target ids"); |
2121 } | 2813 } |
2122 /* FALLTHROUGH */ 2123 case MBOX_COMMAND_COMPLETE: 2124 lp->loggedin = 1; 2125 lp->loopid = loopid; 2126 break; 2127 case MBOX_COMMAND_ERROR: 2128 isp_prt(isp, ISP_LOGINFO, plogierr, 2129 portid, mbs.param[1]); 2130 /* FALLTHROUGH */ 2131 case MBOX_ALL_IDS_USED: /* We're outta IDs */ 2132 default: 2133 loopid = MAX_FC_TARG; 2134 break; | |
2135 } | 2814 } |
2136 } while (lp->loopid == FL_PORT_ID && loopid < MAX_FC_TARG); 2137 2138 /* 2139 * If we get here and we haven't set a Loop ID, 2140 * we failed to log into this device. 2141 */ 2142 2143 if (lp->loopid == FL_PORT_ID) { 2144 lp->loopid = 0; 2145 continue; | 2815 isp_async(isp, ISPASYNC_DEV_ARRIVED, lp); 2816 lp->new_roles = 0; 2817 lp->new_portid = 0; 2818 break; 2819 case FC_PORTDB_STATE_CHANGED: 2820 lp->portid = lp->new_portid; 2821 lp->roles = lp->new_roles; 2822 lp->state = FC_PORTDB_STATE_VALID; 2823 if (lp->ini_map_idx) { 2824 int t = lp->ini_map_idx - 1; 2825 fcp->isp_ini_map[t] = dbidx + 1; 2826 } 2827 isp_async(isp, ISPASYNC_DEV_CHANGED, lp); 2828 lp->new_roles = 0; 2829 lp->new_portid = 0; 2830 break; 2831 case FC_PORTDB_STATE_PENDING_VALID: 2832 lp->portid = lp->new_portid; 2833 lp->roles = lp->new_roles; 2834 lp->state = FC_PORTDB_STATE_VALID; 2835 if (lp->ini_map_idx) { 2836 int t = lp->ini_map_idx - 1; 2837 fcp->isp_ini_map[t] = dbidx + 1; 2838 } 2839 isp_async(isp, ISPASYNC_DEV_STAYED, lp); 2840 if (dbidx != FL_ID) { 2841 lp->new_roles = 0; 2842 lp->new_portid = 0; 2843 } 2844 break; 2845 default: 2846 isp_prt(isp, ISP_LOGERR, "eh? state %d for idx %d", 2847 lp->state, dbidx); 2848 isp_dump_portdb(isp); |
2146 } | 2849 } |
2147 2148 /* 2149 * Make sure we can get the approriate port information. 2150 */ 2151 if (isp_getpdb(isp, lp->loopid, &pdb) != 0) { 2152 isp_prt(isp, ISP_LOGWARN, nopdb, lp->portid); 2153 goto dump_em; 2154 } 2155 2156 if (fcp->isp_fwstate != FW_READY || 2157 fcp->isp_loopstate != LOOP_SYNCING_PDB) { 2158 return (-1); 2159 } 2160 2161 if (pdb.pdb_loopid != lp->loopid) { 2162 isp_prt(isp, ISP_LOGWARN, pdbmfail1, 2163 lp->portid, pdb.pdb_loopid); 2164 goto dump_em; 2165 } 2166 2167 if (lp->portid != (uint32_t) BITS2WORD(pdb.pdb_portid_bits)) { 2168 isp_prt(isp, ISP_LOGWARN, pdbmfail2, 2169 lp->portid, BITS2WORD(pdb.pdb_portid_bits)); 2170 goto dump_em; 2171 } 2172 2173 lp->roles = 2174 (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT; 2175 lp->node_wwn = 2176 (((uint64_t)pdb.pdb_nodename[0]) << 56) | 2177 (((uint64_t)pdb.pdb_nodename[1]) << 48) | 2178 (((uint64_t)pdb.pdb_nodename[2]) << 40) | 2179 (((uint64_t)pdb.pdb_nodename[3]) << 32) | 2180 (((uint64_t)pdb.pdb_nodename[4]) << 24) | 2181 (((uint64_t)pdb.pdb_nodename[5]) << 16) | 2182 (((uint64_t)pdb.pdb_nodename[6]) << 8) | 2183 (((uint64_t)pdb.pdb_nodename[7])); 2184 lp->port_wwn = 2185 (((uint64_t)pdb.pdb_portname[0]) << 56) | 2186 (((uint64_t)pdb.pdb_portname[1]) << 48) | 2187 (((uint64_t)pdb.pdb_portname[2]) << 40) | 2188 (((uint64_t)pdb.pdb_portname[3]) << 32) | 2189 (((uint64_t)pdb.pdb_portname[4]) << 24) | 2190 (((uint64_t)pdb.pdb_portname[5]) << 16) | 2191 (((uint64_t)pdb.pdb_portname[6]) << 8) | 2192 (((uint64_t)pdb.pdb_portname[7])); 2193 /* 2194 * Check to make sure this all makes sense. 2195 */ 2196 if (lp->node_wwn && lp->port_wwn) { 2197 lp->valid = 1; 2198 loopid = lp - fcp->portdb; 2199 (void) isp_async(isp, ISPASYNC_PROMENADE, &loopid); 2200 continue; 2201 } 2202dump_em: 2203 lp->valid = 0; 2204 isp_prt(isp, ISP_LOGINFO, 2205 ldumped, loopid, lp->loopid, lp->portid); 2206 MEMZERO(&mbs, sizeof (mbs)); 2207 mbs.param[0] = MBOX_FABRIC_LOGOUT; 2208 if (IS_2KLOGIN(isp)) { 2209 mbs.param[1] = lp->loopid; 2210 mbs.ibits |= (1 << 10); 2211 } else { 2212 mbs.param[1] = lp->loopid << 8; 2213 } 2214 isp_mboxcmd(isp, &mbs, MBLOGNONE); 2215 if (fcp->isp_fwstate != FW_READY || 2216 fcp->isp_loopstate != LOOP_SYNCING_PDB) { 2217 return (-1); 2218 } | |
2219 } | 2850 } |
2851 |
|
2220 /* 2221 * If we get here, we've for sure seen not only a valid loop 2222 * but know what is or isn't on it, so mark this for usage 2223 * in isp_start. 2224 */ 2225 fcp->loop_seen_once = 1; 2226 fcp->isp_loopstate = LOOP_READY; 2227 return (0); 2228} 2229 | 2852 /* 2853 * If we get here, we've for sure seen not only a valid loop 2854 * but know what is or isn't on it, so mark this for usage 2855 * in isp_start. 2856 */ 2857 fcp->loop_seen_once = 1; 2858 fcp->isp_loopstate = LOOP_READY; 2859 return (0); 2860} 2861 |
2862/* 2863 * Scan local loop for devices. 2864 */ |
|
2230static int 2231isp_scan_loop(ispsoftc_t *isp) 2232{ | 2865static int 2866isp_scan_loop(ispsoftc_t *isp) 2867{ |
2233 struct lportdb *lp; | 2868 fcportdb_t *lp, tmp; |
2234 fcparam *fcp = isp->isp_param; | 2869 fcparam *fcp = isp->isp_param; |
2870 int i; |
|
2235 isp_pdb_t pdb; | 2871 isp_pdb_t pdb; |
2236 int loopid, lim, hival; | 2872 uint16_t dbidx, lim = 0; |
2237 | 2873 |
2874 if (fcp->isp_fwstate < FW_READY || 2875 fcp->isp_loopstate < LOOP_PDB_RCVD) { 2876 return (-1); 2877 } 2878 2879 if (fcp->isp_loopstate > LOOP_SCANNING_LOOP) { 2880 return (0); 2881 } 2882 2883 /* 2884 * Check our connection topology. 2885 * 2886 * If we're a public or private loop, we scan 0..125 as handle values. 2887 * The firmware has (typically) peformed a PLOGI for us. 2888 * 2889 * If we're a N-port connection, we treat this is a short loop (0..1). 2890 * 2891 * If we're in target mode, we can all possible handles to see who 2892 * might have logged into us. 2893 */ |
|
2238 switch (fcp->isp_topo) { 2239 case TOPO_NL_PORT: | 2894 switch (fcp->isp_topo) { 2895 case TOPO_NL_PORT: |
2240 hival = FL_PORT_ID; | 2896 case TOPO_FL_PORT: 2897 lim = LOCAL_LOOP_LIM; |
2241 break; 2242 case TOPO_N_PORT: | 2898 break; 2899 case TOPO_N_PORT: |
2243 hival = 2; | 2900 lim = 2; |
2244 break; | 2901 break; |
2245 case TOPO_FL_PORT: 2246 hival = FC_PORT_ID; 2247 break; | |
2248 default: 2249 isp_prt(isp, ISP_LOGDEBUG0, "no loop topology to scan"); 2250 fcp->isp_loopstate = LOOP_LSCAN_DONE; 2251 return (0); 2252 } | 2902 default: 2903 isp_prt(isp, ISP_LOGDEBUG0, "no loop topology to scan"); 2904 fcp->isp_loopstate = LOOP_LSCAN_DONE; 2905 return (0); 2906 } |
2907 |
|
2253 fcp->isp_loopstate = LOOP_SCANNING_LOOP; | 2908 fcp->isp_loopstate = LOOP_SCANNING_LOOP; |
2909 isp_prt(isp, ISP_LOGDEBUG0, "scanning loop 0..%d", lim-1); |
|
2254 | 2910 |
2255 isp_prt(isp, ISP_LOGDEBUG0, "scanning local loop 0..%d", hival); | |
2256 | 2911 |
2257 | |
2258 /* | 2912 /* |
2259 * make sure the temp port database is clean... | 2913 * Run through the list and get the port database info for each one. |
2260 */ | 2914 */ |
2261 MEMZERO((void *)fcp->tport, sizeof (fcp->tport)); 2262 2263 /* 2264 * Run through the local loop ports and get port database info 2265 * for each loop ID. 2266 * 2267 * There's a somewhat unexplained situation where the f/w passes back 2268 * the wrong database entity- if that happens, just restart (up to 2269 * FL_PORT_ID times). 2270 */ 2271 for (lim = loopid = 0; loopid < hival; loopid++) { 2272 lp = &fcp->tport[loopid]; 2273 | 2915 for (dbidx = 0; dbidx < lim; dbidx++) { |
2274 /* | 2916 /* |
2275 * Don't even try for ourselves... | 2917 * But don't even try for ourselves... |
2276 */ | 2918 */ |
2277 if (loopid == fcp->isp_loopid) { | 2919 if (dbidx == fcp->isp_loopid) { |
2278 continue; 2279 } 2280 | 2920 continue; 2921 } 2922 |
2923 /* 2924 * In older cards with older f/w GET_PORT_DATABASE has been 2925 * known to hang. This trick gets around that problem. 2926 */ |
|
2281 if (IS_2100(isp) || IS_2200(isp)) { | 2927 if (IS_2100(isp) || IS_2200(isp)) { |
2282 lp->node_wwn = isp_get_portname(isp, loopid, 1); | 2928 uint64_t node_wwn = isp_get_portname(isp, dbidx, 1); |
2283 if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) { 2284 return (-1); 2285 } | 2929 if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) { 2930 return (-1); 2931 } |
2286 if (lp->node_wwn == 0) { | 2932 if (node_wwn == 0) { |
2287 continue; 2288 } 2289 } 2290 2291 /* | 2933 continue; 2934 } 2935 } 2936 2937 /* |
2292 * Get an entry.... | 2938 * Get the port database entity for this index. |
2293 */ | 2939 */ |
2294 if (isp_getpdb(isp, loopid, &pdb) != 0) { | 2940 if (isp_getpdb(isp, dbidx, &pdb, 1) != 0) { |
2295 if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) { | 2941 if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) { |
2942 isp_mark_portdb(isp, 1); |
|
2296 return (-1); 2297 } 2298 continue; 2299 } 2300 2301 if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) { | 2943 return (-1); 2944 } 2945 continue; 2946 } 2947 2948 if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) { |
2949 isp_mark_portdb(isp, 1); |
|
2302 return (-1); 2303 } 2304 2305 /* | 2950 return (-1); 2951 } 2952 2953 /* |
2306 * If the returned database element doesn't match what we 2307 * asked for, restart the process entirely (up to a point...). | 2954 * On *very* old 2100 firmware we would end up sometimes 2955 * with the firmware returning the port database entry 2956 * for something else. We used to restart locally, but 2957 * now we punt. |
2308 */ | 2958 */ |
2309 if (pdb.pdb_loopid != loopid) { 2310 loopid = 0; 2311 if (lim++ < hival) { 2312 continue; 2313 } | 2959 if (IS_2100(isp) && pdb.handle != dbidx) { |
2314 isp_prt(isp, ISP_LOGWARN, 2315 "giving up on synchronizing the port database"); | 2960 isp_prt(isp, ISP_LOGWARN, 2961 "giving up on synchronizing the port database"); |
2962 isp_mark_portdb(isp, 1); |
|
2316 return (-1); 2317 } 2318 2319 /* 2320 * Save the pertinent info locally. 2321 */ | 2963 return (-1); 2964 } 2965 2966 /* 2967 * Save the pertinent info locally. 2968 */ |
2322 lp->node_wwn = 2323 (((uint64_t)pdb.pdb_nodename[0]) << 56) | 2324 (((uint64_t)pdb.pdb_nodename[1]) << 48) | 2325 (((uint64_t)pdb.pdb_nodename[2]) << 40) | 2326 (((uint64_t)pdb.pdb_nodename[3]) << 32) | 2327 (((uint64_t)pdb.pdb_nodename[4]) << 24) | 2328 (((uint64_t)pdb.pdb_nodename[5]) << 16) | 2329 (((uint64_t)pdb.pdb_nodename[6]) << 8) | 2330 (((uint64_t)pdb.pdb_nodename[7])); 2331 lp->port_wwn = 2332 (((uint64_t)pdb.pdb_portname[0]) << 56) | 2333 (((uint64_t)pdb.pdb_portname[1]) << 48) | 2334 (((uint64_t)pdb.pdb_portname[2]) << 40) | 2335 (((uint64_t)pdb.pdb_portname[3]) << 32) | 2336 (((uint64_t)pdb.pdb_portname[4]) << 24) | 2337 (((uint64_t)pdb.pdb_portname[5]) << 16) | 2338 (((uint64_t)pdb.pdb_portname[6]) << 8) | 2339 (((uint64_t)pdb.pdb_portname[7])); 2340 lp->roles = 2341 (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT; 2342 lp->portid = BITS2WORD(pdb.pdb_portid_bits); 2343 lp->loopid = pdb.pdb_loopid; 2344 } | 2969 MAKE_WWN_FROM_NODE_NAME(tmp.node_wwn, pdb.nodename); 2970 MAKE_WWN_FROM_NODE_NAME(tmp.port_wwn, pdb.portname); 2971 tmp.roles = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT; 2972 tmp.portid = pdb.portid; 2973 tmp.handle = pdb.handle; |
2345 | 2974 |
2346 /* 2347 * Mark all of the permanent local loop database entries as invalid 2348 * (except our own entry). 2349 */ 2350 for (loopid = 0; loopid < hival; loopid++) { 2351 if (loopid == fcp->isp_iid) { 2352 fcp->portdb[loopid].valid = 1; 2353 fcp->portdb[loopid].loopid = fcp->isp_loopid; 2354 continue; 2355 } 2356 fcp->portdb[loopid].valid = 0; 2357 } 2358 2359 /* 2360 * Now merge our local copy of the port database into our saved copy. 2361 * Notify the outer layers of new devices arriving. 2362 */ 2363 for (loopid = 0; loopid < hival; loopid++) { 2364 int i; 2365 | |
2366 /* | 2975 /* |
2367 * If we don't have a non-zero Port WWN, we're not here. | 2976 * Check to make sure it's still a valid entry. The 24XX seems 2977 * to return a portid but not a WWPN/WWNN or role for devices 2978 * which shift on a loop. |
2368 */ | 2979 */ |
2369 if (fcp->tport[loopid].port_wwn == 0) { | 2980 if (tmp.node_wwn == 0 || tmp.port_wwn == 0 || tmp.portid == 0) { 2981 isp_prt(isp, ISP_LOGWARN, 2982 "bad pdb entry at loop %d", dbidx); 2983 isp_dump_portdb(isp); |
2370 continue; 2371 } 2372 2373 /* | 2984 continue; 2985 } 2986 2987 /* |
2374 * Skip ourselves. | 2988 * Now search the entire port database 2989 * for the same Port and Node WWN. |
2375 */ | 2990 */ |
2376 if (loopid == fcp->isp_iid) { 2377 continue; 2378 } 2379 2380 /* 2381 * For the purposes of deciding whether this is the 2382 * 'same' device or not, we only search for an identical 2383 * Port WWN. Node WWNs may or may not be the same as 2384 * the Port WWN, and there may be multiple different 2385 * Port WWNs with the same Node WWN. It would be chaos 2386 * to have multiple identical Port WWNs, so we don't 2387 * allow that. 2388 */ 2389 2390 for (i = 0; i < hival; i++) { 2391 int j; 2392 if (fcp->portdb[i].port_wwn == 0) | 2991 for (i = 0; i < MAX_FC_TARG; i++) { 2992 lp = &fcp->portdb[i]; 2993 if (lp->state == FC_PORTDB_STATE_NIL) { |
2393 continue; | 2994 continue; |
2394 if (fcp->portdb[i].port_wwn != 2395 fcp->tport[loopid].port_wwn) | 2995 } 2996 if (lp->node_wwn != tmp.node_wwn) { |
2396 continue; | 2997 continue; |
2998 } 2999 if (lp->port_wwn != tmp.port_wwn) { 3000 continue; 3001 } 3002 |
|
2397 /* | 3003 /* |
2398 * We found this WWN elsewhere- it's changed 2399 * loopids then. We don't change it's actual 2400 * position in our cached port database- we 2401 * just change the actual loop ID we'd use. | 3004 * Okay- we've found a non-nil entry that matches. 3005 * Check to make sure it's probational. |
2402 */ | 3006 */ |
2403 if (fcp->portdb[i].loopid != loopid) { 2404 isp_prt(isp, ISP_LOGINFO, portshift, i, 2405 fcp->portdb[i].loopid, 2406 fcp->portdb[i].portid, loopid, 2407 fcp->tport[loopid].portid); | 3007 if (lp->state != FC_PORTDB_STATE_PROBATIONAL) { 3008 isp_prt(isp, ISP_LOGERR, 3009 "portdb entry %d not probational (0x%x)", 3010 i, lp->state); 3011 isp_dump_portdb(isp); 3012 isp_mark_portdb(isp, 1); 3013 return (-1); |
2408 } | 3014 } |
2409 fcp->portdb[i].portid = fcp->tport[loopid].portid; 2410 fcp->portdb[i].loopid = loopid; 2411 fcp->portdb[i].valid = 1; 2412 fcp->portdb[i].roles = fcp->tport[loopid].roles; | |
2413 | 3015 |
3016 lp->autologin = 1; |
|
2414 /* | 3017 /* |
2415 * Now make sure this Port WWN doesn't exist elsewhere 2416 * in the port database. | 3018 * Check to make sure it's really the same 3019 * device and update the initiator map before 3020 * we mark it as pending valid. |
2417 */ | 3021 */ |
2418 for (j = i+1; j < hival; j++) { 2419 if (fcp->portdb[i].port_wwn != 2420 fcp->portdb[j].port_wwn) { 2421 continue; 2422 } 2423 isp_prt(isp, ISP_LOGWARN, portdup, j, i); 2424 /* 2425 * Invalidate the 'old' *and* 'new' ones. 2426 * This is really harsh and not quite right, 2427 * but if this happens, we really don't know 2428 * who is what at this point. 2429 */ 2430 fcp->portdb[i].valid = 0; 2431 fcp->portdb[j].valid = 0; | 3022 if (lp->portid == tmp.portid && 3023 lp->handle == tmp.handle && 3024 lp->roles == tmp.roles) { 3025 lp->new_portid = tmp.portid; 3026 lp->new_roles = tmp.roles; 3027 lp->state = FC_PORTDB_STATE_PENDING_VALID; 3028 break; |
2432 } | 3029 } |
3030 3031 /* 3032 * We can wipe out the old handle value here because 3033 * it's no longer valid. 3034 */ 3035 lp->handle = tmp.handle; 3036 3037 /* 3038 * Claim that this has changed and let somebody else 3039 * decide what to do. 3040 */ 3041 lp->state = FC_PORTDB_STATE_CHANGED; 3042 lp->new_portid = tmp.portid; 3043 lp->new_roles = tmp.roles; |
|
2433 break; 2434 } 2435 2436 /* | 3044 break; 3045 } 3046 3047 /* |
2437 * If we didn't traverse the entire port database, 2438 * then we found (and remapped) an existing entry. 2439 * No need to notify anyone- go for the next one. | 3048 * Did we find and update an old entry? |
2440 */ | 3049 */ |
2441 if (i < hival) { 2442 isp_prt(isp, ISP_LOGINFO, retained, 2443 fcp->portdb[i].loopid, i, fcp->portdb[i].portid); | 3050 if (i < MAX_FC_TARG) { |
2444 continue; 2445 } 2446 2447 /* | 3051 continue; 3052 } 3053 3054 /* |
2448 * We've not found this Port WWN anywhere. It's a new entry. 2449 * See if we can leave it where it is (with target == loopid). | 3055 * Ah. A new device entry. Find an empty slot 3056 * for it and save info for later disposition. |
2450 */ | 3057 */ |
2451 if (fcp->portdb[loopid].port_wwn != 0) { 2452 for (lim = 0; lim < hival; lim++) { 2453 if (fcp->portdb[lim].port_wwn == 0) 2454 break; | 3058 for (i = 0; i < MAX_FC_TARG; i++) { 3059 if (fcp->portdb[i].state == FC_PORTDB_STATE_NIL) { 3060 break; |
2455 } | 3061 } |
2456 /* "Cannot Happen" */ 2457 if (lim == hival) { 2458 isp_prt(isp, ISP_LOGWARN, "Remap Overflow"); 2459 continue; 2460 } 2461 i = lim; 2462 } else { 2463 i = loopid; | |
2464 } | 3062 } |
2465 2466 /* 2467 * NB: The actual loopid we use here is loopid- we may 2468 * in fact be at a completely different index (target). 2469 */ 2470 fcp->portdb[i].loopid = loopid; 2471 fcp->portdb[i].port_wwn = fcp->tport[loopid].port_wwn; 2472 fcp->portdb[i].node_wwn = fcp->tport[loopid].node_wwn; 2473 fcp->portdb[i].roles = fcp->tport[loopid].roles; 2474 fcp->portdb[i].portid = fcp->tport[loopid].portid; 2475 fcp->portdb[i].valid = 1; 2476 2477 /* 2478 * Tell the outside world we've arrived. 2479 */ 2480 (void) isp_async(isp, ISPASYNC_PROMENADE, &i); 2481 } 2482 2483 /* 2484 * Now find all previously used targets that are now invalid and 2485 * notify the outer layers that they're gone. 2486 */ 2487 for (lp = &fcp->portdb[0]; lp < &fcp->portdb[hival]; lp++) { 2488 if (lp->valid || lp->port_wwn == 0) { | 3063 if (i == MAX_FC_TARG) { 3064 isp_prt(isp, ISP_LOGERR, 3065 "could not find slot for new entry"); |
2489 continue; 2490 } | 3066 continue; 3067 } |
3068 lp = &fcp->portdb[i]; |
|
2491 | 3069 |
2492 /* 2493 * Tell the outside world we've gone 2494 * away and erase our pdb entry. 2495 * 2496 */ 2497 loopid = lp - fcp->portdb; 2498 (void) isp_async(isp, ISPASYNC_PROMENADE, &loopid); 2499 MEMZERO((void *) lp, sizeof (*lp)); | 3070 lp->autologin = 1; 3071 lp->state = FC_PORTDB_STATE_NEW; 3072 lp->portid = 0; 3073 lp->roles = 0; 3074 lp->new_portid = tmp.portid; 3075 lp->new_roles = tmp.roles; 3076 lp->handle = tmp.handle; 3077 lp->port_wwn = tmp.port_wwn; 3078 lp->node_wwn = tmp.node_wwn; |
2500 } | 3079 } |
3080 |
|
2501 fcp->isp_loopstate = LOOP_LSCAN_DONE; 2502 return (0); 2503} 2504 | 3081 fcp->isp_loopstate = LOOP_LSCAN_DONE; 3082 return (0); 3083} 3084 |
3085/* 3086 * Scan the fabric for devices and add them to our port database. 3087 * 3088 * Use the GID_FT command to get all Port IDs for FC4 SCSI devices it knows. 3089 * 3090 * For 2100-23XX cards, we can use the SNS mailbox command to pass simple 3091 * name server commands to the switch management server via the QLogic f/w. 3092 * 3093 * For the 24XX card, we have to use CT-Pass through run via the Execute IOCB 3094 * mailbox command. 3095 * 3096 * The net result is to leave the list of Port IDs setting untranslated in 3097 * offset IGPOFF of the FC scratch area, whereupon we'll canonicalize it to 3098 * host order at OGPOFF. 3099 */ |
|
2505 | 3100 |
3101/* 3102 * Take less than half of our scratch area to store Port IDs 3103 */ 3104#define GIDLEN ((ISP2100_SCRLEN >> 1) - 16 - SNS_GID_FT_REQ_SIZE) 3105#define NGENT ((GIDLEN - 16) >> 2) 3106 3107#define IGPOFF (2 * QENTRY_LEN) 3108#define OGPOFF (ISP2100_SCRLEN >> 1) 3109#define ZTXOFF (ISP2100_SCRLEN - (1 * QENTRY_LEN)) 3110#define CTXOFF (ISP2100_SCRLEN - (2 * QENTRY_LEN)) 3111#define XTXOFF (ISP2100_SCRLEN - (3 * QENTRY_LEN)) 3112 |
|
2506static int | 3113static int |
2507isp_fabric_mbox_cmd(ispsoftc_t *isp, mbreg_t *mbp) | 3114isp_gid_ft_sns(ispsoftc_t *isp) |
2508{ | 3115{ |
2509 /* the caller sets up the mailbox */ 2510 isp_mboxcmd(isp, mbp, MBLOGNONE); 2511 if (mbp->param[0] != MBOX_COMMAND_COMPLETE) { 2512 if (FCPARAM(isp)->isp_loopstate == LOOP_SCANNING_FABRIC) { 2513 FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD; | 3116 union { 3117 sns_gid_ft_req_t _x; 3118 uint8_t _y[SNS_GID_FT_REQ_SIZE]; 3119 } un; 3120 fcparam *fcp = FCPARAM(isp); 3121 sns_gid_ft_req_t *rq = &un._x; 3122 mbreg_t mbs; 3123 3124 isp_prt(isp, ISP_LOGDEBUG0, "scanning fabric (GID_FT) via SNS"); 3125 3126 MEMZERO(rq, SNS_GID_FT_REQ_SIZE); 3127 rq->snscb_rblen = GIDLEN >> 1; 3128 rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + IGPOFF); 3129 rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + IGPOFF); 3130 rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + IGPOFF); 3131 rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + IGPOFF); 3132 rq->snscb_sblen = 6; 3133 rq->snscb_cmd = SNS_GID_FT; 3134 rq->snscb_mword_div_2 = NGENT; 3135 rq->snscb_fc4_type = FC4_SCSI; 3136 3137 isp_put_gid_ft_request(isp, rq, fcp->isp_scratch); 3138 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GID_FT_REQ_SIZE); 3139 3140 MEMZERO(&mbs, sizeof (mbs)); 3141 mbs.param[0] = MBOX_SEND_SNS; 3142 mbs.param[1] = SNS_GID_FT_REQ_SIZE >> 1; 3143 mbs.param[2] = DMA_WD1(fcp->isp_scdma); 3144 mbs.param[3] = DMA_WD0(fcp->isp_scdma); 3145 mbs.param[6] = DMA_WD3(fcp->isp_scdma); 3146 mbs.param[7] = DMA_WD2(fcp->isp_scdma); 3147 mbs.logval = MBLOGALL; 3148 mbs.timeout = 1000000; 3149 isp_mboxcmd(isp, &mbs); 3150 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 3151 if (mbs.param[0] == MBOX_INVALID_COMMAND) { 3152 return (1); 3153 } else { 3154 return (-1); |
2514 } | 3155 } |
2515 if (mbp->param[0] == MBOX_COMMAND_ERROR) { 2516 char tbuf[16]; 2517 char *m; 2518 switch (mbp->param[1]) { 2519 case 1: 2520 m = "No Loop"; 2521 break; 2522 case 2: 2523 m = "Failed to allocate IOCB buffer"; 2524 break; 2525 case 3: 2526 m = "Failed to allocate XCB buffer"; 2527 break; 2528 case 4: 2529 m = "timeout or transmit failed"; 2530 break; 2531 case 5: 2532 m = "no fabric loop"; 2533 break; 2534 case 6: 2535 m = "remote device not a target"; 2536 break; 2537 default: 2538 SNPRINTF(tbuf, sizeof tbuf, "%x", 2539 mbp->param[1]); 2540 m = tbuf; 2541 break; 2542 } 2543 isp_prt(isp, ISP_LOGERR, "SNS Failed- %s", m); 2544 } 2545 return (-1); | |
2546 } | 3156 } |
2547 2548 if (FCPARAM(isp)->isp_fwstate != FW_READY || 2549 FCPARAM(isp)->isp_loopstate < LOOP_SCANNING_FABRIC) { 2550 return (-1); 2551 } 2552 return(0); | 3157 return (0); |
2553} 2554 | 3158} 3159 |
2555#ifdef ISP_USE_GA_NXT | |
2556static int | 3160static int |
2557isp_scan_fabric(ispsoftc_t *isp, int ftype) | 3161isp_gid_ft_ct_passthru(ispsoftc_t *isp) |
2558{ | 3162{ |
2559 fcparam *fcp = isp->isp_param; 2560 uint32_t portid, first_portid, last_portid; 2561 int hicap, last_port_same; | 3163 mbreg_t mbs; 3164 fcparam *fcp = FCPARAM(isp); 3165 union { 3166 isp_ct_pt_t plocal; 3167 ct_hdr_t clocal; 3168 uint8_t q[QENTRY_LEN]; 3169 } un; 3170 isp_ct_pt_t *pt; 3171 ct_hdr_t *ct; 3172 uint32_t *rp; 3173 uint8_t *scp = fcp->isp_scratch; |
2562 | 3174 |
2563 if (fcp->isp_onfabric == 0) { 2564 fcp->isp_loopstate = LOOP_FSCAN_DONE; 2565 return (0); | 3175 isp_prt(isp, ISP_LOGDEBUG0, "scanning fabric (GID_FT) via CT"); 3176 3177 if (!IS_24XX(isp)) { 3178 return (1); |
2566 } 2567 | 3179 } 3180 |
2568 isp_prt(isp, ISP_LOGDEBUG0, "scanning fabric (GA_NXT)"); | 3181 /* 3182 * Build a Passthrough IOCB in memory. 3183 */ 3184 pt = &un.plocal; 3185 MEMZERO(un.q, QENTRY_LEN); 3186 pt->ctp_header.rqs_entry_count = 1; 3187 pt->ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU; 3188 pt->ctp_handle = 0xffffffff; 3189 pt->ctp_nphdl = NPH_SNS_ID; 3190 pt->ctp_cmd_cnt = 1; 3191 pt->ctp_time = 30; 3192 pt->ctp_rsp_cnt = 1; 3193 pt->ctp_rsp_bcnt = GIDLEN; 3194 pt->ctp_cmd_bcnt = sizeof (*ct) + sizeof (uint32_t); 3195 pt->ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma+XTXOFF); 3196 pt->ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma+XTXOFF); 3197 pt->ctp_dataseg[0].ds_count = sizeof (*ct) + sizeof (uint32_t); 3198 pt->ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma+IGPOFF); 3199 pt->ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma+IGPOFF); 3200 pt->ctp_dataseg[1].ds_count = GIDLEN; 3201 if (isp->isp_dblev & ISP_LOGDEBUG1) { 3202 isp_print_bytes(isp, "ct IOCB", QENTRY_LEN, pt); 3203 } 3204 isp_put_ct_pt(isp, pt, (isp_ct_pt_t *) &scp[CTXOFF]); |
2569 | 3205 |
2570 FC_SCRATCH_ACQUIRE(isp); 2571 | |
2572 /* | 3206 /* |
2573 * Since Port IDs are 24 bits, we can check against having seen 2574 * anything yet with this value. | 3207 * Build the CT header and command in memory. 3208 * 3209 * Note that the CT header has to end up as Big Endian format in memory. |
2575 */ | 3210 */ |
2576 last_port_same = 0; 2577 last_portid = 0xffffffff; /* not a port */ 2578 first_portid = portid = fcp->isp_portid; 2579 fcp->isp_loopstate = LOOP_SCANNING_FABRIC; | 3211 ct = &un.clocal; 3212 MEMZERO(ct, sizeof (*ct)); 3213 ct->ct_revision = CT_REVISION; 3214 ct->ct_fcs_type = CT_FC_TYPE_FC; 3215 ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS; 3216 ct->ct_cmd_resp = SNS_GID_FT; 3217 ct->ct_bcnt_resid = (GIDLEN - 16) >> 2; |
2580 | 3218 |
2581 for (hicap = 0; hicap < GA_NXT_MAX; hicap++) { 2582 mbreg_t mbs; 2583 sns_screq_t *rq; 2584 sns_ga_nxt_rsp_t *rs0, *rs1; 2585 struct lportdb lcl; 2586 uint8_t sc[SNS_GA_NXT_RESP_SIZE]; 2587 2588 rq = (sns_screq_t *)sc; 2589 MEMZERO((void *) rq, SNS_GA_NXT_REQ_SIZE); 2590 rq->snscb_rblen = SNS_GA_NXT_RESP_SIZE >> 1; 2591 rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+0x100); 2592 rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+0x100); 2593 rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+0x100); 2594 rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+0x100); 2595 rq->snscb_sblen = 6; 2596 rq->snscb_data[0] = SNS_GA_NXT; 2597 rq->snscb_data[4] = portid & 0xffff; 2598 rq->snscb_data[5] = (portid >> 16) & 0xff; 2599 isp_put_sns_request(isp, rq, (sns_screq_t *) fcp->isp_scratch); 2600 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GA_NXT_REQ_SIZE); 2601 MEMZERO(&mbs, sizeof (mbs)); 2602 mbs.param[0] = MBOX_SEND_SNS; 2603 mbs.param[1] = SNS_GA_NXT_REQ_SIZE >> 1; 2604 mbs.param[2] = DMA_WD1(fcp->isp_scdma); 2605 mbs.param[3] = DMA_WD0(fcp->isp_scdma); 2606 /* 2607 * Leave 4 and 5 alone 2608 */ 2609 mbs.param[6] = DMA_WD3(fcp->isp_scdma); 2610 mbs.param[7] = DMA_WD2(fcp->isp_scdma); 2611 if (isp_fabric_mbox_cmd(isp, &mbs)) { 2612 if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) { 2613 fcp->isp_loopstate = LOOP_PDB_RCVD; 2614 } 2615 FC_SCRATCH_RELEASE(isp); 2616 return (-1); 2617 } 2618 MEMORYBARRIER(isp, SYNC_SFORCPU, 0x100, SNS_GA_NXT_RESP_SIZE); 2619 rs1 = (sns_ga_nxt_rsp_t *) sc; 2620 rs0 = (sns_ga_nxt_rsp_t *) ((uint8_t *)fcp->isp_scratch+0x100); 2621 isp_get_ga_nxt_response(isp, rs0, rs1); 2622 if (rs1->snscb_cthdr.ct_response != FS_ACC) { 2623 int level; 2624 if (rs1->snscb_cthdr.ct_reason == 9 && 2625 rs1->snscb_cthdr.ct_explanation == 7) 2626 level = ISP_LOGDEBUG0; 2627 else 2628 level = ISP_LOGWARN; 2629 isp_prt(isp, level, swrej, "GA_NXT", 2630 rs1->snscb_cthdr.ct_reason, 2631 rs1->snscb_cthdr.ct_explanation, portid); 2632 FC_SCRATCH_RELEASE(isp); 2633 fcp->isp_loopstate = LOOP_FSCAN_DONE; 2634 return (0); 2635 } 2636 portid = 2637 (((uint32_t) rs1->snscb_port_id[0]) << 16) | 2638 (((uint32_t) rs1->snscb_port_id[1]) << 8) | 2639 (((uint32_t) rs1->snscb_port_id[2])); 2640 2641 /* 2642 * XXX: We should check to make sure that this entry 2643 * XXX: supports the type(s) we are interested in. 2644 */ 2645 /* 2646 * Okay, we now have information about a fabric object. 2647 * If it is the type we're interested in, tell the outer layers 2648 * about it. The outer layer needs to know: Port ID, WWNN, 2649 * WWPN, FC4 type, and port type. 2650 * 2651 * The lportdb structure is adequate for this. 2652 */ 2653 MEMZERO(&lcl, sizeof (lcl)); 2654 lcl.port_type = rs1->snscb_port_type; 2655 lcl.fc4_type = ftype; 2656 lcl.portid = portid; 2657 lcl.node_wwn = 2658 (((uint64_t)rs1->snscb_nodename[0]) << 56) | 2659 (((uint64_t)rs1->snscb_nodename[1]) << 48) | 2660 (((uint64_t)rs1->snscb_nodename[2]) << 40) | 2661 (((uint64_t)rs1->snscb_nodename[3]) << 32) | 2662 (((uint64_t)rs1->snscb_nodename[4]) << 24) | 2663 (((uint64_t)rs1->snscb_nodename[5]) << 16) | 2664 (((uint64_t)rs1->snscb_nodename[6]) << 8) | 2665 (((uint64_t)rs1->snscb_nodename[7])); 2666 lcl.port_wwn = 2667 (((uint64_t)rs1->snscb_portname[0]) << 56) | 2668 (((uint64_t)rs1->snscb_portname[1]) << 48) | 2669 (((uint64_t)rs1->snscb_portname[2]) << 40) | 2670 (((uint64_t)rs1->snscb_portname[3]) << 32) | 2671 (((uint64_t)rs1->snscb_portname[4]) << 24) | 2672 (((uint64_t)rs1->snscb_portname[5]) << 16) | 2673 (((uint64_t)rs1->snscb_portname[6]) << 8) | 2674 (((uint64_t)rs1->snscb_portname[7])); 2675 2676 /* 2677 * Does this fabric object support the type we want? 2678 * If not, skip it. 2679 */ 2680 if (rs1->snscb_fc4_types[ftype >> 5] & (1 << (ftype & 0x1f))) { 2681 if (first_portid == portid) { 2682 lcl.last_fabric_dev = 1; 2683 } else { 2684 lcl.last_fabric_dev = 0; 2685 } 2686 (void) isp_async(isp, ISPASYNC_FABRIC_DEV, &lcl); 2687 } else { 2688 isp_prt(isp, ISP_LOGDEBUG0, 2689 "PortID 0x%x doesn't support FC4 type 0x%x", 2690 portid, ftype); 2691 } 2692 if (first_portid == portid) { 2693 fcp->isp_loopstate = LOOP_FSCAN_DONE; 2694 FC_SCRATCH_RELEASE(isp); 2695 return (0); 2696 } 2697 if (portid == last_portid) { 2698 if (last_port_same++ > 20) { 2699 isp_prt(isp, ISP_LOGWARN, 2700 "tangled fabric database detected"); 2701 break; 2702 } 2703 } else { 2704 last_port_same = 0 ; 2705 last_portid = portid; 2706 } | 3219 isp_put_ct_hdr(isp, ct, (ct_hdr_t *) &scp[XTXOFF]); 3220 rp = (uint32_t *) &scp[XTXOFF+sizeof (*ct)]; 3221 ISP_IOZPUT_32(isp, FC4_SCSI, rp); 3222 MEMZERO(&scp[ZTXOFF], QENTRY_LEN); 3223 MEMZERO(&mbs, sizeof (mbs)); 3224 mbs.param[0] = MBOX_EXEC_COMMAND_IOCB_A64; 3225 mbs.param[1] = QENTRY_LEN; 3226 mbs.param[2] = DMA_WD1(fcp->isp_scdma + CTXOFF); 3227 mbs.param[3] = DMA_WD0(fcp->isp_scdma + CTXOFF); 3228 mbs.param[6] = DMA_WD3(fcp->isp_scdma + CTXOFF); 3229 mbs.param[7] = DMA_WD2(fcp->isp_scdma + CTXOFF); 3230 mbs.logval = MBLOGALL; 3231 MEMORYBARRIER(isp, SYNC_SFORDEV, XTXOFF, 2 * QENTRY_LEN); 3232 isp_mboxcmd(isp, &mbs); 3233 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 3234 return (-1); |
2707 } | 3235 } |
2708 FC_SCRATCH_RELEASE(isp); 2709 if (hicap >= GA_NXT_MAX) { 2710 isp_prt(isp, ISP_LOGWARN, "fabric too big (> %d)", GA_NXT_MAX); | 3236 MEMORYBARRIER(isp, SYNC_SFORCPU, ZTXOFF, QENTRY_LEN); 3237 pt = &un.plocal; 3238 isp_get_ct_pt(isp, (isp_ct_pt_t *) &scp[ZTXOFF], pt); 3239 if (isp->isp_dblev & ISP_LOGDEBUG1) { 3240 isp_print_bytes(isp, "IOCB response", QENTRY_LEN, pt); |
2711 } | 3241 } |
2712 fcp->isp_loopstate = LOOP_FSCAN_DONE; | 3242 3243 if (pt->ctp_status && pt->ctp_status != RQCS_DATA_UNDERRUN) { 3244 isp_prt(isp, ISP_LOGWARN, "CT Passthrough returned 0x%x", 3245 pt->ctp_status); 3246 return (-1); 3247 } 3248 MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN + 16); |
2713 return (0); 2714} | 3249 return (0); 3250} |
2715#else 2716#define GIDLEN ((ISP2100_SCRLEN >> 1) + 16) 2717#define NGENT ((GIDLEN - 16) >> 2) | |
2718 | 3251 |
2719#define IGPOFF (ISP2100_SCRLEN - GIDLEN) 2720#define GXOFF (256) 2721 | |
2722static int | 3252static int |
2723isp_scan_fabric(ispsoftc_t *isp, int ftype) | 3253isp_scan_fabric(ispsoftc_t *isp) |
2724{ 2725 fcparam *fcp = FCPARAM(isp); | 3254{ 3255 fcparam *fcp = FCPARAM(isp); |
2726 mbreg_t mbs; 2727 int i; 2728 sns_gid_ft_req_t *rq; | 3256 uint32_t portid; 3257 uint16_t handle, oldhandle; 3258 int portidx, portlim, r; |
2729 sns_gid_ft_rsp_t *rs0, *rs1; 2730 | 3259 sns_gid_ft_rsp_t *rs0, *rs1; 3260 |
2731 if (fcp->isp_onfabric == 0) { | 3261 isp_prt(isp, ISP_LOGDEBUG0, "FC Scan Fabric"); 3262 if (fcp->isp_fwstate != FW_READY || 3263 fcp->isp_loopstate < LOOP_LSCAN_DONE) { 3264 return (-1); 3265 } 3266 if (fcp->isp_loopstate > LOOP_SCANNING_FABRIC) { 3267 return (0); 3268 } 3269 if (fcp->isp_topo != TOPO_FL_PORT && fcp->isp_topo != TOPO_F_PORT) { |
2732 fcp->isp_loopstate = LOOP_FSCAN_DONE; | 3270 fcp->isp_loopstate = LOOP_FSCAN_DONE; |
3271 isp_prt(isp, ISP_LOGDEBUG0, "FC Scan Fabric Done (no fabric)"); |
|
2733 return (0); 2734 } 2735 | 3272 return (0); 3273 } 3274 |
2736 isp_prt(isp, ISP_LOGDEBUG0, "scanning fabric (GID_FT)"); 2737 | |
2738 FC_SCRATCH_ACQUIRE(isp); 2739 fcp->isp_loopstate = LOOP_SCANNING_FABRIC; 2740 | 3275 FC_SCRATCH_ACQUIRE(isp); 3276 fcp->isp_loopstate = LOOP_SCANNING_FABRIC; 3277 |
2741 rq = (sns_gid_ft_req_t *)fcp->tport; 2742 MEMZERO((void *) rq, SNS_GID_FT_REQ_SIZE); 2743 rq->snscb_rblen = GIDLEN >> 1; 2744 rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+IGPOFF); 2745 rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+IGPOFF); 2746 rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+IGPOFF); 2747 rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+IGPOFF); 2748 rq->snscb_sblen = 6; 2749 rq->snscb_cmd = SNS_GID_FT; 2750 rq->snscb_mword_div_2 = NGENT; 2751 rq->snscb_fc4_type = ftype; 2752 isp_put_gid_ft_request(isp, rq, (sns_gid_ft_req_t *) fcp->isp_scratch); 2753 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GID_FT_REQ_SIZE); 2754 MEMZERO(&mbs, sizeof (mbs)); 2755 mbs.param[0] = MBOX_SEND_SNS; 2756 mbs.param[1] = SNS_GID_FT_REQ_SIZE >> 1; 2757 mbs.param[2] = DMA_WD1(fcp->isp_scdma); 2758 mbs.param[3] = DMA_WD0(fcp->isp_scdma); | 3278 if (IS_24XX(isp)) { 3279 r = isp_gid_ft_ct_passthru(isp); 3280 } else { 3281 r = isp_gid_ft_sns(isp); 3282 } |
2759 | 3283 |
2760 /* 2761 * Leave 4 and 5 alone 2762 */ 2763 mbs.param[6] = DMA_WD3(fcp->isp_scdma); 2764 mbs.param[7] = DMA_WD2(fcp->isp_scdma); 2765 if (isp_fabric_mbox_cmd(isp, &mbs)) { 2766 if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) { 2767 fcp->isp_loopstate = LOOP_PDB_RCVD; 2768 } | 3284 if (r > 0) { 3285 fcp->isp_loopstate = LOOP_FSCAN_DONE; |
2769 FC_SCRATCH_RELEASE(isp); | 3286 FC_SCRATCH_RELEASE(isp); |
2770 return (-1); | 3287 return (0); 3288 } else if (r < 0) { 3289 fcp->isp_loopstate = LOOP_PDB_RCVD; /* try again */ 3290 FC_SCRATCH_RELEASE(isp); 3291 return (0); |
2771 } 2772 if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) { 2773 FC_SCRATCH_RELEASE(isp); 2774 return (-1); 2775 } | 3292 } 3293 if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) { 3294 FC_SCRATCH_RELEASE(isp); 3295 return (-1); 3296 } |
3297 |
|
2776 MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN); | 3298 MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN); |
2777 rs1 = (sns_gid_ft_rsp_t *) fcp->tport; | |
2778 rs0 = (sns_gid_ft_rsp_t *) ((uint8_t *)fcp->isp_scratch+IGPOFF); | 3299 rs0 = (sns_gid_ft_rsp_t *) ((uint8_t *)fcp->isp_scratch+IGPOFF); |
3300 rs1 = (sns_gid_ft_rsp_t *) ((uint8_t *)fcp->isp_scratch+OGPOFF); |
|
2779 isp_get_gid_ft_response(isp, rs0, rs1, NGENT); | 3301 isp_get_gid_ft_response(isp, rs0, rs1, NGENT); |
2780 if (rs1->snscb_cthdr.ct_response != FS_ACC) { | 3302 if (rs1->snscb_cthdr.ct_cmd_resp != LS_ACC) { |
2781 int level; 2782 if (rs1->snscb_cthdr.ct_reason == 9 && | 3303 int level; 3304 if (rs1->snscb_cthdr.ct_reason == 9 && |
2783 rs1->snscb_cthdr.ct_explanation == 7) | 3305 rs1->snscb_cthdr.ct_explanation == 7) { |
2784 level = ISP_LOGDEBUG0; | 3306 level = ISP_LOGDEBUG0; |
2785 else | 3307 } else { |
2786 level = ISP_LOGWARN; | 3308 level = ISP_LOGWARN; |
2787 isp_prt(isp, level, swrej, "GID_FT", 2788 rs1->snscb_cthdr.ct_reason, 2789 rs1->snscb_cthdr.ct_explanation, 0); | 3309 } 3310 isp_prt(isp, level, "Fabric Nameserver rejected GID_FT " 3311 "(Reason=0x%x Expl=0x%x)", rs1->snscb_cthdr.ct_reason, 3312 rs1->snscb_cthdr.ct_explanation); |
2790 FC_SCRATCH_RELEASE(isp); 2791 fcp->isp_loopstate = LOOP_FSCAN_DONE; 2792 return (0); 2793 } 2794 | 3313 FC_SCRATCH_RELEASE(isp); 3314 fcp->isp_loopstate = LOOP_FSCAN_DONE; 3315 return (0); 3316 } 3317 |
3318 |
|
2795 /* | 3319 /* |
2796 * Okay, we now have a list of Port IDs for this class of device. 2797 * Go through the list and for each one get the WWPN/WWNN for it 2798 * and tell the outer layers about it. The outer layer needs to 2799 * know: Port ID, WWNN, WWPN, FC4 type, and (possibly) port type. | 3320 * If we get this far, we certainly still have the fabric controller. 3321 */ 3322 fcp->portdb[FL_ID].state = FC_PORTDB_STATE_PENDING_VALID; 3323 3324 /* 3325 * Prime the handle we will start using. 3326 */ 3327 oldhandle = 0xffff; 3328 3329 /* 3330 * Okay, we now have a list of Port IDs for all FC4 SCSI devices 3331 * that the Fabric Name server knows about. Go through the list 3332 * and remove duplicate port ids. 3333 */ 3334 3335 portlim = 0; 3336 portidx = 0; 3337 for (portidx = 0; portidx < NGENT-1; portidx++) { 3338 if (rs1->snscb_ports[portidx].control & 0x80) { 3339 break; 3340 } 3341 } 3342 3343 /* 3344 * If we're not at the last entry, our list wasn't big enough. 3345 */ 3346 if ((rs1->snscb_ports[portidx].control & 0x80) == 0) { 3347 isp_prt(isp, ISP_LOGWARN, 3348 "fabric too big for scratch area: increase ISP2100_SCRLEN"); 3349 } 3350 portlim = portidx + 1; 3351 isp_prt(isp, ISP_LOGDEBUG0, "got %d ports back from name server", 3352 portlim); 3353 3354 for (portidx = 0; portidx < portlim; portidx++) { 3355 int npidx; 3356 3357 portid = 3358 ((rs1->snscb_ports[portidx].portid[0]) << 16) | 3359 ((rs1->snscb_ports[portidx].portid[1]) << 8) | 3360 ((rs1->snscb_ports[portidx].portid[2])); 3361 3362 for (npidx = portidx + 1; npidx < portlim; npidx++) { 3363 uint32_t new_portid = 3364 ((rs1->snscb_ports[npidx].portid[0]) << 16) | 3365 ((rs1->snscb_ports[npidx].portid[1]) << 8) | 3366 ((rs1->snscb_ports[npidx].portid[2])); 3367 if (new_portid == portid) { 3368 break; 3369 } 3370 } 3371 3372 if (npidx < portlim) { 3373 rs1->snscb_ports[npidx].portid[0] = 0; 3374 rs1->snscb_ports[npidx].portid[1] = 0; 3375 rs1->snscb_ports[npidx].portid[2] = 0; 3376 isp_prt(isp, ISP_LOGDEBUG0, 3377 "removing duplicate PortID 0x%x entry from list", 3378 portid); 3379 } 3380 } 3381 3382 /* 3383 * Okay, we now have a list of Port IDs for all FC4 SCSI devices 3384 * that the Fabric Name server knows about. |
2800 * | 3385 * |
2801 * The lportdb structure is adequate for this. | 3386 * For each entry on this list go through our port database looking 3387 * for probational entries- if we find one, then an old entry is 3388 * is maybe still this one. We get some information to find out. 3389 * 3390 * Otherwise, it's a new fabric device, and we log into it 3391 * (unconditionally). After searching the entire database 3392 * again to make sure that we never ever ever ever have more 3393 * than one entry that has the same PortID or the same 3394 * WWNN/WWPN duple, we enter the device into our database. |
2802 */ | 3395 */ |
2803 i = -1; 2804 do { 2805 sns_gxn_id_req_t grqbuf, *gq = &grqbuf; 2806 sns_gxn_id_rsp_t *gs0, grsbuf, *gs1 = &grsbuf; 2807 struct lportdb lcl; 2808#if 0 2809 sns_gff_id_rsp_t *fs0, ffsbuf, *fs1 = &ffsbuf; 2810#endif | |
2811 | 3396 |
2812 i++; 2813 MEMZERO(&lcl, sizeof (lcl)); 2814 lcl.fc4_type = ftype; 2815 lcl.portid = 2816 (((uint32_t) rs1->snscb_ports[i].portid[0]) << 16) | 2817 (((uint32_t) rs1->snscb_ports[i].portid[1]) << 8) | 2818 (((uint32_t) rs1->snscb_ports[i].portid[2])); | 3397 for (portidx = 0; portidx < portlim; portidx++) { 3398 fcportdb_t *lp; 3399 isp_pdb_t pdb; 3400 uint64_t wwnn, wwpn; 3401 int dbidx, r, nr; |
2819 | 3402 |
2820 MEMZERO((void *) gq, sizeof (sns_gxn_id_req_t)); 2821 gq->snscb_rblen = SNS_GXN_ID_RESP_SIZE >> 1; 2822 gq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+GXOFF); 2823 gq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+GXOFF); 2824 gq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+GXOFF); 2825 gq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+GXOFF); 2826 gq->snscb_sblen = 6; 2827 gq->snscb_cmd = SNS_GPN_ID; 2828 gq->snscb_portid = lcl.portid; 2829 isp_put_gxn_id_request(isp, gq, 2830 (sns_gxn_id_req_t *) fcp->isp_scratch); 2831 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GXN_ID_REQ_SIZE); 2832 MEMZERO(&mbs, sizeof (mbs)); 2833 mbs.param[0] = MBOX_SEND_SNS; 2834 mbs.param[1] = SNS_GXN_ID_REQ_SIZE >> 1; 2835 mbs.param[2] = DMA_WD1(fcp->isp_scdma); 2836 mbs.param[3] = DMA_WD0(fcp->isp_scdma); | 3403 portid = 3404 ((rs1->snscb_ports[portidx].portid[0]) << 16) | 3405 ((rs1->snscb_ports[portidx].portid[1]) << 8) | 3406 ((rs1->snscb_ports[portidx].portid[2])); 3407 3408 if (portid == 0) { 3409 isp_prt(isp, ISP_LOGDEBUG0, 3410 "skipping null PortID at idx %d", portidx); 3411 continue; 3412 } 3413 |
2837 /* | 3414 /* |
2838 * Leave 4 and 5 alone | 3415 * Skip ourselves... |
2839 */ | 3416 */ |
2840 mbs.param[6] = DMA_WD3(fcp->isp_scdma); 2841 mbs.param[7] = DMA_WD2(fcp->isp_scdma); 2842 if (isp_fabric_mbox_cmd(isp, &mbs)) { 2843 if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) { 2844 fcp->isp_loopstate = LOOP_PDB_RCVD; | 3417 if (portid == fcp->isp_portid) { 3418 isp_prt(isp, ISP_LOGDEBUG0, 3419 "skip ourselves @ PortID 0x%06x", portid); 3420 continue; 3421 } 3422 isp_prt(isp, ISP_LOGDEBUG0, "Fabric Port 0x%06x", portid); 3423 3424 /* 3425 * We now search our Port Database for any 3426 * probational entries with this PortID. 3427 */ 3428 for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) { 3429 lp = &fcp->portdb[dbidx]; 3430 3431 if (lp->state != FC_PORTDB_STATE_PROBATIONAL) { 3432 continue; |
2845 } | 3433 } |
2846 FC_SCRATCH_RELEASE(isp); 2847 return (-1); | 3434 if (lp->portid == portid) { 3435 break; 3436 } |
2848 } | 3437 } |
2849 if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) { 2850 FC_SCRATCH_RELEASE(isp); 2851 return (-1); 2852 } 2853 MEMORYBARRIER(isp, SYNC_SFORCPU, GXOFF, SNS_GXN_ID_RESP_SIZE); 2854 gs0 = (sns_gxn_id_rsp_t *) ((uint8_t *)fcp->isp_scratch+GXOFF); 2855 isp_get_gxn_id_response(isp, gs0, gs1); 2856 if (gs1->snscb_cthdr.ct_response != FS_ACC) { 2857 isp_prt(isp, ISP_LOGWARN, swrej, "GPN_ID", 2858 gs1->snscb_cthdr.ct_reason, 2859 gs1->snscb_cthdr.ct_explanation, lcl.portid); | 3438 3439 /* 3440 * We found a probational entry with this Port ID. 3441 */ 3442 if (dbidx < MAX_FC_TARG) { 3443 int handle_changed = 0; 3444 3445 lp = &fcp->portdb[dbidx]; 3446 3447 /* 3448 * See if we're still logged into it. 3449 * 3450 * If we aren't, mark it as a dead device and 3451 * leave the new portid in the database entry 3452 * for somebody further along to decide what to 3453 * do (policy choice). 3454 * 3455 * If we are, check to see if it's the same 3456 * device still (it should be). If for some 3457 * reason it isn't, mark it as a changed device 3458 * and leave the new portid and role in the 3459 * database entry for somebody further along to 3460 * decide what to do (policy choice). 3461 * 3462 */ 3463 3464 r = isp_getpdb(isp, lp->handle, &pdb, 0); |
2860 if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) { 2861 FC_SCRATCH_RELEASE(isp); | 3465 if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) { 3466 FC_SCRATCH_RELEASE(isp); |
3467 isp_mark_portdb(isp, 1); |
|
2862 return (-1); 2863 } | 3468 return (-1); 3469 } |
3470 if (r != 0) { 3471 lp->new_portid = portid; 3472 lp->state = FC_PORTDB_STATE_DEAD; 3473 continue; 3474 } 3475 3476 3477 /* 3478 * Check to make sure that handle, portid, WWPN and 3479 * WWNN agree. If they don't, then the association 3480 * between this PortID and the stated handle has been 3481 * broken by the firmware. 3482 */ 3483 MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename); 3484 MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname); 3485 if (pdb.handle != lp->handle || 3486 pdb.portid != portid || 3487 wwpn != lp->port_wwn || 3488 wwnn != lp->node_wwn) { 3489 isp_prt(isp, ISP_LOGDEBUG0, fconf, dbidx, 3490 pdb.handle, pdb.portid, 3491 (uint32_t) (wwnn >> 32), (uint32_t) wwnn, 3492 (uint32_t) (wwpn >> 32), (uint32_t) wwpn, 3493 lp->handle, portid, 3494 (uint32_t) (lp->node_wwn >> 32), 3495 (uint32_t) lp->node_wwn, 3496 (uint32_t) (lp->port_wwn >> 32), 3497 (uint32_t) lp->port_wwn); 3498 /* 3499 * Try to re-login to this device using a 3500 * new handle. If that fails, mark it dead. 3501 * 3502 * isp_login_device will check for handle and 3503 * portid consistency after re-login. 3504 * 3505 */ 3506 if (isp_login_device(isp, portid, &pdb, 3507 &oldhandle)) { 3508 lp->new_portid = portid; 3509 lp->state = FC_PORTDB_STATE_DEAD; 3510 if (fcp->isp_loopstate != 3511 LOOP_SCANNING_FABRIC) { 3512 FC_SCRATCH_RELEASE(isp); 3513 isp_mark_portdb(isp, 1); 3514 return (-1); 3515 } 3516 continue; 3517 } 3518 MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename); 3519 MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname); 3520 if (wwpn != lp->port_wwn || 3521 wwnn != lp->node_wwn) { 3522 isp_prt(isp, ISP_LOGWARN, "changed WWN" 3523 " after relogin"); 3524 lp->new_portid = portid; 3525 lp->state = FC_PORTDB_STATE_DEAD; 3526 continue; 3527 } 3528 3529 lp->handle = pdb.handle; 3530 handle_changed++; 3531 } 3532 3533 nr = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT; 3534 3535 /* 3536 * Check to see whether the portid and roles have 3537 * stayed the same. If they have stayed the same, 3538 * we believe that this is the same device and it 3539 * hasn't become disconnected and reconnected, so 3540 * mark it as pending valid. 3541 * 3542 * If they aren't the same, mark the device as a 3543 * changed device and save the new port id and role 3544 * and let somebody else decide. 3545 */ 3546 3547 lp->new_portid = portid; 3548 lp->new_roles = nr; 3549 if (pdb.portid != lp->portid || nr != lp->roles || 3550 handle_changed) { 3551 lp->state = FC_PORTDB_STATE_CHANGED; 3552 } else { 3553 lp->state = FC_PORTDB_STATE_PENDING_VALID; 3554 } |
|
2864 continue; 2865 } | 3555 continue; 3556 } |
2866 lcl.port_wwn = 2867 (((uint64_t)gs1->snscb_wwn[0]) << 56) | 2868 (((uint64_t)gs1->snscb_wwn[1]) << 48) | 2869 (((uint64_t)gs1->snscb_wwn[2]) << 40) | 2870 (((uint64_t)gs1->snscb_wwn[3]) << 32) | 2871 (((uint64_t)gs1->snscb_wwn[4]) << 24) | 2872 (((uint64_t)gs1->snscb_wwn[5]) << 16) | 2873 (((uint64_t)gs1->snscb_wwn[6]) << 8) | 2874 (((uint64_t)gs1->snscb_wwn[7])); | |
2875 | 3557 |
2876 MEMZERO((void *) gq, sizeof (sns_gxn_id_req_t)); 2877 gq->snscb_rblen = SNS_GXN_ID_RESP_SIZE >> 1; 2878 gq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+GXOFF); 2879 gq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+GXOFF); 2880 gq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+GXOFF); 2881 gq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+GXOFF); 2882 gq->snscb_sblen = 6; 2883 gq->snscb_cmd = SNS_GNN_ID; 2884 gq->snscb_portid = lcl.portid; 2885 isp_put_gxn_id_request(isp, gq, 2886 (sns_gxn_id_req_t *) fcp->isp_scratch); 2887 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GXN_ID_REQ_SIZE); 2888 MEMZERO(&mbs, sizeof (mbs)); 2889 mbs.param[0] = MBOX_SEND_SNS; 2890 mbs.param[1] = SNS_GXN_ID_REQ_SIZE >> 1; 2891 mbs.param[2] = DMA_WD1(fcp->isp_scdma); 2892 mbs.param[3] = DMA_WD0(fcp->isp_scdma); | |
2893 /* | 3558 /* |
2894 * Leave 4 and 5 alone | 3559 * Ah- a new entry. Search the database again for all non-NIL 3560 * entries to make sure we never ever make a database entry 3561 * with the same port id. |
2895 */ | 3562 */ |
2896 mbs.param[6] = DMA_WD3(fcp->isp_scdma); 2897 mbs.param[7] = DMA_WD2(fcp->isp_scdma); 2898 if (isp_fabric_mbox_cmd(isp, &mbs)) { 2899 if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) { 2900 fcp->isp_loopstate = LOOP_PDB_RCVD; | 3563 for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) { 3564 if (dbidx >= FL_ID && dbidx <= SNS_ID) { 3565 continue; |
2901 } | 3566 } |
2902 FC_SCRATCH_RELEASE(isp); 2903 return (-1); 2904 } 2905 if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) { 2906 FC_SCRATCH_RELEASE(isp); 2907 return (-1); 2908 } 2909 MEMORYBARRIER(isp, SYNC_SFORCPU, GXOFF, SNS_GXN_ID_RESP_SIZE); 2910 gs0 = (sns_gxn_id_rsp_t *) ((uint8_t *)fcp->isp_scratch+GXOFF); 2911 isp_get_gxn_id_response(isp, gs0, gs1); 2912 if (gs1->snscb_cthdr.ct_response != FS_ACC) { 2913 isp_prt(isp, ISP_LOGWARN, swrej, "GNN_ID", 2914 gs1->snscb_cthdr.ct_reason, 2915 gs1->snscb_cthdr.ct_explanation, lcl.portid); 2916 if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) { 2917 FC_SCRATCH_RELEASE(isp); 2918 return (-1); | 3567 if (fcp->portdb[dbidx].state == FC_PORTDB_STATE_NIL) { 3568 continue; |
2919 } | 3569 } |
3570 if (fcp->portdb[dbidx].portid == portid) { 3571 break; 3572 } 3573 } 3574 3575 if (dbidx != MAX_FC_TARG) { 3576 isp_prt(isp, ISP_LOGWARN, 3577 "PortID 0x%06x already at %d handle %d state %d", 3578 portid, dbidx, fcp->portdb[dbidx].handle, 3579 fcp->portdb[dbidx].state); |
|
2920 continue; 2921 } | 3580 continue; 3581 } |
2922 lcl.node_wwn = 2923 (((uint64_t)gs1->snscb_wwn[0]) << 56) | 2924 (((uint64_t)gs1->snscb_wwn[1]) << 48) | 2925 (((uint64_t)gs1->snscb_wwn[2]) << 40) | 2926 (((uint64_t)gs1->snscb_wwn[3]) << 32) | 2927 (((uint64_t)gs1->snscb_wwn[4]) << 24) | 2928 (((uint64_t)gs1->snscb_wwn[5]) << 16) | 2929 (((uint64_t)gs1->snscb_wwn[6]) << 8) | 2930 (((uint64_t)gs1->snscb_wwn[7])); | |
2931 2932 /* | 3582 3583 /* |
2933 * The QLogic f/w is bouncing this with a parameter error. | 3584 * Find an empty database entry for it. |
2934 */ | 3585 */ |
2935#if 0 2936 /* 2937 * Try and get FC4 Features (FC-GS-3 only). 2938 * We can use the sns_gxn_id_req_t for this request. 2939 */ 2940 MEMZERO((void *) gq, sizeof (sns_gxn_id_req_t)); 2941 gq->snscb_rblen = SNS_GFF_ID_RESP_SIZE >> 1; 2942 gq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+GXOFF); 2943 gq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+GXOFF); 2944 gq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+GXOFF); 2945 gq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+GXOFF); 2946 gq->snscb_sblen = 6; 2947 gq->snscb_cmd = SNS_GFF_ID; 2948 gq->snscb_portid = lcl.portid; 2949 isp_put_gxn_id_request(isp, gq, 2950 (sns_gxn_id_req_t *) fcp->isp_scratch); 2951 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GXN_ID_REQ_SIZE); 2952 MEMZERO(&mbs, sizeof (mbs)); 2953 mbs.param[0] = MBOX_SEND_SNS; 2954 mbs.param[1] = SNS_GXN_ID_REQ_SIZE >> 1; 2955 mbs.param[2] = DMA_WD1(fcp->isp_scdma); 2956 mbs.param[3] = DMA_WD0(fcp->isp_scdma); 2957 /* 2958 * Leave 4 and 5 alone 2959 */ 2960 mbs.param[6] = DMA_WD3(fcp->isp_scdma); 2961 mbs.param[7] = DMA_WD2(fcp->isp_scdma); 2962 if (isp_fabric_mbox_cmd(isp, &mbs)) { 2963 if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) { 2964 fcp->isp_loopstate = LOOP_PDB_RCVD; | 3586 for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) { 3587 if (dbidx >= FL_ID && dbidx <= SNS_ID) { 3588 continue; |
2965 } | 3589 } |
2966 FC_SCRATCH_RELEASE(isp); 2967 return (-1); | 3590 if (fcp->portdb[dbidx].state == FC_PORTDB_STATE_NIL) { 3591 break; 3592 } |
2968 } | 3593 } |
2969 if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) { 2970 FC_SCRATCH_RELEASE(isp); 2971 return (-1); | 3594 3595 if (dbidx == MAX_FC_TARG) { 3596 isp_prt(isp, ISP_LOGERR, 3597 "port database too small to login fabric device" 3598 "- increase MAX_FC_TARG"); 3599 continue; |
2972 } | 3600 } |
2973 MEMORYBARRIER(isp, SYNC_SFORCPU, GXOFF, SNS_GFF_ID_RESP_SIZE); 2974 fs0 = (sns_gff_id_rsp_t *) ((uint8_t *)fcp->isp_scratch+GXOFF); 2975 isp_get_gff_id_response(isp, fs0, fs1); 2976 if (fs1->snscb_cthdr.ct_response != FS_ACC) { 2977 isp_prt(isp, /* ISP_LOGDEBUG0 */ ISP_LOGWARN, 2978 swrej, "GFF_ID", 2979 fs1->snscb_cthdr.ct_reason, 2980 fs1->snscb_cthdr.ct_explanation, lcl.portid); | 3601 3602 /* 3603 * Try to see if we are logged into this device, 3604 * and maybe log into it. 3605 * 3606 * isp_login_device will check for handle and 3607 * portid consistency after login. 3608 */ 3609 if (isp_login_device(isp, portid, &pdb, &oldhandle)) { |
2981 if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) { 2982 FC_SCRATCH_RELEASE(isp); | 3610 if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) { 3611 FC_SCRATCH_RELEASE(isp); |
3612 isp_mark_portdb(isp, 1); |
|
2983 return (-1); 2984 } | 3613 return (-1); 3614 } |
2985 } else { 2986 int index = (ftype >> 3); 2987 int bshft = (ftype & 0x7) * 4; 2988 int fc4_fval = 2989 (fs1->snscb_fc4_features[index] >> bshft) & 0xf; 2990 if (fc4_fval & 0x1) { 2991 lcl.roles |= 2992 (SVC3_INI_ROLE >> SVC3_ROLE_SHIFT); | 3615 continue; 3616 } 3617 3618 handle = pdb.handle; 3619 MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename); 3620 MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname); 3621 nr = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT; 3622 3623 /* 3624 * And go through the database *one* more time to make sure 3625 * that we do not make more than one entry that has the same 3626 * WWNN/WWPN duple 3627 */ 3628 lp = &fcp->portdb[dbidx]; 3629 3630 for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) { 3631 if (fcp->portdb[dbidx].state == FC_PORTDB_STATE_NIL) { 3632 continue; |
2993 } | 3633 } |
2994 if (fc4_fval & 0x2) { 2995 lcl.roles |= 2996 (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT); | 3634 if (dbidx >= FL_ID && dbidx <= SNS_ID) { 3635 continue; |
2997 } | 3636 } |
3637 if (fcp->portdb[dbidx].node_wwn == wwnn && 3638 fcp->portdb[dbidx].port_wwn == wwpn) { 3639 break; 3640 } |
|
2998 } | 3641 } |
2999#endif | |
3000 | 3642 |
3643 if (dbidx != MAX_FC_TARG) { 3644 isp_prt(isp, ISP_LOGWARN, 3645 "PortID 0x%x 0x%08x%08x/0x%08x%08x %ld already at " 3646 "idx %d", portid, 3647 (uint32_t) (wwnn >> 32), (uint32_t) wwnn, 3648 (uint32_t) (wwpn >> 32), (uint32_t) wwpn, 3649 (long) (lp - fcp->portdb), dbidx); 3650 continue; 3651 } 3652 3653 lp->handle = handle; 3654 lp->ini_map_idx = 0; 3655 lp->node_wwn = wwnn; 3656 lp->port_wwn = wwpn; 3657 lp->new_portid = portid; 3658 lp->new_roles = nr; 3659 lp->state = FC_PORTDB_STATE_NEW; 3660 } 3661 3662 3663 FC_SCRATCH_RELEASE(isp); 3664 if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) { 3665 isp_mark_portdb(isp, 1); 3666 return (-1); 3667 } 3668 fcp->isp_loopstate = LOOP_FSCAN_DONE; 3669 isp_prt(isp, ISP_LOGDEBUG0, "FC Scan Fabric Done"); 3670 return (0); 3671} 3672 3673/* 3674 * Find an unused handle and try and use to login to a port. 3675 */ 3676static int 3677isp_login_device(ispsoftc_t *isp, uint32_t portid, isp_pdb_t *p, uint16_t *ohp) 3678{ 3679 int lim, i, r, logval; 3680 uint16_t handle; 3681 3682 if (IS_24XX(isp)) { 3683 lim = NPH_MAX_24XX; 3684 } else { 3685 lim = NPH_MAX; 3686 } 3687 3688 handle = isp_nxt_handle(isp, *ohp); 3689 for (i = 0; i < lim; i++) { |
|
3001 /* | 3690 /* |
3002 * If we really want to know what kind of port type this is, 3003 * we have to run another CT command. Otherwise, we'll leave 3004 * it as undefined. 3005 * 3006 lcl.port_type = 0; | 3691 * See if we're still logged into something with 3692 * this handle and that something agrees with this 3693 * port id. |
3007 */ | 3694 */ |
3008 if (rs1->snscb_ports[i].control & 0x80) { 3009 lcl.last_fabric_dev = 1; | 3695 r = isp_getpdb(isp, handle, p, 0); 3696 if (r == 0 && p->portid != portid) { 3697 if (IS_24XX(isp)) { 3698 logval = 3699 PLOGX_FLG_CMD_LOGO | 3700 PLOGX_FLG_IMPLICIT; 3701 isp_plogx_24xx(isp, handle, portid, &logval); 3702 } else { 3703 isp_port_logout(isp, handle, portid); 3704 } 3705 } else if (r == 0) { 3706 break; 3707 } 3708 if (FCPARAM(isp)->isp_loopstate != LOOP_SCANNING_FABRIC) { 3709 return (-1); 3710 } 3711 /* 3712 * Now try and log into the device 3713 */ 3714 if (IS_24XX(isp)) { 3715 logval = PLOGX_FLG_CMD_PLOGI; 3716 isp_plogx_24xx(isp, handle, portid, &logval); |
3010 } else { | 3717 } else { |
3011 lcl.last_fabric_dev = 0; | 3718 logval = isp_port_login(isp, handle, portid); |
3012 } | 3719 } |
3013 (void) isp_async(isp, ISPASYNC_FABRIC_DEV, &lcl); | 3720 if (FCPARAM(isp)->isp_loopstate != LOOP_SCANNING_FABRIC) { 3721 return (-1); 3722 } 3723 if (logval == 0) { 3724 *ohp = handle; 3725 break; 3726 } else if ((logval & 0xffff) == MBOX_PORT_ID_USED) { 3727 handle = logval >> 16; 3728 break; 3729 } else if (logval != MBOX_LOOP_ID_USED) { 3730 i = lim; 3731 break; 3732 } else { 3733 *ohp = handle; 3734 handle = isp_nxt_handle(isp, *ohp); 3735 } 3736 } |
3014 | 3737 |
3015 } while ((rs1->snscb_ports[i].control & 0x80) == 0 && i < NGENT-1); | 3738 if (i == lim) { 3739 isp_prt(isp, ISP_LOGINFO, "PLOGI 0x%06x failed", portid); 3740 return (-1); 3741 } |
3016 3017 /* | 3742 3743 /* |
3018 * If we're not at the last entry, our list isn't big enough. | 3744 * If we successfully logged into it, get the PDB for it 3745 * so we can crosscheck that it is still what we think it 3746 * is and that we also have the role it plays |
3019 */ | 3747 */ |
3020 if ((rs1->snscb_ports[i].control & 0x80) == 0) { 3021 isp_prt(isp, ISP_LOGWARN, "fabric too big for scratch area"); | 3748 r = isp_getpdb(isp, handle, p, 0); 3749 if (FCPARAM(isp)->isp_loopstate != LOOP_SCANNING_FABRIC) { 3750 return (-1); |
3022 } | 3751 } |
3752 if (r != 0) { 3753 isp_prt(isp, ISP_LOGERR, "new device 0x%06x@0x%x disappeared", 3754 portid, handle); 3755 return (-1); 3756 } |
|
3023 | 3757 |
3024 FC_SCRATCH_RELEASE(isp); 3025 fcp->isp_loopstate = LOOP_FSCAN_DONE; | 3758 if (p->handle != handle || p->portid != portid) { 3759 isp_prt(isp, ISP_LOGERR, 3760 "new device 0x%06x@0x%x changed (0x%06x@0x%0x)", 3761 portid, handle, p->portid, p->handle); 3762 return (-1); 3763 } |
3026 return (0); 3027} | 3764 return (0); 3765} |
3028#endif | |
3029 | 3766 |
3030static void | 3767static int |
3031isp_register_fc4_type(ispsoftc_t *isp) 3032{ 3033 fcparam *fcp = isp->isp_param; 3034 uint8_t local[SNS_RFT_ID_REQ_SIZE]; 3035 sns_screq_t *reqp = (sns_screq_t *) local; 3036 mbreg_t mbs; 3037 3038 MEMZERO((void *) reqp, SNS_RFT_ID_REQ_SIZE); 3039 reqp->snscb_rblen = SNS_RFT_ID_RESP_SIZE >> 1; 3040 reqp->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + 0x100); 3041 reqp->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + 0x100); 3042 reqp->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + 0x100); 3043 reqp->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + 0x100); 3044 reqp->snscb_sblen = 22; 3045 reqp->snscb_data[0] = SNS_RFT_ID; 3046 reqp->snscb_data[4] = fcp->isp_portid & 0xffff; 3047 reqp->snscb_data[5] = (fcp->isp_portid >> 16) & 0xff; 3048 reqp->snscb_data[6] = (1 << FC4_SCSI); | 3768isp_register_fc4_type(ispsoftc_t *isp) 3769{ 3770 fcparam *fcp = isp->isp_param; 3771 uint8_t local[SNS_RFT_ID_REQ_SIZE]; 3772 sns_screq_t *reqp = (sns_screq_t *) local; 3773 mbreg_t mbs; 3774 3775 MEMZERO((void *) reqp, SNS_RFT_ID_REQ_SIZE); 3776 reqp->snscb_rblen = SNS_RFT_ID_RESP_SIZE >> 1; 3777 reqp->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + 0x100); 3778 reqp->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + 0x100); 3779 reqp->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + 0x100); 3780 reqp->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + 0x100); 3781 reqp->snscb_sblen = 22; 3782 reqp->snscb_data[0] = SNS_RFT_ID; 3783 reqp->snscb_data[4] = fcp->isp_portid & 0xffff; 3784 reqp->snscb_data[5] = (fcp->isp_portid >> 16) & 0xff; 3785 reqp->snscb_data[6] = (1 << FC4_SCSI); |
3049#if 0 3050 reqp->snscb_data[6] |= (1 << FC4_IP); /* ISO/IEC 8802-2 LLC/SNAP */ 3051#endif | |
3052 FC_SCRATCH_ACQUIRE(isp); 3053 isp_put_sns_request(isp, reqp, (sns_screq_t *) fcp->isp_scratch); 3054 MEMZERO(&mbs, sizeof (mbs)); 3055 mbs.param[0] = MBOX_SEND_SNS; 3056 mbs.param[1] = SNS_RFT_ID_REQ_SIZE >> 1; 3057 mbs.param[2] = DMA_WD1(fcp->isp_scdma); 3058 mbs.param[3] = DMA_WD0(fcp->isp_scdma); | 3786 FC_SCRATCH_ACQUIRE(isp); 3787 isp_put_sns_request(isp, reqp, (sns_screq_t *) fcp->isp_scratch); 3788 MEMZERO(&mbs, sizeof (mbs)); 3789 mbs.param[0] = MBOX_SEND_SNS; 3790 mbs.param[1] = SNS_RFT_ID_REQ_SIZE >> 1; 3791 mbs.param[2] = DMA_WD1(fcp->isp_scdma); 3792 mbs.param[3] = DMA_WD0(fcp->isp_scdma); |
3059 /* 3060 * Leave 4 and 5 alone 3061 */ | |
3062 mbs.param[6] = DMA_WD3(fcp->isp_scdma); 3063 mbs.param[7] = DMA_WD2(fcp->isp_scdma); | 3793 mbs.param[6] = DMA_WD3(fcp->isp_scdma); 3794 mbs.param[7] = DMA_WD2(fcp->isp_scdma); |
3795 mbs.logval = MBLOGALL; 3796 mbs.timeout = 1000000; |
|
3064 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_RFT_ID_REQ_SIZE); | 3797 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_RFT_ID_REQ_SIZE); |
3065 isp_mboxcmd(isp, &mbs, MBLOGALL); | 3798 isp_mboxcmd(isp, &mbs); |
3066 FC_SCRATCH_RELEASE(isp); 3067 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { | 3799 FC_SCRATCH_RELEASE(isp); 3800 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { |
3068 isp_prt(isp, ISP_LOGDEBUG0, "Register FC4 types succeeded"); | 3801 return (0); 3802 } else { 3803 return (-1); |
3069 } 3070} 3071 | 3804 } 3805} 3806 |
3807static int 3808isp_register_fc4_type_24xx(ispsoftc_t *isp) 3809{ 3810 mbreg_t mbs; 3811 fcparam *fcp = FCPARAM(isp); 3812 union { 3813 isp_ct_pt_t plocal; 3814 rft_id_t clocal; 3815 uint8_t q[QENTRY_LEN]; 3816 } un; 3817 isp_ct_pt_t *pt; 3818 ct_hdr_t *ct; 3819 rft_id_t *rp; 3820 uint8_t *scp = fcp->isp_scratch; 3821 3822 FC_SCRATCH_ACQUIRE(isp); 3823 /* 3824 * Build a Passthrough IOCB in memory. 3825 */ 3826 MEMZERO(un.q, QENTRY_LEN); 3827 pt = &un.plocal; 3828 pt->ctp_header.rqs_entry_count = 1; 3829 pt->ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU; 3830 pt->ctp_handle = 0xffffffff; 3831 pt->ctp_nphdl = NPH_SNS_ID; 3832 pt->ctp_cmd_cnt = 1; 3833 pt->ctp_time = 1; 3834 pt->ctp_rsp_cnt = 1; 3835 pt->ctp_rsp_bcnt = sizeof (ct_hdr_t); 3836 pt->ctp_cmd_bcnt = sizeof (rft_id_t); 3837 pt->ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma+XTXOFF); 3838 pt->ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma+XTXOFF); 3839 pt->ctp_dataseg[0].ds_count = sizeof (rft_id_t); 3840 pt->ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma+IGPOFF); 3841 pt->ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma+IGPOFF); 3842 pt->ctp_dataseg[1].ds_count = sizeof (ct_hdr_t); 3843 isp_put_ct_pt(isp, pt, (isp_ct_pt_t *) &scp[CTXOFF]); 3844 3845 /* 3846 * Build the CT header and command in memory. 3847 * 3848 * Note that the CT header has to end up as Big Endian format in memory. 3849 */ 3850 MEMZERO(&un.clocal, sizeof (un.clocal)); 3851 ct = &un.clocal.rftid_hdr; 3852 ct->ct_revision = CT_REVISION; 3853 ct->ct_fcs_type = CT_FC_TYPE_FC; 3854 ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS; 3855 ct->ct_cmd_resp = SNS_RFT_ID; 3856 ct->ct_bcnt_resid = (sizeof (rft_id_t) - sizeof (ct_hdr_t)) >> 2; 3857 rp = &un.clocal; 3858 rp->rftid_portid[0] = fcp->isp_portid >> 16; 3859 rp->rftid_portid[1] = fcp->isp_portid >> 8; 3860 rp->rftid_portid[2] = fcp->isp_portid; 3861 rp->rftid_fc4types[FC4_SCSI >> 5] = 1 << (FC4_SCSI & 0x1f); 3862 isp_put_rft_id(isp, rp, (rft_id_t *) &scp[XTXOFF]); 3863 3864 MEMZERO(&scp[ZTXOFF], sizeof (ct_hdr_t)); 3865 3866 MEMZERO(&mbs, sizeof (mbs)); 3867 mbs.param[0] = MBOX_EXEC_COMMAND_IOCB_A64; 3868 mbs.param[1] = QENTRY_LEN; 3869 mbs.param[2] = DMA_WD1(fcp->isp_scdma + CTXOFF); 3870 mbs.param[3] = DMA_WD0(fcp->isp_scdma + CTXOFF); 3871 mbs.param[6] = DMA_WD3(fcp->isp_scdma + CTXOFF); 3872 mbs.param[7] = DMA_WD2(fcp->isp_scdma + CTXOFF); 3873 mbs.logval = MBLOGALL; 3874 MEMORYBARRIER(isp, SYNC_SFORDEV, XTXOFF, 2 * QENTRY_LEN); 3875 isp_mboxcmd(isp, &mbs); 3876 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 3877 FC_SCRATCH_RELEASE(isp); 3878 return (-1); 3879 } 3880 MEMORYBARRIER(isp, SYNC_SFORCPU, ZTXOFF, QENTRY_LEN); 3881 pt = &un.plocal; 3882 isp_get_ct_pt(isp, (isp_ct_pt_t *) &scp[ZTXOFF], pt); 3883 if (isp->isp_dblev & ISP_LOGDEBUG1) { 3884 isp_print_bytes(isp, "IOCB response", QENTRY_LEN, pt); 3885 } 3886 if (pt->ctp_status) { 3887 FC_SCRATCH_RELEASE(isp); 3888 isp_prt(isp, ISP_LOGWARN, "CT Passthrough returned 0x%x", 3889 pt->ctp_status); 3890 return (-1); 3891 } 3892 3893 isp_get_ct_hdr(isp, (ct_hdr_t *) &scp[IGPOFF], ct); 3894 FC_SCRATCH_RELEASE(isp); 3895 3896 if (ct->ct_cmd_resp == LS_RJT) { 3897 isp_prt(isp, ISP_LOGWARN, "Register FC4 Type rejected"); 3898 return (-1); 3899 } else if (ct->ct_cmd_resp == LS_ACC) { 3900 isp_prt(isp, ISP_LOGDEBUG0, "Register FC4 Type accepted"); 3901 return(0); 3902 } else { 3903 isp_prt(isp, ISP_LOGWARN, 3904 "Register FC4 Type: %x", ct->ct_cmd_resp); 3905 return (-1); 3906 } 3907} 3908 3909static uint16_t 3910isp_nxt_handle(ispsoftc_t *isp, uint16_t handle) 3911{ 3912 if (handle == 0xffff) { 3913 if (FCPARAM(isp)->isp_topo == TOPO_F_PORT) { 3914 handle = 0; 3915 } else { 3916 handle = SNS_ID+1; 3917 } 3918 } else { 3919 handle += 1; 3920 if (handle >= FL_ID && handle <= SNS_ID) { 3921 handle = SNS_ID+1; 3922 } else if (IS_24XX(isp)) { 3923 if (handle == 0xffff) { 3924 handle = 0; 3925 } 3926 } else { 3927 if (handle == MAX_FC_TARG) { 3928 handle = 0; 3929 } 3930 } 3931 } 3932 if (handle == FCPARAM(isp)->isp_loopid) { 3933 return (isp_nxt_handle(isp, handle)); 3934 } else { 3935 return (handle); 3936 } 3937} 3938 |
|
3072/* 3073 * Start a command. Locking is assumed done in the caller. 3074 */ 3075 3076int 3077isp_start(XS_T *xs) 3078{ 3079 ispsoftc_t *isp; | 3939/* 3940 * Start a command. Locking is assumed done in the caller. 3941 */ 3942 3943int 3944isp_start(XS_T *xs) 3945{ 3946 ispsoftc_t *isp; |
3080 uint16_t nxti, optr, handle; | 3947 uint32_t nxti, optr, handle, isr; 3948 uint16_t sema, mbox; |
3081 uint8_t local[QENTRY_LEN]; 3082 ispreq_t *reqp, *qep; | 3949 uint8_t local[QENTRY_LEN]; 3950 ispreq_t *reqp, *qep; |
3951 void *cdbp; 3952 uint16_t *tptr; |
|
3083 int target, i; 3084 3085 XS_INITERR(xs); 3086 isp = XS_ISP(xs); 3087 3088 /* 3089 * Check to make sure we're supporting initiator role. 3090 */ --- 23 unchanged lines hidden (view full) --- 3114 isp_prt(isp, ISP_LOGERR, 3115 "unsupported cdb length (%d, CDB[0]=0x%x)", 3116 XS_CDBLEN(xs), XS_CDBP(xs)[0] & 0xff); 3117 XS_SETERR(xs, HBA_BOTCH); 3118 return (CMD_COMPLETE); 3119 } 3120 3121 /* | 3953 int target, i; 3954 3955 XS_INITERR(xs); 3956 isp = XS_ISP(xs); 3957 3958 /* 3959 * Check to make sure we're supporting initiator role. 3960 */ --- 23 unchanged lines hidden (view full) --- 3984 isp_prt(isp, ISP_LOGERR, 3985 "unsupported cdb length (%d, CDB[0]=0x%x)", 3986 XS_CDBLEN(xs), XS_CDBP(xs)[0] & 0xff); 3987 XS_SETERR(xs, HBA_BOTCH); 3988 return (CMD_COMPLETE); 3989 } 3990 3991 /* |
3122 * Check to see whether we have good firmware state still or 3123 * need to refresh our port database for this target. | 3992 * Translate the target to device handle as appropriate, checking 3993 * for correct device state as well. |
3124 */ 3125 target = XS_TGT(xs); 3126 if (IS_FC(isp)) { 3127 fcparam *fcp = isp->isp_param; | 3994 */ 3995 target = XS_TGT(xs); 3996 if (IS_FC(isp)) { 3997 fcparam *fcp = isp->isp_param; |
3128 struct lportdb *lp; 3129#ifdef HANDLE_LOOPSTATE_IN_OUTER_LAYERS | 3998 |
3130 if (fcp->isp_fwstate != FW_READY || 3131 fcp->isp_loopstate != LOOP_READY) { 3132 return (CMD_RQLATER); 3133 } 3134 | 3999 if (fcp->isp_fwstate != FW_READY || 4000 fcp->isp_loopstate != LOOP_READY) { 4001 return (CMD_RQLATER); 4002 } 4003 |
3135 /* 3136 * If we're not on a Fabric, we can't have a target 3137 * above FL_PORT_ID-1. 3138 * 3139 * If we're on a fabric and *not* connected as an F-port, 3140 * we can't have a target less than FC_SNS_ID+1. This 3141 * keeps us from having to sort out the difference between 3142 * local public loop devices and those which we might get 3143 * from a switch's database. 3144 */ 3145 if (fcp->isp_onfabric == 0) { 3146 if (target >= FL_PORT_ID) { 3147 XS_SETERR(xs, HBA_SELTIMEOUT); 3148 return (CMD_COMPLETE); 3149 } 3150 } else { 3151 if (target >= FL_PORT_ID && target <= FC_SNS_ID) { 3152 XS_SETERR(xs, HBA_SELTIMEOUT); 3153 return (CMD_COMPLETE); 3154 } 3155 /* 3156 * We used to exclude having local loop ports 3157 * at the same time that we have fabric ports. 3158 * That is, we used to exclude having ports 3159 * at < FL_PORT_ID if we're FL-port. 3160 * 3161 * That's wrong. The only thing that could be 3162 * dicey is if the switch you're connected to 3163 * has these local loop ports appear on the 3164 * fabric and we somehow attach them twice. 3165 */ 3166 } 3167#else 3168 /* 3169 * Check for f/w being in ready state. If the f/w 3170 * isn't in ready state, then we don't know our 3171 * loop ID and the f/w hasn't completed logging 3172 * into all targets on the loop. If this is the 3173 * case, then bounce the command. We pretend this is 3174 * a SELECTION TIMEOUT error if we've never gone to 3175 * FW_READY state at all- in this case we may not 3176 * be hooked to a loop at all and we shouldn't hang 3177 * the machine for this. Otherwise, defer this command 3178 * until later. 3179 */ 3180 if (fcp->isp_fwstate != FW_READY) { 3181 /* 3182 * Give ourselves at most a 250ms delay. 3183 */ 3184 if (isp_fclink_test(isp, 250000)) { 3185 XS_SETERR(xs, HBA_SELTIMEOUT); 3186 if (fcp->loop_seen_once) { 3187 return (CMD_RQLATER); 3188 } else { 3189 return (CMD_COMPLETE); 3190 } 3191 } 3192 } 3193 3194 /* 3195 * If we're not on a Fabric, we can't have a target 3196 * above FL_PORT_ID-1. 3197 * 3198 * If we're on a fabric and *not* connected as an F-port, 3199 * we can't have a target less than FC_SNS_ID+1. This 3200 * keeps us from having to sort out the difference between 3201 * local public loop devices and those which we might get 3202 * from a switch's database. 3203 */ 3204 if (fcp->isp_onfabric == 0) { 3205 if (target >= FL_PORT_ID) { 3206 XS_SETERR(xs, HBA_SELTIMEOUT); 3207 return (CMD_COMPLETE); 3208 } 3209 } else { 3210 if (target >= FL_PORT_ID && target <= FC_SNS_ID) { 3211 XS_SETERR(xs, HBA_SELTIMEOUT); 3212 return (CMD_COMPLETE); 3213 } 3214 if (fcp->isp_topo != TOPO_F_PORT && 3215 target < FL_PORT_ID) { 3216 XS_SETERR(xs, HBA_SELTIMEOUT); 3217 return (CMD_COMPLETE); 3218 } 3219 } 3220 3221 /* 3222 * If our loop state is such that we haven't yet received 3223 * a "Port Database Changed" notification (after a LIP or 3224 * a Loop Reset or firmware initialization), then defer 3225 * sending commands for a little while, but only if we've 3226 * seen a valid loop at one point (otherwise we can get 3227 * stuck at initialization time). 3228 */ 3229 if (fcp->isp_loopstate < LOOP_PDB_RCVD) { | 4004 if (XS_TGT(xs) >= MAX_FC_TARG) { |
3230 XS_SETERR(xs, HBA_SELTIMEOUT); | 4005 XS_SETERR(xs, HBA_SELTIMEOUT); |
3231 if (fcp->loop_seen_once) { 3232 return (CMD_RQLATER); 3233 } else { 3234 return (CMD_COMPLETE); 3235 } | 4006 return (CMD_COMPLETE); |
3236 } 3237 | 4007 } 4008 |
3238 /* 3239 * If we're in the middle of loop or fabric scanning 3240 * or merging the port databases, retry this command later. 3241 */ 3242 if (fcp->isp_loopstate == LOOP_SCANNING_FABRIC || 3243 fcp->isp_loopstate == LOOP_SCANNING_LOOP || 3244 fcp->isp_loopstate == LOOP_SYNCING_PDB) { 3245 return (CMD_RQLATER); 3246 } 3247 3248 /* 3249 * If our loop state is now such that we've just now 3250 * received a Port Database Change notification, then 3251 * we have to go off and (re)scan the fabric. We back 3252 * out and try again later if this doesn't work. 3253 */ 3254 if (fcp->isp_loopstate == LOOP_PDB_RCVD && fcp->isp_onfabric) { 3255 if (isp_scan_fabric(isp, FC4_SCSI)) { 3256 return (CMD_RQLATER); 3257 } 3258 if (fcp->isp_fwstate != FW_READY || 3259 fcp->isp_loopstate < LOOP_FSCAN_DONE) { 3260 return (CMD_RQLATER); 3261 } 3262 } 3263 3264 /* 3265 * If our loop state is now such that we've just now 3266 * received a Port Database Change notification, then 3267 * we have to go off and (re)synchronize our port 3268 * database. 3269 */ 3270 if (fcp->isp_loopstate < LOOP_READY) { 3271 if (isp_pdb_sync(isp)) { 3272 return (CMD_RQLATER); 3273 } 3274 if (fcp->isp_fwstate != FW_READY || 3275 fcp->isp_loopstate != LOOP_READY) { 3276 return (CMD_RQLATER); 3277 } 3278 } 3279 3280 /* 3281 * XXX: Here's were we would cancel any loop_dead flag 3282 * XXX: also cancel in dead_loop timeout that's running 3283 */ 3284#endif 3285 3286 /* 3287 * Now check whether we should even think about pursuing this. 3288 */ 3289 lp = &fcp->portdb[target]; 3290 if (lp->valid == 0) { | 4009 i = fcp->isp_ini_map[XS_TGT(xs)]; 4010 isp_prt(isp, ISP_LOGDEBUG1, "XS_TGT(xs)=%d- handle value %d", 4011 XS_TGT(xs), i); 4012 if (i < 1 || i >= MAX_FC_TARG) { |
3291 XS_SETERR(xs, HBA_SELTIMEOUT); 3292 return (CMD_COMPLETE); 3293 } | 4013 XS_SETERR(xs, HBA_SELTIMEOUT); 4014 return (CMD_COMPLETE); 4015 } |
3294 if ((lp->roles & (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT)) == 0) { 3295 isp_prt(isp, ISP_LOGDEBUG2, 3296 "Target %d does not have target service", target); 3297 XS_SETERR(xs, HBA_SELTIMEOUT); 3298 return (CMD_COMPLETE); 3299 } 3300 /* 3301 * Now turn target into what the actual Loop ID is. 3302 */ 3303 target = lp->loopid; | 4016 target = fcp->portdb[i - 1].handle; |
3304 } 3305 3306 /* | 4017 } 4018 4019 /* |
3307 * Next check to see if any HBA or Device 3308 * parameters need to be updated. | 4020 * Next check to see if any HBA or Device parameters need to be updated. |
3309 */ 3310 if (isp->isp_update != 0) { 3311 isp_update(isp); 3312 } 3313 | 4021 */ 4022 if (isp->isp_update != 0) { 4023 isp_update(isp); 4024 } 4025 |
4026 start_again: 4027 |
|
3314 if (isp_getrqentry(isp, &nxti, &optr, (void *)&qep)) { 3315 isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow"); 3316 XS_SETERR(xs, HBA_BOTCH); 3317 return (CMD_EAGAIN); 3318 } 3319 3320 /* 3321 * Now see if we need to synchronize the ISP with respect to anything. 3322 * We do dual duty here (cough) for synchronizing for busses other 3323 * than which we got here to send a command to. 3324 */ 3325 reqp = (ispreq_t *) local; 3326 if (isp->isp_sendmarker) { | 4028 if (isp_getrqentry(isp, &nxti, &optr, (void *)&qep)) { 4029 isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow"); 4030 XS_SETERR(xs, HBA_BOTCH); 4031 return (CMD_EAGAIN); 4032 } 4033 4034 /* 4035 * Now see if we need to synchronize the ISP with respect to anything. 4036 * We do dual duty here (cough) for synchronizing for busses other 4037 * than which we got here to send a command to. 4038 */ 4039 reqp = (ispreq_t *) local; 4040 if (isp->isp_sendmarker) { |
3327 uint8_t n = (IS_DUALBUS(isp)? 2: 1); 3328 /* 3329 * Check ports to send markers for... 3330 */ 3331 for (i = 0; i < n; i++) { 3332 if ((isp->isp_sendmarker & (1 << i)) == 0) { 3333 continue; 3334 } 3335 MEMZERO((void *) reqp, QENTRY_LEN); 3336 reqp->req_header.rqs_entry_count = 1; 3337 reqp->req_header.rqs_entry_type = RQSTYPE_MARKER; 3338 reqp->req_modifier = SYNC_ALL; 3339 reqp->req_target = i << 7; /* insert bus number */ 3340 isp_put_request(isp, reqp, qep); | 4041 if (IS_24XX(isp)) { 4042 isp_marker_24xx_t *m = (isp_marker_24xx_t *) qep; 4043 MEMZERO(m, QENTRY_LEN); 4044 m->mrk_header.rqs_entry_count = 1; 4045 m->mrk_header.rqs_entry_type = RQSTYPE_MARKER; 4046 m->mrk_modifier = SYNC_ALL; 4047 isp_put_marker_24xx(isp, m, (isp_marker_24xx_t *)qep); |
3341 ISP_ADD_REQUEST(isp, nxti); | 4048 ISP_ADD_REQUEST(isp, nxti); |
3342 isp->isp_sendmarker &= ~(1 << i); 3343 if (isp_getrqentry(isp, &nxti, &optr, (void *) &qep)) { 3344 isp_prt(isp, ISP_LOGDEBUG0, 3345 "Request Queue Overflow+"); 3346 XS_SETERR(xs, HBA_BOTCH); 3347 return (CMD_EAGAIN); | 4049 isp->isp_sendmarker = 0; 4050 goto start_again; 4051 } else { 4052 for (i = 0; i < (IS_DUALBUS(isp)? 2: 1); i++) { 4053 isp_marker_t *m = (isp_marker_t *) qep; 4054 if ((isp->isp_sendmarker & (1 << i)) == 0) { 4055 continue; 4056 } 4057 MEMZERO(m, QENTRY_LEN); 4058 m->mrk_header.rqs_entry_count = 1; 4059 m->mrk_header.rqs_entry_type = RQSTYPE_MARKER; 4060 m->mrk_target = (i << 7); /* bus # */ 4061 m->mrk_modifier = SYNC_ALL; 4062 isp_put_marker(isp, m, (isp_marker_t *) qep); 4063 ISP_ADD_REQUEST(isp, nxti); 4064 isp->isp_sendmarker &= ~(1 << i); 4065 goto start_again; |
3348 } 3349 } 3350 } 3351 3352 MEMZERO((void *)reqp, QENTRY_LEN); 3353 reqp->req_header.rqs_entry_count = 1; | 4066 } 4067 } 4068 } 4069 4070 MEMZERO((void *)reqp, QENTRY_LEN); 4071 reqp->req_header.rqs_entry_count = 1; |
3354 if (IS_FC(isp)) { | 4072 if (IS_24XX(isp)) { 4073 reqp->req_header.rqs_entry_type = RQSTYPE_T7RQS; 4074 } else if (IS_FC(isp)) { |
3355 reqp->req_header.rqs_entry_type = RQSTYPE_T2RQS; 3356 } else { 3357 if (XS_CDBLEN(xs) > 12) 3358 reqp->req_header.rqs_entry_type = RQSTYPE_CMDONLY; 3359 else 3360 reqp->req_header.rqs_entry_type = RQSTYPE_REQUEST; 3361 } 3362 /* reqp->req_header.rqs_flags = 0; */ 3363 /* reqp->req_header.rqs_seqno = 0; */ | 4075 reqp->req_header.rqs_entry_type = RQSTYPE_T2RQS; 4076 } else { 4077 if (XS_CDBLEN(xs) > 12) 4078 reqp->req_header.rqs_entry_type = RQSTYPE_CMDONLY; 4079 else 4080 reqp->req_header.rqs_entry_type = RQSTYPE_REQUEST; 4081 } 4082 /* reqp->req_header.rqs_flags = 0; */ 4083 /* reqp->req_header.rqs_seqno = 0; */ |
3364 if (IS_FC(isp)) { | 4084 if (IS_24XX(isp)) { 4085 int ttype; 4086 if (XS_TAG_P(xs)) { 4087 ttype = XS_TAG_TYPE(xs); 4088 } else { 4089 if (XS_CDBP(xs)[0] == 0x3) { 4090 ttype = REQFLAG_HTAG; 4091 } else { 4092 ttype = REQFLAG_STAG; 4093 } 4094 } 4095 if (ttype == REQFLAG_OTAG) { 4096 ttype = FCP_CMND_TASK_ATTR_ORDERED; 4097 } else if (ttype == REQFLAG_HTAG) { 4098 ttype = FCP_CMND_TASK_ATTR_HEAD; 4099 } else { 4100 ttype = FCP_CMND_TASK_ATTR_SIMPLE; 4101 } 4102 ((ispreqt7_t *)reqp)->req_task_attribute = ttype; 4103 } else if (IS_FC(isp)) { |
3365 /* 3366 * See comment in isp_intr 3367 */ 3368 /* XS_RESID(xs) = 0; */ 3369 3370 /* 3371 * Fibre Channel always requires some kind of tag. 3372 * The Qlogic drivers seem be happy not to use a tag, --- 14 unchanged lines hidden (view full) --- 3387 } else { 3388 sdparam *sdp = (sdparam *)isp->isp_param; 3389 sdp += XS_CHANNEL(xs); 3390 if ((sdp->isp_devparam[target].actv_flags & DPARM_TQING) && 3391 XS_TAG_P(xs)) { 3392 reqp->req_flags = XS_TAG_TYPE(xs); 3393 } 3394 } | 4104 /* 4105 * See comment in isp_intr 4106 */ 4107 /* XS_RESID(xs) = 0; */ 4108 4109 /* 4110 * Fibre Channel always requires some kind of tag. 4111 * The Qlogic drivers seem be happy not to use a tag, --- 14 unchanged lines hidden (view full) --- 4126 } else { 4127 sdparam *sdp = (sdparam *)isp->isp_param; 4128 sdp += XS_CHANNEL(xs); 4129 if ((sdp->isp_devparam[target].actv_flags & DPARM_TQING) && 4130 XS_TAG_P(xs)) { 4131 reqp->req_flags = XS_TAG_TYPE(xs); 4132 } 4133 } |
4134 cdbp = reqp->req_cdb; 4135 tptr = &reqp->req_time; 4136 |
|
3395 if (IS_SCSI(isp)) { 3396 reqp->req_target = target | (XS_CHANNEL(xs) << 7); 3397 reqp->req_lun_trn = XS_LUN(xs); 3398 reqp->req_cdblen = XS_CDBLEN(xs); | 4137 if (IS_SCSI(isp)) { 4138 reqp->req_target = target | (XS_CHANNEL(xs) << 7); 4139 reqp->req_lun_trn = XS_LUN(xs); 4140 reqp->req_cdblen = XS_CDBLEN(xs); |
3399 } else if (IS_2KLOGIN(isp)) { | 4141 } else if (IS_24XX(isp)) { 4142 fcportdb_t *lp; 4143 4144 i = FCPARAM(isp)->isp_ini_map[XS_TGT(xs)] - 1; 4145 lp = &FCPARAM(isp)->portdb[i]; 4146 4147 ((ispreqt7_t *)reqp)->req_nphdl = target; 4148 ((ispreqt7_t *)reqp)->req_tidlo = lp->portid; 4149 ((ispreqt7_t *)reqp)->req_tidhi = lp->portid >> 16; 4150 if (XS_LUN(xs) > 256) { 4151 ((ispreqt7_t *)reqp)->req_lun[0] = XS_LUN(xs) >> 8; 4152 ((ispreqt7_t *)reqp)->req_lun[0] |= 0x40; 4153 } 4154 ((ispreqt7_t *)reqp)->req_lun[1] = XS_LUN(xs); 4155 cdbp = ((ispreqt7_t *)reqp)->req_cdb; 4156 tptr = &((ispreqt7_t *)reqp)->req_time; 4157 } else if (FCPARAM(isp)->isp_2klogin) { |
3400 ((ispreqt2e_t *)reqp)->req_target = target; 3401 ((ispreqt2e_t *)reqp)->req_scclun = XS_LUN(xs); | 4158 ((ispreqt2e_t *)reqp)->req_target = target; 4159 ((ispreqt2e_t *)reqp)->req_scclun = XS_LUN(xs); |
3402 } else if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) { | 4160 } else if (FCPARAM(isp)->isp_sccfw) { |
3403 ((ispreqt2_t *)reqp)->req_target = target; 3404 ((ispreqt2_t *)reqp)->req_scclun = XS_LUN(xs); 3405 } else { 3406 ((ispreqt2_t *)reqp)->req_target = target; 3407 ((ispreqt2_t *)reqp)->req_lun_trn = XS_LUN(xs); 3408 } | 4161 ((ispreqt2_t *)reqp)->req_target = target; 4162 ((ispreqt2_t *)reqp)->req_scclun = XS_LUN(xs); 4163 } else { 4164 ((ispreqt2_t *)reqp)->req_target = target; 4165 ((ispreqt2_t *)reqp)->req_lun_trn = XS_LUN(xs); 4166 } |
3409 MEMCPY(reqp->req_cdb, XS_CDBP(xs), XS_CDBLEN(xs)); | 4167 MEMCPY(cdbp, XS_CDBP(xs), XS_CDBLEN(xs)); |
3410 | 4168 |
3411 reqp->req_time = XS_TIME(xs) / 1000; 3412 if (reqp->req_time == 0 && XS_TIME(xs)) { 3413 reqp->req_time = 1; | 4169 *tptr = XS_TIME(xs) / 1000; 4170 if (*tptr == 0 && XS_TIME(xs)) { 4171 *tptr = 1; |
3414 } | 4172 } |
4173 if (IS_24XX(isp) && *tptr > 0x1999) { 4174 *tptr = 0x1999; 4175 } |
|
3415 3416 if (isp_save_xs(isp, xs, &handle)) { 3417 isp_prt(isp, ISP_LOGDEBUG0, "out of xflist pointers"); 3418 XS_SETERR(xs, HBA_BOTCH); 3419 return (CMD_EAGAIN); 3420 } | 4176 4177 if (isp_save_xs(isp, xs, &handle)) { 4178 isp_prt(isp, ISP_LOGDEBUG0, "out of xflist pointers"); 4179 XS_SETERR(xs, HBA_BOTCH); 4180 return (CMD_EAGAIN); 4181 } |
4182 /* Whew. Thankfully the same for type 7 requests */ |
|
3421 reqp->req_handle = handle; 3422 3423 /* 3424 * Set up DMA and/or do any bus swizzling of the request entry 3425 * so that the Qlogic F/W understands what is being asked of it. 3426 */ 3427 i = ISP_DMASETUP(isp, xs, reqp, &nxti, optr); 3428 if (i != CMD_QUEUED) { --- 6 unchanged lines hidden (view full) --- 3435 } 3436 XS_SETERR(xs, HBA_NOERROR); 3437 isp_prt(isp, ISP_LOGDEBUG2, 3438 "START cmd for %d.%d.%d cmd 0x%x datalen %ld", 3439 XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), XS_CDBP(xs)[0], 3440 (long) XS_XFRLEN(xs)); 3441 ISP_ADD_REQUEST(isp, nxti); 3442 isp->isp_nactive++; | 4183 reqp->req_handle = handle; 4184 4185 /* 4186 * Set up DMA and/or do any bus swizzling of the request entry 4187 * so that the Qlogic F/W understands what is being asked of it. 4188 */ 4189 i = ISP_DMASETUP(isp, xs, reqp, &nxti, optr); 4190 if (i != CMD_QUEUED) { --- 6 unchanged lines hidden (view full) --- 4197 } 4198 XS_SETERR(xs, HBA_NOERROR); 4199 isp_prt(isp, ISP_LOGDEBUG2, 4200 "START cmd for %d.%d.%d cmd 0x%x datalen %ld", 4201 XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), XS_CDBP(xs)[0], 4202 (long) XS_XFRLEN(xs)); 4203 ISP_ADD_REQUEST(isp, nxti); 4204 isp->isp_nactive++; |
4205 if (IS_23XX(isp) || IS_24XX(isp)) { 4206 if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) { 4207 isp_intr(isp, isr, sema, mbox); 4208 } 4209 } |
|
3443 return (CMD_QUEUED); 3444} 3445 3446/* 3447 * isp control 3448 * Locks (ints blocked) assumed held. 3449 */ 3450 3451int 3452isp_control(ispsoftc_t *isp, ispctl_t ctl, void *arg) 3453{ 3454 XS_T *xs; 3455 mbreg_t mbs; 3456 int bus, tgt; | 4210 return (CMD_QUEUED); 4211} 4212 4213/* 4214 * isp control 4215 * Locks (ints blocked) assumed held. 4216 */ 4217 4218int 4219isp_control(ispsoftc_t *isp, ispctl_t ctl, void *arg) 4220{ 4221 XS_T *xs; 4222 mbreg_t mbs; 4223 int bus, tgt; |
3457 uint16_t handle; | 4224 uint32_t handle; |
3458 3459 MEMZERO(&mbs, sizeof (mbs)); 3460 3461 switch (ctl) { 3462 default: 3463 isp_prt(isp, ISP_LOGERR, "Unknown Control Opcode 0x%x", ctl); 3464 break; 3465 3466 case ISPCTL_RESET_BUS: 3467 /* 3468 * Issue a bus reset. 3469 */ | 4225 4226 MEMZERO(&mbs, sizeof (mbs)); 4227 4228 switch (ctl) { 4229 default: 4230 isp_prt(isp, ISP_LOGERR, "Unknown Control Opcode 0x%x", ctl); 4231 break; 4232 4233 case ISPCTL_RESET_BUS: 4234 /* 4235 * Issue a bus reset. 4236 */ |
3470 mbs.param[0] = MBOX_BUS_RESET; 3471 if (IS_SCSI(isp)) { 3472 mbs.param[1] = 3473 ((sdparam *) isp->isp_param)->isp_bus_reset_delay; | 4237 if (IS_24XX(isp)) { 4238 isp_prt(isp, ISP_LOGWARN, "RESET BUS NOT IMPLETENTED"); 4239 break; 4240 } else if (IS_FC(isp)) { 4241 mbs.param[1] = 10; 4242 bus = 0; 4243 } else { 4244 mbs.param[1] = SDPARAM(isp)->isp_bus_reset_delay; |
3474 if (mbs.param[1] < 2) { 3475 mbs.param[1] = 2; 3476 } 3477 bus = *((int *) arg); 3478 if (IS_DUALBUS(isp)) { 3479 mbs.param[2] = bus; 3480 } | 4245 if (mbs.param[1] < 2) { 4246 mbs.param[1] = 2; 4247 } 4248 bus = *((int *) arg); 4249 if (IS_DUALBUS(isp)) { 4250 mbs.param[2] = bus; 4251 } |
3481 } else { 3482 mbs.param[1] = 10; 3483 bus = 0; | |
3484 } | 4252 } |
4253 mbs.param[0] = MBOX_BUS_RESET; |
|
3485 isp->isp_sendmarker |= (1 << bus); | 4254 isp->isp_sendmarker |= (1 << bus); |
3486 isp_mboxcmd(isp, &mbs, MBLOGALL); | 4255 mbs.logval = MBLOGALL; 4256 isp_mboxcmd(isp, &mbs); |
3487 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 3488 break; 3489 } 3490 isp_prt(isp, ISP_LOGINFO, 3491 "driver initiated bus reset of bus %d", bus); 3492 return (0); 3493 3494 case ISPCTL_RESET_DEV: 3495 tgt = (*((int *) arg)) & 0xffff; | 4257 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 4258 break; 4259 } 4260 isp_prt(isp, ISP_LOGINFO, 4261 "driver initiated bus reset of bus %d", bus); 4262 return (0); 4263 4264 case ISPCTL_RESET_DEV: 4265 tgt = (*((int *) arg)) & 0xffff; |
3496 bus = (*((int *) arg)) >> 16; 3497 mbs.param[0] = MBOX_ABORT_TARGET; 3498 if (IS_SCSI(isp)) { 3499 mbs.param[1] = (tgt << 8) | (bus << 15); 3500 } else { 3501 if (IS_2KLOGIN(isp)) { | 4266 if (IS_24XX(isp)) { 4267 isp_prt(isp, ISP_LOGWARN, "RESET DEV NOT IMPLETENTED"); 4268 break; 4269 } else if (IS_FC(isp)) { 4270 if (FCPARAM(isp)->isp_2klogin) { |
3502 mbs.param[1] = tgt; | 4271 mbs.param[1] = tgt; |
3503 mbs.ibits |= (1 << 10); | 4272 mbs.ibits = (1 << 10); |
3504 } else { 3505 mbs.param[1] = (tgt << 8); 3506 } | 4273 } else { 4274 mbs.param[1] = (tgt << 8); 4275 } |
4276 bus = 0; 4277 } else { 4278 bus = (*((int *) arg)) >> 16; 4279 mbs.param[1] = (bus << 15) | (tgt << 8); |
|
3507 } | 4280 } |
4281 mbs.param[0] = MBOX_ABORT_TARGET; |
|
3508 mbs.param[2] = 3; /* 'delay', in seconds */ | 4282 mbs.param[2] = 3; /* 'delay', in seconds */ |
3509 isp_mboxcmd(isp, &mbs, MBLOGALL); | 4283 mbs.logval = MBLOGALL; 4284 isp_mboxcmd(isp, &mbs); |
3510 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 3511 break; 3512 } 3513 isp_prt(isp, ISP_LOGINFO, 3514 "Target %d on Bus %d Reset Succeeded", tgt, bus); 3515 isp->isp_sendmarker |= (1 << bus); 3516 return (0); 3517 3518 case ISPCTL_ABORT_CMD: 3519 xs = (XS_T *) arg; 3520 tgt = XS_TGT(xs); | 4285 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 4286 break; 4287 } 4288 isp_prt(isp, ISP_LOGINFO, 4289 "Target %d on Bus %d Reset Succeeded", tgt, bus); 4290 isp->isp_sendmarker |= (1 << bus); 4291 return (0); 4292 4293 case ISPCTL_ABORT_CMD: 4294 xs = (XS_T *) arg; 4295 tgt = XS_TGT(xs); |
4296 |
|
3521 handle = isp_find_handle(isp, xs); 3522 if (handle == 0) { 3523 isp_prt(isp, ISP_LOGWARN, 3524 "cannot find handle for command to abort"); 3525 break; 3526 } | 4297 handle = isp_find_handle(isp, xs); 4298 if (handle == 0) { 4299 isp_prt(isp, ISP_LOGWARN, 4300 "cannot find handle for command to abort"); 4301 break; 4302 } |
3527 bus = XS_CHANNEL(xs); 3528 mbs.param[0] = MBOX_ABORT; 3529 if (IS_FC(isp)) { 3530 if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) { 3531 if (IS_2KLOGIN(isp)) { | 4303 if (IS_24XX(isp)) { 4304 isp_prt(isp, ISP_LOGWARN, "ABORT CMD NOT IMPLETENTED"); 4305 break; 4306 } else if (IS_FC(isp)) { 4307 if (FCPARAM(isp)->isp_sccfw) { 4308 if (FCPARAM(isp)->isp_2klogin) { |
3532 mbs.param[1] = tgt; 3533 } else { 3534 mbs.param[1] = tgt << 8; 3535 } 3536 mbs.param[6] = XS_LUN(xs); 3537 } else { 3538 mbs.param[1] = tgt << 8 | XS_LUN(xs); 3539 } 3540 } else { | 4309 mbs.param[1] = tgt; 4310 } else { 4311 mbs.param[1] = tgt << 8; 4312 } 4313 mbs.param[6] = XS_LUN(xs); 4314 } else { 4315 mbs.param[1] = tgt << 8 | XS_LUN(xs); 4316 } 4317 } else { |
3541 mbs.param[1] = 3542 (bus << 15) | (XS_TGT(xs) << 8) | XS_LUN(xs); | 4318 bus = XS_CHANNEL(xs); 4319 mbs.param[1] = (bus << 15) | (tgt << 8) | XS_LUN(xs); |
3543 } | 4320 } |
4321 mbs.param[0] = MBOX_ABORT; |
|
3544 mbs.param[2] = handle; | 4322 mbs.param[2] = handle; |
3545 isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_ERROR); 3546 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { 3547 return (0); | 4323 mbs.logval = MBLOGALL & ~MBOX_COMMAND_ERROR; 4324 isp_mboxcmd(isp, &mbs); 4325 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 4326 break; |
3548 } | 4327 } |
3549 /* 3550 * XXX: Look for command in the REQUEST QUEUE. That is, 3551 * XXX: It hasen't been picked up by firmware yet. 3552 */ 3553 break; | 4328 return (0); |
3554 3555 case ISPCTL_UPDATE_PARAMS: 3556 3557 isp_update(isp); 3558 return (0); 3559 3560 case ISPCTL_FCLINK_TEST: 3561 --- 4 unchanged lines hidden (view full) --- 3566 } 3567 return (isp_fclink_test(isp, usdelay)); 3568 } 3569 break; 3570 3571 case ISPCTL_SCAN_FABRIC: 3572 3573 if (IS_FC(isp)) { | 4329 4330 case ISPCTL_UPDATE_PARAMS: 4331 4332 isp_update(isp); 4333 return (0); 4334 4335 case ISPCTL_FCLINK_TEST: 4336 --- 4 unchanged lines hidden (view full) --- 4341 } 4342 return (isp_fclink_test(isp, usdelay)); 4343 } 4344 break; 4345 4346 case ISPCTL_SCAN_FABRIC: 4347 4348 if (IS_FC(isp)) { |
3574 int ftype = (arg)? *((int *) arg) : FC4_SCSI; 3575 return (isp_scan_fabric(isp, ftype)); | 4349 return (isp_scan_fabric(isp)); |
3576 } 3577 break; 3578 3579 case ISPCTL_SCAN_LOOP: 3580 3581 if (IS_FC(isp)) { 3582 return (isp_scan_loop(isp)); 3583 } 3584 break; 3585 3586 case ISPCTL_PDB_SYNC: 3587 3588 if (IS_FC(isp)) { 3589 return (isp_pdb_sync(isp)); 3590 } 3591 break; 3592 3593 case ISPCTL_SEND_LIP: 3594 | 4350 } 4351 break; 4352 4353 case ISPCTL_SCAN_LOOP: 4354 4355 if (IS_FC(isp)) { 4356 return (isp_scan_loop(isp)); 4357 } 4358 break; 4359 4360 case ISPCTL_PDB_SYNC: 4361 4362 if (IS_FC(isp)) { 4363 return (isp_pdb_sync(isp)); 4364 } 4365 break; 4366 4367 case ISPCTL_SEND_LIP: 4368 |
3595 if (IS_FC(isp)) { | 4369 if (IS_FC(isp) && !IS_24XX(isp)) { |
3596 mbs.param[0] = MBOX_INIT_LIP; | 4370 mbs.param[0] = MBOX_INIT_LIP; |
3597 if (IS_2KLOGIN(isp)) { 3598 mbs.ibits |= (1 << 10); | 4371 if (FCPARAM(isp)->isp_2klogin) { 4372 mbs.ibits = (1 << 10); |
3599 } | 4373 } |
3600 isp_mboxcmd(isp, &mbs, MBLOGALL); | 4374 mbs.logval = MBLOGALL; 4375 isp_mboxcmd(isp, &mbs); |
3601 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { 3602 return (0); 3603 } 3604 } 3605 break; 3606 | 4376 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { 4377 return (0); 4378 } 4379 } 4380 break; 4381 |
3607 case ISPCTL_GET_POSMAP: 3608 3609 if (IS_FC(isp) && arg) { 3610 return (isp_getmap(isp, arg)); 3611 } 3612 break; 3613 3614 | |
3615 case ISPCTL_GET_PDB: 3616 if (IS_FC(isp) && arg) { 3617 int id = *((int *)arg); 3618 isp_pdb_t *pdb = arg; | 4382 case ISPCTL_GET_PDB: 4383 if (IS_FC(isp) && arg) { 4384 int id = *((int *)arg); 4385 isp_pdb_t *pdb = arg; |
3619 return (isp_getpdb(isp, id, pdb)); | 4386 return (isp_getpdb(isp, id, pdb, 1)); |
3620 } 3621 break; 3622 | 4387 } 4388 break; 4389 |
4390 case ISPCTL_GET_PORTNAME: 4391 { 4392 uint64_t *wwnp = arg; 4393 int loopid = *wwnp; 4394 *wwnp = isp_get_portname(isp, loopid, 0); 4395 if (*wwnp == (uint64_t) -1) { 4396 break; 4397 } else { 4398 return (0); 4399 } 4400 } |
|
3623 case ISPCTL_RUN_MBOXCMD: 3624 | 4401 case ISPCTL_RUN_MBOXCMD: 4402 |
3625 isp_mboxcmd(isp, arg, MBLOGALL); | 4403 isp_mboxcmd(isp, arg); |
3626 return(0); 3627 3628#ifdef ISP_TARGET_MODE 3629 case ISPCTL_TOGGLE_TMODE: 3630 { 3631 3632 /* 3633 * We don't check/set against role here- that's the 3634 * responsibility for the outer layer to coordinate. 3635 */ 3636 if (IS_SCSI(isp)) { 3637 int param = *(int *)arg; 3638 mbs.param[0] = MBOX_ENABLE_TARGET_MODE; 3639 mbs.param[1] = param & 0xffff; 3640 mbs.param[2] = param >> 16; | 4404 return(0); 4405 4406#ifdef ISP_TARGET_MODE 4407 case ISPCTL_TOGGLE_TMODE: 4408 { 4409 4410 /* 4411 * We don't check/set against role here- that's the 4412 * responsibility for the outer layer to coordinate. 4413 */ 4414 if (IS_SCSI(isp)) { 4415 int param = *(int *)arg; 4416 mbs.param[0] = MBOX_ENABLE_TARGET_MODE; 4417 mbs.param[1] = param & 0xffff; 4418 mbs.param[2] = param >> 16; |
3641 isp_mboxcmd(isp, &mbs, MBLOGALL); | 4419 mbs.logval = MBLOGALL; 4420 isp_mboxcmd(isp, &mbs); |
3642 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 3643 break; 3644 } 3645 } 3646 return (0); 3647 } 3648#endif 3649 } --- 7 unchanged lines hidden (view full) --- 3657 * and the locking will be held throughout this function. 3658 */ 3659 3660/* 3661 * Limit our stack depth by sticking with the max likely number 3662 * of completions on a request queue at any one time. 3663 */ 3664#ifndef MAX_REQUESTQ_COMPLETIONS | 4421 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 4422 break; 4423 } 4424 } 4425 return (0); 4426 } 4427#endif 4428 } --- 7 unchanged lines hidden (view full) --- 4436 * and the locking will be held throughout this function. 4437 */ 4438 4439/* 4440 * Limit our stack depth by sticking with the max likely number 4441 * of completions on a request queue at any one time. 4442 */ 4443#ifndef MAX_REQUESTQ_COMPLETIONS |
3665#define MAX_REQUESTQ_COMPLETIONS 64 | 4444#define MAX_REQUESTQ_COMPLETIONS 32 |
3666#endif 3667 3668void | 4445#endif 4446 4447void |
3669isp_intr(ispsoftc_t *isp, uint16_t isr, uint16_t sema, uint16_t mbox) | 4448isp_intr(ispsoftc_t *isp, uint32_t isr, uint16_t sema, uint16_t mbox) |
3670{ 3671 XS_T *complist[MAX_REQUESTQ_COMPLETIONS], *xs; | 4449{ 4450 XS_T *complist[MAX_REQUESTQ_COMPLETIONS], *xs; |
3672 uint16_t iptr, optr, junk; | 4451 uint32_t iptr, optr, junk; |
3673 int i, nlooked = 0, ndone = 0; 3674 3675again: | 4452 int i, nlooked = 0, ndone = 0; 4453 4454again: |
4455 optr = isp->isp_residx; |
|
3676 /* 3677 * Is this a mailbox related interrupt? 3678 * The mailbox semaphore will be nonzero if so. 3679 */ 3680 if (sema) { 3681 if (mbox & 0x4000) { 3682 isp->isp_intmboxc++; 3683 if (isp->isp_mboxbsy) { --- 9 unchanged lines hidden (view full) --- 3693 if (isp->isp_mbxwrk0) { 3694 if (isp_mbox_continue(isp) == 0) { 3695 return; 3696 } 3697 } 3698 MBOX_NOTIFY_COMPLETE(isp); 3699 } else { 3700 isp_prt(isp, ISP_LOGWARN, | 4456 /* 4457 * Is this a mailbox related interrupt? 4458 * The mailbox semaphore will be nonzero if so. 4459 */ 4460 if (sema) { 4461 if (mbox & 0x4000) { 4462 isp->isp_intmboxc++; 4463 if (isp->isp_mboxbsy) { --- 9 unchanged lines hidden (view full) --- 4473 if (isp->isp_mbxwrk0) { 4474 if (isp_mbox_continue(isp) == 0) { 4475 return; 4476 } 4477 } 4478 MBOX_NOTIFY_COMPLETE(isp); 4479 } else { 4480 isp_prt(isp, ISP_LOGWARN, |
3701 "Mbox Command Async (0x%x) with no waiters", 3702 mbox); | 4481 "mailbox cmd (0x%x) with no waiters", mbox); |
3703 } 3704 } else if (isp_parse_async(isp, mbox) < 0) { 3705 return; 3706 } 3707 if ((IS_FC(isp) && mbox != ASYNC_RIO_RESP) || 3708 isp->isp_state != ISP_RUNSTATE) { | 4482 } 4483 } else if (isp_parse_async(isp, mbox) < 0) { 4484 return; 4485 } 4486 if ((IS_FC(isp) && mbox != ASYNC_RIO_RESP) || 4487 isp->isp_state != ISP_RUNSTATE) { |
3709 ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT); 3710 ISP_WRITE(isp, BIU_SEMA, 0); | 4488 goto out; |
3711 return; 3712 } 3713 } 3714 3715 /* 3716 * We can't be getting this now. 3717 */ 3718 if (isp->isp_state != ISP_RUNSTATE) { | 4489 return; 4490 } 4491 } 4492 4493 /* 4494 * We can't be getting this now. 4495 */ 4496 if (isp->isp_state != ISP_RUNSTATE) { |
3719 isp_prt(isp, ISP_LOGWARN, | 4497 isp_prt(isp, ISP_LOGINFO, |
3720 "interrupt (ISR=%x SEMA=%x) when not ready", isr, sema); 3721 /* 3722 * Thank you very much! *Burrrp*! 3723 */ | 4498 "interrupt (ISR=%x SEMA=%x) when not ready", isr, sema); 4499 /* 4500 * Thank you very much! *Burrrp*! 4501 */ |
3724 WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, 3725 READ_RESPONSE_QUEUE_IN_POINTER(isp)); | 4502 ISP_WRITE(isp, isp->isp_respoutrp, 4503 ISP_READ(isp, isp->isp_respinrp)); 4504 if (IS_24XX(isp)) { 4505 ISP_DISABLE_INTS(isp); 4506 } 4507 goto out; 4508 } |
3726 | 4509 |
3727 ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT); 3728 ISP_WRITE(isp, BIU_SEMA, 0); 3729 return; | 4510#ifdef ISP_TARGET_MODE 4511 /* 4512 * Check for ATIO Queue entries. 4513 */ 4514 if (isp->isp_rspbsy == 0 && (isp->isp_role & ISP_ROLE_TARGET) && 4515 IS_24XX(isp)) { 4516 iptr = ISP_READ(isp, isp->isp_atioinrp); 4517 optr = ISP_READ(isp, isp->isp_atiooutrp); 4518 4519 isp->isp_rspbsy = 1; 4520 while (optr != iptr) { 4521 uint8_t qe[QENTRY_LEN]; 4522 isphdr_t *hp; 4523 uint32_t oop; 4524 void *addr; 4525 4526 oop = optr; 4527 MEMORYBARRIER(isp, SYNC_ATIOQ, oop, QENTRY_LEN); 4528 addr = ISP_QUEUE_ENTRY(isp->isp_atioq, oop); 4529 isp_get_hdr(isp, addr, (isphdr_t *)qe); 4530 hp = (isphdr_t *)qe; 4531 switch (hp->rqs_entry_type) { 4532 case RQSTYPE_NOTIFY: 4533 case RQSTYPE_ATIO: 4534 (void) isp_target_notify(isp, addr, &oop); 4535 break; 4536 default: 4537 isp_print_qentry(isp, "?ATIOQ entry?", 4538 oop, addr); 4539 break; 4540 } 4541 optr = ISP_NXT_QENTRY(oop, RESULT_QUEUE_LEN(isp)); 4542 ISP_WRITE(isp, isp->isp_atiooutrp, optr); 4543 } 4544 isp->isp_rspbsy = 0; |
3730 } | 4545 } |
4546#endif |
|
3731 3732 /* 3733 * Get the current Response Queue Out Pointer. 3734 * | 4547 4548 /* 4549 * Get the current Response Queue Out Pointer. 4550 * |
3735 * If we're a 2300, we can ask what hardware what it thinks. | 4551 * If we're a 2300 or 2400, we can ask what hardware what it thinks. |
3736 */ | 4552 */ |
3737 if (IS_23XX(isp)) { | 4553 if (IS_23XX(isp) || IS_24XX(isp)) { |
3738 optr = ISP_READ(isp, isp->isp_respoutrp); 3739 /* 3740 * Debug: to be taken out eventually 3741 */ 3742 if (isp->isp_residx != optr) { | 4554 optr = ISP_READ(isp, isp->isp_respoutrp); 4555 /* 4556 * Debug: to be taken out eventually 4557 */ 4558 if (isp->isp_residx != optr) { |
3743 isp_prt(isp, ISP_LOGWARN, "optr %x soft optr %x", | 4559 isp_prt(isp, ISP_LOGINFO, 4560 "isp_intr: hard optr=%x, soft optr %x", |
3744 optr, isp->isp_residx); | 4561 optr, isp->isp_residx); |
4562 isp->isp_residx = optr; |
|
3745 } 3746 } else { 3747 optr = isp->isp_residx; 3748 } 3749 3750 /* 3751 * You *must* read the Response Queue In Pointer 3752 * prior to clearing the RISC interrupt. 3753 * 3754 * Debounce the 2300 if revision less than 2. 3755 */ 3756 if (IS_2100(isp) || (IS_2300(isp) && isp->isp_revision < 2)) { 3757 i = 0; 3758 do { | 4563 } 4564 } else { 4565 optr = isp->isp_residx; 4566 } 4567 4568 /* 4569 * You *must* read the Response Queue In Pointer 4570 * prior to clearing the RISC interrupt. 4571 * 4572 * Debounce the 2300 if revision less than 2. 4573 */ 4574 if (IS_2100(isp) || (IS_2300(isp) && isp->isp_revision < 2)) { 4575 i = 0; 4576 do { |
3759 iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp); 3760 junk = READ_RESPONSE_QUEUE_IN_POINTER(isp); | 4577 iptr = ISP_READ(isp, isp->isp_respinrp); 4578 junk = ISP_READ(isp, isp->isp_respinrp); |
3761 } while (junk != iptr && ++i < 1000); 3762 3763 if (iptr != junk) { | 4579 } while (junk != iptr && ++i < 1000); 4580 4581 if (iptr != junk) { |
3764 ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT); | |
3765 isp_prt(isp, ISP_LOGWARN, 3766 "Response Queue Out Pointer Unstable (%x, %x)", 3767 iptr, junk); | 4582 isp_prt(isp, ISP_LOGWARN, 4583 "Response Queue Out Pointer Unstable (%x, %x)", 4584 iptr, junk); |
3768 return; | 4585 goto out; |
3769 } 3770 } else { | 4586 } 4587 } else { |
3771 iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp); | 4588 iptr = ISP_READ(isp, isp->isp_respinrp); |
3772 } 3773 isp->isp_resodx = iptr; 3774 3775 3776 if (optr == iptr && sema == 0) { 3777 /* 3778 * There are a lot of these- reasons unknown- mostly on 3779 * faster Alpha machines. 3780 * 3781 * I tried delaying after writing HCCR_CMD_CLEAR_RISC_INT to 3782 * make sure the old interrupt went away (to avoid 'ringing' 3783 * effects), but that didn't stop this from occurring. 3784 */ | 4589 } 4590 isp->isp_resodx = iptr; 4591 4592 4593 if (optr == iptr && sema == 0) { 4594 /* 4595 * There are a lot of these- reasons unknown- mostly on 4596 * faster Alpha machines. 4597 * 4598 * I tried delaying after writing HCCR_CMD_CLEAR_RISC_INT to 4599 * make sure the old interrupt went away (to avoid 'ringing' 4600 * effects), but that didn't stop this from occurring. 4601 */ |
3785 if (IS_23XX(isp)) { | 4602 if (IS_24XX(isp)) { 4603 junk = 0; 4604 } else if (IS_23XX(isp)) { |
3786 USEC_DELAY(100); | 4605 USEC_DELAY(100); |
3787 iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp); | 4606 iptr = ISP_READ(isp, isp->isp_respinrp); |
3788 junk = ISP_READ(isp, BIU_R2HSTSLO); 3789 } else { 3790 junk = ISP_READ(isp, BIU_ISR); 3791 } 3792 if (optr == iptr) { | 4607 junk = ISP_READ(isp, BIU_R2HSTSLO); 4608 } else { 4609 junk = ISP_READ(isp, BIU_ISR); 4610 } 4611 if (optr == iptr) { |
3793 if (IS_23XX(isp)) { | 4612 if (IS_23XX(isp) || IS_24XX(isp)) { |
3794 ; 3795 } else { 3796 sema = ISP_READ(isp, BIU_SEMA); 3797 mbox = ISP_READ(isp, OUTMAILBOX0); 3798 if ((sema & 0x3) && (mbox & 0x8000)) { 3799 goto again; 3800 } 3801 } 3802 isp->isp_intbogus++; 3803 isp_prt(isp, ISP_LOGDEBUG1, 3804 "bogus intr- isr %x (%x) iptr %x optr %x", 3805 isr, junk, iptr, optr); 3806 } 3807 } 3808 isp->isp_resodx = iptr; | 4613 ; 4614 } else { 4615 sema = ISP_READ(isp, BIU_SEMA); 4616 mbox = ISP_READ(isp, OUTMAILBOX0); 4617 if ((sema & 0x3) && (mbox & 0x8000)) { 4618 goto again; 4619 } 4620 } 4621 isp->isp_intbogus++; 4622 isp_prt(isp, ISP_LOGDEBUG1, 4623 "bogus intr- isr %x (%x) iptr %x optr %x", 4624 isr, junk, iptr, optr); 4625 } 4626 } 4627 isp->isp_resodx = iptr; |
3809 ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT); 3810 ISP_WRITE(isp, BIU_SEMA, 0); | |
3811 | 4628 |
4629 |
|
3812 if (isp->isp_rspbsy) { | 4630 if (isp->isp_rspbsy) { |
3813 return; | 4631 goto out; |
3814 } 3815 isp->isp_rspbsy = 1; | 4632 } 4633 isp->isp_rspbsy = 1; |
3816 | |
3817 while (optr != iptr) { | 4634 while (optr != iptr) { |
3818 ispstatusreq_t local, *sp = &local; | 4635 uint8_t qe[QENTRY_LEN]; 4636 ispstatusreq_t *sp = (ispstatusreq_t *) qe; |
3819 isphdr_t *hp; | 4637 isphdr_t *hp; |
3820 int type; | 4638 int buddaboom, etype, scsi_status, completion_status; 4639 int req_status_flags, req_state_flags; 4640 long resid; |
3821 uint16_t oop; | 4641 uint16_t oop; |
3822 int buddaboom = 0; | |
3823 3824 hp = (isphdr_t *) ISP_QUEUE_ENTRY(isp->isp_result, optr); 3825 oop = optr; 3826 optr = ISP_NXT_QENTRY(optr, RESULT_QUEUE_LEN(isp)); 3827 nlooked++; 3828 read_again: | 4642 4643 hp = (isphdr_t *) ISP_QUEUE_ENTRY(isp->isp_result, optr); 4644 oop = optr; 4645 optr = ISP_NXT_QENTRY(optr, RESULT_QUEUE_LEN(isp)); 4646 nlooked++; 4647 read_again: |
4648 buddaboom = req_status_flags = req_state_flags = 0; 4649 resid = 0L; 4650 |
|
3829 /* 3830 * Synchronize our view of this response queue entry. 3831 */ 3832 MEMORYBARRIER(isp, SYNC_RESULT, oop, QENTRY_LEN); | 4651 /* 4652 * Synchronize our view of this response queue entry. 4653 */ 4654 MEMORYBARRIER(isp, SYNC_RESULT, oop, QENTRY_LEN); |
4655 isp_get_hdr(isp, hp, &sp->req_header); 4656 etype = sp->req_header.rqs_entry_type; |
|
3833 | 4657 |
3834 type = isp_get_response_type(isp, hp); 3835 3836 if (type == RQSTYPE_RESPONSE) { | 4658 if (IS_24XX(isp) && etype == RQSTYPE_T7RQS) { 4659 isp24xx_statusreq_t *sp2 = (isp24xx_statusreq_t *)qe; 4660 isp_get_24xx_response(isp, 4661 (isp24xx_statusreq_t *)hp, sp2); 4662 if (isp->isp_dblev & ISP_LOGDEBUG1) { 4663 isp_print_bytes(isp, 4664 "Response Queue Entry", QENTRY_LEN, sp2); 4665 } 4666 scsi_status = sp2->req_scsi_status; 4667 completion_status = sp2->req_completion_status; 4668 req_state_flags = 0; 4669 resid = sp2->req_resid; 4670 } else if (etype == RQSTYPE_RESPONSE) { |
3837 isp_get_response(isp, (ispstatusreq_t *) hp, sp); | 4671 isp_get_response(isp, (ispstatusreq_t *) hp, sp); |
3838 } else if (type == RQSTYPE_RIO2) { 3839 isp_rio2_t rio; 3840 isp_get_rio2(isp, (isp_rio2_t *) hp, &rio); 3841 for (i = 0; i < rio.req_header.rqs_seqno; i++) { 3842 isp_fastpost_complete(isp, rio.req_handles[i]); | 4672 if (isp->isp_dblev & ISP_LOGDEBUG1) { 4673 isp_print_bytes(isp, 4674 "Response Queue Entry", QENTRY_LEN, sp); |
3843 } | 4675 } |
3844 if (isp->isp_fpcchiwater < rio.req_header.rqs_seqno) 3845 isp->isp_fpcchiwater = rio.req_header.rqs_seqno; | 4676 scsi_status = sp->req_scsi_status; 4677 completion_status = sp->req_completion_status; 4678 req_status_flags = sp->req_status_flags; 4679 req_state_flags = sp->req_state_flags; 4680 resid = sp->req_resid; 4681 } else if (etype == RQSTYPE_RIO2) { 4682 isp_rio2_t *rio = (isp_rio2_t *)qe; 4683 isp_get_rio2(isp, (isp_rio2_t *) hp, rio); 4684 if (isp->isp_dblev & ISP_LOGDEBUG1) { 4685 isp_print_bytes(isp, 4686 "Response Queue Entry", QENTRY_LEN, rio); 4687 } 4688 for (i = 0; i < rio->req_header.rqs_seqno; i++) { 4689 isp_fastpost_complete(isp, rio->req_handles[i]); 4690 } 4691 if (isp->isp_fpcchiwater < rio->req_header.rqs_seqno) { 4692 isp->isp_fpcchiwater = 4693 rio->req_header.rqs_seqno; 4694 } |
3846 MEMZERO(hp, QENTRY_LEN); /* PERF */ 3847 continue; 3848 } else { 3849 /* 3850 * Somebody reachable via isp_handle_other_response 3851 * may have updated the response queue pointers for 3852 * us, so we reload our goal index. 3853 */ | 4695 MEMZERO(hp, QENTRY_LEN); /* PERF */ 4696 continue; 4697 } else { 4698 /* 4699 * Somebody reachable via isp_handle_other_response 4700 * may have updated the response queue pointers for 4701 * us, so we reload our goal index. 4702 */ |
3854 int i = isp_handle_other_response(isp, type, hp, &optr); 3855 if (i < 0) { | 4703 int r; 4704 r = isp_handle_other_response(isp, etype, hp, &optr); 4705 if (r < 0) { |
3856 goto read_again; | 4706 goto read_again; |
3857 } else if (i > 0) { | 4707 } 4708 if (r > 0) { |
3858 iptr = isp->isp_resodx; 3859 MEMZERO(hp, QENTRY_LEN); /* PERF */ 3860 continue; 3861 } 3862 3863 /* 3864 * After this point, we'll just look at the header as 3865 * we don't know how to deal with the rest of the 3866 * response. 3867 */ | 4709 iptr = isp->isp_resodx; 4710 MEMZERO(hp, QENTRY_LEN); /* PERF */ 4711 continue; 4712 } 4713 4714 /* 4715 * After this point, we'll just look at the header as 4716 * we don't know how to deal with the rest of the 4717 * response. 4718 */ |
3868 isp_get_response(isp, (ispstatusreq_t *) hp, sp); | |
3869 3870 /* 3871 * It really has to be a bounced request just copied 3872 * from the request queue to the response queue. If 3873 * not, something bad has happened. 3874 */ | 4719 4720 /* 4721 * It really has to be a bounced request just copied 4722 * from the request queue to the response queue. If 4723 * not, something bad has happened. 4724 */ |
3875 if (sp->req_header.rqs_entry_type != RQSTYPE_REQUEST) { | 4725 if (etype != RQSTYPE_REQUEST) { |
3876 isp_prt(isp, ISP_LOGERR, notresp, | 4726 isp_prt(isp, ISP_LOGERR, notresp, |
3877 sp->req_header.rqs_entry_type, oop, optr, 3878 nlooked); 3879 if (isp->isp_dblev & ISP_LOGDEBUG0) { 3880 isp_print_bytes(isp, "Queue Entry", 3881 QENTRY_LEN, sp); 3882 } | 4727 etype, oop, optr, nlooked); 4728 isp_print_bytes(isp, 4729 "Reqeonse Queue Entry", QENTRY_LEN, sp); |
3883 MEMZERO(hp, QENTRY_LEN); /* PERF */ 3884 continue; 3885 } 3886 buddaboom = 1; | 4730 MEMZERO(hp, QENTRY_LEN); /* PERF */ 4731 continue; 4732 } 4733 buddaboom = 1; |
4734 scsi_status = sp->req_scsi_status; 4735 completion_status = sp->req_completion_status; 4736 req_status_flags = sp->req_status_flags; 4737 req_state_flags = sp->req_state_flags; 4738 resid = sp->req_resid; |
|
3887 } 3888 | 4739 } 4740 |
3889 if (sp->req_header.rqs_flags & 0xf) { 3890#define _RQS_OFLAGS \ 3891 ~(RQSFLAG_CONTINUATION|RQSFLAG_FULL|RQSFLAG_BADHEADER|RQSFLAG_BADPACKET) | 4741 if (sp->req_header.rqs_flags & RQSFLAG_MASK) { |
3892 if (sp->req_header.rqs_flags & RQSFLAG_CONTINUATION) { 3893 isp_prt(isp, ISP_LOGWARN, 3894 "continuation segment"); | 4742 if (sp->req_header.rqs_flags & RQSFLAG_CONTINUATION) { 4743 isp_prt(isp, ISP_LOGWARN, 4744 "continuation segment"); |
3895 WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr); | 4745 ISP_WRITE(isp, isp->isp_respoutrp, optr); |
3896 continue; 3897 } 3898 if (sp->req_header.rqs_flags & RQSFLAG_FULL) { 3899 isp_prt(isp, ISP_LOGDEBUG1, 3900 "internal queues full"); 3901 /* 3902 * We'll synthesize a QUEUE FULL message below. 3903 */ 3904 } 3905 if (sp->req_header.rqs_flags & RQSFLAG_BADHEADER) { | 4746 continue; 4747 } 4748 if (sp->req_header.rqs_flags & RQSFLAG_FULL) { 4749 isp_prt(isp, ISP_LOGDEBUG1, 4750 "internal queues full"); 4751 /* 4752 * We'll synthesize a QUEUE FULL message below. 4753 */ 4754 } 4755 if (sp->req_header.rqs_flags & RQSFLAG_BADHEADER) { |
3906 isp_prt(isp, ISP_LOGERR, "bad header flag"); | 4756 isp_print_bytes(isp, "bad header flag", 4757 QENTRY_LEN, sp); |
3907 buddaboom++; 3908 } 3909 if (sp->req_header.rqs_flags & RQSFLAG_BADPACKET) { | 4758 buddaboom++; 4759 } 4760 if (sp->req_header.rqs_flags & RQSFLAG_BADPACKET) { |
3910 isp_prt(isp, ISP_LOGERR, "bad request packet"); | 4761 isp_print_bytes(isp, "bad request packet", 4762 QENTRY_LEN, sp); |
3911 buddaboom++; 3912 } | 4763 buddaboom++; 4764 } |
3913 if (sp->req_header.rqs_flags & _RQS_OFLAGS) { 3914 isp_prt(isp, ISP_LOGERR, 3915 "unknown flags (0x%x) in response", 3916 sp->req_header.rqs_flags); 3917 buddaboom++; 3918 } 3919#undef _RQS_OFLAGS | |
3920 } | 4765 } |
4766 |
|
3921 if (sp->req_handle > isp->isp_maxcmds || sp->req_handle < 1) { | 4767 if (sp->req_handle > isp->isp_maxcmds || sp->req_handle < 1) { |
3922 MEMZERO(hp, QENTRY_LEN); /* PERF */ | |
3923 isp_prt(isp, ISP_LOGERR, | 4768 isp_prt(isp, ISP_LOGERR, |
3924 "bad request handle %d (type 0x%x, flags 0x%x)", 3925 sp->req_handle, sp->req_header.rqs_entry_type, 3926 sp->req_header.rqs_flags); 3927 WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr); | 4769 "bad request handle %d (type 0x%x)", 4770 sp->req_handle, etype); 4771 MEMZERO(hp, QENTRY_LEN); /* PERF */ 4772 ISP_WRITE(isp, isp->isp_respoutrp, optr); |
3928 continue; 3929 } 3930 xs = isp_find_xs(isp, sp->req_handle); 3931 if (xs == NULL) { | 4773 continue; 4774 } 4775 xs = isp_find_xs(isp, sp->req_handle); 4776 if (xs == NULL) { |
3932 uint8_t ts = sp->req_completion_status & 0xff; 3933 MEMZERO(hp, QENTRY_LEN); /* PERF */ | 4777 uint8_t ts = completion_status & 0xff; |
3934 /* 3935 * Only whine if this isn't the expected fallout of 3936 * aborting the command. 3937 */ | 4778 /* 4779 * Only whine if this isn't the expected fallout of 4780 * aborting the command. 4781 */ |
3938 if (sp->req_header.rqs_entry_type != RQSTYPE_RESPONSE) { | 4782 if (etype != RQSTYPE_RESPONSE) { |
3939 isp_prt(isp, ISP_LOGERR, 3940 "cannot find handle 0x%x (type 0x%x)", | 4783 isp_prt(isp, ISP_LOGERR, 4784 "cannot find handle 0x%x (type 0x%x)", |
3941 sp->req_handle, 3942 sp->req_header.rqs_entry_type); | 4785 sp->req_handle, etype); |
3943 } else if (ts != RQCS_ABORTED) { 3944 isp_prt(isp, ISP_LOGERR, 3945 "cannot find handle 0x%x (status 0x%x)", 3946 sp->req_handle, ts); 3947 } | 4786 } else if (ts != RQCS_ABORTED) { 4787 isp_prt(isp, ISP_LOGERR, 4788 "cannot find handle 0x%x (status 0x%x)", 4789 sp->req_handle, ts); 4790 } |
3948 WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr); | 4791 MEMZERO(hp, QENTRY_LEN); /* PERF */ 4792 ISP_WRITE(isp, isp->isp_respoutrp, optr); |
3949 continue; 3950 } 3951 isp_destroy_handle(isp, sp->req_handle); | 4793 continue; 4794 } 4795 isp_destroy_handle(isp, sp->req_handle); |
3952 if (sp->req_status_flags & RQSTF_BUS_RESET) { | 4796 if (req_status_flags & RQSTF_BUS_RESET) { |
3953 XS_SETERR(xs, HBA_BUSRESET); 3954 isp->isp_sendmarker |= (1 << XS_CHANNEL(xs)); 3955 } 3956 if (buddaboom) { 3957 XS_SETERR(xs, HBA_BOTCH); 3958 } 3959 | 4797 XS_SETERR(xs, HBA_BUSRESET); 4798 isp->isp_sendmarker |= (1 << XS_CHANNEL(xs)); 4799 } 4800 if (buddaboom) { 4801 XS_SETERR(xs, HBA_BOTCH); 4802 } 4803 |
3960 if (IS_FC(isp) && (sp->req_scsi_status & RQCS_SV)) { | 4804 if (IS_FC(isp) && (scsi_status & RQCS_SV) != 0) { |
3961 /* 3962 * Fibre Channel F/W doesn't say we got status 3963 * if there's Sense Data instead. I guess they 3964 * think it goes w/o saying. 3965 */ | 4805 /* 4806 * Fibre Channel F/W doesn't say we got status 4807 * if there's Sense Data instead. I guess they 4808 * think it goes w/o saying. 4809 */ |
3966 sp->req_state_flags |= RQSF_GOT_STATUS; | 4810 req_state_flags |= RQSF_GOT_STATUS; |
3967 } | 4811 } |
3968 if (sp->req_state_flags & RQSF_GOT_STATUS) { 3969 *XS_STSP(xs) = sp->req_scsi_status & 0xff; | 4812 if (req_state_flags & RQSF_GOT_STATUS) { 4813 *XS_STSP(xs) = scsi_status & 0xff; |
3970 } 3971 | 4814 } 4815 |
3972 switch (sp->req_header.rqs_entry_type) { | 4816 switch (etype) { |
3973 case RQSTYPE_RESPONSE: | 4817 case RQSTYPE_RESPONSE: |
4818 /* XXX won't work for 24xx */ |
|
3974 XS_SET_STATE_STAT(isp, xs, sp); | 4819 XS_SET_STATE_STAT(isp, xs, sp); |
3975 isp_parse_status(isp, sp, xs); | 4820 if (IS_24XX(isp)) { 4821 isp_parse_status_24xx(isp, 4822 (isp24xx_statusreq_t *)sp, xs, &resid); 4823 } else { 4824 isp_parse_status(isp, (void *)sp, xs, &resid); 4825 } |
3976 if ((XS_NOERR(xs) || XS_ERR(xs) == HBA_NOERROR) && 3977 (*XS_STSP(xs) == SCSI_BUSY)) { 3978 XS_SETERR(xs, HBA_TGTBSY); 3979 } 3980 if (IS_SCSI(isp)) { | 4826 if ((XS_NOERR(xs) || XS_ERR(xs) == HBA_NOERROR) && 4827 (*XS_STSP(xs) == SCSI_BUSY)) { 4828 XS_SETERR(xs, HBA_TGTBSY); 4829 } 4830 if (IS_SCSI(isp)) { |
3981 XS_RESID(xs) = sp->req_resid; 3982 if ((sp->req_state_flags & RQSF_GOT_STATUS) && | 4831 XS_RESID(xs) = resid; 4832 if ((req_state_flags & RQSF_GOT_STATUS) && |
3983 (*XS_STSP(xs) == SCSI_CHECK) && | 4833 (*XS_STSP(xs) == SCSI_CHECK) && |
3984 (sp->req_state_flags & RQSF_GOT_SENSE)) { | 4834 (req_state_flags & RQSF_GOT_SENSE)) { |
3985 XS_SAVE_SENSE(xs, sp); 3986 } 3987 /* 3988 * A new synchronous rate was negotiated for 3989 * this target. Mark state such that we'll go 3990 * look up that which has changed later. 3991 */ | 4835 XS_SAVE_SENSE(xs, sp); 4836 } 4837 /* 4838 * A new synchronous rate was negotiated for 4839 * this target. Mark state such that we'll go 4840 * look up that which has changed later. 4841 */ |
3992 if (sp->req_status_flags & RQSTF_NEGOTIATION) { | 4842 if (req_status_flags & RQSTF_NEGOTIATION) { |
3993 int t = XS_TGT(xs); 3994 sdparam *sdp = isp->isp_param; 3995 sdp += XS_CHANNEL(xs); 3996 sdp->isp_devparam[t].dev_refresh = 1; 3997 isp->isp_update |= 3998 (1 << XS_CHANNEL(xs)); 3999 } 4000 } else { | 4843 int t = XS_TGT(xs); 4844 sdparam *sdp = isp->isp_param; 4845 sdp += XS_CHANNEL(xs); 4846 sdp->isp_devparam[t].dev_refresh = 1; 4847 isp->isp_update |= 4848 (1 << XS_CHANNEL(xs)); 4849 } 4850 } else { |
4001 if (sp->req_status_flags & RQSF_XFER_COMPLETE) { | 4851 if (req_status_flags & RQSF_XFER_COMPLETE) { |
4002 XS_RESID(xs) = 0; | 4852 XS_RESID(xs) = 0; |
4003 } else if (sp->req_scsi_status & RQCS_RESID) { 4004 XS_RESID(xs) = sp->req_resid; | 4853 } else if (scsi_status & RQCS_RESID) { 4854 XS_RESID(xs) = resid; |
4005 } else { 4006 XS_RESID(xs) = 0; 4007 } | 4855 } else { 4856 XS_RESID(xs) = 0; 4857 } |
4008 if ((sp->req_state_flags & RQSF_GOT_STATUS) && | 4858 if ((req_state_flags & RQSF_GOT_STATUS) && |
4009 (*XS_STSP(xs) == SCSI_CHECK) && | 4859 (*XS_STSP(xs) == SCSI_CHECK) && |
4010 (sp->req_scsi_status & RQCS_SV)) { | 4860 (scsi_status & RQCS_SV)) { |
4011 XS_SAVE_SENSE(xs, sp); 4012 /* solely for the benefit of debug */ | 4861 XS_SAVE_SENSE(xs, sp); 4862 /* solely for the benefit of debug */ |
4013 sp->req_state_flags |= RQSF_GOT_SENSE; | 4863 req_state_flags |= RQSF_GOT_SENSE; |
4014 } 4015 } 4016 isp_prt(isp, ISP_LOGDEBUG2, 4017 "asked for %ld got raw resid %ld settled for %ld", | 4864 } 4865 } 4866 isp_prt(isp, ISP_LOGDEBUG2, 4867 "asked for %ld got raw resid %ld settled for %ld", |
4018 (long) XS_XFRLEN(xs), (long) sp->req_resid, 4019 (long) XS_RESID(xs)); | 4868 (long) XS_XFRLEN(xs), resid, (long) XS_RESID(xs)); |
4020 break; 4021 case RQSTYPE_REQUEST: | 4869 break; 4870 case RQSTYPE_REQUEST: |
4871 case RQSTYPE_A64: 4872 case RQSTYPE_T2RQS: 4873 case RQSTYPE_T3RQS: 4874 case RQSTYPE_T7RQS: |
|
4022 if (sp->req_header.rqs_flags & RQSFLAG_FULL) { 4023 /* 4024 * Force Queue Full status. 4025 */ 4026 *XS_STSP(xs) = SCSI_QFULL; 4027 XS_SETERR(xs, HBA_NOERROR); 4028 } else if (XS_NOERR(xs)) { 4029 /* 4030 * ???? 4031 */ | 4875 if (sp->req_header.rqs_flags & RQSFLAG_FULL) { 4876 /* 4877 * Force Queue Full status. 4878 */ 4879 *XS_STSP(xs) = SCSI_QFULL; 4880 XS_SETERR(xs, HBA_NOERROR); 4881 } else if (XS_NOERR(xs)) { 4882 /* 4883 * ???? 4884 */ |
4885 XS_SETERR(xs, HBA_BOTCH); |
|
4032 isp_prt(isp, ISP_LOGDEBUG0, 4033 "Request Queue Entry bounced back"); | 4886 isp_prt(isp, ISP_LOGDEBUG0, 4887 "Request Queue Entry bounced back"); |
4034 XS_SETERR(xs, HBA_BOTCH); | 4888 if ((isp->isp_dblev & ISP_LOGDEBUG1) == 0) { 4889 isp_print_bytes(isp, "Bounced Request", 4890 QENTRY_LEN, qe); 4891 } |
4035 } 4036 XS_RESID(xs) = XS_XFRLEN(xs); 4037 break; 4038 default: | 4892 } 4893 XS_RESID(xs) = XS_XFRLEN(xs); 4894 break; 4895 default: |
4039 isp_prt(isp, ISP_LOGWARN, 4040 "unhandled response queue type 0x%x", 4041 sp->req_header.rqs_entry_type); | 4896 isp_print_bytes(isp, "Unhandled Response Type", 4897 QENTRY_LEN, qe); |
4042 if (XS_NOERR(xs)) { 4043 XS_SETERR(xs, HBA_BOTCH); 4044 } 4045 break; 4046 } 4047 4048 /* 4049 * Free any DMA resources. As a side effect, this may 4050 * also do any cache flushing necessary for data coherence. */ 4051 if (XS_XFRLEN(xs)) { 4052 ISP_DMAFREE(isp, xs, sp->req_handle); 4053 } 4054 4055 if (((isp->isp_dblev & (ISP_LOGDEBUG2|ISP_LOGDEBUG3))) || 4056 ((isp->isp_dblev & ISP_LOGDEBUG1) && ((!XS_NOERR(xs)) || 4057 (*XS_STSP(xs) != SCSI_GOOD)))) { 4058 char skey; | 4898 if (XS_NOERR(xs)) { 4899 XS_SETERR(xs, HBA_BOTCH); 4900 } 4901 break; 4902 } 4903 4904 /* 4905 * Free any DMA resources. As a side effect, this may 4906 * also do any cache flushing necessary for data coherence. */ 4907 if (XS_XFRLEN(xs)) { 4908 ISP_DMAFREE(isp, xs, sp->req_handle); 4909 } 4910 4911 if (((isp->isp_dblev & (ISP_LOGDEBUG2|ISP_LOGDEBUG3))) || 4912 ((isp->isp_dblev & ISP_LOGDEBUG1) && ((!XS_NOERR(xs)) || 4913 (*XS_STSP(xs) != SCSI_GOOD)))) { 4914 char skey; |
4059 if (sp->req_state_flags & RQSF_GOT_SENSE) { | 4915 if (req_state_flags & RQSF_GOT_SENSE) { |
4060 skey = XS_SNSKEY(xs) & 0xf; 4061 if (skey < 10) 4062 skey += '0'; 4063 else 4064 skey += 'a' - 10; 4065 } else if (*XS_STSP(xs) == SCSI_CHECK) { 4066 skey = '?'; 4067 } else { --- 14 unchanged lines hidden (view full) --- 4082 } 4083 4084 /* 4085 * If we looked at any commands, then it's valid to find out 4086 * what the outpointer is. It also is a trigger to update the 4087 * ISP's notion of what we've seen so far. 4088 */ 4089 if (nlooked) { | 4916 skey = XS_SNSKEY(xs) & 0xf; 4917 if (skey < 10) 4918 skey += '0'; 4919 else 4920 skey += 'a' - 10; 4921 } else if (*XS_STSP(xs) == SCSI_CHECK) { 4922 skey = '?'; 4923 } else { --- 14 unchanged lines hidden (view full) --- 4938 } 4939 4940 /* 4941 * If we looked at any commands, then it's valid to find out 4942 * what the outpointer is. It also is a trigger to update the 4943 * ISP's notion of what we've seen so far. 4944 */ 4945 if (nlooked) { |
4090 WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr); | 4946 ISP_WRITE(isp, isp->isp_respoutrp, optr); |
4091 /* 4092 * While we're at it, read the requst queue out pointer. 4093 */ | 4947 /* 4948 * While we're at it, read the requst queue out pointer. 4949 */ |
4094 isp->isp_reqodx = READ_REQUEST_QUEUE_OUT_POINTER(isp); 4095 if (isp->isp_rscchiwater < ndone) | 4950 isp->isp_reqodx = ISP_READ(isp, isp->isp_rqstoutrp); 4951 if (isp->isp_rscchiwater < ndone) { |
4096 isp->isp_rscchiwater = ndone; | 4952 isp->isp_rscchiwater = ndone; |
4953 } |
|
4097 } 4098 | 4954 } 4955 |
4956out: 4957 4958 if (IS_24XX(isp)) { 4959 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT); 4960 } else { 4961 ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT); 4962 ISP_WRITE(isp, BIU_SEMA, 0); 4963 } 4964 |
|
4099 isp->isp_residx = optr; 4100 isp->isp_rspbsy = 0; 4101 for (i = 0; i < ndone; i++) { 4102 xs = complist[i]; 4103 if (xs) { 4104 isp->isp_rsltccmplt++; 4105 isp_done(xs); 4106 } --- 16 unchanged lines hidden (view full) --- 4123 bus = 0; 4124 } 4125 isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox); 4126 4127 switch (mbox) { 4128 case ASYNC_BUS_RESET: 4129 isp->isp_sendmarker |= (1 << bus); 4130#ifdef ISP_TARGET_MODE | 4965 isp->isp_residx = optr; 4966 isp->isp_rspbsy = 0; 4967 for (i = 0; i < ndone; i++) { 4968 xs = complist[i]; 4969 if (xs) { 4970 isp->isp_rsltccmplt++; 4971 isp_done(xs); 4972 } --- 16 unchanged lines hidden (view full) --- 4989 bus = 0; 4990 } 4991 isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox); 4992 4993 switch (mbox) { 4994 case ASYNC_BUS_RESET: 4995 isp->isp_sendmarker |= (1 << bus); 4996#ifdef ISP_TARGET_MODE |
4131 if (isp_target_async(isp, bus, mbox)) | 4997 if (isp_target_async(isp, bus, mbox)) { |
4132 rval = -1; | 4998 rval = -1; |
4999 } |
|
4133#endif 4134 isp_async(isp, ISPASYNC_BUS_RESET, &bus); 4135 break; 4136 case ASYNC_SYSTEM_ERROR: 4137 isp->isp_state = ISP_CRASHED; 4138 if (IS_FC(isp)) { 4139 FCPARAM(isp)->isp_loopstate = LOOP_NIL; 4140 FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT; --- 33 unchanged lines hidden (view full) --- 4174 break; 4175 4176 case ASYNC_QWAKEUP: 4177 /* 4178 * We've just been notified that the Queue has woken up. 4179 * We don't need to be chatty about this- just unlatch things 4180 * and move on. 4181 */ | 5000#endif 5001 isp_async(isp, ISPASYNC_BUS_RESET, &bus); 5002 break; 5003 case ASYNC_SYSTEM_ERROR: 5004 isp->isp_state = ISP_CRASHED; 5005 if (IS_FC(isp)) { 5006 FCPARAM(isp)->isp_loopstate = LOOP_NIL; 5007 FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT; --- 33 unchanged lines hidden (view full) --- 5041 break; 5042 5043 case ASYNC_QWAKEUP: 5044 /* 5045 * We've just been notified that the Queue has woken up. 5046 * We don't need to be chatty about this- just unlatch things 5047 * and move on. 5048 */ |
4182 mbox = READ_REQUEST_QUEUE_OUT_POINTER(isp); | 5049 mbox = ISP_READ(isp, isp->isp_rqstoutrp); |
4183 break; 4184 4185 case ASYNC_TIMEOUT_RESET: 4186 isp_prt(isp, ISP_LOGWARN, 4187 "timeout initiated SCSI bus reset of bus %d", bus); 4188 isp->isp_sendmarker |= (1 << bus); 4189#ifdef ISP_TARGET_MODE | 5050 break; 5051 5052 case ASYNC_TIMEOUT_RESET: 5053 isp_prt(isp, ISP_LOGWARN, 5054 "timeout initiated SCSI bus reset of bus %d", bus); 5055 isp->isp_sendmarker |= (1 << bus); 5056#ifdef ISP_TARGET_MODE |
4190 if (isp_target_async(isp, bus, mbox)) | 5057 if (isp_target_async(isp, bus, mbox)) { |
4191 rval = -1; | 5058 rval = -1; |
5059 } |
|
4192#endif 4193 break; 4194 4195 case ASYNC_DEVICE_RESET: 4196 isp_prt(isp, ISP_LOGINFO, "device reset on bus %d", bus); 4197 isp->isp_sendmarker |= (1 << bus); 4198#ifdef ISP_TARGET_MODE | 5060#endif 5061 break; 5062 5063 case ASYNC_DEVICE_RESET: 5064 isp_prt(isp, ISP_LOGINFO, "device reset on bus %d", bus); 5065 isp->isp_sendmarker |= (1 << bus); 5066#ifdef ISP_TARGET_MODE |
4199 if (isp_target_async(isp, bus, mbox)) | 5067 if (isp_target_async(isp, bus, mbox)) { |
4200 rval = -1; | 5068 rval = -1; |
5069 } |
|
4201#endif 4202 break; 4203 4204 case ASYNC_EXTMSG_UNDERRUN: 4205 isp_prt(isp, ISP_LOGWARN, "extended message underrun"); 4206 break; 4207 4208 case ASYNC_SCAM_INT: --- 86 unchanged lines hidden (view full) --- 4295 isp->isp_fphccmplt++; 4296 } 4297#else 4298 isp_prt(isp, ISP_LOGINFO, "Fast Posting CTIO done"); 4299 isp->isp_fphccmplt++; /* count it as a fast posting intr */ 4300#endif 4301 break; 4302 } | 5070#endif 5071 break; 5072 5073 case ASYNC_EXTMSG_UNDERRUN: 5074 isp_prt(isp, ISP_LOGWARN, "extended message underrun"); 5075 break; 5076 5077 case ASYNC_SCAM_INT: --- 86 unchanged lines hidden (view full) --- 5164 isp->isp_fphccmplt++; 5165 } 5166#else 5167 isp_prt(isp, ISP_LOGINFO, "Fast Posting CTIO done"); 5168 isp->isp_fphccmplt++; /* count it as a fast posting intr */ 5169#endif 5170 break; 5171 } |
5172 case ASYNC_LIP_ERROR: |
|
4303 case ASYNC_LIP_F8: 4304 case ASYNC_LIP_OCCURRED: 4305 FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT; 4306 FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD; 4307 isp->isp_sendmarker = 1; | 5173 case ASYNC_LIP_F8: 5174 case ASYNC_LIP_OCCURRED: 5175 FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT; 5176 FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD; 5177 isp->isp_sendmarker = 1; |
4308 isp_mark_getpdb_all(isp); | 5178 isp_mark_portdb(isp, 1); |
4309 isp_async(isp, ISPASYNC_LIP, NULL); 4310#ifdef ISP_TARGET_MODE | 5179 isp_async(isp, ISPASYNC_LIP, NULL); 5180#ifdef ISP_TARGET_MODE |
4311 if (isp_target_async(isp, bus, mbox)) | 5181 if (isp_target_async(isp, bus, mbox)) { |
4312 rval = -1; | 5182 rval = -1; |
5183 } |
|
4313#endif 4314 /* 4315 * We've had problems with data corruption occuring on 4316 * commands that complete (with no apparent error) after 4317 * we receive a LIP. This has been observed mostly on 4318 * Local Loop topologies. To be safe, let's just mark 4319 * all active commands as dead. 4320 */ --- 14 unchanged lines hidden (view full) --- 4335 } 4336 } 4337 break; 4338 4339 case ASYNC_LOOP_UP: 4340 isp->isp_sendmarker = 1; 4341 FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT; 4342 FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD; | 5184#endif 5185 /* 5186 * We've had problems with data corruption occuring on 5187 * commands that complete (with no apparent error) after 5188 * we receive a LIP. This has been observed mostly on 5189 * Local Loop topologies. To be safe, let's just mark 5190 * all active commands as dead. 5191 */ --- 14 unchanged lines hidden (view full) --- 5206 } 5207 } 5208 break; 5209 5210 case ASYNC_LOOP_UP: 5211 isp->isp_sendmarker = 1; 5212 FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT; 5213 FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD; |
4343 isp_mark_getpdb_all(isp); | 5214 isp_mark_portdb(isp, 1); |
4344 isp_async(isp, ISPASYNC_LOOP_UP, NULL); 4345#ifdef ISP_TARGET_MODE 4346 if (isp_target_async(isp, bus, mbox)) { 4347 rval = -1; 4348 } 4349#endif 4350 break; 4351 4352 case ASYNC_LOOP_DOWN: 4353 isp->isp_sendmarker = 1; 4354 FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT; 4355 FCPARAM(isp)->isp_loopstate = LOOP_NIL; | 5215 isp_async(isp, ISPASYNC_LOOP_UP, NULL); 5216#ifdef ISP_TARGET_MODE 5217 if (isp_target_async(isp, bus, mbox)) { 5218 rval = -1; 5219 } 5220#endif 5221 break; 5222 5223 case ASYNC_LOOP_DOWN: 5224 isp->isp_sendmarker = 1; 5225 FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT; 5226 FCPARAM(isp)->isp_loopstate = LOOP_NIL; |
4356 isp_mark_getpdb_all(isp); | 5227 isp_mark_portdb(isp, 1); |
4357 isp_async(isp, ISPASYNC_LOOP_DOWN, NULL); 4358#ifdef ISP_TARGET_MODE 4359 if (isp_target_async(isp, bus, mbox)) { 4360 rval = -1; 4361 } 4362#endif 4363 break; 4364 4365 case ASYNC_LOOP_RESET: 4366 isp->isp_sendmarker = 1; 4367 FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT; 4368 FCPARAM(isp)->isp_loopstate = LOOP_NIL; | 5228 isp_async(isp, ISPASYNC_LOOP_DOWN, NULL); 5229#ifdef ISP_TARGET_MODE 5230 if (isp_target_async(isp, bus, mbox)) { 5231 rval = -1; 5232 } 5233#endif 5234 break; 5235 5236 case ASYNC_LOOP_RESET: 5237 isp->isp_sendmarker = 1; 5238 FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT; 5239 FCPARAM(isp)->isp_loopstate = LOOP_NIL; |
4369 isp_mark_getpdb_all(isp); | 5240 isp_mark_portdb(isp, 1); |
4370 isp_async(isp, ISPASYNC_LOOP_RESET, NULL); 4371#ifdef ISP_TARGET_MODE 4372 if (isp_target_async(isp, bus, mbox)) { 4373 rval = -1; 4374 } 4375#endif 4376 break; 4377 4378 case ASYNC_PDB_CHANGED: 4379 isp->isp_sendmarker = 1; 4380 FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD; | 5241 isp_async(isp, ISPASYNC_LOOP_RESET, NULL); 5242#ifdef ISP_TARGET_MODE 5243 if (isp_target_async(isp, bus, mbox)) { 5244 rval = -1; 5245 } 5246#endif 5247 break; 5248 5249 case ASYNC_PDB_CHANGED: 5250 isp->isp_sendmarker = 1; 5251 FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD; |
4381 isp_mark_getpdb_all(isp); | 5252 isp_mark_portdb(isp, 1); |
4382 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_PDB); 4383 break; 4384 4385 case ASYNC_CHANGE_NOTIFY: | 5253 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_PDB); 5254 break; 5255 5256 case ASYNC_CHANGE_NOTIFY: |
4386 /* 4387 * Not correct, but it will force us to rescan the loop. 4388 */ 4389 FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD; 4390 isp_mark_getpdb_all(isp); | 5257 if (FCPARAM(isp)->isp_topo == TOPO_F_PORT) { 5258 FCPARAM(isp)->isp_loopstate = LOOP_LSCAN_DONE; 5259 } else { 5260 FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD; 5261 } 5262 isp_mark_portdb(isp, 1); |
4391 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_SNS); 4392 break; 4393 4394 case ASYNC_PTPMODE: | 5263 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_SNS); 5264 break; 5265 5266 case ASYNC_PTPMODE: |
4395 if (FCPARAM(isp)->isp_onfabric) 4396 FCPARAM(isp)->isp_topo = TOPO_F_PORT; 4397 else 4398 FCPARAM(isp)->isp_topo = TOPO_N_PORT; 4399 isp_mark_getpdb_all(isp); | 5267 isp_mark_portdb(isp, 1); |
4400 isp->isp_sendmarker = 1; 4401 FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT; 4402 FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD; 4403 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER); 4404#ifdef ISP_TARGET_MODE | 5268 isp->isp_sendmarker = 1; 5269 FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT; 5270 FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD; 5271 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER); 5272#ifdef ISP_TARGET_MODE |
4405 if (isp_target_async(isp, bus, mbox)) | 5273 if (isp_target_async(isp, bus, mbox)) { |
4406 rval = -1; | 5274 rval = -1; |
5275 } |
|
4407#endif 4408 isp_prt(isp, ISP_LOGINFO, "Point-to-Point mode"); 4409 break; 4410 4411 case ASYNC_CONNMODE: 4412 mbox = ISP_READ(isp, OUTMAILBOX1); | 5276#endif 5277 isp_prt(isp, ISP_LOGINFO, "Point-to-Point mode"); 5278 break; 5279 5280 case ASYNC_CONNMODE: 5281 mbox = ISP_READ(isp, OUTMAILBOX1); |
4413 isp_mark_getpdb_all(isp); | 5282 isp_mark_portdb(isp, 1); |
4414 switch (mbox) { 4415 case ISP_CONN_LOOP: 4416 isp_prt(isp, ISP_LOGINFO, 4417 "Point-to-Point -> Loop mode"); 4418 break; 4419 case ISP_CONN_PTP: 4420 isp_prt(isp, ISP_LOGINFO, 4421 "Loop -> Point-to-Point mode"); --- 22 unchanged lines hidden (view full) --- 4444 break; 4445 } 4446 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER); 4447 isp->isp_sendmarker = 1; 4448 FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT; 4449 FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD; 4450 break; 4451 | 5283 switch (mbox) { 5284 case ISP_CONN_LOOP: 5285 isp_prt(isp, ISP_LOGINFO, 5286 "Point-to-Point -> Loop mode"); 5287 break; 5288 case ISP_CONN_PTP: 5289 isp_prt(isp, ISP_LOGINFO, 5290 "Loop -> Point-to-Point mode"); --- 22 unchanged lines hidden (view full) --- 5313 break; 5314 } 5315 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER); 5316 isp->isp_sendmarker = 1; 5317 FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT; 5318 FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD; 5319 break; 5320 |
5321 case ASYNC_RJT_SENT: /* same as ASYNC_QFULL_SENT */ 5322 if (IS_24XX(isp)) { 5323 isp_prt(isp, ISP_LOGTDEBUG0, "LS_RJT sent"); 5324 break; 5325 } else if (IS_2200(isp)) { 5326 isp_prt(isp, ISP_LOGTDEBUG0, "QFULL sent"); 5327 break; 5328 } 5329 /* FALLTHROUGH */ |
|
4452 default: 4453 isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox); 4454 break; 4455 } 4456 4457 if (bus & 0x100) { 4458 int i, nh; 4459 uint16_t handles[16]; --- 4 unchanged lines hidden (view full) --- 4464 } 4465 handles[nh++] = ISP_READ(isp, MBOX_OFF(i)); 4466 } 4467 for (i = 0; i < nh; i++) { 4468 isp_fastpost_complete(isp, handles[i]); 4469 isp_prt(isp, ISP_LOGDEBUG3, 4470 "fast post completion of %u", handles[i]); 4471 } | 5330 default: 5331 isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox); 5332 break; 5333 } 5334 5335 if (bus & 0x100) { 5336 int i, nh; 5337 uint16_t handles[16]; --- 4 unchanged lines hidden (view full) --- 5342 } 5343 handles[nh++] = ISP_READ(isp, MBOX_OFF(i)); 5344 } 5345 for (i = 0; i < nh; i++) { 5346 isp_fastpost_complete(isp, handles[i]); 5347 isp_prt(isp, ISP_LOGDEBUG3, 5348 "fast post completion of %u", handles[i]); 5349 } |
4472 if (isp->isp_fpcchiwater < nh) | 5350 if (isp->isp_fpcchiwater < nh) { |
4473 isp->isp_fpcchiwater = nh; | 5351 isp->isp_fpcchiwater = nh; |
5352 } |
|
4474 } else { 4475 isp->isp_intoasync++; 4476 } 4477 return (rval); 4478} 4479 4480/* 4481 * Handle other response entries. A pointer to the request queue output 4482 * index is here in case we want to eat several entries at once, although 4483 * this is not used currently. 4484 */ 4485 4486static int 4487isp_handle_other_response(ispsoftc_t *isp, int type, | 5353 } else { 5354 isp->isp_intoasync++; 5355 } 5356 return (rval); 5357} 5358 5359/* 5360 * Handle other response entries. A pointer to the request queue output 5361 * index is here in case we want to eat several entries at once, although 5362 * this is not used currently. 5363 */ 5364 5365static int 5366isp_handle_other_response(ispsoftc_t *isp, int type, |
4488 isphdr_t *hp, uint16_t *optrp) | 5367 isphdr_t *hp, uint32_t *optrp) |
4489{ 4490 switch (type) { 4491 case RQSTYPE_STATUS_CONT: | 5368{ 5369 switch (type) { 5370 case RQSTYPE_STATUS_CONT: |
4492 isp_prt(isp, ISP_LOGINFO, "Ignored Continuation Response"); | 5371 isp_prt(isp, ISP_LOGDEBUG0, "Ignored Continuation Response"); |
4493 return (1); | 5372 return (1); |
5373 case RQSTYPE_MARKER: 5374 isp_prt(isp, ISP_LOGDEBUG0, "Marker Response"); 5375 return (1); |
|
4494 case RQSTYPE_ATIO: 4495 case RQSTYPE_CTIO: 4496 case RQSTYPE_ENABLE_LUN: 4497 case RQSTYPE_MODIFY_LUN: 4498 case RQSTYPE_NOTIFY: 4499 case RQSTYPE_NOTIFY_ACK: 4500 case RQSTYPE_CTIO1: 4501 case RQSTYPE_ATIO2: 4502 case RQSTYPE_CTIO2: 4503 case RQSTYPE_CTIO3: | 5376 case RQSTYPE_ATIO: 5377 case RQSTYPE_CTIO: 5378 case RQSTYPE_ENABLE_LUN: 5379 case RQSTYPE_MODIFY_LUN: 5380 case RQSTYPE_NOTIFY: 5381 case RQSTYPE_NOTIFY_ACK: 5382 case RQSTYPE_CTIO1: 5383 case RQSTYPE_ATIO2: 5384 case RQSTYPE_CTIO2: 5385 case RQSTYPE_CTIO3: |
5386 case RQSTYPE_CTIO7: 5387 case RQSTYPE_ABTS_RCVD: 5388 case RQSTYPE_ABTS_RSP: |
|
4504 isp->isp_rsltccmplt++; /* count as a response completion */ 4505#ifdef ISP_TARGET_MODE 4506 if (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp)) { 4507 return (1); 4508 } 4509#endif 4510 /* FALLTHROUGH */ 4511 case RQSTYPE_REQUEST: --- 17 unchanged lines hidden (view full) --- 4529 if (isp_async(isp, ISPASYNC_UNHANDLED_RESPONSE, hp)) { 4530 return (1); 4531 } 4532 return (0); 4533 } 4534} 4535 4536static void | 5389 isp->isp_rsltccmplt++; /* count as a response completion */ 5390#ifdef ISP_TARGET_MODE 5391 if (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp)) { 5392 return (1); 5393 } 5394#endif 5395 /* FALLTHROUGH */ 5396 case RQSTYPE_REQUEST: --- 17 unchanged lines hidden (view full) --- 5414 if (isp_async(isp, ISPASYNC_UNHANDLED_RESPONSE, hp)) { 5415 return (1); 5416 } 5417 return (0); 5418 } 5419} 5420 5421static void |
4537isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs) | 5422isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp) |
4538{ 4539 switch (sp->req_completion_status & 0xff) { 4540 case RQCS_COMPLETE: 4541 if (XS_NOERR(xs)) { 4542 XS_SETERR(xs, HBA_NOERROR); 4543 } 4544 return; 4545 4546 case RQCS_INCOMPLETE: 4547 if ((sp->req_state_flags & RQSF_GOT_TARGET) == 0) { 4548 isp_prt(isp, ISP_LOGDEBUG1, 4549 "Selection Timeout for %d.%d.%d", 4550 XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); 4551 if (XS_NOERR(xs)) { 4552 XS_SETERR(xs, HBA_SELTIMEOUT); | 5423{ 5424 switch (sp->req_completion_status & 0xff) { 5425 case RQCS_COMPLETE: 5426 if (XS_NOERR(xs)) { 5427 XS_SETERR(xs, HBA_NOERROR); 5428 } 5429 return; 5430 5431 case RQCS_INCOMPLETE: 5432 if ((sp->req_state_flags & RQSF_GOT_TARGET) == 0) { 5433 isp_prt(isp, ISP_LOGDEBUG1, 5434 "Selection Timeout for %d.%d.%d", 5435 XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); 5436 if (XS_NOERR(xs)) { 5437 XS_SETERR(xs, HBA_SELTIMEOUT); |
5438 *rp = XS_XFRLEN(xs); |
|
4553 } 4554 return; 4555 } 4556 isp_prt(isp, ISP_LOGERR, 4557 "command incomplete for %d.%d.%d, state 0x%x", 4558 XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), 4559 sp->req_state_flags); 4560 break; 4561 4562 case RQCS_DMA_ERROR: 4563 isp_prt(isp, ISP_LOGERR, "DMA error for command on %d.%d.%d", 4564 XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); | 5439 } 5440 return; 5441 } 5442 isp_prt(isp, ISP_LOGERR, 5443 "command incomplete for %d.%d.%d, state 0x%x", 5444 XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), 5445 sp->req_state_flags); 5446 break; 5447 5448 case RQCS_DMA_ERROR: 5449 isp_prt(isp, ISP_LOGERR, "DMA error for command on %d.%d.%d", 5450 XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); |
5451 *rp = XS_XFRLEN(xs); |
|
4565 break; 4566 4567 case RQCS_TRANSPORT_ERROR: 4568 { 4569 char buf[172]; 4570 SNPRINTF(buf, sizeof (buf), "states=>"); 4571 if (sp->req_state_flags & RQSF_GOT_BUS) { 4572 SNPRINTF(buf, sizeof (buf), "%s GOT_BUS", buf); --- 39 unchanged lines hidden (view full) --- 4612 SNPRINTF(buf, sizeof (buf), "%s Timeout", buf); 4613 } 4614 if (sp->req_status_flags & RQSTF_NEGOTIATION) { 4615 SNPRINTF(buf, sizeof (buf), "%s Negotiation", buf); 4616 } 4617 isp_prt(isp, ISP_LOGERR, "%s", buf); 4618 isp_prt(isp, ISP_LOGERR, "transport error for %d.%d.%d:\n%s", 4619 XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), buf); | 5452 break; 5453 5454 case RQCS_TRANSPORT_ERROR: 5455 { 5456 char buf[172]; 5457 SNPRINTF(buf, sizeof (buf), "states=>"); 5458 if (sp->req_state_flags & RQSF_GOT_BUS) { 5459 SNPRINTF(buf, sizeof (buf), "%s GOT_BUS", buf); --- 39 unchanged lines hidden (view full) --- 5499 SNPRINTF(buf, sizeof (buf), "%s Timeout", buf); 5500 } 5501 if (sp->req_status_flags & RQSTF_NEGOTIATION) { 5502 SNPRINTF(buf, sizeof (buf), "%s Negotiation", buf); 5503 } 5504 isp_prt(isp, ISP_LOGERR, "%s", buf); 5505 isp_prt(isp, ISP_LOGERR, "transport error for %d.%d.%d:\n%s", 5506 XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), buf); |
5507 *rp = XS_XFRLEN(xs); |
|
4620 break; 4621 } 4622 case RQCS_RESET_OCCURRED: 4623 isp_prt(isp, ISP_LOGWARN, 4624 "bus reset destroyed command for %d.%d.%d", 4625 XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); 4626 isp->isp_sendmarker |= (1 << XS_CHANNEL(xs)); 4627 if (XS_NOERR(xs)) { 4628 XS_SETERR(xs, HBA_BUSRESET); 4629 } | 5508 break; 5509 } 5510 case RQCS_RESET_OCCURRED: 5511 isp_prt(isp, ISP_LOGWARN, 5512 "bus reset destroyed command for %d.%d.%d", 5513 XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); 5514 isp->isp_sendmarker |= (1 << XS_CHANNEL(xs)); 5515 if (XS_NOERR(xs)) { 5516 XS_SETERR(xs, HBA_BUSRESET); 5517 } |
5518 *rp = XS_XFRLEN(xs); |
|
4630 return; 4631 4632 case RQCS_ABORTED: 4633 isp_prt(isp, ISP_LOGERR, "command aborted for %d.%d.%d", 4634 XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); 4635 isp->isp_sendmarker |= (1 << XS_CHANNEL(xs)); 4636 if (XS_NOERR(xs)) { 4637 XS_SETERR(xs, HBA_ABORTED); 4638 } 4639 return; 4640 4641 case RQCS_TIMEOUT: 4642 isp_prt(isp, ISP_LOGWARN, "command timed out for %d.%d.%d", 4643 XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); 4644 /* | 5519 return; 5520 5521 case RQCS_ABORTED: 5522 isp_prt(isp, ISP_LOGERR, "command aborted for %d.%d.%d", 5523 XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); 5524 isp->isp_sendmarker |= (1 << XS_CHANNEL(xs)); 5525 if (XS_NOERR(xs)) { 5526 XS_SETERR(xs, HBA_ABORTED); 5527 } 5528 return; 5529 5530 case RQCS_TIMEOUT: 5531 isp_prt(isp, ISP_LOGWARN, "command timed out for %d.%d.%d", 5532 XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); 5533 /* |
4645 * Check to see if we logged out the device. | 5534 * XXX: Check to see if we logged out of the device. |
4646 */ | 5535 */ |
4647 if (IS_FC(isp)) { 4648 if ((sp->req_completion_status & RQSTF_LOGOUT) && 4649 FCPARAM(isp)->portdb[XS_TGT(xs)].valid && 4650 FCPARAM(isp)->portdb[XS_TGT(xs)].fabric_dev) { 4651 FCPARAM(isp)->portdb[XS_TGT(xs)].relogin = 1; 4652 } 4653 } | |
4654 if (XS_NOERR(xs)) { 4655 XS_SETERR(xs, HBA_CMDTIMEOUT); 4656 } 4657 return; 4658 4659 case RQCS_DATA_OVERRUN: 4660 XS_RESID(xs) = sp->req_resid; 4661 isp_prt(isp, ISP_LOGERR, "data overrun for command on %d.%d.%d", --- 190 unchanged lines hidden (view full) --- 4852 XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs)); 4853 break; 4854 4855 case RQCS_PORT_UNAVAILABLE: 4856 /* 4857 * No such port on the loop. Moral equivalent of SELTIMEO 4858 */ 4859 case RQCS_PORT_LOGGED_OUT: | 5536 if (XS_NOERR(xs)) { 5537 XS_SETERR(xs, HBA_CMDTIMEOUT); 5538 } 5539 return; 5540 5541 case RQCS_DATA_OVERRUN: 5542 XS_RESID(xs) = sp->req_resid; 5543 isp_prt(isp, ISP_LOGERR, "data overrun for command on %d.%d.%d", --- 190 unchanged lines hidden (view full) --- 5734 XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs)); 5735 break; 5736 5737 case RQCS_PORT_UNAVAILABLE: 5738 /* 5739 * No such port on the loop. Moral equivalent of SELTIMEO 5740 */ 5741 case RQCS_PORT_LOGGED_OUT: |
5742 { 5743 char *reason; 5744 uint8_t sts = sp->req_completion_status & 0xff; 5745 |
|
4860 /* 4861 * It was there (maybe)- treat as a selection timeout. 4862 */ | 5746 /* 5747 * It was there (maybe)- treat as a selection timeout. 5748 */ |
4863 if ((sp->req_completion_status & 0xff) == RQCS_PORT_UNAVAILABLE) 4864 isp_prt(isp, ISP_LOGINFO, 4865 "port unavailable for target %d", XS_TGT(xs)); 4866 else 4867 isp_prt(isp, ISP_LOGINFO, 4868 "port logout for target %d", XS_TGT(xs)); | 5749 if (sts == RQCS_PORT_UNAVAILABLE) { 5750 reason = "unavailable"; 5751 } else { 5752 reason = "logout"; 5753 } 5754 5755 isp_prt(isp, ISP_LOGINFO, "port %s for target %d", 5756 reason, XS_TGT(xs)); 5757 |
4869 /* 4870 * If we're on a local loop, force a LIP (which is overkill) 4871 * to force a re-login of this unit. If we're on fabric, | 5758 /* 5759 * If we're on a local loop, force a LIP (which is overkill) 5760 * to force a re-login of this unit. If we're on fabric, |
4872 * then we'll have to relogin as a matter of course. | 5761 * then we'll have to log in again as a matter of course. |
4873 */ 4874 if (FCPARAM(isp)->isp_topo == TOPO_NL_PORT || 4875 FCPARAM(isp)->isp_topo == TOPO_FL_PORT) { 4876 mbreg_t mbs; 4877 MEMZERO(&mbs, sizeof (mbs)); 4878 mbs.param[0] = MBOX_INIT_LIP; | 5762 */ 5763 if (FCPARAM(isp)->isp_topo == TOPO_NL_PORT || 5764 FCPARAM(isp)->isp_topo == TOPO_FL_PORT) { 5765 mbreg_t mbs; 5766 MEMZERO(&mbs, sizeof (mbs)); 5767 mbs.param[0] = MBOX_INIT_LIP; |
4879 if (IS_2KLOGIN(isp)) { 4880 mbs.ibits |= (1 << 10); | 5768 if (FCPARAM(isp)->isp_2klogin) { 5769 mbs.ibits = (1 << 10); |
4881 } | 5770 } |
5771 mbs.logval = MBLOGALL; |
|
4882 isp_mboxcmd_qnw(isp, &mbs, 1); 4883 } 4884 4885 /* 4886 * Probably overkill. 4887 */ 4888 isp->isp_sendmarker = 1; 4889 FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD; | 5772 isp_mboxcmd_qnw(isp, &mbs, 1); 5773 } 5774 5775 /* 5776 * Probably overkill. 5777 */ 5778 isp->isp_sendmarker = 1; 5779 FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD; |
4890 isp_mark_getpdb_all(isp); | 5780 isp_mark_portdb(isp, 1); |
4891 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER); 4892 if (XS_NOERR(xs)) { 4893 XS_SETERR(xs, HBA_SELTIMEOUT); 4894 } 4895 return; | 5781 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER); 5782 if (XS_NOERR(xs)) { 5783 XS_SETERR(xs, HBA_SELTIMEOUT); 5784 } 5785 return; |
4896 | 5786 } |
4897 case RQCS_PORT_CHANGED: 4898 isp_prt(isp, ISP_LOGWARN, 4899 "port changed for target %d", XS_TGT(xs)); 4900 if (XS_NOERR(xs)) { 4901 XS_SETERR(xs, HBA_SELTIMEOUT); 4902 } 4903 return; 4904 --- 11 unchanged lines hidden (view full) --- 4916 break; 4917 } 4918 if (XS_NOERR(xs)) { 4919 XS_SETERR(xs, HBA_BOTCH); 4920 } 4921} 4922 4923static void | 5787 case RQCS_PORT_CHANGED: 5788 isp_prt(isp, ISP_LOGWARN, 5789 "port changed for target %d", XS_TGT(xs)); 5790 if (XS_NOERR(xs)) { 5791 XS_SETERR(xs, HBA_SELTIMEOUT); 5792 } 5793 return; 5794 --- 11 unchanged lines hidden (view full) --- 5806 break; 5807 } 5808 if (XS_NOERR(xs)) { 5809 XS_SETERR(xs, HBA_BOTCH); 5810 } 5811} 5812 5813static void |
5814isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp, 5815 XS_T *xs, long *rp) 5816{ 5817 switch (sp->req_completion_status) { 5818 case RQCS_COMPLETE: 5819 if (XS_NOERR(xs)) { 5820 XS_SETERR(xs, HBA_NOERROR); 5821 } 5822 return; 5823 5824 case RQCS_DMA_ERROR: 5825 isp_prt(isp, ISP_LOGERR, "DMA error for command on %d.%d.%d", 5826 XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); 5827 break; 5828 5829 case RQCS_TRANSPORT_ERROR: 5830 isp_prt(isp, ISP_LOGERR, "transport error for %d.%d.%d", 5831 XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); 5832 break; 5833 5834 case RQCS_RESET_OCCURRED: 5835 isp_prt(isp, ISP_LOGWARN, 5836 "bus reset destroyed command for %d.%d.%d", 5837 XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); 5838 isp->isp_sendmarker |= (1 << XS_CHANNEL(xs)); 5839 if (XS_NOERR(xs)) { 5840 XS_SETERR(xs, HBA_BUSRESET); 5841 } 5842 return; 5843 5844 case RQCS_ABORTED: 5845 isp_prt(isp, ISP_LOGERR, "command aborted for %d.%d.%d", 5846 XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); 5847 isp->isp_sendmarker |= (1 << XS_CHANNEL(xs)); 5848 if (XS_NOERR(xs)) { 5849 XS_SETERR(xs, HBA_ABORTED); 5850 } 5851 return; 5852 5853 case RQCS_TIMEOUT: 5854 isp_prt(isp, ISP_LOGWARN, "command timed out for %d.%d.%d", 5855 XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); 5856 if (XS_NOERR(xs)) { 5857 XS_SETERR(xs, HBA_CMDTIMEOUT); 5858 } 5859 return; 5860 5861 case RQCS_DATA_OVERRUN: 5862 XS_RESID(xs) = sp->req_resid; 5863 isp_prt(isp, ISP_LOGERR, "data overrun for command on %d.%d.%d", 5864 XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); 5865 if (XS_NOERR(xs)) { 5866 XS_SETERR(xs, HBA_DATAOVR); 5867 } 5868 return; 5869 5870 case RQCS_24XX_DRE: /* data reassembly error */ 5871 isp_prt(isp, ISP_LOGERR, "data reassembly error for target %d", 5872 XS_TGT(xs)); 5873 if (XS_NOERR(xs)) { 5874 XS_SETERR(xs, HBA_ABORTED); 5875 } 5876 *rp = XS_XFRLEN(xs); 5877 return; 5878 5879 case RQCS_24XX_TABORT: /* aborted by target */ 5880 isp_prt(isp, ISP_LOGERR, "target %d sent ABTS", 5881 XS_TGT(xs)); 5882 if (XS_NOERR(xs)) { 5883 XS_SETERR(xs, HBA_ABORTED); 5884 } 5885 return; 5886 5887 case RQCS_DATA_UNDERRUN: 5888 5889 XS_RESID(xs) = sp->req_resid; 5890 if (XS_NOERR(xs)) { 5891 XS_SETERR(xs, HBA_NOERROR); 5892 } 5893 return; 5894 5895 case RQCS_PORT_UNAVAILABLE: 5896 /* 5897 * No such port on the loop. Moral equivalent of SELTIMEO 5898 */ 5899 case RQCS_PORT_LOGGED_OUT: 5900 { 5901 char *reason; 5902 uint8_t sts = sp->req_completion_status & 0xff; 5903 5904 /* 5905 * It was there (maybe)- treat as a selection timeout. 5906 */ 5907 if (sts == RQCS_PORT_UNAVAILABLE) { 5908 reason = "unavailable"; 5909 } else { 5910 reason = "logout"; 5911 } 5912 5913 isp_prt(isp, ISP_LOGINFO, "port %s for target %d", 5914 reason, XS_TGT(xs)); 5915 5916 /* 5917 * If we're on a local loop, force a LIP (which is overkill) 5918 * to force a re-login of this unit. If we're on fabric, 5919 * then we'll have to log in again as a matter of course. 5920 */ 5921 if (FCPARAM(isp)->isp_topo == TOPO_NL_PORT || 5922 FCPARAM(isp)->isp_topo == TOPO_FL_PORT) { 5923 mbreg_t mbs; 5924 MEMZERO(&mbs, sizeof (mbs)); 5925 mbs.param[0] = MBOX_INIT_LIP; 5926 if (FCPARAM(isp)->isp_2klogin) { 5927 mbs.ibits = (1 << 10); 5928 } 5929 mbs.logval = MBLOGALL; 5930 isp_mboxcmd_qnw(isp, &mbs, 1); 5931 } 5932 5933 /* 5934 * Probably overkill. 5935 */ 5936 isp->isp_sendmarker = 1; 5937 FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD; 5938 isp_mark_portdb(isp, 1); 5939 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER); 5940 if (XS_NOERR(xs)) { 5941 XS_SETERR(xs, HBA_SELTIMEOUT); 5942 } 5943 return; 5944 } 5945 case RQCS_PORT_CHANGED: 5946 isp_prt(isp, ISP_LOGWARN, 5947 "port changed for target %d", XS_TGT(xs)); 5948 if (XS_NOERR(xs)) { 5949 XS_SETERR(xs, HBA_SELTIMEOUT); 5950 } 5951 return; 5952 5953 5954 case RQCS_24XX_ENOMEM: /* f/w resource unavailable */ 5955 isp_prt(isp, ISP_LOGWARN, 5956 "f/w resource unavailable for target %d", XS_TGT(xs)); 5957 if (XS_NOERR(xs)) { 5958 *XS_STSP(xs) = SCSI_BUSY; 5959 XS_SETERR(xs, HBA_TGTBSY); 5960 } 5961 return; 5962 5963 case RQCS_24XX_TMO: /* task management overrun */ 5964 isp_prt(isp, ISP_LOGWARN, 5965 "command for target %d overlapped task management", 5966 XS_TGT(xs)); 5967 if (XS_NOERR(xs)) { 5968 *XS_STSP(xs) = SCSI_BUSY; 5969 XS_SETERR(xs, HBA_TGTBSY); 5970 } 5971 return; 5972 5973 default: 5974 isp_prt(isp, ISP_LOGERR, "Unknown Completion Status 0x%x", 5975 sp->req_completion_status); 5976 break; 5977 } 5978 if (XS_NOERR(xs)) { 5979 XS_SETERR(xs, HBA_BOTCH); 5980 } 5981} 5982 5983static void |
|
4924isp_fastpost_complete(ispsoftc_t *isp, uint16_t fph) 4925{ 4926 XS_T *xs; 4927 4928 if (fph == 0) { 4929 return; 4930 } 4931 xs = isp_find_xs(isp, fph); --- 40 unchanged lines hidden (view full) --- 4972 if (isp->isp_mboxtmp[0] != MBOX_COMMAND_COMPLETE) { 4973 isp->isp_mbxwrk0 = 0; 4974 return (-1); 4975 } 4976 4977 /* 4978 * Clear the previous interrupt. 4979 */ | 5984isp_fastpost_complete(ispsoftc_t *isp, uint16_t fph) 5985{ 5986 XS_T *xs; 5987 5988 if (fph == 0) { 5989 return; 5990 } 5991 xs = isp_find_xs(isp, fph); --- 40 unchanged lines hidden (view full) --- 6032 if (isp->isp_mboxtmp[0] != MBOX_COMMAND_COMPLETE) { 6033 isp->isp_mbxwrk0 = 0; 6034 return (-1); 6035 } 6036 6037 /* 6038 * Clear the previous interrupt. 6039 */ |
4980 ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT); 4981 ISP_WRITE(isp, BIU_SEMA, 0); | 6040 if (IS_24XX(isp)) { 6041 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT); 6042 } else { 6043 ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT); 6044 ISP_WRITE(isp, BIU_SEMA, 0); 6045 } |
4982 4983 /* 4984 * Continue with next word. 4985 */ 4986 MEMZERO(&mbs, sizeof (mbs)); 4987 ptr = isp->isp_mbxworkp; 4988 switch (isp->isp_lastmbxcmd) { 4989 case MBOX_WRITE_RAM_WORD: 4990 mbs.param[1] = isp->isp_mbxwrk1++;; 4991 mbs.param[2] = *ptr++;; 4992 break; 4993 case MBOX_READ_RAM_WORD: 4994 *ptr++ = isp->isp_mboxtmp[2]; 4995 mbs.param[1] = isp->isp_mbxwrk1++; 4996 break; 4997 case MBOX_WRITE_RAM_WORD_EXTENDED: 4998 offset = isp->isp_mbxwrk1; | 6046 6047 /* 6048 * Continue with next word. 6049 */ 6050 MEMZERO(&mbs, sizeof (mbs)); 6051 ptr = isp->isp_mbxworkp; 6052 switch (isp->isp_lastmbxcmd) { 6053 case MBOX_WRITE_RAM_WORD: 6054 mbs.param[1] = isp->isp_mbxwrk1++;; 6055 mbs.param[2] = *ptr++;; 6056 break; 6057 case MBOX_READ_RAM_WORD: 6058 *ptr++ = isp->isp_mboxtmp[2]; 6059 mbs.param[1] = isp->isp_mbxwrk1++; 6060 break; 6061 case MBOX_WRITE_RAM_WORD_EXTENDED: 6062 offset = isp->isp_mbxwrk1; |
4999 offset |= ((uint32_t) isp->isp_mbxwrk8 << 16); | 6063 offset |= isp->isp_mbxwrk8 << 16; |
5000 5001 mbs.param[2] = *ptr++;; 5002 mbs.param[1] = offset; 5003 mbs.param[8] = offset >> 16; 5004 isp->isp_mbxwrk1 = ++offset; 5005 isp->isp_mbxwrk8 = offset >> 16; 5006 break; 5007 case MBOX_READ_RAM_WORD_EXTENDED: 5008 offset = isp->isp_mbxwrk1; | 6064 6065 mbs.param[2] = *ptr++;; 6066 mbs.param[1] = offset; 6067 mbs.param[8] = offset >> 16; 6068 isp->isp_mbxwrk1 = ++offset; 6069 isp->isp_mbxwrk8 = offset >> 16; 6070 break; 6071 case MBOX_READ_RAM_WORD_EXTENDED: 6072 offset = isp->isp_mbxwrk1; |
5009 offset |= ((uint32_t) isp->isp_mbxwrk8 << 16); | 6073 offset |= isp->isp_mbxwrk8 << 16; |
5010 5011 *ptr++ = isp->isp_mboxtmp[2]; 5012 mbs.param[1] = offset; 5013 mbs.param[8] = offset >> 16; 5014 isp->isp_mbxwrk1 = ++offset; 5015 isp->isp_mbxwrk8 = offset >> 16; 5016 break; 5017 } 5018 isp->isp_mbxworkp = ptr; 5019 isp->isp_mbxwrk0--; 5020 mbs.param[0] = isp->isp_lastmbxcmd; | 6074 6075 *ptr++ = isp->isp_mboxtmp[2]; 6076 mbs.param[1] = offset; 6077 mbs.param[8] = offset >> 16; 6078 isp->isp_mbxwrk1 = ++offset; 6079 isp->isp_mbxwrk8 = offset >> 16; 6080 break; 6081 } 6082 isp->isp_mbxworkp = ptr; 6083 isp->isp_mbxwrk0--; 6084 mbs.param[0] = isp->isp_lastmbxcmd; |
6085 mbs.logval = MBLOGALL; |
|
5021 isp_mboxcmd_qnw(isp, &mbs, 0); 5022 return (0); 5023} 5024 | 6086 isp_mboxcmd_qnw(isp, &mbs, 0); 6087 return (0); 6088} 6089 |
5025 | |
5026#define HIWRD(x) ((x) >> 16) 5027#define LOWRD(x) ((x) & 0xffff) 5028#define ISPOPMAP(a, b) (((a) << 16) | (b)) 5029static const uint32_t mbpscsi[] = { 5030 ISPOPMAP(0x01, 0x01), /* 0x00: MBOX_NO_OP */ 5031 ISPOPMAP(0x1f, 0x01), /* 0x01: MBOX_LOAD_RAM */ 5032 ISPOPMAP(0x03, 0x01), /* 0x02: MBOX_EXEC_FIRMWARE */ 5033 ISPOPMAP(0x1f, 0x01), /* 0x03: MBOX_DUMP_RAM */ --- 72 unchanged lines hidden (view full) --- 5106 ISPOPMAP(0x00, 0x00), /* 0x4c: */ 5107 ISPOPMAP(0x00, 0x00), /* 0x4d: */ 5108 ISPOPMAP(0x00, 0x00), /* 0x4e: */ 5109 ISPOPMAP(0x00, 0x00), /* 0x4f: */ 5110 ISPOPMAP(0xdf, 0xdf), /* 0x50: LOAD RAM A64 */ 5111 ISPOPMAP(0xdf, 0xdf), /* 0x51: DUMP RAM A64 */ 5112 ISPOPMAP(0xdf, 0xff), /* 0x52: INITIALIZE REQUEST QUEUE A64 */ 5113 ISPOPMAP(0xef, 0xff), /* 0x53: INITIALIZE RESPONSE QUEUE A64 */ | 6090#define HIWRD(x) ((x) >> 16) 6091#define LOWRD(x) ((x) & 0xffff) 6092#define ISPOPMAP(a, b) (((a) << 16) | (b)) 6093static const uint32_t mbpscsi[] = { 6094 ISPOPMAP(0x01, 0x01), /* 0x00: MBOX_NO_OP */ 6095 ISPOPMAP(0x1f, 0x01), /* 0x01: MBOX_LOAD_RAM */ 6096 ISPOPMAP(0x03, 0x01), /* 0x02: MBOX_EXEC_FIRMWARE */ 6097 ISPOPMAP(0x1f, 0x01), /* 0x03: MBOX_DUMP_RAM */ --- 72 unchanged lines hidden (view full) --- 6170 ISPOPMAP(0x00, 0x00), /* 0x4c: */ 6171 ISPOPMAP(0x00, 0x00), /* 0x4d: */ 6172 ISPOPMAP(0x00, 0x00), /* 0x4e: */ 6173 ISPOPMAP(0x00, 0x00), /* 0x4f: */ 6174 ISPOPMAP(0xdf, 0xdf), /* 0x50: LOAD RAM A64 */ 6175 ISPOPMAP(0xdf, 0xdf), /* 0x51: DUMP RAM A64 */ 6176 ISPOPMAP(0xdf, 0xff), /* 0x52: INITIALIZE REQUEST QUEUE A64 */ 6177 ISPOPMAP(0xef, 0xff), /* 0x53: INITIALIZE RESPONSE QUEUE A64 */ |
5114 ISPOPMAP(0xcf, 0x01), /* 0x54: EXECUTE IOCB A64 */ | 6178 ISPOPMAP(0xcf, 0x01), /* 0x54: EXECUCUTE COMMAND IOCB A64 */ |
5115 ISPOPMAP(0x07, 0x01), /* 0x55: ENABLE TARGET MODE */ 5116 ISPOPMAP(0x03, 0x0f), /* 0x56: GET TARGET STATUS */ 5117 ISPOPMAP(0x00, 0x00), /* 0x57: */ 5118 ISPOPMAP(0x00, 0x00), /* 0x58: */ 5119 ISPOPMAP(0x00, 0x00), /* 0x59: */ 5120 ISPOPMAP(0x03, 0x03), /* 0x5a: SET DATA OVERRUN RECOVERY MODE */ 5121 ISPOPMAP(0x01, 0x03), /* 0x5b: GET DATA OVERRUN RECOVERY MODE */ 5122 ISPOPMAP(0x0f, 0x0f), /* 0x5c: SET HOST DATA */ 5123 ISPOPMAP(0x01, 0x01) /* 0x5d: GET NOST DATA */ 5124}; 5125 | 6179 ISPOPMAP(0x07, 0x01), /* 0x55: ENABLE TARGET MODE */ 6180 ISPOPMAP(0x03, 0x0f), /* 0x56: GET TARGET STATUS */ 6181 ISPOPMAP(0x00, 0x00), /* 0x57: */ 6182 ISPOPMAP(0x00, 0x00), /* 0x58: */ 6183 ISPOPMAP(0x00, 0x00), /* 0x59: */ 6184 ISPOPMAP(0x03, 0x03), /* 0x5a: SET DATA OVERRUN RECOVERY MODE */ 6185 ISPOPMAP(0x01, 0x03), /* 0x5b: GET DATA OVERRUN RECOVERY MODE */ 6186 ISPOPMAP(0x0f, 0x0f), /* 0x5c: SET HOST DATA */ 6187 ISPOPMAP(0x01, 0x01) /* 0x5d: GET NOST DATA */ 6188}; 6189 |
5126#ifndef ISP_STRIPPED | |
5127static char *scsi_mbcmd_names[] = { 5128 "NO-OP", 5129 "LOAD RAM", 5130 "EXEC FIRMWARE", 5131 "DUMP RAM", 5132 "WRITE RAM WORD", 5133 "READ RAM WORD", 5134 "MAILBOX REG TEST", --- 80 unchanged lines hidden (view full) --- 5215 NULL, 5216 NULL, 5217 NULL, 5218 "SET DATA OVERRUN RECOVERY MODE", 5219 "GET DATA OVERRUN RECOVERY MODE", 5220 "SET HOST DATA", 5221 "GET NOST DATA", 5222}; | 6190static char *scsi_mbcmd_names[] = { 6191 "NO-OP", 6192 "LOAD RAM", 6193 "EXEC FIRMWARE", 6194 "DUMP RAM", 6195 "WRITE RAM WORD", 6196 "READ RAM WORD", 6197 "MAILBOX REG TEST", --- 80 unchanged lines hidden (view full) --- 6278 NULL, 6279 NULL, 6280 NULL, 6281 "SET DATA OVERRUN RECOVERY MODE", 6282 "GET DATA OVERRUN RECOVERY MODE", 6283 "SET HOST DATA", 6284 "GET NOST DATA", 6285}; |
5223#endif | |
5224 5225static const uint32_t mbpfc[] = { 5226 ISPOPMAP(0x01, 0x01), /* 0x00: MBOX_NO_OP */ 5227 ISPOPMAP(0x1f, 0x01), /* 0x01: MBOX_LOAD_RAM */ | 6286 6287static const uint32_t mbpfc[] = { 6288 ISPOPMAP(0x01, 0x01), /* 0x00: MBOX_NO_OP */ 6289 ISPOPMAP(0x1f, 0x01), /* 0x01: MBOX_LOAD_RAM */ |
5228 ISPOPMAP(0x07, 0x01), /* 0x02: MBOX_EXEC_FIRMWARE */ | 6290 ISPOPMAP(0x0f, 0x01), /* 0x02: MBOX_EXEC_FIRMWARE */ |
5229 ISPOPMAP(0xdf, 0x01), /* 0x03: MBOX_DUMP_RAM */ 5230 ISPOPMAP(0x07, 0x07), /* 0x04: MBOX_WRITE_RAM_WORD */ 5231 ISPOPMAP(0x03, 0x07), /* 0x05: MBOX_READ_RAM_WORD */ 5232 ISPOPMAP(0xff, 0xff), /* 0x06: MBOX_MAILBOX_REG_TEST */ | 6291 ISPOPMAP(0xdf, 0x01), /* 0x03: MBOX_DUMP_RAM */ 6292 ISPOPMAP(0x07, 0x07), /* 0x04: MBOX_WRITE_RAM_WORD */ 6293 ISPOPMAP(0x03, 0x07), /* 0x05: MBOX_READ_RAM_WORD */ 6294 ISPOPMAP(0xff, 0xff), /* 0x06: MBOX_MAILBOX_REG_TEST */ |
5233 ISPOPMAP(0x03, 0x05), /* 0x07: MBOX_VERIFY_CHECKSUM */ | 6295 ISPOPMAP(0x03, 0x07), /* 0x07: MBOX_VERIFY_CHECKSUM */ |
5234 ISPOPMAP(0x01, 0x4f), /* 0x08: MBOX_ABOUT_FIRMWARE */ 5235 ISPOPMAP(0xdf, 0x01), /* 0x09: LOAD RAM */ 5236 ISPOPMAP(0xdf, 0x01), /* 0x0a: DUMP RAM */ | 6296 ISPOPMAP(0x01, 0x4f), /* 0x08: MBOX_ABOUT_FIRMWARE */ 6297 ISPOPMAP(0xdf, 0x01), /* 0x09: LOAD RAM */ 6298 ISPOPMAP(0xdf, 0x01), /* 0x0a: DUMP RAM */ |
5237 ISPOPMAP(0x00, 0x00), /* 0x0b: */ | 6299 ISPOPMAP(0x1ff, 0x01), /* 0x0b: MBOX_LOAD_RISC_RAM */ |
5238 ISPOPMAP(0x00, 0x00), /* 0x0c: */ | 6300 ISPOPMAP(0x00, 0x00), /* 0x0c: */ |
5239 ISPOPMAP(0x10f, 0x01), /* 0x0d: MBOX_WRITE_RAM_WORD_EXTENDED) */ | 6301 ISPOPMAP(0x10f, 0x01), /* 0x0d: MBOX_WRITE_RAM_WORD_EXTENDED */ |
5240 ISPOPMAP(0x01, 0x05), /* 0x0e: MBOX_CHECK_FIRMWARE */ 5241 ISPOPMAP(0x10f, 0x05), /* 0x0f: MBOX_READ_RAM_WORD_EXTENDED */ 5242 ISPOPMAP(0x1f, 0x11), /* 0x10: MBOX_INIT_REQ_QUEUE */ 5243 ISPOPMAP(0x2f, 0x21), /* 0x11: MBOX_INIT_RES_QUEUE */ 5244 ISPOPMAP(0x0f, 0x01), /* 0x12: MBOX_EXECUTE_IOCB */ 5245 ISPOPMAP(0x03, 0x03), /* 0x13: MBOX_WAKE_UP */ 5246 ISPOPMAP(0x01, 0xff), /* 0x14: MBOX_STOP_FIRMWARE */ 5247 ISPOPMAP(0x4f, 0x01), /* 0x15: MBOX_ABORT */ --- 36 unchanged lines hidden (view full) --- 5284 ISPOPMAP(0x00, 0x00), /* 0x3a: */ 5285 ISPOPMAP(0x00, 0x00), /* 0x3b: */ 5286 ISPOPMAP(0x00, 0x00), /* 0x3c: */ 5287 ISPOPMAP(0x00, 0x00), /* 0x3d: */ 5288 ISPOPMAP(0x00, 0x00), /* 0x3e: */ 5289 ISPOPMAP(0x00, 0x00), /* 0x3f: */ 5290 ISPOPMAP(0x03, 0x01), /* 0x40: MBOX_LOOP_PORT_BYPASS */ 5291 ISPOPMAP(0x03, 0x01), /* 0x41: MBOX_LOOP_PORT_ENABLE */ | 6302 ISPOPMAP(0x01, 0x05), /* 0x0e: MBOX_CHECK_FIRMWARE */ 6303 ISPOPMAP(0x10f, 0x05), /* 0x0f: MBOX_READ_RAM_WORD_EXTENDED */ 6304 ISPOPMAP(0x1f, 0x11), /* 0x10: MBOX_INIT_REQ_QUEUE */ 6305 ISPOPMAP(0x2f, 0x21), /* 0x11: MBOX_INIT_RES_QUEUE */ 6306 ISPOPMAP(0x0f, 0x01), /* 0x12: MBOX_EXECUTE_IOCB */ 6307 ISPOPMAP(0x03, 0x03), /* 0x13: MBOX_WAKE_UP */ 6308 ISPOPMAP(0x01, 0xff), /* 0x14: MBOX_STOP_FIRMWARE */ 6309 ISPOPMAP(0x4f, 0x01), /* 0x15: MBOX_ABORT */ --- 36 unchanged lines hidden (view full) --- 6346 ISPOPMAP(0x00, 0x00), /* 0x3a: */ 6347 ISPOPMAP(0x00, 0x00), /* 0x3b: */ 6348 ISPOPMAP(0x00, 0x00), /* 0x3c: */ 6349 ISPOPMAP(0x00, 0x00), /* 0x3d: */ 6350 ISPOPMAP(0x00, 0x00), /* 0x3e: */ 6351 ISPOPMAP(0x00, 0x00), /* 0x3f: */ 6352 ISPOPMAP(0x03, 0x01), /* 0x40: MBOX_LOOP_PORT_BYPASS */ 6353 ISPOPMAP(0x03, 0x01), /* 0x41: MBOX_LOOP_PORT_ENABLE */ |
5292 ISPOPMAP(0x03, 0x07), /* 0x42: MBOX_GET_RESOURCE_COUNTS */ 5293 ISPOPMAP(0x01, 0x01), /* 0x43: MBOX_REQUEST_NON_PARTICIPATING_MODE */ | 6354 ISPOPMAP(0x03, 0x07), /* 0x42: MBOX_GET_RESOURCE_COUNT */ 6355 ISPOPMAP(0x01, 0x01), /* 0x43: MBOX_REQUEST_OFFLINE_MODE */ |
5294 ISPOPMAP(0x00, 0x00), /* 0x44: */ 5295 ISPOPMAP(0x00, 0x00), /* 0x45: */ 5296 ISPOPMAP(0x00, 0x00), /* 0x46: */ 5297 ISPOPMAP(0xcf, 0x03), /* 0x47: GET PORT_DATABASE ENHANCED */ 5298 ISPOPMAP(0x00, 0x00), /* 0x48: */ 5299 ISPOPMAP(0x00, 0x00), /* 0x49: */ 5300 ISPOPMAP(0x00, 0x00), /* 0x4a: */ 5301 ISPOPMAP(0x00, 0x00), /* 0x4b: */ --- 12 unchanged lines hidden (view full) --- 5314 ISPOPMAP(0x00, 0x00), /* 0x58: */ 5315 ISPOPMAP(0x00, 0x00), /* 0x59: */ 5316 ISPOPMAP(0x00, 0x00), /* 0x5a: */ 5317 ISPOPMAP(0x03, 0x01), /* 0x5b: MBOX_DRIVER_HEARTBEAT */ 5318 ISPOPMAP(0xcf, 0x01), /* 0x5c: MBOX_FW_HEARTBEAT */ 5319 ISPOPMAP(0x07, 0x03), /* 0x5d: MBOX_GET_SET_DATA_RATE */ 5320 ISPOPMAP(0x00, 0x00), /* 0x5e: */ 5321 ISPOPMAP(0x00, 0x00), /* 0x5f: */ | 6356 ISPOPMAP(0x00, 0x00), /* 0x44: */ 6357 ISPOPMAP(0x00, 0x00), /* 0x45: */ 6358 ISPOPMAP(0x00, 0x00), /* 0x46: */ 6359 ISPOPMAP(0xcf, 0x03), /* 0x47: GET PORT_DATABASE ENHANCED */ 6360 ISPOPMAP(0x00, 0x00), /* 0x48: */ 6361 ISPOPMAP(0x00, 0x00), /* 0x49: */ 6362 ISPOPMAP(0x00, 0x00), /* 0x4a: */ 6363 ISPOPMAP(0x00, 0x00), /* 0x4b: */ --- 12 unchanged lines hidden (view full) --- 6376 ISPOPMAP(0x00, 0x00), /* 0x58: */ 6377 ISPOPMAP(0x00, 0x00), /* 0x59: */ 6378 ISPOPMAP(0x00, 0x00), /* 0x5a: */ 6379 ISPOPMAP(0x03, 0x01), /* 0x5b: MBOX_DRIVER_HEARTBEAT */ 6380 ISPOPMAP(0xcf, 0x01), /* 0x5c: MBOX_FW_HEARTBEAT */ 6381 ISPOPMAP(0x07, 0x03), /* 0x5d: MBOX_GET_SET_DATA_RATE */ 6382 ISPOPMAP(0x00, 0x00), /* 0x5e: */ 6383 ISPOPMAP(0x00, 0x00), /* 0x5f: */ |
5322 ISPOPMAP(0xcd, 0x31), /* 0x60: MBOX_INIT_FIRMWARE */ | 6384 ISPOPMAP(0xcd, 0x01), /* 0x60: MBOX_INIT_FIRMWARE */ |
5323 ISPOPMAP(0x00, 0x00), /* 0x61: */ 5324 ISPOPMAP(0x01, 0x01), /* 0x62: MBOX_INIT_LIP */ 5325 ISPOPMAP(0xcd, 0x03), /* 0x63: MBOX_GET_FC_AL_POSITION_MAP */ 5326 ISPOPMAP(0xcf, 0x01), /* 0x64: MBOX_GET_PORT_DB */ 5327 ISPOPMAP(0x07, 0x01), /* 0x65: MBOX_CLEAR_ACA */ 5328 ISPOPMAP(0x07, 0x01), /* 0x66: MBOX_TARGET_RESET */ 5329 ISPOPMAP(0x07, 0x01), /* 0x67: MBOX_CLEAR_TASK_SET */ 5330 ISPOPMAP(0x07, 0x01), /* 0x68: MBOX_ABORT_TASK_SET */ --- 24 unchanged lines hidden (view full) --- 5355 * Footnotes 5356 * 5357 * (1): this sets bits 21..16 in mailbox register #8, which we nominally 5358 * do not access at this time in the core driver. The caller is 5359 * responsible for setting this register first (Gross!). The assumption 5360 * is that we won't overflow. 5361 */ 5362 | 6385 ISPOPMAP(0x00, 0x00), /* 0x61: */ 6386 ISPOPMAP(0x01, 0x01), /* 0x62: MBOX_INIT_LIP */ 6387 ISPOPMAP(0xcd, 0x03), /* 0x63: MBOX_GET_FC_AL_POSITION_MAP */ 6388 ISPOPMAP(0xcf, 0x01), /* 0x64: MBOX_GET_PORT_DB */ 6389 ISPOPMAP(0x07, 0x01), /* 0x65: MBOX_CLEAR_ACA */ 6390 ISPOPMAP(0x07, 0x01), /* 0x66: MBOX_TARGET_RESET */ 6391 ISPOPMAP(0x07, 0x01), /* 0x67: MBOX_CLEAR_TASK_SET */ 6392 ISPOPMAP(0x07, 0x01), /* 0x68: MBOX_ABORT_TASK_SET */ --- 24 unchanged lines hidden (view full) --- 6417 * Footnotes 6418 * 6419 * (1): this sets bits 21..16 in mailbox register #8, which we nominally 6420 * do not access at this time in the core driver. The caller is 6421 * responsible for setting this register first (Gross!). The assumption 6422 * is that we won't overflow. 6423 */ 6424 |
5363#ifndef ISP_STRIPPED | |
5364static char *fc_mbcmd_names[] = { 5365 "NO-OP", 5366 "LOAD RAM", 5367 "EXEC FIRMWARE", 5368 "DUMP RAM", 5369 "WRITE RAM WORD", 5370 "READ RAM WORD", 5371 "MAILBOX REG TEST", --- 51 unchanged lines hidden (view full) --- 5423 NULL, 5424 NULL, 5425 NULL, 5426 NULL, 5427 NULL, 5428 NULL, 5429 "LOOP PORT BYPASS", 5430 "LOOP PORT ENABLE", | 6425static char *fc_mbcmd_names[] = { 6426 "NO-OP", 6427 "LOAD RAM", 6428 "EXEC FIRMWARE", 6429 "DUMP RAM", 6430 "WRITE RAM WORD", 6431 "READ RAM WORD", 6432 "MAILBOX REG TEST", --- 51 unchanged lines hidden (view full) --- 6484 NULL, 6485 NULL, 6486 NULL, 6487 NULL, 6488 NULL, 6489 NULL, 6490 "LOOP PORT BYPASS", 6491 "LOOP PORT ENABLE", |
5431 "GET RESOURCE COUNTS", | 6492 "GET RESOURCE COUNT", |
5432 "REQUEST NON PARTICIPATING MODE", 5433 NULL, 5434 NULL, 5435 NULL, 5436 "GET PORT DATABASE ENHANCED", 5437 NULL, 5438 NULL, 5439 NULL, --- 45 unchanged lines hidden (view full) --- 5485 NULL, 5486 NULL, 5487 NULL, 5488 NULL, 5489 "Get ID List", 5490 "SEND LFA", 5491 "Lun RESET" 5492}; | 6493 "REQUEST NON PARTICIPATING MODE", 6494 NULL, 6495 NULL, 6496 NULL, 6497 "GET PORT DATABASE ENHANCED", 6498 NULL, 6499 NULL, 6500 NULL, --- 45 unchanged lines hidden (view full) --- 6546 NULL, 6547 NULL, 6548 NULL, 6549 NULL, 6550 "Get ID List", 6551 "SEND LFA", 6552 "Lun RESET" 6553}; |
5493#endif | |
5494 5495static void 5496isp_mboxcmd_qnw(ispsoftc_t *isp, mbreg_t *mbp, int nodelay) 5497{ 5498 unsigned int ibits, obits, box, opcode; 5499 const uint32_t *mcp; 5500 5501 if (IS_FC(isp)) { --- 14 unchanged lines hidden (view full) --- 5516 isp->isp_mboxtmp[box] = mbp->param[box] = 0; 5517 } 5518 } 5519 if (nodelay == 0) { 5520 isp->isp_lastmbxcmd = opcode; 5521 isp->isp_obits = obits; 5522 isp->isp_mboxbsy = 1; 5523 } | 6554 6555static void 6556isp_mboxcmd_qnw(ispsoftc_t *isp, mbreg_t *mbp, int nodelay) 6557{ 6558 unsigned int ibits, obits, box, opcode; 6559 const uint32_t *mcp; 6560 6561 if (IS_FC(isp)) { --- 14 unchanged lines hidden (view full) --- 6576 isp->isp_mboxtmp[box] = mbp->param[box] = 0; 6577 } 6578 } 6579 if (nodelay == 0) { 6580 isp->isp_lastmbxcmd = opcode; 6581 isp->isp_obits = obits; 6582 isp->isp_mboxbsy = 1; 6583 } |
5524 ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT); | 6584 if (IS_24XX(isp)) { 6585 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_SET_HOST_INT); 6586 } else { 6587 ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT); 6588 } |
5525 /* 5526 * Oddly enough, if we're not delaying for an answer, 5527 * delay a bit to give the f/w a chance to pick up the 5528 * command. 5529 */ 5530 if (nodelay) { | 6589 /* 6590 * Oddly enough, if we're not delaying for an answer, 6591 * delay a bit to give the f/w a chance to pick up the 6592 * command. 6593 */ 6594 if (nodelay) { |
5531 USEC_DELAY(100); | 6595 USEC_DELAY(1000); |
5532 } 5533} 5534 5535static void | 6596 } 6597} 6598 6599static void |
5536isp_mboxcmd(ispsoftc_t *isp, mbreg_t *mbp, int logmask) | 6600isp_mboxcmd(ispsoftc_t *isp, mbreg_t *mbp) |
5537{ 5538 char *cname, *xname, tname[16], mname[16]; 5539 unsigned int lim, ibits, obits, box, opcode; 5540 const uint32_t *mcp; 5541 5542 if (IS_FC(isp)) { 5543 mcp = mbpfc; 5544 lim = (sizeof (mbpfc) / sizeof (mbpfc[0])); --- 21 unchanged lines hidden (view full) --- 5566 mbp->param[0] = MBOX_COMMAND_PARAM_ERROR; 5567 isp_prt(isp, ISP_LOGERR, "no parameters for 0x%x", opcode); 5568 return; 5569 } 5570 5571 /* 5572 * Get exclusive usage of mailbox registers. 5573 */ | 6601{ 6602 char *cname, *xname, tname[16], mname[16]; 6603 unsigned int lim, ibits, obits, box, opcode; 6604 const uint32_t *mcp; 6605 6606 if (IS_FC(isp)) { 6607 mcp = mbpfc; 6608 lim = (sizeof (mbpfc) / sizeof (mbpfc[0])); --- 21 unchanged lines hidden (view full) --- 6630 mbp->param[0] = MBOX_COMMAND_PARAM_ERROR; 6631 isp_prt(isp, ISP_LOGERR, "no parameters for 0x%x", opcode); 6632 return; 6633 } 6634 6635 /* 6636 * Get exclusive usage of mailbox registers. 6637 */ |
5574 MBOX_ACQUIRE(isp); | 6638 if (MBOX_ACQUIRE(isp)) { 6639 mbp->param[0] = MBOX_REGS_BUSY; 6640 goto out; 6641 } |
5575 5576 for (box = 0; box < MAX_MAILBOX(isp); box++) { 5577 if (ibits & (1 << box)) { | 6642 6643 for (box = 0; box < MAX_MAILBOX(isp); box++) { 6644 if (ibits & (1 << box)) { |
5578 isp_prt(isp, ISP_LOGDEBUG1, "IN mbox %d = 0x%x", box, | 6645 isp_prt(isp, ISP_LOGDEBUG1, "IN mbox %d = 0x%04x", box, |
5579 mbp->param[box]); 5580 ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]); 5581 } 5582 isp->isp_mboxtmp[box] = mbp->param[box] = 0; 5583 } 5584 5585 isp->isp_lastmbxcmd = opcode; 5586 5587 /* 5588 * We assume that we can't overwrite a previous command. 5589 */ 5590 isp->isp_obits = obits; 5591 isp->isp_mboxbsy = 1; 5592 5593 /* 5594 * Set Host Interrupt condition so that RISC will pick up mailbox regs. 5595 */ | 6646 mbp->param[box]); 6647 ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]); 6648 } 6649 isp->isp_mboxtmp[box] = mbp->param[box] = 0; 6650 } 6651 6652 isp->isp_lastmbxcmd = opcode; 6653 6654 /* 6655 * We assume that we can't overwrite a previous command. 6656 */ 6657 isp->isp_obits = obits; 6658 isp->isp_mboxbsy = 1; 6659 6660 /* 6661 * Set Host Interrupt condition so that RISC will pick up mailbox regs. 6662 */ |
5596 ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT); | 6663 if (IS_24XX(isp)) { 6664 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_SET_HOST_INT); 6665 } else { 6666 ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT); 6667 } |
5597 5598 /* 5599 * While we haven't finished the command, spin our wheels here. 5600 */ | 6668 6669 /* 6670 * While we haven't finished the command, spin our wheels here. 6671 */ |
5601 MBOX_WAIT_COMPLETE(isp); | 6672 MBOX_WAIT_COMPLETE(isp, mbp); |
5602 5603 /* 5604 * Did the command time out? 5605 */ | 6673 6674 /* 6675 * Did the command time out? 6676 */ |
5606 if (isp->isp_mboxbsy) { 5607 isp->isp_mboxbsy = 0; | 6677 if (mbp->param[0] == MBOX_TIMEOUT) { |
5608 MBOX_RELEASE(isp); | 6678 MBOX_RELEASE(isp); |
5609 return; | 6679 goto out; |
5610 } 5611 5612 /* 5613 * Copy back output registers. 5614 */ 5615 for (box = 0; box < MAX_MAILBOX(isp); box++) { 5616 if (obits & (1 << box)) { 5617 mbp->param[box] = isp->isp_mboxtmp[box]; | 6680 } 6681 6682 /* 6683 * Copy back output registers. 6684 */ 6685 for (box = 0; box < MAX_MAILBOX(isp); box++) { 6686 if (obits & (1 << box)) { 6687 mbp->param[box] = isp->isp_mboxtmp[box]; |
5618 isp_prt(isp, ISP_LOGDEBUG1, "OUT mbox %d = 0x%x", box, | 6688 isp_prt(isp, ISP_LOGDEBUG1, "OUT mbox %d = 0x%04x", box, |
5619 mbp->param[box]); 5620 } 5621 } 5622 5623 MBOX_RELEASE(isp); | 6689 mbp->param[box]); 6690 } 6691 } 6692 6693 MBOX_RELEASE(isp); |
5624 5625 if (logmask == 0 || opcode == MBOX_EXEC_FIRMWARE) { | 6694 out: 6695 isp->isp_mboxbsy = 0; 6696 if (mbp->logval == 0 || opcode == MBOX_EXEC_FIRMWARE) { |
5626 return; 5627 } | 6697 return; 6698 } |
5628#ifdef ISP_STRIPPED 5629 cname = NULL; 5630#else | |
5631 cname = (IS_FC(isp))? fc_mbcmd_names[opcode] : scsi_mbcmd_names[opcode]; | 6699 cname = (IS_FC(isp))? fc_mbcmd_names[opcode] : scsi_mbcmd_names[opcode]; |
5632#endif | |
5633 if (cname == NULL) { 5634 cname = tname; 5635 SNPRINTF(tname, sizeof tname, "opcode %x", opcode); 5636 } 5637 5638 /* 5639 * Just to be chatty here... 5640 */ 5641 xname = NULL; 5642 switch (mbp->param[0]) { 5643 case MBOX_COMMAND_COMPLETE: 5644 break; 5645 case MBOX_INVALID_COMMAND: | 6700 if (cname == NULL) { 6701 cname = tname; 6702 SNPRINTF(tname, sizeof tname, "opcode %x", opcode); 6703 } 6704 6705 /* 6706 * Just to be chatty here... 6707 */ 6708 xname = NULL; 6709 switch (mbp->param[0]) { 6710 case MBOX_COMMAND_COMPLETE: 6711 break; 6712 case MBOX_INVALID_COMMAND: |
5646 if (logmask & MBLOGMASK(MBOX_COMMAND_COMPLETE)) { | 6713 if (mbp->logval & MBLOGMASK(MBOX_COMMAND_COMPLETE)) { |
5647 xname = "INVALID COMMAND"; 5648 } 5649 break; 5650 case MBOX_HOST_INTERFACE_ERROR: | 6714 xname = "INVALID COMMAND"; 6715 } 6716 break; 6717 case MBOX_HOST_INTERFACE_ERROR: |
5651 if (logmask & MBLOGMASK(MBOX_HOST_INTERFACE_ERROR)) { | 6718 if (mbp->logval & MBLOGMASK(MBOX_HOST_INTERFACE_ERROR)) { |
5652 xname = "HOST INTERFACE ERROR"; 5653 } 5654 break; 5655 case MBOX_TEST_FAILED: | 6719 xname = "HOST INTERFACE ERROR"; 6720 } 6721 break; 6722 case MBOX_TEST_FAILED: |
5656 if (logmask & MBLOGMASK(MBOX_TEST_FAILED)) { | 6723 if (mbp->logval & MBLOGMASK(MBOX_TEST_FAILED)) { |
5657 xname = "TEST FAILED"; 5658 } 5659 break; 5660 case MBOX_COMMAND_ERROR: | 6724 xname = "TEST FAILED"; 6725 } 6726 break; 6727 case MBOX_COMMAND_ERROR: |
5661 if (logmask & MBLOGMASK(MBOX_COMMAND_ERROR)) { | 6728 if (mbp->logval & MBLOGMASK(MBOX_COMMAND_ERROR)) { |
5662 xname = "COMMAND ERROR"; 5663 } 5664 break; 5665 case MBOX_COMMAND_PARAM_ERROR: | 6729 xname = "COMMAND ERROR"; 6730 } 6731 break; 6732 case MBOX_COMMAND_PARAM_ERROR: |
5666 if (logmask & MBLOGMASK(MBOX_COMMAND_PARAM_ERROR)) { | 6733 if (mbp->logval & MBLOGMASK(MBOX_COMMAND_PARAM_ERROR)) { |
5667 xname = "COMMAND PARAMETER ERROR"; 5668 } 5669 break; 5670 case MBOX_LOOP_ID_USED: | 6734 xname = "COMMAND PARAMETER ERROR"; 6735 } 6736 break; 6737 case MBOX_LOOP_ID_USED: |
5671 if (logmask & MBLOGMASK(MBOX_LOOP_ID_USED)) { | 6738 if (mbp->logval & MBLOGMASK(MBOX_LOOP_ID_USED)) { |
5672 xname = "LOOP ID ALREADY IN USE"; 5673 } 5674 break; 5675 case MBOX_PORT_ID_USED: | 6739 xname = "LOOP ID ALREADY IN USE"; 6740 } 6741 break; 6742 case MBOX_PORT_ID_USED: |
5676 if (logmask & MBLOGMASK(MBOX_PORT_ID_USED)) { | 6743 if (mbp->logval & MBLOGMASK(MBOX_PORT_ID_USED)) { |
5677 xname = "PORT ID ALREADY IN USE"; 5678 } 5679 break; 5680 case MBOX_ALL_IDS_USED: | 6744 xname = "PORT ID ALREADY IN USE"; 6745 } 6746 break; 6747 case MBOX_ALL_IDS_USED: |
5681 if (logmask & MBLOGMASK(MBOX_ALL_IDS_USED)) { | 6748 if (mbp->logval & MBLOGMASK(MBOX_ALL_IDS_USED)) { |
5682 xname = "ALL LOOP IDS IN USE"; 5683 } 5684 break; | 6749 xname = "ALL LOOP IDS IN USE"; 6750 } 6751 break; |
5685 case 0: /* special case */ | 6752 case MBOX_REGS_BUSY: 6753 xname = "REGISTERS BUSY"; 6754 break; 6755 case MBOX_TIMEOUT: |
5686 xname = "TIMEOUT"; 5687 break; 5688 default: 5689 SNPRINTF(mname, sizeof mname, "error 0x%x", mbp->param[0]); 5690 xname = mname; 5691 break; 5692 } 5693 if (xname) { --- 6 unchanged lines hidden (view full) --- 5700isp_fw_state(ispsoftc_t *isp) 5701{ 5702 if (IS_FC(isp)) { 5703 mbreg_t mbs; 5704 fcparam *fcp = isp->isp_param; 5705 5706 MEMZERO(&mbs, sizeof (mbs)); 5707 mbs.param[0] = MBOX_GET_FW_STATE; | 6756 xname = "TIMEOUT"; 6757 break; 6758 default: 6759 SNPRINTF(mname, sizeof mname, "error 0x%x", mbp->param[0]); 6760 xname = mname; 6761 break; 6762 } 6763 if (xname) { --- 6 unchanged lines hidden (view full) --- 6770isp_fw_state(ispsoftc_t *isp) 6771{ 6772 if (IS_FC(isp)) { 6773 mbreg_t mbs; 6774 fcparam *fcp = isp->isp_param; 6775 6776 MEMZERO(&mbs, sizeof (mbs)); 6777 mbs.param[0] = MBOX_GET_FW_STATE; |
5708 isp_mboxcmd(isp, &mbs, MBLOGALL); | 6778 mbs.logval = MBLOGALL; 6779 mbs.timeout = 100000; 6780 isp_mboxcmd(isp, &mbs); |
5709 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { 5710 fcp->isp_fwstate = mbs.param[1]; 5711 } 5712 } 5713} 5714 5715static void 5716isp_update(ispsoftc_t *isp) --- 45 unchanged lines hidden (view full) --- 5762 5763 MEMZERO(&mbs, sizeof (mbs)); 5764 5765 /* 5766 * Refresh overrides set 5767 */ 5768 if (sdp->isp_devparam[tgt].dev_refresh) { 5769 mbs.param[0] = MBOX_GET_TARGET_PARAMS; | 6781 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { 6782 fcp->isp_fwstate = mbs.param[1]; 6783 } 6784 } 6785} 6786 6787static void 6788isp_update(ispsoftc_t *isp) --- 45 unchanged lines hidden (view full) --- 6834 6835 MEMZERO(&mbs, sizeof (mbs)); 6836 6837 /* 6838 * Refresh overrides set 6839 */ 6840 if (sdp->isp_devparam[tgt].dev_refresh) { 6841 mbs.param[0] = MBOX_GET_TARGET_PARAMS; |
5770 sdp->isp_devparam[tgt].dev_refresh = 0; | |
5771 get = 1; 5772 } else if (sdp->isp_devparam[tgt].dev_update) { 5773 mbs.param[0] = MBOX_SET_TARGET_PARAMS; | 6842 get = 1; 6843 } else if (sdp->isp_devparam[tgt].dev_update) { 6844 mbs.param[0] = MBOX_SET_TARGET_PARAMS; |
6845 |
|
5774 /* 5775 * Make sure goal_flags has "Renegotiate on Error" 5776 * on and "Freeze Queue on Error" off. 5777 */ 5778 sdp->isp_devparam[tgt].goal_flags |= DPARM_RENEG; 5779 sdp->isp_devparam[tgt].goal_flags &= ~DPARM_QFRZ; | 6846 /* 6847 * Make sure goal_flags has "Renegotiate on Error" 6848 * on and "Freeze Queue on Error" off. 6849 */ 6850 sdp->isp_devparam[tgt].goal_flags |= DPARM_RENEG; 6851 sdp->isp_devparam[tgt].goal_flags &= ~DPARM_QFRZ; |
5780 | |
5781 mbs.param[2] = sdp->isp_devparam[tgt].goal_flags; 5782 5783 /* 5784 * Insist that PARITY must be enabled 5785 * if SYNC or WIDE is enabled. 5786 */ 5787 if ((mbs.param[2] & (DPARM_SYNC|DPARM_WIDE)) != 0) { 5788 mbs.param[2] |= DPARM_PARITY; --- 17 unchanged lines hidden (view full) --- 5806 */ 5807 sdp->isp_devparam[tgt].actv_flags &= ~DPARM_TQING; 5808 sdp->isp_devparam[tgt].actv_flags |= 5809 (sdp->isp_devparam[tgt].goal_flags & DPARM_TQING); 5810 isp_prt(isp, ISP_LOGDEBUG0, 5811 "bus %d set tgt %d flags 0x%x off 0x%x period 0x%x", 5812 bus, tgt, mbs.param[2], mbs.param[3] >> 8, 5813 mbs.param[3] & 0xff); | 6852 mbs.param[2] = sdp->isp_devparam[tgt].goal_flags; 6853 6854 /* 6855 * Insist that PARITY must be enabled 6856 * if SYNC or WIDE is enabled. 6857 */ 6858 if ((mbs.param[2] & (DPARM_SYNC|DPARM_WIDE)) != 0) { 6859 mbs.param[2] |= DPARM_PARITY; --- 17 unchanged lines hidden (view full) --- 6877 */ 6878 sdp->isp_devparam[tgt].actv_flags &= ~DPARM_TQING; 6879 sdp->isp_devparam[tgt].actv_flags |= 6880 (sdp->isp_devparam[tgt].goal_flags & DPARM_TQING); 6881 isp_prt(isp, ISP_LOGDEBUG0, 6882 "bus %d set tgt %d flags 0x%x off 0x%x period 0x%x", 6883 bus, tgt, mbs.param[2], mbs.param[3] >> 8, 6884 mbs.param[3] & 0xff); |
5814 sdp->isp_devparam[tgt].dev_update = 0; 5815 sdp->isp_devparam[tgt].dev_refresh = 1; | |
5816 get = 0; 5817 } else { 5818 continue; 5819 } 5820 mbs.param[1] = (bus << 15) | (tgt << 8); | 6885 get = 0; 6886 } else { 6887 continue; 6888 } 6889 mbs.param[1] = (bus << 15) | (tgt << 8); |
5821 isp_mboxcmd(isp, &mbs, MBLOGALL); | 6890 mbs.logval = MBLOGALL; 6891 isp_mboxcmd(isp, &mbs); 6892 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 6893 continue; 6894 } |
5822 if (get == 0) { 5823 isp->isp_sendmarker |= (1 << bus); | 6895 if (get == 0) { 6896 isp->isp_sendmarker |= (1 << bus); |
5824 continue; | 6897 sdp->isp_devparam[tgt].dev_update = 0; 6898 sdp->isp_devparam[tgt].dev_refresh = 1; 6899 } else { 6900 sdp->isp_devparam[tgt].dev_refresh = 0; 6901 flags = mbs.param[2]; 6902 period = mbs.param[3] & 0xff; 6903 offset = mbs.param[3] >> 8; 6904 sdp->isp_devparam[tgt].actv_flags = flags; 6905 sdp->isp_devparam[tgt].actv_period = period; 6906 sdp->isp_devparam[tgt].actv_offset = offset; 6907 get = (bus << 16) | tgt; 6908 (void) isp_async(isp, ISPASYNC_NEW_TGT_PARAMS, &get); |
5825 } | 6909 } |
5826 flags = mbs.param[2]; 5827 period = mbs.param[3] & 0xff; 5828 offset = mbs.param[3] >> 8; 5829 sdp->isp_devparam[tgt].actv_flags = flags; 5830 sdp->isp_devparam[tgt].actv_period = period; 5831 sdp->isp_devparam[tgt].actv_offset = offset; 5832 get = (bus << 16) | tgt; 5833 (void) isp_async(isp, ISPASYNC_NEW_TGT_PARAMS, &get); | |
5834 } 5835 5836 for (tgt = 0; tgt < MAX_TARGETS; tgt++) { 5837 if (sdp->isp_devparam[tgt].dev_update || 5838 sdp->isp_devparam[tgt].dev_refresh) { 5839 isp->isp_update |= (1 << bus); 5840 break; 5841 } --- 74 unchanged lines hidden (view full) --- 5916 } else { 5917 /* 5918 * We always start out with values derived 5919 * from NVRAM or our platform default. 5920 */ 5921 ISP_NODEWWN(isp) = fcp->isp_nodewwn; 5922 if (fcp->isp_nodewwn == 0) { 5923 isp_prt(isp, ISP_LOGCONFIG, | 6910 } 6911 6912 for (tgt = 0; tgt < MAX_TARGETS; tgt++) { 6913 if (sdp->isp_devparam[tgt].dev_update || 6914 sdp->isp_devparam[tgt].dev_refresh) { 6915 isp->isp_update |= (1 << bus); 6916 break; 6917 } --- 74 unchanged lines hidden (view full) --- 6992 } else { 6993 /* 6994 * We always start out with values derived 6995 * from NVRAM or our platform default. 6996 */ 6997 ISP_NODEWWN(isp) = fcp->isp_nodewwn; 6998 if (fcp->isp_nodewwn == 0) { 6999 isp_prt(isp, ISP_LOGCONFIG, |
5924 "bad WWNN- using default\n"); | 7000 "bad WWNN- using default"); |
5925 ISP_NODEWWN(isp) = DEFAULT_NODEWWN(isp); 5926 } 5927 } 5928 if (isp->isp_confopts & ISP_CFG_OWNWWPN) { 5929 isp_prt(isp, ISP_LOGCONFIG, "Using Port WWN 0x%08x%08x", 5930 (uint32_t) (DEFAULT_PORTWWN(isp) >> 32), 5931 (uint32_t) (DEFAULT_PORTWWN(isp) & 0xffffffff)); 5932 ISP_PORTWWN(isp) = DEFAULT_PORTWWN(isp); 5933 } else { 5934 /* 5935 * We always start out with values derived 5936 * from NVRAM or our platform default. 5937 */ 5938 ISP_PORTWWN(isp) = fcp->isp_portwwn; 5939 if (fcp->isp_portwwn == 0) { 5940 isp_prt(isp, ISP_LOGCONFIG, | 7001 ISP_NODEWWN(isp) = DEFAULT_NODEWWN(isp); 7002 } 7003 } 7004 if (isp->isp_confopts & ISP_CFG_OWNWWPN) { 7005 isp_prt(isp, ISP_LOGCONFIG, "Using Port WWN 0x%08x%08x", 7006 (uint32_t) (DEFAULT_PORTWWN(isp) >> 32), 7007 (uint32_t) (DEFAULT_PORTWWN(isp) & 0xffffffff)); 7008 ISP_PORTWWN(isp) = DEFAULT_PORTWWN(isp); 7009 } else { 7010 /* 7011 * We always start out with values derived 7012 * from NVRAM or our platform default. 7013 */ 7014 ISP_PORTWWN(isp) = fcp->isp_portwwn; 7015 if (fcp->isp_portwwn == 0) { 7016 isp_prt(isp, ISP_LOGCONFIG, |
5941 "bad WWPN- using default\n"); | 7017 "bad WWPN- using default"); |
5942 ISP_PORTWWN(isp) = DEFAULT_PORTWWN(isp); 5943 } 5944 } 5945 return; 5946 } 5947 5948 sdp = (sdparam *) isp->isp_param; 5949 sdp += channel; --- 50 unchanged lines hidden (view full) --- 6000 /* 6001 * Now try and see whether we have specific values for them. 6002 */ 6003 if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) { 6004 mbreg_t mbs; 6005 6006 MEMZERO(&mbs, sizeof (mbs)); 6007 mbs.param[0] = MBOX_GET_ACT_NEG_STATE; | 7018 ISP_PORTWWN(isp) = DEFAULT_PORTWWN(isp); 7019 } 7020 } 7021 return; 7022 } 7023 7024 sdp = (sdparam *) isp->isp_param; 7025 sdp += channel; --- 50 unchanged lines hidden (view full) --- 7076 /* 7077 * Now try and see whether we have specific values for them. 7078 */ 7079 if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) { 7080 mbreg_t mbs; 7081 7082 MEMZERO(&mbs, sizeof (mbs)); 7083 mbs.param[0] = MBOX_GET_ACT_NEG_STATE; |
6008 isp_mboxcmd(isp, &mbs, MBLOGNONE); | 7084 mbs.logval = MBLOGNONE; 7085 isp_mboxcmd(isp, &mbs); |
6009 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 6010 sdp->isp_req_ack_active_neg = 1; 6011 sdp->isp_data_line_active_neg = 1; 6012 } else { 6013 sdp->isp_req_ack_active_neg = 6014 (mbs.param[1+channel] >> 4) & 0x1; 6015 sdp->isp_data_line_active_neg = 6016 (mbs.param[1+channel] >> 5) & 0x1; --- 60 unchanged lines hidden (view full) --- 6077 sdp->isp_devparam[tgt].nvrm_period); 6078 } 6079} 6080 6081/* 6082 * Re-initialize the ISP and complete all orphaned commands 6083 * with a 'botched' notice. The reset/init routines should 6084 * not disturb an already active list of commands. | 7086 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 7087 sdp->isp_req_ack_active_neg = 1; 7088 sdp->isp_data_line_active_neg = 1; 7089 } else { 7090 sdp->isp_req_ack_active_neg = 7091 (mbs.param[1+channel] >> 4) & 0x1; 7092 sdp->isp_data_line_active_neg = 7093 (mbs.param[1+channel] >> 5) & 0x1; --- 60 unchanged lines hidden (view full) --- 7154 sdp->isp_devparam[tgt].nvrm_period); 7155 } 7156} 7157 7158/* 7159 * Re-initialize the ISP and complete all orphaned commands 7160 * with a 'botched' notice. The reset/init routines should 7161 * not disturb an already active list of commands. |
6085 * 6086 * Locks held prior to coming here. | |
6087 */ 6088 6089void 6090isp_reinit(ispsoftc_t *isp) 6091{ 6092 XS_T *xs; | 7162 */ 7163 7164void 7165isp_reinit(ispsoftc_t *isp) 7166{ 7167 XS_T *xs; |
6093 int i; | 7168 uint32_t tmp; |
6094 6095 if (IS_FC(isp)) { | 7169 7170 if (IS_FC(isp)) { |
6096 isp_mark_getpdb_all(isp); | 7171 isp_mark_portdb(isp, 0); |
6097 } 6098 isp_reset(isp); 6099 if (isp->isp_state != ISP_RESETSTATE) { 6100 isp_prt(isp, ISP_LOGERR, "isp_reinit cannot reset card"); 6101 } else if (isp->isp_role != ISP_ROLE_NONE) { 6102 isp_init(isp); 6103 if (isp->isp_state == ISP_INITSTATE) { 6104 isp->isp_state = ISP_RUNSTATE; 6105 } 6106 if (isp->isp_state != ISP_RUNSTATE) { 6107 isp_prt(isp, ISP_LOGERR, 6108 "isp_reinit cannot restart card"); | 7172 } 7173 isp_reset(isp); 7174 if (isp->isp_state != ISP_RESETSTATE) { 7175 isp_prt(isp, ISP_LOGERR, "isp_reinit cannot reset card"); 7176 } else if (isp->isp_role != ISP_ROLE_NONE) { 7177 isp_init(isp); 7178 if (isp->isp_state == ISP_INITSTATE) { 7179 isp->isp_state = ISP_RUNSTATE; 7180 } 7181 if (isp->isp_state != ISP_RUNSTATE) { 7182 isp_prt(isp, ISP_LOGERR, 7183 "isp_reinit cannot restart card"); |
7184 ISP_DISABLE_INTS(isp); |
|
6109 } | 7185 } |
6110 } | 7186 } else { 7187 ISP_DISABLE_INTS(isp); 7188 if (IS_FC(isp)) { 7189 /* 7190 * If we're in ISP_ROLE_NONE, turn off the lasers. 7191 */ 7192 if (!IS_24XX(isp)) { 7193 ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS); 7194 ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET); 7195 ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS); 7196 ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL); 7197 ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS); 7198 } 7199 } 7200 } |
6111 isp->isp_nactive = 0; 6112 | 7201 isp->isp_nactive = 0; 7202 |
6113 for (i = 0; i < isp->isp_maxcmds; i++) { 6114 uint16_t handle; 6115 xs = isp->isp_xflist[i]; | 7203 for (tmp = 0; tmp < isp->isp_maxcmds; tmp++) { 7204 uint32_t handle; 7205 7206 xs = isp->isp_xflist[tmp]; |
6116 if (xs == NULL) { 6117 continue; 6118 } | 7207 if (xs == NULL) { 7208 continue; 7209 } |
6119 handle = isp_index_handle(i); | 7210 handle = isp_find_handle(isp, xs); 7211 if (handle == 0) { 7212 continue; 7213 } |
6120 isp_destroy_handle(isp, handle); 6121 if (XS_XFRLEN(xs)) { 6122 ISP_DMAFREE(isp, xs, handle); 6123 XS_RESID(xs) = XS_XFRLEN(xs); 6124 } else { 6125 XS_RESID(xs) = 0; 6126 } 6127 XS_SETERR(xs, HBA_BUSRESET); 6128 isp_done(xs); 6129 } | 7214 isp_destroy_handle(isp, handle); 7215 if (XS_XFRLEN(xs)) { 7216 ISP_DMAFREE(isp, xs, handle); 7217 XS_RESID(xs) = XS_XFRLEN(xs); 7218 } else { 7219 XS_RESID(xs) = 0; 7220 } 7221 XS_SETERR(xs, HBA_BUSRESET); 7222 isp_done(xs); 7223 } |
7224#ifdef ISP_TARGET_MODE 7225 MEMZERO(isp->isp_tgtlist, isp->isp_maxcmds * sizeof (void **)); 7226#endif |
|
6130} 6131 6132/* 6133 * NVRAM Routines 6134 */ 6135static int 6136isp_read_nvram(ispsoftc_t *isp) 6137{ 6138 int i, amt, retval; 6139 uint8_t csum, minversion; 6140 union { 6141 uint8_t _x[ISP2100_NVRAM_SIZE]; 6142 uint16_t _s[ISP2100_NVRAM_SIZE>>1]; 6143 } _n; 6144#define nvram_data _n._x 6145#define nvram_words _n._s 6146 | 7227} 7228 7229/* 7230 * NVRAM Routines 7231 */ 7232static int 7233isp_read_nvram(ispsoftc_t *isp) 7234{ 7235 int i, amt, retval; 7236 uint8_t csum, minversion; 7237 union { 7238 uint8_t _x[ISP2100_NVRAM_SIZE]; 7239 uint16_t _s[ISP2100_NVRAM_SIZE>>1]; 7240 } _n; 7241#define nvram_data _n._x 7242#define nvram_words _n._s 7243 |
6147 if (IS_FC(isp)) { | 7244 if (IS_24XX(isp)) { 7245 return (isp_read_nvram_2400(isp)); 7246 } else if (IS_FC(isp)) { |
6148 amt = ISP2100_NVRAM_SIZE; 6149 minversion = 1; 6150 } else if (IS_ULTRA2(isp)) { 6151 amt = ISP1080_NVRAM_SIZE; 6152 minversion = 0; 6153 } else { 6154 amt = ISP_NVRAM_SIZE; 6155 minversion = 2; 6156 } 6157 | 7247 amt = ISP2100_NVRAM_SIZE; 7248 minversion = 1; 7249 } else if (IS_ULTRA2(isp)) { 7250 amt = ISP1080_NVRAM_SIZE; 7251 minversion = 0; 7252 } else { 7253 amt = ISP_NVRAM_SIZE; 7254 minversion = 2; 7255 } 7256 |
6158 /* 6159 * Just read the first two words first to see if we have a valid 6160 * NVRAM to continue reading the rest with. 6161 */ 6162 for (i = 0; i < 2; i++) { | 7257 for (i = 0; i < amt>>1; i++) { |
6163 isp_rdnvram_word(isp, i, &nvram_words[i]); 6164 } | 7258 isp_rdnvram_word(isp, i, &nvram_words[i]); 7259 } |
7260 |
|
6165 if (nvram_data[0] != 'I' || nvram_data[1] != 'S' || 6166 nvram_data[2] != 'P') { 6167 if (isp->isp_bustype != ISP_BT_SBUS) { 6168 isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header"); 6169 isp_prt(isp, ISP_LOGDEBUG0, "%x %x %x", 6170 nvram_data[0], nvram_data[1], nvram_data[2]); 6171 } 6172 retval = -1; 6173 goto out; 6174 } | 7261 if (nvram_data[0] != 'I' || nvram_data[1] != 'S' || 7262 nvram_data[2] != 'P') { 7263 if (isp->isp_bustype != ISP_BT_SBUS) { 7264 isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header"); 7265 isp_prt(isp, ISP_LOGDEBUG0, "%x %x %x", 7266 nvram_data[0], nvram_data[1], nvram_data[2]); 7267 } 7268 retval = -1; 7269 goto out; 7270 } |
6175 for (i = 2; i < amt>>1; i++) { 6176 isp_rdnvram_word(isp, i, &nvram_words[i]); 6177 } | 7271 |
6178 for (csum = 0, i = 0; i < amt; i++) { 6179 csum += nvram_data[i]; 6180 } 6181 if (csum != 0) { 6182 isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum"); 6183 retval = -1; 6184 goto out; 6185 } | 7272 for (csum = 0, i = 0; i < amt; i++) { 7273 csum += nvram_data[i]; 7274 } 7275 if (csum != 0) { 7276 isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum"); 7277 retval = -1; 7278 goto out; 7279 } |
7280 |
|
6186 if (ISP_NVRAM_VERSION(nvram_data) < minversion) { 6187 isp_prt(isp, ISP_LOGWARN, "version %d NVRAM not understood", 6188 ISP_NVRAM_VERSION(nvram_data)); 6189 retval = -1; 6190 goto out; 6191 } 6192 6193 if (IS_ULTRA3(isp)) { --- 12 unchanged lines hidden (view full) --- 6206 } 6207 retval = 0; 6208out: 6209 return (retval); 6210#undef nvram_data 6211#undef nvram_words 6212} 6213 | 7281 if (ISP_NVRAM_VERSION(nvram_data) < minversion) { 7282 isp_prt(isp, ISP_LOGWARN, "version %d NVRAM not understood", 7283 ISP_NVRAM_VERSION(nvram_data)); 7284 retval = -1; 7285 goto out; 7286 } 7287 7288 if (IS_ULTRA3(isp)) { --- 12 unchanged lines hidden (view full) --- 7301 } 7302 retval = 0; 7303out: 7304 return (retval); 7305#undef nvram_data 7306#undef nvram_words 7307} 7308 |
7309static int 7310isp_read_nvram_2400(ispsoftc_t *isp) 7311{ 7312 uint8_t *nvram_data = FCPARAM(isp)->isp_scratch; 7313 int retval = 0; 7314 uint32_t addr, csum, lwrds, *dptr; 7315 7316 if (isp->isp_port) { 7317 addr = ISP2400_NVRAM_PORT1_ADDR; 7318 } else { 7319 addr = ISP2400_NVRAM_PORT0_ADDR; 7320 } 7321 7322 dptr = (uint32_t *) nvram_data; 7323 for (lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) { 7324 isp_rd_2400_nvram(isp, addr++, dptr++); 7325 } 7326 if (nvram_data[0] != 'I' || nvram_data[1] != 'S' || 7327 nvram_data[2] != 'P') { 7328 isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header"); 7329 retval = -1; 7330 goto out; 7331 } 7332 dptr = (uint32_t *) nvram_data; 7333 for (csum = 0, lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) { 7334 csum += dptr[lwrds]; 7335 } 7336 if (csum != 0) { 7337 isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum"); 7338 retval = -1; 7339 goto out; 7340 } 7341 isp_parse_nvram_2400(isp, nvram_data); 7342out: 7343 return (retval); 7344} 7345 |
|
6214static void 6215isp_rdnvram_word(ispsoftc_t *isp, int wo, uint16_t *rp) 6216{ 6217 int i, cbits; 6218 uint16_t bit, rqst, junk; 6219 6220 ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT); 6221 USEC_DELAY(10); --- 56 unchanged lines hidden (view full) --- 6278 } 6279 ISP_WRITE(isp, BIU_NVRAM, 0); 6280 USEC_DELAY(10); 6281 junk = ISP_READ(isp, BIU_NVRAM); /* force PCI flush */ 6282 ISP_SWIZZLE_NVRAM_WORD(isp, rp); 6283} 6284 6285static void | 7346static void 7347isp_rdnvram_word(ispsoftc_t *isp, int wo, uint16_t *rp) 7348{ 7349 int i, cbits; 7350 uint16_t bit, rqst, junk; 7351 7352 ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT); 7353 USEC_DELAY(10); --- 56 unchanged lines hidden (view full) --- 7410 } 7411 ISP_WRITE(isp, BIU_NVRAM, 0); 7412 USEC_DELAY(10); 7413 junk = ISP_READ(isp, BIU_NVRAM); /* force PCI flush */ 7414 ISP_SWIZZLE_NVRAM_WORD(isp, rp); 7415} 7416 7417static void |
7418isp_rd_2400_nvram(ispsoftc_t *isp, uint32_t addr, uint32_t *rp) 7419{ 7420 int loops = 0; 7421 const uint32_t base = 0x7ffe0000; 7422 uint32_t tmp; 7423 7424 ISP_WRITE(isp, BIU2400_FLASH_ADDR, base | addr); 7425 for (loops = 0; loops < 5000; loops++) { 7426 USEC_DELAY(10); 7427 tmp = ISP_READ(isp, BIU2400_FLASH_ADDR); 7428 if ((tmp & (1 << 31)) != 0) { 7429 break; 7430 } 7431 } 7432 if (tmp & (1 << 31)) { 7433 tmp = ISP_READ(isp, BIU2400_FLASH_DATA); 7434 *rp = tmp; 7435 } else { 7436 *rp = 0xffffffff; 7437 } 7438} 7439 7440static void |
|
6286isp_parse_nvram_1020(ispsoftc_t *isp, uint8_t *nvram_data) 6287{ 6288 sdparam *sdp = (sdparam *) isp->isp_param; 6289 int tgt; 6290 6291 sdp->isp_fifo_threshold = 6292 ISP_NVRAM_FIFO_THRESHOLD(nvram_data) | 6293 (ISP_NVRAM_FIFO_THRESHOLD_128(nvram_data) << 2); --- 293 unchanged lines hidden (view full) --- 6587 sdp->isp_devparam[tgt].goal_period = 6588 sdp->isp_devparam[tgt].nvrm_period; 6589 sdp->isp_devparam[tgt].goal_flags = 6590 sdp->isp_devparam[tgt].nvrm_flags; 6591 } 6592} 6593 6594static void | 7441isp_parse_nvram_1020(ispsoftc_t *isp, uint8_t *nvram_data) 7442{ 7443 sdparam *sdp = (sdparam *) isp->isp_param; 7444 int tgt; 7445 7446 sdp->isp_fifo_threshold = 7447 ISP_NVRAM_FIFO_THRESHOLD(nvram_data) | 7448 (ISP_NVRAM_FIFO_THRESHOLD_128(nvram_data) << 2); --- 293 unchanged lines hidden (view full) --- 7742 sdp->isp_devparam[tgt].goal_period = 7743 sdp->isp_devparam[tgt].nvrm_period; 7744 sdp->isp_devparam[tgt].goal_flags = 7745 sdp->isp_devparam[tgt].nvrm_flags; 7746 } 7747} 7748 7749static void |
7750isp_fix_nvram_wwns(ispsoftc_t *isp) 7751{ 7752 fcparam *fcp = FCPARAM(isp); 7753 7754 /* 7755 * Make sure we have both Node and Port as non-zero values. 7756 */ 7757 if (fcp->isp_nodewwn != 0 && fcp->isp_portwwn == 0) { 7758 fcp->isp_portwwn = fcp->isp_nodewwn; 7759 } else if (fcp->isp_nodewwn == 0 && fcp->isp_portwwn != 0) { 7760 fcp->isp_nodewwn = fcp->isp_portwwn; 7761 } 7762 7763 /* 7764 * Make the Node and Port values sane if they're NAA == 2. 7765 * This means to clear bits 48..56 for the Node WWN and 7766 * make sure that there's some non-zero value in 48..56 7767 * for the Port WWN. 7768 */ 7769 if (fcp->isp_nodewwn && fcp->isp_portwwn) { 7770 if ((fcp->isp_nodewwn & (((uint64_t) 0xfff) << 48)) != 0 && 7771 (fcp->isp_nodewwn >> 60) == 2) { 7772 fcp->isp_nodewwn &= ~((uint64_t) 0xfff << 48); 7773 } 7774 if ((fcp->isp_portwwn & (((uint64_t) 0xfff) << 48)) == 0 && 7775 (fcp->isp_portwwn >> 60) == 2) { 7776 fcp->isp_portwwn |= ((uint64_t) 1 << 56); 7777 } 7778 } 7779} 7780 7781static void |
|
6595isp_parse_nvram_2100(ispsoftc_t *isp, uint8_t *nvram_data) 6596{ | 7782isp_parse_nvram_2100(ispsoftc_t *isp, uint8_t *nvram_data) 7783{ |
6597 fcparam *fcp = (fcparam *) isp->isp_param; | 7784 fcparam *fcp = FCPARAM(isp); |
6598 uint64_t wwn; 6599 6600 /* 6601 * There is NVRAM storage for both Port and Node entities- 6602 * but the Node entity appears to be unused on all the cards 6603 * I can find. However, we should account for this being set 6604 * at some point in the future. 6605 * --- 21 unchanged lines hidden (view full) --- 6627 wwn |= (((uint64_t) 2)<< 60); 6628 } 6629 } 6630 } else { 6631 wwn &= ~((uint64_t) 0xfff << 48); 6632 } 6633 fcp->isp_nodewwn = wwn; 6634 | 7785 uint64_t wwn; 7786 7787 /* 7788 * There is NVRAM storage for both Port and Node entities- 7789 * but the Node entity appears to be unused on all the cards 7790 * I can find. However, we should account for this being set 7791 * at some point in the future. 7792 * --- 21 unchanged lines hidden (view full) --- 7814 wwn |= (((uint64_t) 2)<< 60); 7815 } 7816 } 7817 } else { 7818 wwn &= ~((uint64_t) 0xfff << 48); 7819 } 7820 fcp->isp_nodewwn = wwn; 7821 |
6635 /* 6636 * Make sure we have both Node and Port as non-zero values. 6637 */ 6638 if (fcp->isp_nodewwn != 0 && fcp->isp_portwwn == 0) { 6639 fcp->isp_portwwn = fcp->isp_nodewwn; 6640 } else if (fcp->isp_nodewwn == 0 && fcp->isp_portwwn != 0) { 6641 fcp->isp_nodewwn = fcp->isp_portwwn; 6642 } | 7822 isp_fix_nvram_wwns(isp); |
6643 | 7823 |
6644 /* 6645 * Make the Node and Port values sane if they're NAA == 2. 6646 * This means to clear bits 48..56 for the Node WWN and 6647 * make sure that there's some non-zero value in 48..56 6648 * for the Port WWN. 6649 */ 6650 if (fcp->isp_nodewwn && fcp->isp_portwwn) { 6651 if ((fcp->isp_nodewwn & (((uint64_t) 0xfff) << 48)) != 0 && 6652 (fcp->isp_nodewwn >> 60) == 2) { 6653 fcp->isp_nodewwn &= ~((uint64_t) 0xfff << 48); 6654 } 6655 if ((fcp->isp_portwwn & (((uint64_t) 0xfff) << 48)) == 0 && 6656 (fcp->isp_portwwn >> 60) == 2) { 6657 fcp->isp_portwwn |= ((uint64_t) 1 << 56); 6658 } | 7824 fcp->isp_maxalloc = ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data); 7825 if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) { 7826 fcp->isp_maxfrmlen = ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data); |
6659 } | 7827 } |
6660 6661 fcp->isp_maxalloc = 6662 ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data); 6663 if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) 6664 fcp->isp_maxfrmlen = 6665 ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data); 6666 fcp->isp_retry_delay = 6667 ISP2100_NVRAM_RETRY_DELAY(nvram_data); 6668 fcp->isp_retry_count = 6669 ISP2100_NVRAM_RETRY_COUNT(nvram_data); 6670 if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) 6671 fcp->isp_loopid = 6672 ISP2100_NVRAM_HARDLOOPID(nvram_data); 6673 if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0) | 7828 fcp->isp_retry_delay = ISP2100_NVRAM_RETRY_DELAY(nvram_data); 7829 fcp->isp_retry_count = ISP2100_NVRAM_RETRY_COUNT(nvram_data); 7830 if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) { 7831 fcp->isp_loopid = ISP2100_NVRAM_HARDLOOPID(nvram_data); 7832 } 7833 if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0) { |
6674 fcp->isp_execthrottle = 6675 ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data); | 7834 fcp->isp_execthrottle = 7835 ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data); |
7836 } |
|
6676 fcp->isp_fwoptions = ISP2100_NVRAM_OPTIONS(nvram_data); 6677 isp_prt(isp, ISP_LOGDEBUG0, 6678 "NVRAM 0x%08x%08x 0x%08x%08x maxalloc %d maxframelen %d", 6679 (uint32_t) (fcp->isp_nodewwn >> 32), (uint32_t) fcp->isp_nodewwn, 6680 (uint32_t) (fcp->isp_portwwn >> 32), (uint32_t) fcp->isp_portwwn, 6681 ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data), 6682 ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data)); 6683 isp_prt(isp, ISP_LOGDEBUG0, --- 4 unchanged lines hidden (view full) --- 6688 ISP2100_NVRAM_TOV(nvram_data)); 6689 fcp->isp_xfwoptions = ISP2100_XFW_OPTIONS(nvram_data); 6690 fcp->isp_zfwoptions = ISP2100_ZFW_OPTIONS(nvram_data); 6691 isp_prt(isp, ISP_LOGDEBUG0, 6692 "xfwoptions 0x%x zfw options 0x%x", 6693 ISP2100_XFW_OPTIONS(nvram_data), ISP2100_ZFW_OPTIONS(nvram_data)); 6694} 6695 | 7837 fcp->isp_fwoptions = ISP2100_NVRAM_OPTIONS(nvram_data); 7838 isp_prt(isp, ISP_LOGDEBUG0, 7839 "NVRAM 0x%08x%08x 0x%08x%08x maxalloc %d maxframelen %d", 7840 (uint32_t) (fcp->isp_nodewwn >> 32), (uint32_t) fcp->isp_nodewwn, 7841 (uint32_t) (fcp->isp_portwwn >> 32), (uint32_t) fcp->isp_portwwn, 7842 ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data), 7843 ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data)); 7844 isp_prt(isp, ISP_LOGDEBUG0, --- 4 unchanged lines hidden (view full) --- 7849 ISP2100_NVRAM_TOV(nvram_data)); 7850 fcp->isp_xfwoptions = ISP2100_XFW_OPTIONS(nvram_data); 7851 fcp->isp_zfwoptions = ISP2100_ZFW_OPTIONS(nvram_data); 7852 isp_prt(isp, ISP_LOGDEBUG0, 7853 "xfwoptions 0x%x zfw options 0x%x", 7854 ISP2100_XFW_OPTIONS(nvram_data), ISP2100_ZFW_OPTIONS(nvram_data)); 7855} 7856 |
7857static void 7858isp_parse_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data) 7859{ 7860 fcparam *fcp = FCPARAM(isp); 7861 uint64_t wwn; 7862 7863 isp_prt(isp, ISP_LOGDEBUG0, 7864 "NVRAM 0x%08x%08x 0x%08x%08x exchg_cnt %d maxframelen %d", 7865 (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data) >> 32), 7866 (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data)), 7867 (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data) >> 32), 7868 (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data)), 7869 ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data), 7870 ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data)); 7871 isp_prt(isp, ISP_LOGDEBUG0, 7872 "NVRAM execthr %d loopid %d fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x", 7873 ISP2400_NVRAM_EXECUTION_THROTTLE(nvram_data), 7874 ISP2400_NVRAM_HARDLOOPID(nvram_data), 7875 ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data), 7876 ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data), 7877 ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data)); 7878 7879 wwn = ISP2400_NVRAM_PORT_NAME(nvram_data); 7880 if (wwn) { 7881 if ((wwn >> 60) != 2 && (wwn >> 60) != 5) { 7882 wwn = 0; 7883 } 7884 } 7885 fcp->isp_portwwn = wwn; 7886 7887 wwn = ISP2400_NVRAM_NODE_NAME(nvram_data); 7888 if (wwn) { 7889 if ((wwn >> 60) != 2 && (wwn >> 60) != 5) { 7890 wwn = 0; 7891 } 7892 } 7893 fcp->isp_nodewwn = wwn; 7894 7895 isp_fix_nvram_wwns(isp); 7896 7897 if (ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data)) { 7898 fcp->isp_maxalloc = ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data); 7899 } 7900 if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) { 7901 fcp->isp_maxfrmlen = ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data); 7902 } 7903 if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) { 7904 fcp->isp_loopid = ISP2400_NVRAM_HARDLOOPID(nvram_data); 7905 } 7906 if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0) { 7907 fcp->isp_execthrottle = 7908 ISP2400_NVRAM_EXECUTION_THROTTLE(nvram_data); 7909 } 7910 fcp->isp_fwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data); 7911 fcp->isp_xfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data); 7912 fcp->isp_zfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data); 7913} 7914 |
|
6696#ifdef ISP_FW_CRASH_DUMP 6697static void isp2200_fw_dump(ispsoftc_t *); 6698static void isp2300_fw_dump(ispsoftc_t *); 6699 6700static void 6701isp2200_fw_dump(ispsoftc_t *isp) 6702{ 6703 int i, j; --- 114 unchanged lines hidden (view full) --- 6818 ISP_WRITE(isp, RISC_EMB, 0xf2); 6819 ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE); 6820 for (i = 0; i < 100; i++) { 6821 USEC_DELAY(100); 6822 if ((ISP_READ(isp, HCCR) & HCCR_PAUSE) == 0) { 6823 break; 6824 } 6825 } | 7915#ifdef ISP_FW_CRASH_DUMP 7916static void isp2200_fw_dump(ispsoftc_t *); 7917static void isp2300_fw_dump(ispsoftc_t *); 7918 7919static void 7920isp2200_fw_dump(ispsoftc_t *isp) 7921{ 7922 int i, j; --- 114 unchanged lines hidden (view full) --- 8037 ISP_WRITE(isp, RISC_EMB, 0xf2); 8038 ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE); 8039 for (i = 0; i < 100; i++) { 8040 USEC_DELAY(100); 8041 if ((ISP_READ(isp, HCCR) & HCCR_PAUSE) == 0) { 8042 break; 8043 } 8044 } |
6826 ENABLE_INTS(isp); | 8045 ISP_ENABLE_INTS(isp); |
6827 mbs.param[0] = MBOX_READ_RAM_WORD; 6828 mbs.param[1] = 0x1000; 6829 isp->isp_mbxworkp = (void *) ptr; 6830 isp->isp_mbxwrk0 = 0xefff; /* continuation count */ 6831 isp->isp_mbxwrk1 = 0x1001; /* next SRAM address */ 6832 isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs); 6833 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 6834 isp_prt(isp, ISP_LOGWARN, --- 126 unchanged lines hidden (view full) --- 6961 if (ISP_READ(isp, OUTMAILBOX0) == 0) { 6962 break; 6963 } 6964 } 6965 if (ISP_READ(isp, OUTMAILBOX0) != 0) { 6966 isp_prt(isp, ISP_LOGERR, "Board Would Not Reset"); 6967 return; 6968 } | 8046 mbs.param[0] = MBOX_READ_RAM_WORD; 8047 mbs.param[1] = 0x1000; 8048 isp->isp_mbxworkp = (void *) ptr; 8049 isp->isp_mbxwrk0 = 0xefff; /* continuation count */ 8050 isp->isp_mbxwrk1 = 0x1001; /* next SRAM address */ 8051 isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs); 8052 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 8053 isp_prt(isp, ISP_LOGWARN, --- 126 unchanged lines hidden (view full) --- 8180 if (ISP_READ(isp, OUTMAILBOX0) == 0) { 8181 break; 8182 } 8183 } 8184 if (ISP_READ(isp, OUTMAILBOX0) != 0) { 8185 isp_prt(isp, ISP_LOGERR, "Board Would Not Reset"); 8186 return; 8187 } |
6969 ENABLE_INTS(isp); | 8188 ISP_ENABLE_INTS(isp); |
6970 MEMZERO(&mbs, sizeof (mbs)); 6971 mbs.param[0] = MBOX_READ_RAM_WORD; 6972 mbs.param[1] = 0x800; 6973 isp->isp_mbxworkp = (void *) ptr; 6974 isp->isp_mbxwrk0 = 0xf7ff; /* continuation count */ 6975 isp->isp_mbxwrk1 = 0x801; /* next SRAM address */ 6976 isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs); 6977 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { --- 25 unchanged lines hidden (view full) --- 7003 7004void 7005isp_fw_dump(ispsoftc_t *isp) 7006{ 7007 if (IS_2200(isp)) 7008 isp2200_fw_dump(isp); 7009 else if (IS_23XX(isp)) 7010 isp2300_fw_dump(isp); | 8189 MEMZERO(&mbs, sizeof (mbs)); 8190 mbs.param[0] = MBOX_READ_RAM_WORD; 8191 mbs.param[1] = 0x800; 8192 isp->isp_mbxworkp = (void *) ptr; 8193 isp->isp_mbxwrk0 = 0xf7ff; /* continuation count */ 8194 isp->isp_mbxwrk1 = 0x801; /* next SRAM address */ 8195 isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs); 8196 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { --- 25 unchanged lines hidden (view full) --- 8222 8223void 8224isp_fw_dump(ispsoftc_t *isp) 8225{ 8226 if (IS_2200(isp)) 8227 isp2200_fw_dump(isp); 8228 else if (IS_23XX(isp)) 8229 isp2300_fw_dump(isp); |
8230 else if (IS_24XX(isp)) 8231 isp_prt(isp, ISP_LOGERR, "24XX dump method undefined"); 8232 |
|
7011} 7012#endif | 8233} 8234#endif |