Deleted Added
full compact
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 ---