isp_freebsd.c revision 47073
1/* $Id: isp_freebsd.c,v 1.18 1999/05/11 05:10:06 mjacob Exp $ */
2/* release_5_11_99 */
3/*
4 * Platform (FreeBSD) dependent common attachment code for Qlogic adapters.
5 *
6 *---------------------------------------
7 * Copyright (c) 1997, 1998 by Matthew Jacob
8 * NASA/Ames Research Center
9 * All rights reserved.
10 *---------------------------------------
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 *    notice immediately at the beginning of the file, without modification,
17 *    this list of conditions, and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 *    notice, this list of conditions and the following disclaimer in the
20 *    documentation and/or other materials provided with the distribution.
21 * 3. The name of the author may not be used to endorse or promote products
22 *    derived from this software without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
28 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36#include <dev/isp/isp_freebsd.h>
37
38#if	__FreeBSD_version >= 300004
39
40static void isp_cam_async __P((void *, u_int32_t, struct cam_path *, void *));
41static void isp_poll __P((struct cam_sim *));
42static void isp_action __P((struct cam_sim *, union ccb *));
43
44void
45isp_attach(struct ispsoftc *isp)
46{
47	int primary, secondary;
48	struct ccb_setasync csa;
49	struct cam_devq *devq;
50	struct cam_sim *sim;
51	struct cam_path *path;
52
53	/*
54	 * Establish (in case of 12X0) which bus is the primary.
55	 */
56
57	primary = 0;
58	secondary = 1;
59
60	/*
61	 * Create the device queue for our SIM(s).
62	 */
63	devq = cam_simq_alloc(MAXISPREQUEST);
64	if (devq == NULL) {
65		return;
66	}
67
68	/*
69	 * Construct our SIM entry.
70	 */
71	sim = cam_sim_alloc(isp_action, isp_poll, "isp", isp,
72	    isp->isp_unit, 1, MAXISPREQUEST, devq);
73	if (sim == NULL) {
74		cam_simq_free(devq);
75		return;
76	}
77	if (xpt_bus_register(sim, primary) != CAM_SUCCESS) {
78		cam_sim_free(sim, TRUE);
79		return;
80	}
81
82	if (xpt_create_path(&path, NULL, cam_sim_path(sim),
83	    CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
84		xpt_bus_deregister(cam_sim_path(sim));
85		cam_sim_free(sim, TRUE);
86		return;
87	}
88
89	xpt_setup_ccb(&csa.ccb_h, path, 5);
90	csa.ccb_h.func_code = XPT_SASYNC_CB;
91	csa.event_enable = AC_LOST_DEVICE;
92	csa.callback = isp_cam_async;
93	csa.callback_arg = sim;
94	xpt_action((union ccb *)&csa);
95	isp->isp_sim = sim;
96	isp->isp_path = path;
97
98	/*
99	 * If we have a second channel, construct SIM entry for that.
100	 */
101	if (IS_12X0(isp)) {
102		sim = cam_sim_alloc(isp_action, isp_poll, "isp", isp,
103		    isp->isp_unit, 1, MAXISPREQUEST, devq);
104		if (sim == NULL) {
105			xpt_bus_deregister(cam_sim_path(isp->isp_sim));
106			xpt_free_path(isp->isp_path);
107			cam_simq_free(devq);
108			return;
109		}
110		if (xpt_bus_register(sim, secondary) != CAM_SUCCESS) {
111			xpt_bus_deregister(cam_sim_path(isp->isp_sim));
112			xpt_free_path(isp->isp_path);
113			cam_sim_free(sim, TRUE);
114			return;
115		}
116
117		if (xpt_create_path(&path, NULL, cam_sim_path(sim),
118		    CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
119			xpt_bus_deregister(cam_sim_path(isp->isp_sim));
120			xpt_free_path(isp->isp_path);
121			xpt_bus_deregister(cam_sim_path(sim));
122			cam_sim_free(sim, TRUE);
123			return;
124		}
125
126		xpt_setup_ccb(&csa.ccb_h, path, 5);
127		csa.ccb_h.func_code = XPT_SASYNC_CB;
128		csa.event_enable = AC_LOST_DEVICE;
129		csa.callback = isp_cam_async;
130		csa.callback_arg = sim;
131		xpt_action((union ccb *)&csa);
132		isp->isp_sim2 = sim;
133		isp->isp_path2 = path;
134	}
135	if (isp->isp_state == ISP_INITSTATE)
136		isp->isp_state = ISP_RUNSTATE;
137}
138
139static void
140isp_cam_async(void *cbarg, u_int32_t code, struct cam_path *path, void *arg)
141{
142	struct cam_sim *sim;
143	struct ispsoftc *isp;
144
145	sim = (struct cam_sim *)cbarg;
146	isp = (struct ispsoftc *) cam_sim_softc(sim);
147	switch (code) {
148	case AC_LOST_DEVICE:
149		if (isp->isp_type & ISP_HA_SCSI) {
150			u_int16_t oflags, nflags;
151			sdparam *sdp = isp->isp_param;
152			int s, tgt = xpt_path_target_id(path);
153
154			s = splcam();
155			sdp += cam_sim_bus(sim);
156			isp->isp_update |= (1 << cam_sim_bus(sim));
157
158			nflags = DPARM_SAFE_DFLT;
159			if (ISP_FW_REVX(isp->isp_fwrev) >=
160			    ISP_FW_REV(7, 55, 0)) {
161				nflags |= DPARM_NARROW | DPARM_ASYNC;
162			}
163			oflags = sdp->isp_devparam[tgt].dev_flags;
164			sdp->isp_devparam[tgt].dev_flags = nflags;
165			sdp->isp_devparam[tgt].dev_update = 1;
166			(void) isp_control(isp, ISPCTL_UPDATE_PARAMS, NULL);
167			sdp->isp_devparam[tgt].dev_flags = oflags;
168			(void) splx(s);
169		}
170		break;
171	default:
172		break;
173	}
174}
175
176static void
177isp_poll(struct cam_sim *sim)
178{
179	isp_intr((struct ispsoftc *) cam_sim_softc(sim));
180}
181
182
183static void
184isp_action(struct cam_sim *sim, union ccb *ccb)
185{
186	int s, tgt, error;
187	struct ispsoftc *isp;
188	struct ccb_trans_settings *cts;
189
190	CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("isp_action\n"));
191
192	isp = (struct ispsoftc *)cam_sim_softc(sim);
193	ccb->ccb_h.sim_priv.entries[0].field = 0;
194	ccb->ccb_h.sim_priv.entries[1].ptr = isp;
195	/*
196	 * This should only happen for Fibre Channel adapters.
197	 * We want to pass through all but XPT_SCSI_IO (e.g.,
198	 * path inquiry) but fail if we can't get good Fibre
199	 * Channel link status.
200	 */
201	if (ccb->ccb_h.func_code == XPT_SCSI_IO &&
202	    isp->isp_state != ISP_RUNSTATE) {
203		s = splcam();
204		DISABLE_INTS(isp);
205		isp_init(isp);
206		if (isp->isp_state != ISP_INITSTATE) {
207			(void) splx(s);
208			/*
209			 * Lie. Say it was a selection timeout.
210			 */
211			ccb->ccb_h.status = CAM_SEL_TIMEOUT;
212			xpt_done(ccb);
213			return;
214		}
215		isp->isp_state = ISP_RUNSTATE;
216		ENABLE_INTS(isp);
217		(void) splx(s);
218	}
219
220	IDPRINTF(4, ("%s: isp_action code %x\n", isp->isp_name,
221	    ccb->ccb_h.func_code));
222
223	switch (ccb->ccb_h.func_code) {
224	case XPT_SCSI_IO:	/* Execute the requested I/O operation */
225		/*
226		 * Do a couple of preliminary checks...
227		 */
228		if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) {
229			if ((ccb->ccb_h.flags & CAM_CDB_PHYS) != 0) {
230				ccb->ccb_h.status = CAM_REQ_INVALID;
231				xpt_done(ccb);
232				break;
233			}
234		}
235
236
237		if (isp->isp_type & ISP_HA_SCSI) {
238			if (ccb->ccb_h.target_id > (MAX_TARGETS-1)) {
239				ccb->ccb_h.status = CAM_PATH_INVALID;
240			} else if (ISP_FW_REVX(isp->isp_fwrev) >=
241			    ISP_FW_REV(7, 55, 0)) {
242				/*
243				 * Too much breakage.
244				 */
245#if	0
246				if (ccb->ccb_h.target_lun > 31) {
247					ccb->ccb_h.status = CAM_PATH_INVALID;
248				}
249#else
250				if (ccb->ccb_h.target_lun > 7) {
251					ccb->ccb_h.status = CAM_PATH_INVALID;
252				}
253#endif
254			} else if (ccb->ccb_h.target_lun > 7) {
255				ccb->ccb_h.status = CAM_PATH_INVALID;
256			}
257		} else {
258			if (ccb->ccb_h.target_id > (MAX_FC_TARG-1)) {
259				ccb->ccb_h.status = CAM_PATH_INVALID;
260#ifdef	SCCLUN
261			} else if (ccb->ccb_h.target_lun > 15) {
262				ccb->ccb_h.status = CAM_PATH_INVALID;
263#else
264			} else if (ccb->ccb_h.target_lun > 65535) {
265				ccb->ccb_h.status = CAM_PATH_INVALID;
266#endif
267			}
268		}
269		if (ccb->ccb_h.status == CAM_PATH_INVALID) {
270			printf("%s: invalid tgt/lun (%d.%d) in XPT_SCSI_IO\n",
271			    isp->isp_name, ccb->ccb_h.target_id,
272			    ccb->ccb_h.target_lun);
273			xpt_done(ccb);
274			break;
275		}
276		s = splcam();
277		DISABLE_INTS(isp);
278		switch (ispscsicmd((ISP_SCSI_XFER_T *) ccb)) {
279		case CMD_QUEUED:
280			ccb->ccb_h.status |= CAM_SIM_QUEUED;
281			break;
282		case CMD_EAGAIN:
283			if (!(isp->isp_osinfo.simqfrozen & SIMQFRZ_RESOURCE)) {
284				xpt_freeze_simq(sim, 1);
285				isp->isp_osinfo.simqfrozen |= SIMQFRZ_RESOURCE;
286			}
287			ccb->ccb_h.status &= ~CAM_STATUS_MASK;
288                        ccb->ccb_h.status |= CAM_REQUEUE_REQ;
289			xpt_done(ccb);
290			break;
291		case CMD_COMPLETE:
292			/*
293			 * Just make sure that we didn't get it returned
294			 * as completed, but with the request still in
295			 * progress. In theory, 'cannot happen'.
296			 */
297			if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
298			    CAM_REQ_INPROG) {
299				ccb->ccb_h.status &= ~CAM_STATUS_MASK;
300				ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
301			}
302			xpt_done(ccb);
303			break;
304		}
305		ENABLE_INTS(isp);
306		splx(s);
307		break;
308
309	case XPT_EN_LUN:		/* Enable LUN as a target */
310	case XPT_TARGET_IO:		/* Execute target I/O request */
311	case XPT_ACCEPT_TARGET_IO:	/* Accept Host Target Mode CDB */
312	case XPT_CONT_TARGET_IO:	/* Continue Host Target I/O Connection*/
313		ccb->ccb_h.status = CAM_REQ_INVALID;
314		xpt_done(ccb);
315		break;
316
317	case XPT_RESET_DEV:		/* BDR the specified SCSI device */
318		tgt = ccb->ccb_h.target_id; /* XXX: Which Bus? */
319		s = splcam();
320		error = isp_control(isp, ISPCTL_RESET_DEV, &tgt);
321		(void) splx(s);
322		if (error) {
323			ccb->ccb_h.status = CAM_REQ_CMP_ERR;
324		} else {
325			ccb->ccb_h.status = CAM_REQ_CMP;
326		}
327		xpt_done(ccb);
328		break;
329	case XPT_ABORT:			/* Abort the specified CCB */
330		s = splcam();
331		error = isp_control(isp, ISPCTL_ABORT_CMD, ccb);
332		(void) splx(s);
333		if (error) {
334			ccb->ccb_h.status = CAM_REQ_CMP_ERR;
335		} else {
336			ccb->ccb_h.status = CAM_REQ_CMP;
337		}
338		xpt_done(ccb);
339		break;
340
341	case XPT_SET_TRAN_SETTINGS:	/* Nexus Settings */
342
343		cts = &ccb->cts;
344		tgt = cts->ccb_h.target_id;
345		s = splcam();
346		if (isp->isp_type & ISP_HA_FC) {
347			;	/* nothing to change */
348		} else {
349			sdparam *sdp = isp->isp_param;
350			u_int16_t *dptr;
351			int bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path));
352
353			sdp += bus;
354#if	0
355			if (cts->flags & CCB_TRANS_CURRENT_SETTINGS)
356				dptr = &sdp->isp_devparam[tgt].cur_dflags;
357			else
358				dptr = &sdp->isp_devparam[tgt].dev_flags;
359#else
360			/*
361			 * We always update (internally) from dev_flags
362			 * so any request to change settings just gets
363			 * vectored to that location.
364			 */
365			dptr = &sdp->isp_devparam[tgt].dev_flags;
366#endif
367
368			/*
369			 * Note that these operations affect the
370			 * the goal flags (dev_flags)- not
371			 * the current state flags. Then we mark
372			 * things so that the next operation to
373			 * this HBA will cause the update to occur.
374			 */
375			if (cts->valid & CCB_TRANS_DISC_VALID) {
376				if ((cts->flags & CCB_TRANS_DISC_ENB) != 0) {
377					*dptr |= DPARM_DISC;
378				} else {
379					*dptr &= ~DPARM_DISC;
380				}
381			}
382			if (cts->valid & CCB_TRANS_TQ_VALID) {
383				if ((cts->flags & CCB_TRANS_TAG_ENB) != 0) {
384					*dptr |= DPARM_TQING;
385				} else {
386					*dptr &= ~DPARM_TQING;
387				}
388			}
389			if (cts->valid & CCB_TRANS_BUS_WIDTH_VALID) {
390				switch (cts->bus_width) {
391				case MSG_EXT_WDTR_BUS_16_BIT:
392					*dptr |= DPARM_WIDE;
393					break;
394				default:
395					*dptr &= ~DPARM_WIDE;
396				}
397			}
398			/*
399			 * Any SYNC RATE of nonzero and SYNC_OFFSET
400			 * of nonzero will cause us to go to the
401			 * selected (from NVRAM) maximum value for
402			 * this device. At a later point, we'll
403			 * allow finer control.
404			 */
405			if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) &&
406			    (cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) &&
407			    (cts->sync_offset > 0)) {
408				*dptr |= DPARM_SYNC;
409			} else {
410				*dptr &= ~DPARM_SYNC;
411			}
412			if (bootverbose || isp->isp_dblev >= 3)
413				printf("%s: %d.%d set %s period 0x%x offset "
414				    "0x%x flags 0x%x\n", isp->isp_name, bus,
415				    tgt,
416				    (cts->flags & CCB_TRANS_CURRENT_SETTINGS)?
417				    "current" : "user",
418				    sdp->isp_devparam[tgt].sync_period,
419				    sdp->isp_devparam[tgt].sync_offset,
420				    sdp->isp_devparam[tgt].dev_flags);
421			s = splcam();
422			sdp->isp_devparam[tgt].dev_update = 1;
423			isp->isp_update |= (1 << bus);
424			(void) isp_control(isp, ISPCTL_UPDATE_PARAMS, NULL);
425			(void) splx(s);
426		}
427		(void) splx(s);
428		ccb->ccb_h.status = CAM_REQ_CMP;
429		xpt_done(ccb);
430		break;
431
432	case XPT_GET_TRAN_SETTINGS:
433
434		cts = &ccb->cts;
435		tgt = cts->ccb_h.target_id;
436		if (isp->isp_type & ISP_HA_FC) {
437			/*
438			 * a lot of normal SCSI things don't make sense.
439			 */
440			cts->flags = CCB_TRANS_TAG_ENB | CCB_TRANS_DISC_ENB;
441			cts->valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
442			/*
443			 * How do you measure the width of a high
444			 * speed serial bus? Well, in bytes.
445			 *
446			 * Offset and period make no sense, though, so we set
447			 * (above) a 'base' transfer speed to be gigabit.
448			 */
449			cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
450		} else {
451			sdparam *sdp = isp->isp_param;
452			u_int16_t dval, pval, oval;
453			int bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path));
454
455			sdp += bus;
456			if (cts->flags & CCB_TRANS_CURRENT_SETTINGS) {
457				s = splcam();
458				/*
459				 * First do a refresh to see if things
460				 * have changed recently!
461				 */
462				sdp->isp_devparam[tgt].dev_refresh = 1;
463				isp->isp_update |= (1 << bus);
464				(void) isp_control(isp, ISPCTL_UPDATE_PARAMS,
465				    NULL);
466				(void) splx(s);
467				dval = sdp->isp_devparam[tgt].cur_dflags;
468				oval = sdp->isp_devparam[tgt].cur_offset;
469				pval = sdp->isp_devparam[tgt].cur_period;
470			} else {
471				dval = sdp->isp_devparam[tgt].dev_flags;
472				oval = sdp->isp_devparam[tgt].sync_offset;
473				pval = sdp->isp_devparam[tgt].sync_period;
474			}
475
476			s = splcam();
477			cts->flags &= ~(CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB);
478
479			if (dval & DPARM_DISC) {
480				cts->flags |= CCB_TRANS_DISC_ENB;
481			}
482			if (dval & DPARM_TQING) {
483				cts->flags |= CCB_TRANS_TAG_ENB;
484			}
485			if (dval & DPARM_WIDE) {
486				cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
487			} else {
488				cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
489			}
490			cts->valid = CCB_TRANS_BUS_WIDTH_VALID |
491			    CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
492
493			if ((dval & DPARM_SYNC) && oval != 0) {
494				cts->sync_period = pval;
495				cts->sync_offset = oval;
496				cts->valid |=
497				    CCB_TRANS_SYNC_RATE_VALID |
498				    CCB_TRANS_SYNC_OFFSET_VALID;
499			}
500			splx(s);
501			if (bootverbose || isp->isp_dblev >= 3)
502				printf("%s: %d.%d get %s period 0x%x offset "
503				    "0x%x flags 0x%x\n", isp->isp_name, bus,
504				    tgt,
505			    	    (cts->flags & CCB_TRANS_CURRENT_SETTINGS)?
506				    "current" : "user", pval, oval, dval);
507		}
508		ccb->ccb_h.status = CAM_REQ_CMP;
509		xpt_done(ccb);
510		break;
511
512	case XPT_CALC_GEOMETRY:
513	{
514		struct ccb_calc_geometry *ccg;
515		u_int32_t secs_per_cylinder;
516		u_int32_t size_mb;
517
518		ccg = &ccb->ccg;
519		if (ccg->block_size == 0) {
520			printf("%s: %d.%d XPT_CALC_GEOMETRY block size 0?\n",
521				isp->isp_name, ccg->ccb_h.target_id,
522				ccg->ccb_h.target_lun);
523			ccb->ccb_h.status = CAM_REQ_INVALID;
524			xpt_done(ccb);
525			break;
526		}
527		size_mb = ccg->volume_size /((1024L * 1024L) / ccg->block_size);
528		if (size_mb > 1024) {
529			ccg->heads = 255;
530			ccg->secs_per_track = 63;
531		} else {
532			ccg->heads = 64;
533			ccg->secs_per_track = 32;
534		}
535		secs_per_cylinder = ccg->heads * ccg->secs_per_track;
536		ccg->cylinders = ccg->volume_size / secs_per_cylinder;
537		ccb->ccb_h.status = CAM_REQ_CMP;
538		xpt_done(ccb);
539		break;
540	}
541	case XPT_RESET_BUS:		/* Reset the specified bus */
542		tgt = cam_sim_bus(sim);
543		s = splcam();
544		error = isp_control(isp, ISPCTL_RESET_BUS, &tgt);
545		(void) splx(s);
546		if (error)
547			ccb->ccb_h.status = CAM_REQ_CMP_ERR;
548		else {
549			if (cam_sim_bus(sim) && isp->isp_path2 != NULL)
550				xpt_async(AC_BUS_RESET, isp->isp_path2, NULL);
551			else if (isp->isp_path != NULL)
552				xpt_async(AC_BUS_RESET, isp->isp_path, NULL);
553			ccb->ccb_h.status = CAM_REQ_CMP;
554		}
555		xpt_done(ccb);
556		break;
557
558	case XPT_TERM_IO:		/* Terminate the I/O process */
559		/* Does this need to be implemented? */
560		ccb->ccb_h.status = CAM_REQ_INVALID;
561		xpt_done(ccb);
562		break;
563
564	case XPT_PATH_INQ:		/* Path routing inquiry */
565	{
566		struct ccb_pathinq *cpi = &ccb->cpi;
567
568		cpi->version_num = 1;
569		cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16;
570		cpi->target_sprt = 0;
571		cpi->hba_eng_cnt = 0;
572		if (IS_FC(isp)) {
573			cpi->hba_misc = PIM_NOBUSRESET;
574			cpi->max_target = MAX_FC_TARG-1;
575			cpi->initiator_id =
576			    ((fcparam *)isp->isp_param)->isp_loopid;
577#ifdef	SCCLUN
578			cpi->max_lun = (1 << 16) - 1;
579#else
580			cpi->max_lun = (1 << 4) - 1;
581#endif
582			/*
583			 * Set base transfer capabilities for Fibre Channel.
584			 * Technically not correct because we don't know
585			 * what media we're running on top of- but we'll
586			 * look good if we always say 100MB/s.
587			 */
588			cpi->base_transfer_speed = 100000;
589		} else {
590			sdparam *sdp = isp->isp_param;
591			sdp += cam_sim_bus(xpt_path_sim(cpi->ccb_h.path));
592			cpi->hba_misc = 0;
593			cpi->initiator_id = sdp->isp_initiator_id;
594			cpi->max_target =  MAX_TARGETS-1;
595			if (ISP_FW_REVX(isp->isp_fwrev) >=
596			    ISP_FW_REV(7, 55, 0)) {
597#if	0
598				/*
599				 * Too much breakage.
600				 */
601				cpi->max_lun = (1 << 5) - 1;
602#else
603				cpi->max_lun = (1 << 3) - 1;
604#endif
605			} else {
606				cpi->max_lun = (1 << 3) - 1;
607			}
608			cpi->base_transfer_speed = 3300;
609		}
610
611		cpi->bus_id = cam_sim_bus(sim);
612		strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
613		strncpy(cpi->hba_vid, "Qlogic", HBA_IDLEN);
614		strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
615		cpi->unit_number = cam_sim_unit(sim);
616		cpi->ccb_h.status = CAM_REQ_CMP;
617		xpt_done(ccb);
618		break;
619	}
620	default:
621		ccb->ccb_h.status = CAM_REQ_INVALID;
622		xpt_done(ccb);
623		break;
624	}
625}
626
627#define	ISPDDB	(CAM_DEBUG_INFO|CAM_DEBUG_TRACE|CAM_DEBUG_CDB)
628void
629isp_done(struct ccb_scsiio *sccb)
630{
631	struct ispsoftc *isp = XS_ISP(sccb);
632
633	if (XS_NOERR(sccb))
634		XS_SETERR(sccb, CAM_REQ_CMP);
635	sccb->ccb_h.status &= ~CAM_STATUS_MASK;
636	sccb->ccb_h.status |= sccb->ccb_h.spriv_field0;
637	if ((sccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP &&
638	    (sccb->scsi_status != SCSI_STATUS_OK)) {
639		sccb->ccb_h.status &= ~CAM_STATUS_MASK;
640		sccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
641	}
642	if ((sccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
643		if ((sccb->ccb_h.status & CAM_DEV_QFRZN) == 0) {
644			IDPRINTF(3, ("%s: freeze devq %d.%d ccbstat 0x%x\n",
645			    isp->isp_name, sccb->ccb_h.target_id,
646			    sccb->ccb_h.target_lun, sccb->ccb_h.status));
647			xpt_freeze_devq(sccb->ccb_h.path, 1);
648			sccb->ccb_h.status |= CAM_DEV_QFRZN;
649		}
650	}
651	if (isp->isp_osinfo.simqfrozen & SIMQFRZ_RESOURCE) {
652		isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_RESOURCE;
653		sccb->ccb_h.status |= CAM_RELEASE_SIMQ;
654		xpt_release_simq(isp->isp_sim, 1);
655	}
656	sccb->ccb_h.status &= ~CAM_SIM_QUEUED;
657	if (CAM_DEBUGGED(sccb->ccb_h.path, ISPDDB) &&
658	    (sccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
659		xpt_print_path(sccb->ccb_h.path);
660		printf("cam completion status 0x%x\n", sccb->ccb_h.status);
661	}
662	xpt_done((union ccb *) sccb);
663}
664
665int
666isp_async(isp, cmd, arg)
667	struct ispsoftc *isp;
668	ispasync_t cmd;
669	void *arg;
670{
671	int bus, rv = 0;
672	switch (cmd) {
673	case ISPASYNC_NEW_TGT_PARAMS:
674		if (isp->isp_type & ISP_HA_SCSI) {
675			int flags, tgt;
676			sdparam *sdp = isp->isp_param;
677			struct ccb_trans_settings neg;
678			struct cam_path *tmppath;
679
680			tgt = *((int *)arg);
681			bus = (tgt >> 16) & 0xffff;
682			tgt &= 0xffff;
683			sdp += bus;
684			if (xpt_create_path(&tmppath, NULL,
685			    cam_sim_path(bus? isp->isp_sim2 : isp->isp_sim),
686			    tgt, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
687				xpt_print_path(isp->isp_path);
688				printf("isp_async cannot make temp path for "
689				    "target %d bus %d\n", tgt, bus);
690				rv = -1;
691				break;
692			}
693			flags = sdp->isp_devparam[tgt].cur_dflags;
694			neg.valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
695			if (flags & DPARM_DISC) {
696				neg.flags |= CCB_TRANS_DISC_ENB;
697			}
698			if (flags & DPARM_TQING) {
699				neg.flags |= CCB_TRANS_TAG_ENB;
700			}
701			neg.valid |= CCB_TRANS_BUS_WIDTH_VALID;
702			neg.bus_width = (flags & DPARM_WIDE)?
703			    MSG_EXT_WDTR_BUS_8_BIT : MSG_EXT_WDTR_BUS_16_BIT;
704			neg.sync_period = sdp->isp_devparam[tgt].cur_period;
705			neg.sync_offset = sdp->isp_devparam[tgt].cur_offset;
706			if (flags & DPARM_SYNC) {
707				neg.valid |=
708				    CCB_TRANS_SYNC_RATE_VALID |
709				    CCB_TRANS_SYNC_OFFSET_VALID;
710			}
711			IDPRINTF(3, ("%s: NEW_TGT_PARAMS bus %d tgt %d period "
712			    "0x%x offset 0x%x flags 0x%x\n", isp->isp_name,
713			    bus, tgt, neg.sync_period, neg.sync_offset, flags));
714			xpt_setup_ccb(&neg.ccb_h, tmppath, 1);
715			xpt_async(AC_TRANSFER_NEG, tmppath, &neg);
716			xpt_free_path(tmppath);
717		}
718		break;
719	case ISPASYNC_BUS_RESET:
720		bus = *((int *)arg);
721		printf("%s: SCSI bus reset on bus %d detected\n",
722		    isp->isp_name, bus);
723		if (bus > 0 && isp->isp_path2) {
724			xpt_async(AC_BUS_RESET, isp->isp_path2, NULL);
725		} else if (isp->isp_path) {
726			xpt_async(AC_BUS_RESET, isp->isp_path, NULL);
727		}
728		break;
729	case ISPASYNC_LOOP_DOWN:
730		if (isp->isp_path) {
731			/*
732			 * We can get multiple LOOP downs, so only count one.
733			 */
734			if (!(isp->isp_osinfo.simqfrozen & SIMQFRZ_LOOPDOWN)) {
735				xpt_freeze_simq(isp->isp_sim, 1);
736				isp->isp_osinfo.simqfrozen |= SIMQFRZ_LOOPDOWN;
737				printf("%s: Loop DOWN- freezing SIMQ until Loop"
738				    " comes up\n", isp->isp_name);
739			}
740		} else {
741			printf("%s: Loop DOWN\n", isp->isp_name);
742		}
743		break;
744	case ISPASYNC_LOOP_UP:
745		if (isp->isp_path) {
746			if (isp->isp_osinfo.simqfrozen & SIMQFRZ_LOOPDOWN) {
747				xpt_release_simq(isp->isp_sim, 1);
748				isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_LOOPDOWN;
749				if (isp->isp_osinfo.simqfrozen) {
750					printf("%s: Loop UP- SIMQ still "
751					    "frozen\n", isp->isp_name);
752				} else {
753					printf("%s: Loop UP-releasing frozen "
754					    "SIMQ\n", isp->isp_name);
755				}
756			}
757		} else {
758			printf("%s: Loop UP\n", isp->isp_name);
759		}
760		break;
761	case ISPASYNC_PDB_CHANGE_COMPLETE:
762	if (IS_FC(isp)) {
763		long i = (long) arg;
764		static char *roles[4] = {
765		    "No", "Target", "Initiator", "Target/Initiator"
766		};
767		isp_pdb_t *pdbp = &((fcparam *)isp->isp_param)->isp_pdb[i];
768		if (pdbp->pdb_options == INVALID_PDB_OPTIONS) {
769			break;
770		}
771		printf("%s: Loop ID %d, %s role\n", isp->isp_name,
772		    pdbp->pdb_loopid, roles[(pdbp->pdb_prli_svc3 >> 4) & 0x3]);
773		printf("     Node Address 0x%x WWN 0x"
774		    "%02x%02x%02x%02x%02x%02x%02x%02x\n",
775		    BITS2WORD(pdbp->pdb_portid_bits),
776		    pdbp->pdb_portname[0], pdbp->pdb_portname[1],
777		    pdbp->pdb_portname[2], pdbp->pdb_portname[3],
778		    pdbp->pdb_portname[4], pdbp->pdb_portname[5],
779		    pdbp->pdb_portname[6], pdbp->pdb_portname[7]);
780		if (pdbp->pdb_options & PDB_OPTIONS_ADISC)
781			printf("     Hard Address 0x%x WWN 0x"
782			    "%02x%02x%02x%02x%02x%02x%02x%02x\n",
783			    BITS2WORD(pdbp->pdb_hardaddr_bits),
784			    pdbp->pdb_nodename[0], pdbp->pdb_nodename[1],
785			    pdbp->pdb_nodename[2], pdbp->pdb_nodename[3],
786			    pdbp->pdb_nodename[4], pdbp->pdb_nodename[5],
787			    pdbp->pdb_nodename[6], pdbp->pdb_nodename[7]);
788		switch (pdbp->pdb_prli_svc3 & SVC3_ROLE_MASK) {
789		case SVC3_TGT_ROLE|SVC3_INI_ROLE:
790			printf("     Master State=%s, Slave State=%s\n",
791			    isp2100_pdb_statename(pdbp->pdb_mstate),
792			    isp2100_pdb_statename(pdbp->pdb_sstate));
793			break;
794		case SVC3_TGT_ROLE:
795			printf("     Master State=%s\n",
796			    isp2100_pdb_statename(pdbp->pdb_mstate));
797			break;
798		case SVC3_INI_ROLE:
799			printf("     Slave State=%s\n",
800			    isp2100_pdb_statename(pdbp->pdb_sstate));
801			break;
802		default:
803			break;
804		}
805		break;
806	}
807	case ISPASYNC_CHANGE_NOTIFY:
808		printf("%s: Name Server Database Changed\n", isp->isp_name);
809		break;
810	default:
811		break;
812	}
813	return (rv);
814}
815
816
817/*
818 * Locks are held before coming here.
819 */
820void
821isp_uninit(struct ispsoftc *isp)
822{
823	ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
824	DISABLE_INTS(isp);
825}
826#else
827
828#define WATCH_INTERVAL          30
829
830static void ispminphys __P((struct buf *));
831static u_int32_t isp_adapter_info __P((int));
832static int ispcmd __P((ISP_SCSI_XFER_T *));
833static void isp_watch __P((void *arg));
834
835static struct scsi_adapter isp_switch = {
836	ispcmd, ispminphys, 0, 0, isp_adapter_info, "isp", { 0, 0 }
837};
838static struct scsi_device isp_dev = {
839	NULL, NULL, NULL, NULL, "isp", 0, { 0, 0 }
840};
841static int isp_poll __P((struct ispsoftc *, ISP_SCSI_XFER_T *, int));
842
843
844/*
845 * Complete attachment of hardware, include subdevices.
846 */
847void
848isp_attach(struct ispsoftc *isp)
849{
850	struct scsibus_data *scbus;
851
852	scbus = scsi_alloc_bus();
853	if(!scbus) {
854		return;
855	}
856	if (isp->isp_state == ISP_INITSTATE)
857		isp->isp_state = ISP_RUNSTATE;
858
859        timeout(isp_watch, isp, WATCH_INTERVAL * hz);
860	isp->isp_dogactive = 1;
861
862	isp->isp_osinfo._link.adapter_unit = isp->isp_osinfo.unit;
863	isp->isp_osinfo._link.adapter_softc = isp;
864	isp->isp_osinfo._link.adapter = &isp_switch;
865	isp->isp_osinfo._link.device = &isp_dev;
866	isp->isp_osinfo._link.flags = 0;
867	if (isp->isp_type & ISP_HA_FC) {
868		isp->isp_osinfo._link.adapter_targ =
869			((fcparam *)isp->isp_param)->isp_loopid;
870		scbus->maxtarg = MAX_FC_TARG-1;
871	} else {
872		int tmp = 0;	/* XXXX: Which Bus? */
873		isp->isp_osinfo.delay_throttle_count = 1;
874		isp->isp_osinfo._link.adapter_targ =
875			((sdparam *)isp->isp_param)->isp_initiator_id;
876		scbus->maxtarg = MAX_TARGETS-1;
877		(void) isp_control(isp, ISPCTL_RESET_BUS, &tmp);
878	}
879
880	/*
881	 * Prepare the scsibus_data area for the upperlevel scsi code.
882	 */
883	scbus->adapter_link = &isp->isp_osinfo._link;
884
885	/*
886	 * ask the adapter what subunits are present
887	 */
888	scsi_attachdevs(scbus);
889}
890
891
892/*
893 * minphys our xfers
894 *
895 * Unfortunately, the buffer pointer describes the target device- not the
896 * adapter device, so we can't use the pointer to find out what kind of
897 * adapter we are and adjust accordingly.
898 */
899
900static void
901ispminphys(struct buf *bp)
902{
903	/*
904	 * Only the 10X0 has a 24 bit limit.
905	 */
906	if (bp->b_bcount >= (1 << 24)) {
907		bp->b_bcount = (1 << 24);
908	}
909}
910
911static u_int32_t
912isp_adapter_info(int unit)
913{
914	/*
915 	 * XXX: FIND ISP BASED UPON UNIT AND GET REAL QUEUE LIMIT FROM THAT
916	 */
917	return (2);
918}
919
920static int
921ispcmd(ISP_SCSI_XFER_T *xs)
922{
923	struct ispsoftc *isp;
924	int r, s;
925
926	isp = XS_ISP(xs);
927	s = splbio();
928	DISABLE_INTS(isp);
929	if (isp->isp_state != ISP_RUNSTATE) {
930		isp_init(isp);
931		if (isp->isp_state != ISP_INITSTATE) {
932			ENABLE_INTS(isp);
933			(void) splx(s);
934			XS_SETERR(xs, HBA_BOTCH);
935			return (CMD_COMPLETE);
936		}
937		isp->isp_state = ISP_RUNSTATE;
938	}
939	r = ispscsicmd(xs);
940	ENABLE_INTS(isp);
941	if (r != CMD_QUEUED || (xs->flags & SCSI_NOMASK) == 0) {
942		(void) splx(s);
943		return (r);
944	}
945
946	/*
947	 * If we can't use interrupts, poll on completion.
948	 */
949	if (isp_poll(isp, xs, XS_TIME(xs))) {
950		/*
951		 * If no other error occurred but we didn't finish,
952		 * something bad happened.
953		 */
954		if (XS_IS_CMD_DONE(xs) == 0) {
955			isp->isp_nactive--;
956			if (isp->isp_nactive < 0)
957				isp->isp_nactive = 0;
958			if (XS_NOERR(xs)) {
959				isp_lostcmd(isp, xs);
960				XS_SETERR(xs, HBA_BOTCH);
961			}
962		}
963	}
964	(void) splx(s);
965	return (CMD_COMPLETE);
966}
967
968static int
969isp_poll(struct ispsoftc *isp, ISP_SCSI_XFER_T *xs, int mswait)
970{
971
972	while (mswait) {
973		/* Try the interrupt handling routine */
974		(void)isp_intr((void *)isp);
975
976		/* See if the xs is now done */
977		if (XS_IS_CMD_DONE(xs))
978			return (0);
979		SYS_DELAY(1000);	/* wait one millisecond */
980		mswait--;
981	}
982	return (1);
983}
984
985static void
986isp_watch(void *arg)
987{
988	int i;
989	struct ispsoftc *isp = arg;
990	ISP_SCSI_XFER_T *xs;
991	int s;
992
993	/*
994	 * Look for completely dead commands (but not polled ones).
995	 */
996	s = splbio();
997	for (i = 0; i < RQUEST_QUEUE_LEN; i++) {
998		if ((xs = (ISP_SCSI_XFER_T *) isp->isp_xflist[i]) == NULL) {
999			continue;
1000		}
1001		if (XS_TIME(xs) == 0) {
1002			continue;
1003		}
1004		XS_TIME(xs) -= (WATCH_INTERVAL * 1000);
1005
1006		/*
1007		 * Avoid later thinking that this
1008		 * transaction is not being timed.
1009		 * Then give ourselves to watchdog
1010		 * periods of grace.
1011		 */
1012		if (XS_TIME(xs) == 0)
1013			XS_TIME(xs) = 1;
1014		else if (XS_TIME(xs) > -(2 * WATCH_INTERVAL * 1000)) {
1015			continue;
1016		}
1017		if (IS_SCSI(isp)) {
1018			isp->isp_osinfo.delay_throttle_count = 1;
1019		}
1020		if (isp_control(isp, ISPCTL_ABORT_CMD, xs)) {
1021			printf("%s: isp_watch failed to abort command\n",
1022			    isp->isp_name);
1023			isp_restart(isp);
1024			break;
1025		}
1026	}
1027	if (isp->isp_osinfo.delay_throttle_count) {
1028		if (--isp->isp_osinfo.delay_throttle_count == 0) {
1029			sdparam *sdp = isp->isp_param;
1030			for (i = 0; i < MAX_TARGETS; i++) {
1031				sdp->isp_devparam[i].dev_flags |=
1032					DPARM_WIDE|DPARM_SYNC|DPARM_TQING;
1033				sdp->isp_devparam[i].dev_update = 1;
1034			}
1035			isp->isp_update = 1;
1036		}
1037	}
1038        timeout(isp_watch, isp, WATCH_INTERVAL * hz);
1039	isp->isp_dogactive = 1;
1040	splx(s);
1041}
1042
1043int
1044isp_async(isp, cmd, arg)
1045	struct ispsoftc *isp;
1046	ispasync_t cmd;
1047	void *arg;
1048{
1049	switch (cmd) {
1050	case ISPASYNC_NEW_TGT_PARAMS:
1051		if (isp->isp_type & ISP_HA_SCSI) {
1052			sdparam *sdp = isp->isp_param;
1053			char *wt;
1054			int mhz, flags, tgt, period;
1055
1056			tgt = *((int *) arg);
1057
1058			flags = sdp->isp_devparam[tgt].cur_dflags;
1059			period = sdp->isp_devparam[tgt].cur_period;
1060			if ((flags & DPARM_SYNC) && period &&
1061			    (sdp->isp_devparam[tgt].cur_offset) != 0) {
1062				if (sdp->isp_lvdmode) {
1063					switch (period) {
1064					case 0xa:
1065						mhz = 40;
1066						break;
1067					case 0xb:
1068						mhz = 33;
1069						break;
1070					case 0xc:
1071						mhz = 25;
1072						break;
1073					default:
1074						mhz = 1000 / (period * 4);
1075						break;
1076					}
1077				} else {
1078					mhz = 1000 / (period * 4);
1079				}
1080			} else {
1081				mhz = 0;
1082			}
1083			switch (flags & (DPARM_WIDE|DPARM_TQING)) {
1084			case DPARM_WIDE:
1085				wt = ", 16 bit wide\n";
1086				break;
1087			case DPARM_TQING:
1088				wt = ", Tagged Queueing Enabled\n";
1089				break;
1090			case DPARM_WIDE|DPARM_TQING:
1091				wt = ", 16 bit wide, Tagged Queueing Enabled\n";
1092				break;
1093			default:
1094				wt = "\n";
1095				break;
1096			}
1097			if (mhz) {
1098				printf("%s: Target %d at %dMHz Max Offset %d%s",
1099				    isp->isp_name, tgt, mhz,
1100				    sdp->isp_devparam[tgt].cur_offset, wt);
1101			} else {
1102				printf("%s: Target %d Async Mode%s",
1103				    isp->isp_name, tgt, wt);
1104			}
1105		}
1106		break;
1107	case ISPASYNC_BUS_RESET:
1108		printf("%s: SCSI bus reset detected\n", isp->isp_name);
1109		break;
1110	case ISPASYNC_LOOP_DOWN:
1111		printf("%s: Loop DOWN\n", isp->isp_name);
1112		break;
1113	case ISPASYNC_LOOP_UP:
1114		printf("%s: Loop UP\n", isp->isp_name);
1115		break;
1116	case ISPASYNC_PDB_CHANGE_COMPLETE:
1117	if (isp->isp_type & ISP_HA_FC) {
1118		int i;
1119		static char *roles[4] = {
1120		    "No", "Target", "Initiator", "Target/Initiator"
1121		};
1122		for (i = 0; i < MAX_FC_TARG; i++)  {
1123			isp_pdb_t *pdbp =
1124			    &((fcparam *)isp->isp_param)->isp_pdb[i];
1125			if (pdbp->pdb_options == INVALID_PDB_OPTIONS)
1126				continue;
1127			printf("%s: Loop ID %d, %s role\n",
1128			    isp->isp_name, pdbp->pdb_loopid,
1129			    roles[(pdbp->pdb_prli_svc3 >> 4) & 0x3]);
1130			printf("     Node Address 0x%x WWN 0x"
1131			    "%02x%02x%02x%02x%02x%02x%02x%02x\n",
1132			    BITS2WORD(pdbp->pdb_portid_bits),
1133			    pdbp->pdb_portname[0], pdbp->pdb_portname[1],
1134			    pdbp->pdb_portname[2], pdbp->pdb_portname[3],
1135			    pdbp->pdb_portname[4], pdbp->pdb_portname[5],
1136			    pdbp->pdb_portname[6], pdbp->pdb_portname[7]);
1137			if (pdbp->pdb_options & PDB_OPTIONS_ADISC)
1138				printf("     Hard Address 0x%x WWN 0x"
1139				    "%02x%02x%02x%02x%02x%02x%02x%02x\n",
1140				    BITS2WORD(pdbp->pdb_hardaddr_bits),
1141				    pdbp->pdb_nodename[0],
1142				    pdbp->pdb_nodename[1],
1143				    pdbp->pdb_nodename[2],
1144				    pdbp->pdb_nodename[3],
1145				    pdbp->pdb_nodename[4],
1146				    pdbp->pdb_nodename[5],
1147				    pdbp->pdb_nodename[6],
1148				    pdbp->pdb_nodename[7]);
1149			switch (pdbp->pdb_prli_svc3 & SVC3_ROLE_MASK) {
1150			case SVC3_TGT_ROLE|SVC3_INI_ROLE:
1151				printf("     Master State=%s, Slave State=%s\n",
1152				    isp2100_pdb_statename(pdbp->pdb_mstate),
1153				    isp2100_pdb_statename(pdbp->pdb_sstate));
1154				break;
1155			case SVC3_TGT_ROLE:
1156				printf("     Master State=%s\n",
1157				    isp2100_pdb_statename(pdbp->pdb_mstate));
1158				break;
1159			case SVC3_INI_ROLE:
1160				printf("     Slave State=%s\n",
1161				    isp2100_pdb_statename(pdbp->pdb_sstate));
1162				break;
1163			default:
1164				break;
1165			}
1166		}
1167		break;
1168	}
1169	case ISPASYNC_CHANGE_NOTIFY:
1170		printf("%s: Name Server Database Changed\n", isp->isp_name);
1171		break;
1172	default:
1173		break;
1174	}
1175	return (0);
1176}
1177
1178/*
1179 * Free any associated resources prior to decommissioning and
1180 * set the card to a known state (so it doesn't wake up and kick
1181 * us when we aren't expecting it to).
1182 *
1183 * Locks are held before coming here.
1184 */
1185void
1186isp_uninit(isp)
1187	struct ispsoftc *isp;
1188{
1189	int s = splbio();
1190	/*
1191	 * Leave with interrupts disabled.
1192	 */
1193	ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
1194	DISABLE_INTS(isp);
1195
1196	/*
1197	 * Turn off the watchdog (if active).
1198	 */
1199	if (isp->isp_dogactive) {
1200		untimeout(isp_watch, isp);
1201		isp->isp_dogactive = 0;
1202	}
1203	/*
1204	 * And out...
1205	 */
1206	splx(s);
1207}
1208#endif
1209