isp.c (92893) | isp.c (93837) |
---|---|
1/* $FreeBSD: head/sys/dev/isp/isp.c 92893 2002-03-21 21:10:16Z mjacob $ */ | 1/* $FreeBSD: head/sys/dev/isp/isp.c 93837 2002-04-04 23:46:01Z mjacob $ */ |
2/* 3 * Machine and OS Independent (well, as best as possible) 4 * code for the Qlogic ISP SCSI adapters. 5 * 6 * Copyright (c) 1997, 1998, 1999, 2000, 2001 by Matthew Jacob 7 * Feral Software 8 * All rights reserved. 9 * --- 81 unchanged lines hidden (view full) --- 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[] = 98 "Loop ID %d, AL_PA 0x%x, Port ID 0x%x, Loop State 0x%x, Topology '%s'"; | 2/* 3 * Machine and OS Independent (well, as best as possible) 4 * code for the Qlogic ISP SCSI adapters. 5 * 6 * Copyright (c) 1997, 1998, 1999, 2000, 2001 by Matthew Jacob 7 * Feral Software 8 * All rights reserved. 9 * --- 81 unchanged lines hidden (view full) --- 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[] = 98 "Loop ID %d, AL_PA 0x%x, 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"; |
|
99static const char finmsg[] = 100 "(%d.%d.%d): FIN dl%d resid %d STS 0x%x SKEY %c XS_ERR=0x%x"; 101static const char sc0[] = 102 "%s CHAN %d FTHRSH %d IID %d RESETD %d RETRYC %d RETRYD %d ASD 0x%x"; 103static const char sc1[] = 104 "%s RAAN 0x%x DLAN 0x%x DDMAB 0x%x CDMAB 0x%x SELTIME %d MQD %d"; 105static const char sc2[] = "%s CHAN %d TGT %d FLAGS 0x%x 0x%x/0x%x"; 106static const char sc3[] = "Generated"; --- 15 unchanged lines hidden (view full) --- 122static void isp_mark_getpdb_all(struct ispsoftc *); 123static int isp_getmap(struct ispsoftc *, fcpos_map_t *); 124static int isp_getpdb(struct ispsoftc *, int, isp_pdb_t *); 125static u_int64_t isp_get_portname(struct ispsoftc *, int, int); 126static int isp_fclink_test(struct ispsoftc *, int); 127static char *isp2100_fw_statename(int); 128static int isp_pdb_sync(struct ispsoftc *); 129static int isp_scan_loop(struct ispsoftc *); | 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"; --- 15 unchanged lines hidden (view full) --- 124static void isp_mark_getpdb_all(struct ispsoftc *); 125static int isp_getmap(struct ispsoftc *, fcpos_map_t *); 126static int isp_getpdb(struct ispsoftc *, int, isp_pdb_t *); 127static u_int64_t isp_get_portname(struct ispsoftc *, int, int); 128static int isp_fclink_test(struct ispsoftc *, int); 129static char *isp2100_fw_statename(int); 130static int isp_pdb_sync(struct ispsoftc *); 131static int isp_scan_loop(struct ispsoftc *); |
130static int isp_scan_fabric(struct ispsoftc *); | 132static int isp_fabric_mbox_cmd(struct ispsoftc *, mbreg_t *); 133static int isp_scan_fabric(struct ispsoftc *, int); |
131static void isp_register_fc4_type(struct ispsoftc *); 132static void isp_fw_state(struct ispsoftc *); 133static void isp_mboxcmd_qnw(struct ispsoftc *, mbreg_t *, int); 134static void isp_mboxcmd(struct ispsoftc *, mbreg_t *, int); 135 136static void isp_update(struct ispsoftc *); 137static void isp_update_bus(struct ispsoftc *, int); 138static void isp_setdfltparm(struct ispsoftc *, int); --- 2154 unchanged lines hidden (view full) --- 2293 loopid = lp - fcp->portdb; 2294 (void) isp_async(isp, ISPASYNC_PROMENADE, &loopid); 2295 MEMZERO((void *) lp, sizeof (*lp)); 2296 } 2297 fcp->isp_loopstate = LOOP_LSCAN_DONE; 2298 return (0); 2299} 2300 | 134static void isp_register_fc4_type(struct ispsoftc *); 135static void isp_fw_state(struct ispsoftc *); 136static void isp_mboxcmd_qnw(struct ispsoftc *, mbreg_t *, int); 137static void isp_mboxcmd(struct ispsoftc *, mbreg_t *, int); 138 139static void isp_update(struct ispsoftc *); 140static void isp_update_bus(struct ispsoftc *, int); 141static void isp_setdfltparm(struct ispsoftc *, int); --- 2154 unchanged lines hidden (view full) --- 2296 loopid = lp - fcp->portdb; 2297 (void) isp_async(isp, ISPASYNC_PROMENADE, &loopid); 2298 MEMZERO((void *) lp, sizeof (*lp)); 2299 } 2300 fcp->isp_loopstate = LOOP_LSCAN_DONE; 2301 return (0); 2302} 2303 |
2301#ifndef HICAP_MAX 2302#define HICAP_MAX 256 2303#endif | 2304 |
2304static int | 2305static int |
2305isp_scan_fabric(struct ispsoftc *isp) | 2306isp_fabric_mbox_cmd(struct ispsoftc *isp, mbreg_t *mbp) |
2306{ | 2307{ |
2308 isp_mboxcmd(isp, mbp, MBLOGNONE); 2309 if (mbp->param[0] != MBOX_COMMAND_COMPLETE) { 2310 if (FCPARAM(isp)->isp_loopstate == LOOP_SCANNING_FABRIC) { 2311 FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD; 2312 } 2313 if (mbp->param[0] == MBOX_COMMAND_ERROR) { 2314 char tbuf[16]; 2315 char *m; 2316 switch (mbp->param[1]) { 2317 case 1: 2318 m = "No Loop"; 2319 break; 2320 case 2: 2321 m = "Failed to allocate IOCB buffer"; 2322 break; 2323 case 3: 2324 m = "Failed to allocate XCB buffer"; 2325 break; 2326 case 4: 2327 m = "timeout or transmit failed"; 2328 break; 2329 case 5: 2330 m = "no fabric loop"; 2331 break; 2332 case 6: 2333 m = "remote device not a target"; 2334 break; 2335 default: 2336 SNPRINTF(tbuf, sizeof tbuf, "%x", 2337 mbp->param[1]); 2338 m = tbuf; 2339 break; 2340 } 2341 isp_prt(isp, ISP_LOGERR, "SNS Failed- %s", m); 2342 } 2343 return (-1); 2344 } 2345 2346 if (FCPARAM(isp)->isp_fwstate != FW_READY || 2347 FCPARAM(isp)->isp_loopstate < LOOP_SCANNING_FABRIC) { 2348 return (-1); 2349 } 2350 return(0); 2351} 2352 2353#ifdef ISP_USE_GA_NXT 2354static int 2355isp_scan_fabric(struct ispsoftc *isp, int ftype) 2356{ |
|
2307 fcparam *fcp = isp->isp_param; 2308 u_int32_t portid, first_portid, last_portid; | 2357 fcparam *fcp = isp->isp_param; 2358 u_int32_t portid, first_portid, last_portid; |
2309 int hicap, first_portid_seen, last_port_same; | 2359 int hicap, last_port_same; |
2310 2311 if (fcp->isp_onfabric == 0) { 2312 fcp->isp_loopstate = LOOP_FSCAN_DONE; 2313 return (0); 2314 } 2315 | 2360 2361 if (fcp->isp_onfabric == 0) { 2362 fcp->isp_loopstate = LOOP_FSCAN_DONE; 2363 return (0); 2364 } 2365 |
2366 FC_SCRATCH_ACQUIRE(isp); |
|
2316 2317 /* 2318 * Since Port IDs are 24 bits, we can check against having seen 2319 * anything yet with this value. 2320 */ 2321 last_port_same = 0; 2322 last_portid = 0xffffffff; /* not a port */ 2323 first_portid = portid = fcp->isp_portid; 2324 fcp->isp_loopstate = LOOP_SCANNING_FABRIC; 2325 | 2367 2368 /* 2369 * Since Port IDs are 24 bits, we can check against having seen 2370 * anything yet with this value. 2371 */ 2372 last_port_same = 0; 2373 last_portid = 0xffffffff; /* not a port */ 2374 first_portid = portid = fcp->isp_portid; 2375 fcp->isp_loopstate = LOOP_SCANNING_FABRIC; 2376 |
2326 for (first_portid_seen = hicap = 0; hicap < HICAP_MAX; hicap++) { | 2377 for (hicap = 0; hicap < GA_NXT_MAX; hicap++) { |
2327 mbreg_t mbs; 2328 sns_screq_t *rq; | 2378 mbreg_t mbs; 2379 sns_screq_t *rq; |
2329 sns_ganrsp_t *rs0, *rs1; 2330 u_int8_t sc[SNS_GAN_REQ_SIZE]; | 2380 sns_ga_nxt_rsp_t *rs0, *rs1; 2381 struct lportdb lcl; 2382 u_int8_t sc[SNS_GA_NXT_RESP_SIZE]; |
2331 2332 rq = (sns_screq_t *)sc; | 2383 2384 rq = (sns_screq_t *)sc; |
2333 MEMZERO((void *) rq, SNS_GAN_REQ_SIZE); 2334 rq->snscb_rblen = SNS_GAN_RESP_SIZE >> 1; | 2385 MEMZERO((void *) rq, SNS_GA_NXT_REQ_SIZE); 2386 rq->snscb_rblen = SNS_GA_NXT_RESP_SIZE >> 1; |
2335 rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+0x100); 2336 rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+0x100); 2337 rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+0x100); 2338 rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+0x100); 2339 rq->snscb_sblen = 6; | 2387 rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+0x100); 2388 rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+0x100); 2389 rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+0x100); 2390 rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+0x100); 2391 rq->snscb_sblen = 6; |
2340 rq->snscb_data[0] = SNS_GAN; | 2392 rq->snscb_data[0] = SNS_GA_NXT; |
2341 rq->snscb_data[4] = portid & 0xffff; 2342 rq->snscb_data[5] = (portid >> 16) & 0xff; | 2393 rq->snscb_data[4] = portid & 0xffff; 2394 rq->snscb_data[5] = (portid >> 16) & 0xff; |
2343 FC_SCRATCH_ACQUIRE(isp); | |
2344 isp_put_sns_request(isp, rq, (sns_screq_t *) fcp->isp_scratch); | 2395 isp_put_sns_request(isp, rq, (sns_screq_t *) fcp->isp_scratch); |
2345 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GAN_REQ_SIZE); | 2396 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GA_NXT_REQ_SIZE); |
2346 mbs.param[0] = MBOX_SEND_SNS; | 2397 mbs.param[0] = MBOX_SEND_SNS; |
2347 mbs.param[1] = SNS_GAN_REQ_SIZE >> 1; | 2398 mbs.param[1] = SNS_GA_NXT_REQ_SIZE >> 1; |
2348 mbs.param[2] = DMA_WD1(fcp->isp_scdma); 2349 mbs.param[3] = DMA_WD0(fcp->isp_scdma); 2350 /* 2351 * Leave 4 and 5 alone 2352 */ 2353 mbs.param[6] = DMA_WD3(fcp->isp_scdma); 2354 mbs.param[7] = DMA_WD2(fcp->isp_scdma); | 2399 mbs.param[2] = DMA_WD1(fcp->isp_scdma); 2400 mbs.param[3] = DMA_WD0(fcp->isp_scdma); 2401 /* 2402 * Leave 4 and 5 alone 2403 */ 2404 mbs.param[6] = DMA_WD3(fcp->isp_scdma); 2405 mbs.param[7] = DMA_WD2(fcp->isp_scdma); |
2355 isp_mboxcmd(isp, &mbs, MBLOGNONE); 2356 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { 2357 if (fcp->isp_loopstate == LOOP_SCANNING_FABRIC) { | 2406 if (isp_fabric_mbox_cmd(isp, &mbs)) { 2407 if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) { |
2358 fcp->isp_loopstate = LOOP_PDB_RCVD; 2359 } | 2408 fcp->isp_loopstate = LOOP_PDB_RCVD; 2409 } |
2360 if (mbs.param[0] == MBOX_COMMAND_ERROR) { 2361 char tbuf[16]; 2362 char *m; 2363 switch (mbs.param[1]) { 2364 case 1: 2365 m = "No Loop"; 2366 break; 2367 case 2: 2368 m = "Failed to allocate IOCB buffer"; 2369 break; 2370 case 3: 2371 m = "Failed to allocate XCB buffer"; 2372 break; 2373 case 4: 2374 m = "timeout or transmit failed"; 2375 break; 2376 case 5: 2377 m = "no fabric loop"; 2378 break; 2379 case 6: 2380 m = "remote device not a target"; 2381 break; 2382 default: 2383 SNPRINTF(tbuf, sizeof tbuf, "%x", 2384 mbs.param[1]); 2385 m = tbuf; 2386 break; 2387 } 2388 isp_prt(isp, ISP_LOGERR, "SNS Failed- %s", m); 2389 } | 2410 FC_SCRATCH_RELEASE(isp); |
2390 return (-1); 2391 } | 2411 return (-1); 2412 } |
2392 if (fcp->isp_fwstate != FW_READY || 2393 fcp->isp_loopstate < LOOP_SCANNING_FABRIC) { | 2413 MEMORYBARRIER(isp, SYNC_SFORCPU, 0x100, SNS_GA_NXT_RESP_SIZE); 2414 rs1 = (sns_ga_nxt_rsp_t *) sc; 2415 rs0 = (sns_ga_nxt_rsp_t *) ((u_int8_t *)fcp->isp_scratch+0x100); 2416 isp_get_ga_nxt_response(isp, rs0, rs1); 2417 if (rs1->snscb_cthdr.ct_response != FS_ACC) { 2418 isp_prt(isp, ISP_LOGWARN, swrej, "GA_NXT", 2419 rs1->snscb_cthdr.ct_reason, 2420 rs1->snscb_cthdr.ct_explanation, portid); |
2394 FC_SCRATCH_RELEASE(isp); | 2421 FC_SCRATCH_RELEASE(isp); |
2395 return (-1); | 2422 fcp->isp_loopstate = LOOP_FSCAN_DONE; 2423 return (0); |
2396 } | 2424 } |
2397 MEMORYBARRIER(isp, SYNC_SFORCPU, 0x100, SNS_GAN_RESP_SIZE); 2398 rs1 = (sns_ganrsp_t *) fcp->isp_scratch; 2399 rs0 = (sns_ganrsp_t *) ((u_int8_t *)fcp->isp_scratch + 0x100); 2400 isp_get_gan_response(isp, rs0, rs1); 2401 FC_SCRATCH_RELEASE(isp); 2402 portid = (((u_int32_t) rs1->snscb_port_id[0]) << 16) | | 2425 portid = 2426 (((u_int32_t) rs1->snscb_port_id[0]) << 16) | |
2403 (((u_int32_t) rs1->snscb_port_id[1]) << 8) | 2404 (((u_int32_t) rs1->snscb_port_id[2])); | 2427 (((u_int32_t) rs1->snscb_port_id[1]) << 8) | 2428 (((u_int32_t) rs1->snscb_port_id[2])); |
2405 (void) isp_async(isp, ISPASYNC_FABRIC_DEV, rs1); | 2429 2430 /* 2431 * Okay, we now have information about a fabric object. 2432 * If it is the type we're interested in, tell the outer layers 2433 * about it. The outer layer needs to know: Port ID, WWNN, 2434 * WWPN, FC4 type, and port type. 2435 * 2436 * The lportdb structure is adequate for this. 2437 */ 2438 MEMZERO(&lcl, sizeof (lcl)); 2439 lcl.port_type = rs1->snscb_port_type; 2440 lcl.fc4_type = ftype; 2441 lcl.portid = portid; 2442 lcl.node_wwn = 2443 (((u_int64_t)rs1->snscb_nodename[0]) << 56) | 2444 (((u_int64_t)rs1->snscb_nodename[1]) << 48) | 2445 (((u_int64_t)rs1->snscb_nodename[2]) << 40) | 2446 (((u_int64_t)rs1->snscb_nodename[3]) << 32) | 2447 (((u_int64_t)rs1->snscb_nodename[4]) << 24) | 2448 (((u_int64_t)rs1->snscb_nodename[5]) << 16) | 2449 (((u_int64_t)rs1->snscb_nodename[6]) << 8) | 2450 (((u_int64_t)rs1->snscb_nodename[7])); 2451 lcl.port_wwn = 2452 (((u_int64_t)rs1->snscb_portname[0]) << 56) | 2453 (((u_int64_t)rs1->snscb_portname[1]) << 48) | 2454 (((u_int64_t)rs1->snscb_portname[2]) << 40) | 2455 (((u_int64_t)rs1->snscb_portname[3]) << 32) | 2456 (((u_int64_t)rs1->snscb_portname[4]) << 24) | 2457 (((u_int64_t)rs1->snscb_portname[5]) << 16) | 2458 (((u_int64_t)rs1->snscb_portname[6]) << 8) | 2459 (((u_int64_t)rs1->snscb_portname[7])); 2460 2461 /* 2462 * Does this fabric object support the type we want? 2463 * If not, skip it. 2464 */ 2465 if (rs1->snscb_fc4_types[ftype >> 5] & (1 << (ftype & 0x1f))) { 2466 if (first_portid == portid) { 2467 lcl.last_fabric_dev = 1; 2468 } else { 2469 lcl.last_fabric_dev = 0; 2470 } 2471 (void) isp_async(isp, ISPASYNC_FABRIC_DEV, &lcl); 2472 } else { 2473 isp_prt(isp, ISP_LOGDEBUG0, 2474 "PortID 0x%x doesn't support FC4 type 0x%x", 2475 portid, ftype); 2476 } |
2406 if (first_portid == portid) { 2407 fcp->isp_loopstate = LOOP_FSCAN_DONE; | 2477 if (first_portid == portid) { 2478 fcp->isp_loopstate = LOOP_FSCAN_DONE; |
2479 FC_SCRATCH_RELEASE(isp); |
|
2408 return (0); 2409 } 2410 if (portid == last_portid) { 2411 if (last_port_same++ > 20) { 2412 isp_prt(isp, ISP_LOGWARN, 2413 "tangled fabric database detected"); 2414 break; 2415 } 2416 } else { | 2480 return (0); 2481 } 2482 if (portid == last_portid) { 2483 if (last_port_same++ > 20) { 2484 isp_prt(isp, ISP_LOGWARN, 2485 "tangled fabric database detected"); 2486 break; 2487 } 2488 } else { |
2489 last_port_same = 0 ; |
|
2417 last_portid = portid; 2418 } 2419 } | 2490 last_portid = portid; 2491 } 2492 } |
2493 FC_SCRATCH_RELEASE(isp); 2494 if (hicap >= GA_NXT_MAX) { 2495 isp_prt(isp, ISP_LOGWARN, "fabric too big (> %d)", GA_NXT_MAX); 2496 } 2497 fcp->isp_loopstate = LOOP_FSCAN_DONE; 2498 return (0); 2499} 2500#else 2501#define GIDLEN ((ISP2100_SCRLEN >> 1) + 16) 2502#define NGENT ((GIDLEN - 16) >> 2) |
|
2420 | 2503 |
2421 if (hicap >= 65535) { 2422 isp_prt(isp, ISP_LOGWARN, "fabric too big (> 65535)"); | 2504#define IGPOFF (ISP2100_SCRLEN - GIDLEN) 2505#define GXOFF (256) 2506 2507static int 2508isp_scan_fabric(struct ispsoftc *isp, int ftype) 2509{ 2510 fcparam *fcp = FCPARAM(isp); 2511 mbreg_t mbs; 2512 u_int8_t sc[GIDLEN]; /* XXX USE ->tport */ 2513 int i; 2514 sns_gid_ft_req_t *rq; 2515 sns_gid_ft_rsp_t *rs0, *rs1; 2516 2517 if (fcp->isp_onfabric == 0) { 2518 fcp->isp_loopstate = LOOP_FSCAN_DONE; 2519 return (0); |
2423 } 2424 | 2520 } 2521 |
2522 FC_SCRATCH_ACQUIRE(isp); 2523 fcp->isp_loopstate = LOOP_SCANNING_FABRIC; 2524 2525 rq = (sns_gid_ft_req_t *)sc; 2526 MEMZERO((void *) rq, SNS_GID_FT_REQ_SIZE); 2527 rq->snscb_rblen = GIDLEN >> 1; 2528 rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+IGPOFF); 2529 rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+IGPOFF); 2530 rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+IGPOFF); 2531 rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+IGPOFF); 2532 rq->snscb_sblen = 6; 2533 rq->snscb_cmd = SNS_GID_FT; 2534 rq->snscb_mword_div_2 = NGENT; 2535 rq->snscb_fc4_type = ftype; 2536 isp_put_gid_ft_request(isp, rq, (sns_gid_ft_req_t *) fcp->isp_scratch); 2537 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GID_FT_REQ_SIZE); 2538 mbs.param[0] = MBOX_SEND_SNS; 2539 mbs.param[1] = SNS_GID_FT_REQ_SIZE >> 1; 2540 mbs.param[2] = DMA_WD1(fcp->isp_scdma); 2541 mbs.param[3] = DMA_WD0(fcp->isp_scdma); 2542 |
|
2425 /* | 2543 /* |
2426 * We either have a broken name server or a huge fabric if we get here. | 2544 * Leave 4 and 5 alone |
2427 */ | 2545 */ |
2546 mbs.param[6] = DMA_WD3(fcp->isp_scdma); 2547 mbs.param[7] = DMA_WD2(fcp->isp_scdma); 2548 if (isp_fabric_mbox_cmd(isp, &mbs)) { 2549 if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) { 2550 fcp->isp_loopstate = LOOP_PDB_RCVD; 2551 } 2552 FC_SCRATCH_RELEASE(isp); 2553 return (-1); 2554 } 2555 if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) { 2556 FC_SCRATCH_RELEASE(isp); 2557 return (-1); 2558 } 2559 MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN); 2560 rs1 = (sns_gid_ft_rsp_t *) sc; 2561 rs0 = (sns_gid_ft_rsp_t *) ((u_int8_t *)fcp->isp_scratch+IGPOFF); 2562 isp_get_gid_ft_response(isp, rs0, rs1, NGENT); 2563 if (rs1->snscb_cthdr.ct_response != FS_ACC) { 2564 isp_prt(isp, ISP_LOGWARN, swrej, "GID_FT", 2565 rs1->snscb_cthdr.ct_reason, 2566 rs1->snscb_cthdr.ct_explanation, 0); 2567 FC_SCRATCH_RELEASE(isp); 2568 fcp->isp_loopstate = LOOP_FSCAN_DONE; 2569 return (0); 2570 } 2571 2572 /* 2573 * Okay, we now have a list of Port IDs for this class of device. 2574 * Go through the list and for each one get the WWPN/WWNN for it 2575 * and tell the outer layers about it. The outer layer needs to 2576 * know: Port ID, WWNN, WWPN, FC4 type, and (possibly) port type. 2577 * 2578 * The lportdb structure is adequate for this. 2579 */ 2580 i = -1; 2581 do { 2582 sns_gxn_id_req_t grqbuf, *gq = &grqbuf; 2583 sns_gxn_id_rsp_t *gs0, grsbuf, *gs1 = &grsbuf; 2584 struct lportdb lcl; 2585 2586 i++; 2587 MEMZERO(&lcl, sizeof (lcl)); 2588 lcl.fc4_type = ftype; 2589 lcl.portid = 2590 (((u_int32_t) rs1->snscb_ports[i].portid[0]) << 16) | 2591 (((u_int32_t) rs1->snscb_ports[i].portid[1]) << 8) | 2592 (((u_int32_t) rs1->snscb_ports[i].portid[2])); 2593 2594 MEMZERO((void *) gq, sizeof (sns_gxn_id_req_t)); 2595 gq->snscb_rblen = SNS_GXN_ID_RESP_SIZE >> 1; 2596 gq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+GXOFF); 2597 gq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+GXOFF); 2598 gq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+GXOFF); 2599 gq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+GXOFF); 2600 gq->snscb_sblen = 6; 2601 gq->snscb_cmd = SNS_GPN_ID; 2602 gq->snscb_portid = lcl.portid; 2603 isp_put_gxn_id_request(isp, gq, 2604 (sns_gxn_id_req_t *) fcp->isp_scratch); 2605 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GXN_ID_REQ_SIZE); 2606 mbs.param[0] = MBOX_SEND_SNS; 2607 mbs.param[1] = SNS_GXN_ID_REQ_SIZE >> 1; 2608 mbs.param[2] = DMA_WD1(fcp->isp_scdma); 2609 mbs.param[3] = DMA_WD0(fcp->isp_scdma); 2610 /* 2611 * Leave 4 and 5 alone 2612 */ 2613 mbs.param[6] = DMA_WD3(fcp->isp_scdma); 2614 mbs.param[7] = DMA_WD2(fcp->isp_scdma); 2615 if (isp_fabric_mbox_cmd(isp, &mbs)) { 2616 if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) { 2617 fcp->isp_loopstate = LOOP_PDB_RCVD; 2618 } 2619 FC_SCRATCH_RELEASE(isp); 2620 return (-1); 2621 } 2622 if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) { 2623 FC_SCRATCH_RELEASE(isp); 2624 return (-1); 2625 } 2626 MEMORYBARRIER(isp, SYNC_SFORCPU, GXOFF, SNS_GXN_ID_RESP_SIZE); 2627 gs0 = (sns_gxn_id_rsp_t *) ((u_int8_t *)fcp->isp_scratch+GXOFF); 2628 isp_get_gxn_id_response(isp, gs0, gs1); 2629 if (gs1->snscb_cthdr.ct_response != FS_ACC) { 2630 isp_prt(isp, ISP_LOGWARN, swrej, "GPN_ID", 2631 rs1->snscb_cthdr.ct_reason, 2632 rs1->snscb_cthdr.ct_explanation, lcl.portid); 2633 if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) { 2634 FC_SCRATCH_RELEASE(isp); 2635 return (-1); 2636 } 2637 continue; 2638 } 2639 lcl.port_wwn = 2640 (((u_int64_t)gs1->snscb_wwn[0]) << 56) | 2641 (((u_int64_t)gs1->snscb_wwn[1]) << 48) | 2642 (((u_int64_t)gs1->snscb_wwn[2]) << 40) | 2643 (((u_int64_t)gs1->snscb_wwn[3]) << 32) | 2644 (((u_int64_t)gs1->snscb_wwn[4]) << 24) | 2645 (((u_int64_t)gs1->snscb_wwn[5]) << 16) | 2646 (((u_int64_t)gs1->snscb_wwn[6]) << 8) | 2647 (((u_int64_t)gs1->snscb_wwn[7])); 2648 2649 MEMZERO((void *) gq, sizeof (sns_gxn_id_req_t)); 2650 gq->snscb_rblen = SNS_GXN_ID_RESP_SIZE >> 1; 2651 gq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+GXOFF); 2652 gq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+GXOFF); 2653 gq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+GXOFF); 2654 gq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+GXOFF); 2655 gq->snscb_sblen = 6; 2656 gq->snscb_cmd = SNS_GNN_ID; 2657 gq->snscb_portid = lcl.portid; 2658 isp_put_gxn_id_request(isp, gq, 2659 (sns_gxn_id_req_t *) fcp->isp_scratch); 2660 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GXN_ID_REQ_SIZE); 2661 mbs.param[0] = MBOX_SEND_SNS; 2662 mbs.param[1] = SNS_GXN_ID_REQ_SIZE >> 1; 2663 mbs.param[2] = DMA_WD1(fcp->isp_scdma); 2664 mbs.param[3] = DMA_WD0(fcp->isp_scdma); 2665 /* 2666 * Leave 4 and 5 alone 2667 */ 2668 mbs.param[6] = DMA_WD3(fcp->isp_scdma); 2669 mbs.param[7] = DMA_WD2(fcp->isp_scdma); 2670 if (isp_fabric_mbox_cmd(isp, &mbs)) { 2671 if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) { 2672 fcp->isp_loopstate = LOOP_PDB_RCVD; 2673 } 2674 FC_SCRATCH_RELEASE(isp); 2675 return (-1); 2676 } 2677 if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) { 2678 FC_SCRATCH_RELEASE(isp); 2679 return (-1); 2680 } 2681 MEMORYBARRIER(isp, SYNC_SFORCPU, GXOFF, SNS_GXN_ID_RESP_SIZE); 2682 gs0 = (sns_gxn_id_rsp_t *) ((u_int8_t *)fcp->isp_scratch+GXOFF); 2683 isp_get_gxn_id_response(isp, gs0, gs1); 2684 if (gs1->snscb_cthdr.ct_response != FS_ACC) { 2685 isp_prt(isp, ISP_LOGWARN, swrej, "GNN_ID", 2686 rs1->snscb_cthdr.ct_reason, 2687 rs1->snscb_cthdr.ct_explanation, lcl.portid); 2688 if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) { 2689 FC_SCRATCH_RELEASE(isp); 2690 return (-1); 2691 } 2692 continue; 2693 } 2694 lcl.node_wwn = 2695 (((u_int64_t)gs1->snscb_wwn[0]) << 56) | 2696 (((u_int64_t)gs1->snscb_wwn[1]) << 48) | 2697 (((u_int64_t)gs1->snscb_wwn[2]) << 40) | 2698 (((u_int64_t)gs1->snscb_wwn[3]) << 32) | 2699 (((u_int64_t)gs1->snscb_wwn[4]) << 24) | 2700 (((u_int64_t)gs1->snscb_wwn[5]) << 16) | 2701 (((u_int64_t)gs1->snscb_wwn[6]) << 8) | 2702 (((u_int64_t)gs1->snscb_wwn[7])); 2703 2704 /* 2705 * XXX: Argh! I saw some PDF which I now can't find that 2706 * XXX: had proposed that the bottom nibble of CONTROL 2707 * XXX: would have the SCSI-FCP role flags, which would 2708 * XXX: be *awesome*. 2709 * 2710 lcl.roles = rs1->snscb_port[i].control & 0xf; 2711 */ 2712 2713 /* 2714 * If we really want to know what kind of port type this is, 2715 * we have to run another CT command. Otherwise, we'll leave 2716 * it as undefined. 2717 * 2718 lcl.port_type = 0; 2719 */ 2720 if (rs1->snscb_ports[i].control & 0x80) { 2721 lcl.last_fabric_dev = 1; 2722 } else { 2723 lcl.last_fabric_dev = 0; 2724 } 2725 (void) isp_async(isp, ISPASYNC_FABRIC_DEV, &lcl); 2726 2727 } while ((rs1->snscb_ports[i].control & 0x80) == 0 && i < NGENT-1); 2728 2729 /* 2730 * If we're not at the last entry, our list isn't big enough. 2731 */ 2732 if ((rs1->snscb_ports[i].control & 0x80) == 0) { 2733 isp_prt(isp, ISP_LOGWARN, "fabric too big for scratch area"); 2734 } 2735 2736 FC_SCRATCH_RELEASE(isp); |
|
2428 fcp->isp_loopstate = LOOP_FSCAN_DONE; 2429 return (0); 2430} | 2737 fcp->isp_loopstate = LOOP_FSCAN_DONE; 2738 return (0); 2739} |
2740#endif |
|
2431 2432static void 2433isp_register_fc4_type(struct ispsoftc *isp) 2434{ 2435 fcparam *fcp = isp->isp_param; | 2741 2742static void 2743isp_register_fc4_type(struct ispsoftc *isp) 2744{ 2745 fcparam *fcp = isp->isp_param; |
2436 u_int8_t local[SNS_RFT_REQ_SIZE]; | 2746 u_int8_t local[SNS_RFT_ID_REQ_SIZE]; |
2437 sns_screq_t *reqp = (sns_screq_t *) local; 2438 mbreg_t mbs; 2439 | 2747 sns_screq_t *reqp = (sns_screq_t *) local; 2748 mbreg_t mbs; 2749 |
2440 MEMZERO((void *) reqp, SNS_RFT_REQ_SIZE); 2441 reqp->snscb_rblen = SNS_RFT_RESP_SIZE >> 1; | 2750 MEMZERO((void *) reqp, SNS_RFT_ID_REQ_SIZE); 2751 reqp->snscb_rblen = SNS_RFT_ID_RESP_SIZE >> 1; |
2442 reqp->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + 0x100); 2443 reqp->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + 0x100); 2444 reqp->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + 0x100); 2445 reqp->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + 0x100); 2446 reqp->snscb_sblen = 22; | 2752 reqp->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + 0x100); 2753 reqp->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + 0x100); 2754 reqp->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + 0x100); 2755 reqp->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + 0x100); 2756 reqp->snscb_sblen = 22; |
2447 reqp->snscb_data[0] = SNS_RFT; | 2757 reqp->snscb_data[0] = SNS_RFT_ID; |
2448 reqp->snscb_data[4] = fcp->isp_portid & 0xffff; 2449 reqp->snscb_data[5] = (fcp->isp_portid >> 16) & 0xff; | 2758 reqp->snscb_data[4] = fcp->isp_portid & 0xffff; 2759 reqp->snscb_data[5] = (fcp->isp_portid >> 16) & 0xff; |
2450 reqp->snscb_data[6] = 0x100; /* SCS - FCP */ | 2760 reqp->snscb_data[6] = (1 << FC4_SCSI); |
2451#if 0 | 2761#if 0 |
2452 reqp->snscb_data[6] |= 20; /* ISO/IEC 8802-2 LLC/SNAP */ | 2762 reqp->snscb_data[6] |= (1 << FC4_IP); /* ISO/IEC 8802-2 LLC/SNAP */ |
2453#endif 2454 FC_SCRATCH_ACQUIRE(isp); 2455 isp_put_sns_request(isp, reqp, (sns_screq_t *) fcp->isp_scratch); 2456 mbs.param[0] = MBOX_SEND_SNS; | 2763#endif 2764 FC_SCRATCH_ACQUIRE(isp); 2765 isp_put_sns_request(isp, reqp, (sns_screq_t *) fcp->isp_scratch); 2766 mbs.param[0] = MBOX_SEND_SNS; |
2457 mbs.param[1] = SNS_RFT_REQ_SIZE >> 1; | 2767 mbs.param[1] = SNS_RFT_ID_REQ_SIZE >> 1; |
2458 mbs.param[2] = DMA_WD1(fcp->isp_scdma); 2459 mbs.param[3] = DMA_WD0(fcp->isp_scdma); 2460 /* 2461 * Leave 4 and 5 alone 2462 */ 2463 mbs.param[6] = DMA_WD3(fcp->isp_scdma); 2464 mbs.param[7] = DMA_WD2(fcp->isp_scdma); 2465 isp_mboxcmd(isp, &mbs, MBLOGALL); --- 181 unchanged lines hidden (view full) --- 2647 2648 /* 2649 * If our loop state is now such that we've just now 2650 * received a Port Database Change notification, then 2651 * we have to go off and (re)scan the fabric. We back 2652 * out and try again later if this doesn't work. 2653 */ 2654 if (fcp->isp_loopstate == LOOP_PDB_RCVD && fcp->isp_onfabric) { | 2768 mbs.param[2] = DMA_WD1(fcp->isp_scdma); 2769 mbs.param[3] = DMA_WD0(fcp->isp_scdma); 2770 /* 2771 * Leave 4 and 5 alone 2772 */ 2773 mbs.param[6] = DMA_WD3(fcp->isp_scdma); 2774 mbs.param[7] = DMA_WD2(fcp->isp_scdma); 2775 isp_mboxcmd(isp, &mbs, MBLOGALL); --- 181 unchanged lines hidden (view full) --- 2957 2958 /* 2959 * If our loop state is now such that we've just now 2960 * received a Port Database Change notification, then 2961 * we have to go off and (re)scan the fabric. We back 2962 * out and try again later if this doesn't work. 2963 */ 2964 if (fcp->isp_loopstate == LOOP_PDB_RCVD && fcp->isp_onfabric) { |
2655 if (isp_scan_fabric(isp)) { | 2965 if (isp_scan_fabric(isp, FC4_SCSI)) { |
2656 return (CMD_RQLATER); 2657 } 2658 if (fcp->isp_fwstate != FW_READY || 2659 fcp->isp_loopstate < LOOP_PDB_RCVD) { 2660 return (CMD_RQLATER); 2661 } 2662 } 2663 --- 282 unchanged lines hidden (view full) --- 2946 int usdelay = (arg)? *((int *) arg) : 250000; 2947 return (isp_fclink_test(isp, usdelay)); 2948 } 2949 break; 2950 2951 case ISPCTL_SCAN_FABRIC: 2952 2953 if (IS_FC(isp)) { | 2966 return (CMD_RQLATER); 2967 } 2968 if (fcp->isp_fwstate != FW_READY || 2969 fcp->isp_loopstate < LOOP_PDB_RCVD) { 2970 return (CMD_RQLATER); 2971 } 2972 } 2973 --- 282 unchanged lines hidden (view full) --- 3256 int usdelay = (arg)? *((int *) arg) : 250000; 3257 return (isp_fclink_test(isp, usdelay)); 3258 } 3259 break; 3260 3261 case ISPCTL_SCAN_FABRIC: 3262 3263 if (IS_FC(isp)) { |
2954 return (isp_scan_fabric(isp)); | 3264 int ftype = (arg)? *((int *) arg) : FC4_SCSI; 3265 return (isp_scan_fabric(isp, ftype)); |
2955 } 2956 break; 2957 2958 case ISPCTL_SCAN_LOOP: 2959 2960 if (IS_FC(isp)) { 2961 return (isp_scan_loop(isp)); 2962 } --- 3224 unchanged lines hidden --- | 3266 } 3267 break; 3268 3269 case ISPCTL_SCAN_LOOP: 3270 3271 if (IS_FC(isp)) { 3272 return (isp_scan_loop(isp)); 3273 } --- 3224 unchanged lines hidden --- |