twe.c revision 118508
1/*-
2 * Copyright (c) 2000 Michael Smith
3 * Copyright (c) 2000 BSDi
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 *	$FreeBSD: head/sys/dev/twe/twe.c 118508 2003-08-05 19:55:21Z ps $
28 */
29
30/*
31 * Driver for the 3ware Escalade family of IDE RAID controllers.
32 */
33
34#include <dev/twe/twe_compat.h>
35#include <dev/twe/twereg.h>
36#include <dev/twe/tweio.h>
37#include <dev/twe/twevar.h>
38#define TWE_DEFINE_TABLES
39#include <dev/twe/twe_tables.h>
40
41/*
42 * Command submission.
43 */
44static int	twe_get_param_1(struct twe_softc *sc, int table_id, int param_id, u_int8_t *result);
45static int	twe_get_param_2(struct twe_softc *sc, int table_id, int param_id, u_int16_t *result);
46static int	twe_get_param_4(struct twe_softc *sc, int table_id, int param_id, u_int32_t *result);
47static void	*twe_get_param(struct twe_softc *sc, int table_id, int parameter_id, size_t size,
48					       void (* func)(struct twe_request *tr));
49#ifdef TWE_SHUTDOWN_NOTIFICATION
50static int	twe_set_param_1(struct twe_softc *sc, int table_id, int param_id, u_int8_t value);
51#endif
52#if 0
53static int	twe_set_param_2(struct twe_softc *sc, int table_id, int param_id, u_int16_t value);
54static int	twe_set_param_4(struct twe_softc *sc, int table_id, int param_id, u_int32_t value);
55#endif
56static int	twe_set_param(struct twe_softc *sc, int table_id, int param_id, int param_size,
57					      void *data);
58static int	twe_init_connection(struct twe_softc *sc, int mode);
59static int	twe_wait_request(struct twe_request *tr);
60static int	twe_immediate_request(struct twe_request *tr);
61static void	twe_completeio(struct twe_request *tr);
62static void	twe_reset(struct twe_softc *sc);
63static void	twe_add_unit(struct twe_softc *sc, int unit);
64static void	twe_del_unit(struct twe_softc *sc, int unit);
65
66/*
67 * Command I/O to controller.
68 */
69static int	twe_start(struct twe_request *tr);
70static void	twe_done(struct twe_softc *sc);
71static void	twe_complete(struct twe_softc *sc);
72static int	twe_wait_status(struct twe_softc *sc, u_int32_t status, int timeout);
73static int	twe_drain_response_queue(struct twe_softc *sc);
74static int	twe_check_bits(struct twe_softc *sc, u_int32_t status_reg);
75static int	twe_soft_reset(struct twe_softc *sc);
76
77/*
78 * Interrupt handling.
79 */
80static void	twe_host_intr(struct twe_softc *sc);
81static void	twe_attention_intr(struct twe_softc *sc);
82static void	twe_command_intr(struct twe_softc *sc);
83
84/*
85 * Asynchronous event handling.
86 */
87static int	twe_fetch_aen(struct twe_softc *sc);
88static void	twe_handle_aen(struct twe_request *tr);
89static void	twe_enqueue_aen(struct twe_softc *sc, u_int16_t aen);
90static int	twe_dequeue_aen(struct twe_softc *sc);
91static int	twe_drain_aen_queue(struct twe_softc *sc);
92static int	twe_find_aen(struct twe_softc *sc, u_int16_t aen);
93
94/*
95 * Command buffer management.
96 */
97static int	twe_get_request(struct twe_softc *sc, struct twe_request **tr);
98static void	twe_release_request(struct twe_request *tr);
99
100/*
101 * Debugging.
102 */
103static char 	*twe_format_aen(struct twe_softc *sc, u_int16_t aen);
104static int	twe_report_request(struct twe_request *tr);
105static void	twe_panic(struct twe_softc *sc, char *reason);
106
107/********************************************************************************
108 ********************************************************************************
109                                                                Public Interfaces
110 ********************************************************************************
111 ********************************************************************************/
112
113/********************************************************************************
114 * Initialise the controller, set up driver data structures.
115 */
116int
117twe_setup(struct twe_softc *sc)
118{
119    struct twe_request	*tr;
120    u_int32_t		status_reg;
121    int			i;
122
123    debug_called(4);
124
125    /*
126     * Initialise request queues.
127     */
128    twe_initq_free(sc);
129    twe_initq_bio(sc);
130    twe_initq_ready(sc);
131    twe_initq_busy(sc);
132    twe_initq_complete(sc);
133    sc->twe_wait_aen = -1;
134
135    /*
136     * Allocate request structures up front.
137     */
138    for (i = 0; i < TWE_Q_LENGTH; i++) {
139	if ((tr = twe_allocate_request(sc)) == NULL)
140	    return(ENOMEM);
141	/*
142	 * Set global defaults that won't change.
143	 */
144	tr->tr_command.generic.host_id = sc->twe_host_id;	/* controller-assigned host ID */
145	tr->tr_command.generic.request_id = i;			/* our index number */
146	sc->twe_lookup[i] = tr;
147
148	/*
149	 * Put command onto the freelist.
150	 */
151	twe_release_request(tr);
152    }
153
154    /*
155     * Check status register for errors, clear them.
156     */
157    status_reg = TWE_STATUS(sc);
158    twe_check_bits(sc, status_reg);
159
160    /*
161     * Wait for the controller to come ready.
162     */
163    if (twe_wait_status(sc, TWE_STATUS_MICROCONTROLLER_READY, 60)) {
164	twe_printf(sc, "microcontroller not ready\n");
165	return(ENXIO);
166    }
167
168    /*
169     * Disable interrupts from the card.
170     */
171    twe_disable_interrupts(sc);
172
173    /*
174     * Soft reset the controller, look for the AEN acknowledging the reset,
175     * check for errors, drain the response queue.
176     */
177    for (i = 0; i < TWE_MAX_RESET_TRIES; i++) {
178
179	if (i > 0)
180	    twe_printf(sc, "reset %d failed, trying again\n", i);
181
182	if (!twe_soft_reset(sc))
183	    break;			/* reset process complete */
184    }
185    /* did we give up? */
186    if (i >= TWE_MAX_RESET_TRIES) {
187	twe_printf(sc, "can't initialise controller, giving up\n");
188	return(ENXIO);
189    }
190
191    return(0);
192}
193
194static void
195twe_add_unit(struct twe_softc *sc, int unit)
196{
197    struct twe_drive		*dr;
198    int				table;
199    u_int16_t			dsize;
200    TWE_Param			*drives = NULL, *param = NULL;
201    TWE_Unit_Descriptor		*ud;
202
203    if (unit < 0 || unit > TWE_MAX_UNITS)
204	return;
205
206    /*
207     * The controller is in a safe state, so try to find drives attached to it.
208     */
209    if ((drives = twe_get_param(sc, TWE_PARAM_UNITSUMMARY, TWE_PARAM_UNITSUMMARY_Status,
210				TWE_MAX_UNITS, NULL)) == NULL) {
211	twe_printf(sc, "can't detect attached units\n");
212	return;
213    }
214
215    dr = &sc->twe_drive[unit];
216    /* check that the drive is online */
217    if (!(drives->data[unit] & TWE_PARAM_UNITSTATUS_Online))
218	goto out;
219
220    table = TWE_PARAM_UNITINFO + unit;
221
222    if (twe_get_param_4(sc, table, TWE_PARAM_UNITINFO_Capacity, &dr->td_size)) {
223	twe_printf(sc, "error fetching capacity for unit %d\n", unit);
224	goto out;
225    }
226    if (twe_get_param_1(sc, table, TWE_PARAM_UNITINFO_Status, &dr->td_state)) {
227	twe_printf(sc, "error fetching state for unit %d\n", unit);
228	goto out;
229    }
230    if (twe_get_param_2(sc, table, TWE_PARAM_UNITINFO_DescriptorSize, &dsize)) {
231	twe_printf(sc, "error fetching descriptor size for unit %d\n", unit);
232	goto out;
233    }
234    if ((param = twe_get_param(sc, table, TWE_PARAM_UNITINFO_Descriptor, dsize - 3, NULL)) == NULL) {
235	twe_printf(sc, "error fetching descriptor for unit %d\n", unit);
236	goto out;
237    }
238    ud = (TWE_Unit_Descriptor *)param->data;
239    dr->td_type = ud->configuration;
240
241    /* build synthetic geometry as per controller internal rules */
242    if (dr->td_size > 0x200000) {
243	dr->td_heads = 255;
244	dr->td_sectors = 63;
245    } else {
246	dr->td_heads = 64;
247	dr->td_sectors = 32;
248    }
249    dr->td_cylinders = dr->td_size / (dr->td_heads * dr->td_sectors);
250    dr->td_unit = unit;
251
252    twe_attach_drive(sc, dr);
253
254out:
255    if (param != NULL)
256	free(param, M_DEVBUF);
257    if (drives != NULL)
258	free(drives, M_DEVBUF);
259}
260
261static void
262twe_del_unit(struct twe_softc *sc, int unit)
263{
264
265    if (unit < 0 || unit > TWE_MAX_UNITS)
266	return;
267
268    twe_detach_drive(sc, unit);
269}
270
271/********************************************************************************
272 * Locate disk devices and attach children to them.
273 */
274void
275twe_init(struct twe_softc *sc)
276{
277    int 		i;
278
279    /*
280     * Scan for drives
281     */
282    for (i = 0; i < TWE_MAX_UNITS; i++)
283	twe_add_unit(sc, i);
284
285    /*
286     * Initialise connection with controller.
287     */
288    twe_init_connection(sc, TWE_INIT_MESSAGE_CREDITS);
289
290#ifdef TWE_SHUTDOWN_NOTIFICATION
291    /*
292     * Tell the controller we support shutdown notification.
293     */
294    twe_set_param_1(sc, TWE_PARAM_FEATURES, TWE_PARAM_FEATURES_DriverShutdown, 1);
295#endif
296
297    /*
298     * Mark controller up and ready to run.
299     */
300    sc->twe_state &= ~TWE_STATE_SHUTDOWN;
301
302    /*
303     * Finally enable interrupts.
304     */
305    twe_enable_interrupts(sc);
306}
307
308/********************************************************************************
309 * Stop the controller
310 */
311void
312twe_deinit(struct twe_softc *sc)
313{
314    /*
315     * Mark the controller as shutting down, and disable any further interrupts.
316     */
317    sc->twe_state |= TWE_STATE_SHUTDOWN;
318    twe_disable_interrupts(sc);
319
320#ifdef TWE_SHUTDOWN_NOTIFICATION
321    /*
322     * Disconnect from the controller
323     */
324    twe_init_connection(sc, TWE_SHUTDOWN_MESSAGE_CREDITS);
325#endif
326}
327
328/*******************************************************************************
329 * Take an interrupt, or be poked by other code to look for interrupt-worthy
330 * status.
331 */
332void
333twe_intr(struct twe_softc *sc)
334{
335    u_int32_t		status_reg;
336
337    debug_called(4);
338
339    /*
340     * Collect current interrupt status.
341     */
342    status_reg = TWE_STATUS(sc);
343    twe_check_bits(sc, status_reg);
344
345    /*
346     * Dispatch based on interrupt status
347     */
348    if (status_reg & TWE_STATUS_HOST_INTERRUPT)
349	twe_host_intr(sc);
350    if (status_reg & TWE_STATUS_ATTENTION_INTERRUPT)
351	twe_attention_intr(sc);
352    if (status_reg & TWE_STATUS_COMMAND_INTERRUPT)
353	twe_command_intr(sc);
354    if (status_reg & TWE_STATUS_RESPONSE_INTERRUPT)
355	twe_done(sc);
356};
357
358/********************************************************************************
359 * Pull as much work off the softc's work queue as possible and give it to the
360 * controller.
361 */
362void
363twe_startio(struct twe_softc *sc)
364{
365    struct twe_request	*tr;
366    TWE_Command		*cmd;
367    twe_bio		*bp;
368    int			error;
369
370    debug_called(4);
371
372    /* spin until something prevents us from doing any work */
373    for (;;) {
374
375	/* try to get a command that's already ready to go */
376	tr = twe_dequeue_ready(sc);
377
378	/* build a command from an outstanding bio */
379	if (tr == NULL) {
380
381	    /* see if there's work to be done */
382	    if ((bp = twe_dequeue_bio(sc)) == NULL)
383		break;
384
385	    /* get a command to handle the bio with */
386	    if (twe_get_request(sc, &tr)) {
387		twe_enqueue_bio(sc, bp);	/* failed, put the bio back */
388		break;
389	    }
390
391	    /* connect the bio to the command */
392	    tr->tr_complete = twe_completeio;
393	    tr->tr_private = bp;
394	    tr->tr_data = TWE_BIO_DATA(bp);
395	    tr->tr_length = TWE_BIO_LENGTH(bp);
396	    cmd = &tr->tr_command;
397	    if (TWE_BIO_IS_READ(bp)) {
398		tr->tr_flags |= TWE_CMD_DATAIN;
399		cmd->io.opcode = TWE_OP_READ;
400	    } else {
401		tr->tr_flags |= TWE_CMD_DATAOUT;
402		cmd->io.opcode = TWE_OP_WRITE;
403	    }
404
405	    /* build a suitable I/O command (assumes 512-byte rounded transfers) */
406	    cmd->io.size = 3;
407	    cmd->io.unit = TWE_BIO_UNIT(bp);
408	    cmd->io.block_count = (tr->tr_length + TWE_BLOCK_SIZE - 1) / TWE_BLOCK_SIZE;
409	    cmd->io.lba = TWE_BIO_LBA(bp);
410
411	    /* map the command so the controller can work with it */
412	    twe_map_request(tr);
413	}
414
415	/* did we find something to do? */
416	if (tr == NULL)
417	    break;
418
419	/* try to give command to controller */
420	error = twe_start(tr);
421
422	if (error != 0) {
423	    if (error == EBUSY) {
424		twe_requeue_ready(tr);		/* try it again later */
425		break;				/* don't try anything more for now */
426	    }
427	    /* we don't support any other return from twe_start */
428	    twe_panic(sc, "twe_start returned nonsense");
429	}
430    }
431}
432
433/********************************************************************************
434 * Write blocks from memory to disk, for system crash dumps.
435 */
436int
437twe_dump_blocks(struct twe_softc *sc, int unit,	u_int32_t lba, void *data, int nblks)
438{
439    struct twe_request	*tr;
440    TWE_Command		*cmd;
441    int			error;
442
443    if (twe_get_request(sc, &tr))
444	return(ENOMEM);
445
446    tr->tr_data = data;
447    tr->tr_status = TWE_CMD_SETUP;
448    tr->tr_length = nblks * TWE_BLOCK_SIZE;
449    tr->tr_flags = TWE_CMD_DATAOUT;
450
451    cmd = &tr->tr_command;
452    cmd->io.opcode = TWE_OP_WRITE;
453    cmd->io.size = 3;
454    cmd->io.unit = unit;
455    cmd->io.block_count = nblks;
456    cmd->io.lba = lba;
457
458    twe_map_request(tr);
459    error = twe_immediate_request(tr);
460    if (error == 0)
461	if (twe_report_request(tr))
462	    error = EIO;
463    twe_release_request(tr);
464    return(error);
465}
466
467/********************************************************************************
468 * Handle controller-specific control operations.
469 */
470int
471twe_ioctl(struct twe_softc *sc, int cmd, void *addr)
472{
473    struct twe_usercommand	*tu = (struct twe_usercommand *)addr;
474    struct twe_paramcommand	*tp = (struct twe_paramcommand *)addr;
475    struct twe_drivecommand	*td = (struct twe_drivecommand *)addr;
476    union twe_statrequest	*ts = (union twe_statrequest *)addr;
477    TWE_Param			*param;
478    void			*data;
479    int				*arg = (int *)addr;
480    struct twe_request		*tr;
481    u_int8_t			srid;
482    int				s, error;
483
484    error = 0;
485    switch(cmd) {
486	/* handle a command from userspace */
487    case TWEIO_COMMAND:
488	/* get a request */
489	while (twe_get_request(sc, &tr))
490	    tsleep(NULL, PPAUSE, "twioctl", hz);
491
492	/*
493	 * Save the command's request ID, copy the user-supplied command in,
494	 * restore the request ID.
495	 */
496	srid = tr->tr_command.generic.request_id;
497	bcopy(&tu->tu_command, &tr->tr_command, sizeof(TWE_Command));
498	tr->tr_command.generic.request_id = srid;
499
500	/*
501	 * if there's a data buffer, allocate and copy it in.
502	 * Must be in multipled of 512 bytes.
503	 */
504	tr->tr_length = (tu->tu_size + 511) & ~511;
505	if (tr->tr_length > 0) {
506	    if ((tr->tr_data = malloc(tr->tr_length, M_DEVBUF, M_WAITOK)) == NULL) {
507		error = ENOMEM;
508		goto cmd_done;
509	    }
510	    if ((error = copyin(tu->tu_data, tr->tr_data, tu->tu_size)) != 0)
511		goto cmd_done;
512	    tr->tr_flags |= TWE_CMD_DATAIN | TWE_CMD_DATAOUT;
513	}
514
515	/* run the command */
516	twe_map_request(tr);
517	twe_wait_request(tr);
518
519	/* copy the command out again */
520	bcopy(&tr->tr_command, &tu->tu_command, sizeof(TWE_Command));
521
522	/* if there was a data buffer, copy it out */
523	if (tr->tr_length > 0)
524	    error = copyout(tr->tr_data, tu->tu_data, tu->tu_size);
525
526    cmd_done:
527	/* free resources */
528	if (tr->tr_data != NULL)
529	    free(tr->tr_data, M_DEVBUF);
530	if (tr != NULL)
531	    twe_release_request(tr);
532
533	break;
534
535	/* fetch statistics counter */
536    case TWEIO_STATS:
537	switch (ts->ts_item) {
538#ifdef TWE_PERFORMANCE_MONITOR
539	case TWEQ_FREE:
540	case TWEQ_BIO:
541	case TWEQ_READY:
542	case TWEQ_BUSY:
543	case TWEQ_COMPLETE:
544	    bcopy(&sc->twe_qstat[ts->ts_item], &ts->ts_qstat, sizeof(struct twe_qstat));
545	    break;
546#endif
547	default:
548	    error = ENOENT;
549	    break;
550	}
551	break;
552
553	/* poll for an AEN */
554    case TWEIO_AEN_POLL:
555	*arg = twe_dequeue_aen(sc);
556	break;
557
558	/* wait for another AEN to show up */
559    case TWEIO_AEN_WAIT:
560	s = splbio();
561	while ((*arg = twe_dequeue_aen(sc)) == TWE_AEN_QUEUE_EMPTY) {
562	    error = tsleep(&sc->twe_aen_queue, PRIBIO | PCATCH, "tweaen", 0);
563	    if (error == EINTR)
564		break;
565	}
566	splx(s);
567	break;
568
569    case TWEIO_GET_PARAM:
570	if ((param = twe_get_param(sc, tp->tp_table_id, tp->tp_param_id, tp->tp_size, NULL)) == NULL) {
571	    twe_printf(sc, "TWEIO_GET_PARAM failed for 0x%x/0x%x/%d\n",
572		       tp->tp_table_id, tp->tp_param_id, tp->tp_size);
573	    error = EINVAL;
574	} else {
575	    if (param->parameter_size_bytes > tp->tp_size) {
576		twe_printf(sc, "TWEIO_GET_PARAM parameter too large (%d > %d)\n",
577			   param->parameter_size_bytes, tp->tp_size);
578		error = EFAULT;
579	    } else {
580		error = copyout(param->data, tp->tp_data, param->parameter_size_bytes);
581	    }
582	    free(param, M_DEVBUF);
583	}
584	break;
585
586    case TWEIO_SET_PARAM:
587	if ((data = malloc(tp->tp_size, M_DEVBUF, M_WAITOK)) == NULL) {
588	    error = ENOMEM;
589	} else {
590	    error = copyin(tp->tp_data, data, tp->tp_size);
591	    if (error == 0)
592		error = twe_set_param(sc, tp->tp_table_id, tp->tp_param_id, tp->tp_size, data);
593	    free(data, M_DEVBUF);
594	}
595	break;
596
597    case TWEIO_RESET:
598	twe_reset(sc);
599	break;
600
601    case TWEIO_ADD_UNIT:
602	twe_add_unit(sc, td->td_unit);
603	break;
604
605    case TWEIO_DEL_UNIT:
606	twe_del_unit(sc, td->td_unit);
607	break;
608
609	/* XXX implement ATA PASSTHROUGH */
610
611	/* nothing we understand */
612    default:
613	error = ENOTTY;
614    }
615
616    return(error);
617}
618
619/********************************************************************************
620 * Enable the useful interrupts from the controller.
621 */
622void
623twe_enable_interrupts(struct twe_softc *sc)
624{
625    sc->twe_state |= TWE_STATE_INTEN;
626    TWE_CONTROL(sc,
627	       TWE_CONTROL_CLEAR_ATTENTION_INTERRUPT |
628	       TWE_CONTROL_UNMASK_RESPONSE_INTERRUPT |
629	       TWE_CONTROL_ENABLE_INTERRUPTS);
630}
631
632/********************************************************************************
633 * Disable interrupts from the controller.
634 */
635void
636twe_disable_interrupts(struct twe_softc *sc)
637{
638    TWE_CONTROL(sc, TWE_CONTROL_DISABLE_INTERRUPTS);
639    sc->twe_state &= ~TWE_STATE_INTEN;
640}
641
642/********************************************************************************
643 ********************************************************************************
644                                                               Command Submission
645 ********************************************************************************
646 ********************************************************************************/
647
648/********************************************************************************
649 * Read integer parameter table entries.
650 */
651static int
652twe_get_param_1(struct twe_softc *sc, int table_id, int param_id, u_int8_t *result)
653{
654    TWE_Param	*param;
655
656    if ((param = twe_get_param(sc, table_id, param_id, 1, NULL)) == NULL)
657	return(ENOENT);
658    *result = *(u_int8_t *)param->data;
659    free(param, M_DEVBUF);
660    return(0);
661}
662
663static int
664twe_get_param_2(struct twe_softc *sc, int table_id, int param_id, u_int16_t *result)
665{
666    TWE_Param	*param;
667
668    if ((param = twe_get_param(sc, table_id, param_id, 2, NULL)) == NULL)
669	return(ENOENT);
670    *result = *(u_int16_t *)param->data;
671    free(param, M_DEVBUF);
672    return(0);
673}
674
675static int
676twe_get_param_4(struct twe_softc *sc, int table_id, int param_id, u_int32_t *result)
677{
678    TWE_Param	*param;
679
680    if ((param = twe_get_param(sc, table_id, param_id, 4, NULL)) == NULL)
681	return(ENOENT);
682    *result = *(u_int32_t *)param->data;
683    free(param, M_DEVBUF);
684    return(0);
685}
686
687/********************************************************************************
688 * Perform a TWE_OP_GET_PARAM command.  If a callback function is provided, it
689 * will be called with the command when it's completed.  If no callback is
690 * provided, we will wait for the command to complete and then return just the data.
691 * The caller is responsible for freeing the data when done with it.
692 */
693static void *
694twe_get_param(struct twe_softc *sc, int table_id, int param_id, size_t param_size,
695	      void (* func)(struct twe_request *tr))
696{
697    struct twe_request	*tr;
698    TWE_Command		*cmd;
699    TWE_Param		*param;
700    int			error;
701
702    debug_called(4);
703
704    tr = NULL;
705    param = NULL;
706
707    /* get a command */
708    if (twe_get_request(sc, &tr))
709	goto err;
710
711    /* get a buffer */
712    if ((param = (TWE_Param *)malloc(TWE_SECTOR_SIZE, M_DEVBUF, M_NOWAIT)) == NULL)
713	goto err;
714    tr->tr_data = param;
715    tr->tr_length = TWE_SECTOR_SIZE;
716    tr->tr_flags = TWE_CMD_DATAIN | TWE_CMD_DATAOUT;
717
718    /* build the command for the controller */
719    cmd = &tr->tr_command;
720    cmd->param.opcode = TWE_OP_GET_PARAM;
721    cmd->param.size = 2;
722    cmd->param.unit = 0;
723    cmd->param.param_count = 1;
724
725    /* map the command/data into controller-visible space */
726    twe_map_request(tr);
727
728    /* fill in the outbound parameter data */
729    param->table_id = table_id;
730    param->parameter_id = param_id;
731    param->parameter_size_bytes = param_size;
732
733    /* submit the command and either wait or let the callback handle it */
734    if (func == NULL) {
735	/* XXX could use twe_wait_request here if interrupts were enabled? */
736	error = twe_immediate_request(tr);
737	if (error == 0) {
738	    if (twe_report_request(tr))
739		goto err;
740	}
741	twe_release_request(tr);
742	return(param);
743    } else {
744	tr->tr_complete = func;
745	error = twe_start(tr);
746	if (error == 0)
747	    return(func);
748    }
749
750    /* something failed */
751err:
752    debug(1, "failed");
753    if (tr != NULL)
754	twe_release_request(tr);
755    if (param != NULL)
756	free(param, M_DEVBUF);
757    return(NULL);
758}
759
760/********************************************************************************
761 * Set integer parameter table entries.
762 */
763#ifdef TWE_SHUTDOWN_NOTIFICATION
764static int
765twe_set_param_1(struct twe_softc *sc, int table_id, int param_id, u_int8_t value)
766{
767    return(twe_set_param(sc, table_id, param_id, sizeof(value), &value));
768}
769#endif
770
771#if 0
772static int
773twe_set_param_2(struct twe_softc *sc, int table_id, int param_id, u_int16_t value)
774{
775    return(twe_set_param(sc, table_id, param_id, sizeof(value), &value));
776}
777
778static int
779twe_set_param_4(struct twe_softc *sc, int table_id, int param_id, u_int32_t value)
780{
781    return(twe_set_param(sc, table_id, param_id, sizeof(value), &value));
782}
783#endif
784
785/********************************************************************************
786 * Perform a TWE_OP_SET_PARAM command, returns nonzero on error.
787 */
788static int
789twe_set_param(struct twe_softc *sc, int table_id, int param_id, int param_size, void *data)
790{
791    struct twe_request	*tr;
792    TWE_Command		*cmd;
793    TWE_Param		*param;
794    int			error;
795
796    debug_called(4);
797
798    tr = NULL;
799    param = NULL;
800    error = ENOMEM;
801
802    /* get a command */
803    if (twe_get_request(sc, &tr))
804	goto out;
805
806    /* get a buffer */
807    if ((param = (TWE_Param *)malloc(TWE_SECTOR_SIZE, M_DEVBUF, M_NOWAIT)) == NULL)
808	goto out;
809    tr->tr_data = param;
810    tr->tr_length = TWE_SECTOR_SIZE;
811    tr->tr_flags = TWE_CMD_DATAIN | TWE_CMD_DATAOUT;
812
813    /* build the command for the controller */
814    cmd = &tr->tr_command;
815    cmd->param.opcode = TWE_OP_SET_PARAM;
816    cmd->param.size = 2;
817    cmd->param.unit = 0;
818    cmd->param.param_count = 1;
819
820    /* map the command/data into controller-visible space */
821    twe_map_request(tr);
822
823    /* fill in the outbound parameter data */
824    param->table_id = table_id;
825    param->parameter_id = param_id;
826    param->parameter_size_bytes = param_size;
827    bcopy(data, param->data, param_size);
828
829    /* XXX could use twe_wait_request here if interrupts were enabled? */
830    error = twe_immediate_request(tr);
831    if (error == 0) {
832	if (twe_report_request(tr))
833	    error = EIO;
834    }
835
836out:
837    if (tr != NULL)
838	twe_release_request(tr);
839    if (param != NULL)
840	free(param, M_DEVBUF);
841    return(error);
842}
843
844/********************************************************************************
845 * Perform a TWE_OP_INIT_CONNECTION command, returns nonzero on error.
846 *
847 * Typically called with interrupts disabled.
848 */
849static int
850twe_init_connection(struct twe_softc *sc, int mode)
851{
852    struct twe_request	*tr;
853    TWE_Command		*cmd;
854    int			error;
855
856    debug_called(4);
857
858    /* get a command */
859    if (twe_get_request(sc, &tr))
860	return(0);
861
862    /* build the command */
863    cmd = &tr->tr_command;
864    cmd->initconnection.opcode = TWE_OP_INIT_CONNECTION;
865    cmd->initconnection.size = 3;
866    cmd->initconnection.host_id = 0;
867    cmd->initconnection.message_credits = mode;
868    cmd->initconnection.response_queue_pointer = 0;
869
870    /* map the command into controller-visible space */
871    twe_map_request(tr);
872
873    /* submit the command */
874    error = twe_immediate_request(tr);
875    /* XXX check command result? */
876    twe_unmap_request(tr);
877    twe_release_request(tr);
878
879    if (mode == TWE_INIT_MESSAGE_CREDITS)
880	sc->twe_host_id = cmd->initconnection.host_id;
881    return(error);
882}
883
884/********************************************************************************
885 * Start the command (tr) and sleep waiting for it to complete.
886 *
887 * Successfully completed commands are dequeued.
888 */
889static int
890twe_wait_request(struct twe_request *tr)
891{
892    int		s;
893
894    debug_called(4);
895
896    tr->tr_flags |= TWE_CMD_SLEEPER;
897    tr->tr_status = TWE_CMD_BUSY;
898    twe_enqueue_ready(tr);
899    twe_startio(tr->tr_sc);
900    s = splbio();
901    while (tr->tr_status == TWE_CMD_BUSY)
902	tsleep(tr, PRIBIO, "twewait", 0);
903    splx(s);
904
905    return(0);
906}
907
908/********************************************************************************
909 * Start the command (tr) and busy-wait for it to complete.
910 * This should only be used when interrupts are actually disabled (although it
911 * will work if they are not).
912 */
913static int
914twe_immediate_request(struct twe_request *tr)
915{
916    int		error;
917
918    debug_called(4);
919
920    error = 0;
921
922    if ((error = twe_start(tr)) != 0)
923	return(error);
924    while (tr->tr_status == TWE_CMD_BUSY){
925	twe_done(tr->tr_sc);
926    }
927    return(tr->tr_status != TWE_CMD_COMPLETE);
928}
929
930/********************************************************************************
931 * Handle completion of an I/O command.
932 */
933static void
934twe_completeio(struct twe_request *tr)
935{
936    struct twe_softc	*sc = tr->tr_sc;
937    twe_bio		*bp = (twe_bio *)tr->tr_private;
938
939    debug_called(4);
940
941    if (tr->tr_status == TWE_CMD_COMPLETE) {
942
943	if (twe_report_request(tr))
944	    TWE_BIO_SET_ERROR(bp, EIO);
945
946    } else {
947	twe_panic(sc, "twe_completeio on incomplete command");
948    }
949    tr->tr_private = NULL;
950    twed_intr(bp);
951    twe_release_request(tr);
952}
953
954/********************************************************************************
955 * Reset the controller and pull all the active commands back onto the ready
956 * queue.  Used to restart a controller that's exhibiting bad behaviour.
957 */
958static void
959twe_reset(struct twe_softc *sc)
960{
961    struct twe_request	*tr;
962    int			i, s;
963
964    /*
965     * Sleep for a short period to allow AENs to be signalled.
966     */
967    tsleep(NULL, PRIBIO, "twereset", hz);
968
969    /*
970     * Disable interrupts from the controller, and mask any accidental entry
971     * into our interrupt handler.
972     */
973    twe_printf(sc, "controller reset in progress...\n");
974    twe_disable_interrupts(sc);
975    s = splbio();
976
977    /*
978     * Try to soft-reset the controller.
979     */
980    for (i = 0; i < TWE_MAX_RESET_TRIES; i++) {
981
982	if (i > 0)
983	    twe_printf(sc, "reset %d failed, trying again\n", i);
984
985	if (!twe_soft_reset(sc))
986	    break;			/* reset process complete */
987    }
988    /* did we give up? */
989    if (i >= TWE_MAX_RESET_TRIES) {
990	twe_printf(sc, "can't reset controller, giving up\n");
991	goto out;
992    }
993
994    /*
995     * Move all of the commands that were busy back to the ready queue.
996     */
997    i = 0;
998    while ((tr = twe_dequeue_busy(sc)) != NULL) {
999	twe_enqueue_ready(tr);
1000	i++;
1001    }
1002
1003    /*
1004     * Kick the controller to start things going again, then re-enable interrupts.
1005     */
1006    twe_startio(sc);
1007    twe_enable_interrupts(sc);
1008    twe_printf(sc, "controller reset done, %d commands restarted\n", i);
1009
1010out:
1011    splx(s);
1012    twe_enable_interrupts(sc);
1013}
1014
1015/********************************************************************************
1016 ********************************************************************************
1017                                                        Command I/O to Controller
1018 ********************************************************************************
1019 ********************************************************************************/
1020
1021/********************************************************************************
1022 * Try to deliver (tr) to the controller.
1023 *
1024 * Can be called at any interrupt level, with or without interrupts enabled.
1025 */
1026static int
1027twe_start(struct twe_request *tr)
1028{
1029    struct twe_softc	*sc = tr->tr_sc;
1030    int			i, s, done;
1031    u_int32_t		status_reg;
1032
1033    debug_called(4);
1034
1035    /* mark the command as currently being processed */
1036    tr->tr_status = TWE_CMD_BUSY;
1037
1038    /*
1039     * Spin briefly waiting for the controller to come ready
1040     *
1041     * XXX it might be more efficient to return EBUSY immediately
1042     *     and let the command be rescheduled.
1043     */
1044    for (i = 100000, done = 0; (i > 0) && !done; i--) {
1045	s = splbio();
1046
1047	/* check to see if we can post a command */
1048	status_reg = TWE_STATUS(sc);
1049	twe_check_bits(sc, status_reg);
1050
1051	if (!(status_reg & TWE_STATUS_COMMAND_QUEUE_FULL)) {
1052	    TWE_COMMAND_QUEUE(sc, tr->tr_cmdphys);
1053	    done = 1;
1054	    /* move command to work queue */
1055	    twe_enqueue_busy(tr);
1056#ifdef TWE_DEBUG
1057	    if (tr->tr_complete != NULL) {
1058		debug(3, "queued request %d with callback %p", tr->tr_command.generic.request_id, tr->tr_complete);
1059	    } else if (tr->tr_flags & TWE_CMD_SLEEPER) {
1060		debug(3, "queued request %d with wait channel %p", tr->tr_command.generic.request_id, tr);
1061	    } else {
1062		debug(3, "queued request %d for polling caller", tr->tr_command.generic.request_id);
1063	    }
1064#endif
1065	}
1066	splx(s);	/* drop spl to allow completion interrupts */
1067    }
1068
1069    /* command is enqueued */
1070    if (done)
1071	return(0);
1072
1073    /*
1074     * We couldn't get the controller to take the command; try submitting it again later.
1075     * This should only happen if something is wrong with the controller, or if we have
1076     * overestimated the number of commands it can accept.  (Should we actually reject
1077     * the command at this point?)
1078     */
1079    return(EBUSY);
1080}
1081
1082/********************************************************************************
1083 * Poll the controller (sc) for completed commands.
1084 *
1085 * Can be called at any interrupt level, with or without interrupts enabled.
1086 */
1087static void
1088twe_done(struct twe_softc *sc)
1089{
1090    TWE_Response_Queue	rq;
1091    struct twe_request	*tr;
1092    int			s, found;
1093    u_int32_t		status_reg;
1094
1095    debug_called(5);
1096
1097    /* loop collecting completed commands */
1098    found = 0;
1099    s = splbio();
1100    for (;;) {
1101	status_reg = TWE_STATUS(sc);
1102	twe_check_bits(sc, status_reg);		/* XXX should this fail? */
1103
1104	if (!(status_reg & TWE_STATUS_RESPONSE_QUEUE_EMPTY)) {
1105	    found = 1;
1106	    rq = TWE_RESPONSE_QUEUE(sc);
1107	    tr = sc->twe_lookup[rq.u.response_id];	/* find command */
1108	    if (tr->tr_status != TWE_CMD_BUSY)
1109		twe_printf(sc, "completion event for nonbusy command\n");
1110	    tr->tr_status = TWE_CMD_COMPLETE;
1111	    debug(3, "completed request id %d with status %d",
1112		  tr->tr_command.generic.request_id, tr->tr_command.generic.status);
1113	    /* move to completed queue */
1114	    twe_remove_busy(tr);
1115	    twe_enqueue_complete(tr);
1116	} else {
1117	    break;					/* no response ready */
1118	}
1119    }
1120    splx(s);
1121
1122    /* if we've completed any commands, try posting some more */
1123    if (found)
1124	twe_startio(sc);
1125
1126    /* handle completion and timeouts */
1127    twe_complete(sc);		/* XXX use deferred completion? */
1128}
1129
1130/********************************************************************************
1131 * Perform post-completion processing for commands on (sc).
1132 *
1133 * This is split from twe_done as it can be safely deferred and run at a lower
1134 * priority level should facilities for such a thing become available.
1135 */
1136static void
1137twe_complete(struct twe_softc *sc)
1138{
1139    struct twe_request	*tr;
1140
1141    debug_called(5);
1142
1143    /*
1144     * Pull commands off the completed list, dispatch them appropriately
1145     */
1146    while ((tr = twe_dequeue_complete(sc)) != NULL) {
1147
1148	/* unmap the command's data buffer */
1149	twe_unmap_request(tr);
1150
1151	/* dispatch to suit command originator */
1152	if (tr->tr_complete != NULL) {		/* completion callback */
1153	    debug(2, "call completion handler %p", tr->tr_complete);
1154	    tr->tr_complete(tr);
1155
1156	} else if (tr->tr_flags & TWE_CMD_SLEEPER) {	/* caller is asleep waiting */
1157	    debug(2, "wake up command owner on %p", tr);
1158	    wakeup_one(tr);
1159
1160	} else {					/* caller is polling command */
1161	    debug(2, "command left for owner");
1162	}
1163    }
1164}
1165
1166/********************************************************************************
1167 * Wait for (status) to be set in the controller status register for up to
1168 * (timeout) seconds.  Returns 0 if found, nonzero if we time out.
1169 *
1170 * Note: this busy-waits, rather than sleeping, since we may be called with
1171 * eg. clock interrupts masked.
1172 */
1173static int
1174twe_wait_status(struct twe_softc *sc, u_int32_t status, int timeout)
1175{
1176    time_t	expiry;
1177    u_int32_t	status_reg;
1178
1179    debug_called(4);
1180
1181    expiry = time_second + timeout;
1182
1183    do {
1184	status_reg = TWE_STATUS(sc);
1185	if (status_reg & status)	/* got the required bit(s)? */
1186	    return(0);
1187	DELAY(100000);
1188    } while (time_second <= expiry);
1189
1190    return(1);
1191}
1192
1193/********************************************************************************
1194 * Drain the response queue, which may contain responses to commands we know
1195 * nothing about.
1196 */
1197static int
1198twe_drain_response_queue(struct twe_softc *sc)
1199{
1200    TWE_Response_Queue	rq;
1201    u_int32_t		status_reg;
1202
1203    debug_called(4);
1204
1205    for (;;) {				/* XXX give up eventually? */
1206	status_reg = TWE_STATUS(sc);
1207	if (twe_check_bits(sc, status_reg))
1208	    return(1);
1209	if (status_reg & TWE_STATUS_RESPONSE_QUEUE_EMPTY)
1210	    return(0);
1211	rq = TWE_RESPONSE_QUEUE(sc);
1212    }
1213}
1214
1215/********************************************************************************
1216 * Soft-reset the controller
1217 */
1218static int
1219twe_soft_reset(struct twe_softc *sc)
1220{
1221    u_int32_t		status_reg;
1222
1223    debug_called(2);
1224
1225    TWE_SOFT_RESET(sc);
1226
1227    if (twe_wait_status(sc, TWE_STATUS_ATTENTION_INTERRUPT, 30)) {
1228	twe_printf(sc, "no attention interrupt\n");
1229	return(1);
1230    }
1231    TWE_CONTROL(sc, TWE_CONTROL_CLEAR_ATTENTION_INTERRUPT);
1232    if (twe_drain_aen_queue(sc)) {
1233	twe_printf(sc, "can't drain AEN queue\n");
1234	return(1);
1235    }
1236    if (twe_find_aen(sc, TWE_AEN_SOFT_RESET)) {
1237	twe_printf(sc, "reset not reported\n");
1238	return(1);
1239    }
1240    status_reg = TWE_STATUS(sc);
1241    if (TWE_STATUS_ERRORS(status_reg) || twe_check_bits(sc, status_reg)) {
1242	twe_printf(sc, "controller errors detected\n");
1243	return(1);
1244    }
1245    if (twe_drain_response_queue(sc)) {
1246	twe_printf(sc, "can't drain response queue\n");
1247	return(1);
1248    }
1249    return(0);
1250}
1251
1252/********************************************************************************
1253 ********************************************************************************
1254                                                               Interrupt Handling
1255 ********************************************************************************
1256 ********************************************************************************/
1257
1258/********************************************************************************
1259 * Host interrupt.
1260 *
1261 * XXX what does this mean?
1262 */
1263static void
1264twe_host_intr(struct twe_softc *sc)
1265{
1266    debug_called(4);
1267
1268    twe_printf(sc, "host interrupt\n");
1269    TWE_CONTROL(sc, TWE_CONTROL_CLEAR_HOST_INTERRUPT);
1270}
1271
1272/********************************************************************************
1273 * Attention interrupt.
1274 *
1275 * Signalled when the controller has one or more AENs for us.
1276 */
1277static void
1278twe_attention_intr(struct twe_softc *sc)
1279{
1280    debug_called(4);
1281
1282    /* instigate a poll for AENs */
1283    if (twe_fetch_aen(sc)) {
1284	twe_printf(sc, "error polling for signalled AEN\n");
1285    } else {
1286	TWE_CONTROL(sc, TWE_CONTROL_CLEAR_ATTENTION_INTERRUPT);
1287    }
1288}
1289
1290/********************************************************************************
1291 * Command interrupt.
1292 *
1293 * Signalled when the controller can handle more commands.
1294 */
1295static void
1296twe_command_intr(struct twe_softc *sc)
1297{
1298    debug_called(4);
1299
1300    /*
1301     * We don't use this, rather we try to submit commands when we receive
1302     * them, and when other commands have completed.  Mask it so we don't get
1303     * another one.
1304     */
1305    twe_printf(sc, "command interrupt\n");
1306    TWE_CONTROL(sc, TWE_CONTROL_MASK_COMMAND_INTERRUPT);
1307}
1308
1309/********************************************************************************
1310 ********************************************************************************
1311                                                      Asynchronous Event Handling
1312 ********************************************************************************
1313 ********************************************************************************/
1314
1315/********************************************************************************
1316 * Request an AEN from the controller.
1317 */
1318static int
1319twe_fetch_aen(struct twe_softc *sc)
1320{
1321
1322    debug_called(4);
1323
1324    if ((twe_get_param(sc, TWE_PARAM_AEN, TWE_PARAM_AEN_UnitCode, 2, twe_handle_aen)) == NULL)
1325	return(EIO);
1326    return(0);
1327}
1328
1329/********************************************************************************
1330 * Handle an AEN returned by the controller.
1331 */
1332static void
1333twe_handle_aen(struct twe_request *tr)
1334{
1335    struct twe_softc	*sc = tr->tr_sc;
1336    TWE_Param		*param;
1337    u_int16_t		aen;
1338
1339    debug_called(4);
1340
1341    /* XXX check for command success somehow? */
1342
1343    param = (TWE_Param *)tr->tr_data;
1344    aen = *(u_int16_t *)(param->data);
1345
1346    free(tr->tr_data, M_DEVBUF);
1347    twe_release_request(tr);
1348    twe_enqueue_aen(sc, aen);
1349
1350    /* XXX poll for more AENs? */
1351}
1352
1353/********************************************************************************
1354 * Pull AENs out of the controller and park them in the queue, in a context where
1355 * interrupts aren't active.  Return nonzero if we encounter any errors in the
1356 * process of obtaining all the available AENs.
1357 */
1358static int
1359twe_drain_aen_queue(struct twe_softc *sc)
1360{
1361    u_int16_t	aen;
1362
1363    for (;;) {
1364	if (twe_get_param_2(sc, TWE_PARAM_AEN, TWE_PARAM_AEN_UnitCode, &aen))
1365	    return(1);
1366	if (aen == TWE_AEN_QUEUE_EMPTY)
1367	    return(0);
1368	twe_enqueue_aen(sc, aen);
1369    }
1370}
1371
1372/********************************************************************************
1373 * Push an AEN that we've received onto the queue.
1374 *
1375 * Note that we have to lock this against reentrance, since it may be called
1376 * from both interrupt and non-interrupt context.
1377 *
1378 * If someone is waiting for the AEN we have, wake them up.
1379 */
1380static void
1381twe_enqueue_aen(struct twe_softc *sc, u_int16_t aen)
1382{
1383    char	*msg;
1384    int		s, next, nextnext;
1385
1386    debug_called(4);
1387
1388    if ((msg = twe_format_aen(sc, aen)) != NULL)
1389	twe_printf(sc, "AEN: <%s>\n", msg);
1390
1391    s = splbio();
1392    /* enqueue the AEN */
1393    next = ((sc->twe_aen_head + 1) % TWE_Q_LENGTH);
1394    nextnext = ((sc->twe_aen_head + 2) % TWE_Q_LENGTH);
1395
1396    /* check to see if this is the last free slot, and subvert the AEN if it is */
1397    if (nextnext == sc->twe_aen_tail)
1398	aen = TWE_AEN_QUEUE_FULL;
1399
1400    /* look to see if there's room for this AEN */
1401    if (next != sc->twe_aen_tail) {
1402	sc->twe_aen_queue[sc->twe_aen_head] = aen;
1403	sc->twe_aen_head = next;
1404    }
1405
1406    /* wake up anyone asleep on the queue */
1407    wakeup(&sc->twe_aen_queue);
1408
1409    /* anyone looking for this AEN? */
1410    if (sc->twe_wait_aen == aen) {
1411	sc->twe_wait_aen = -1;
1412	wakeup(&sc->twe_wait_aen);
1413    }
1414    splx(s);
1415}
1416
1417/********************************************************************************
1418 * Pop an AEN off the queue, or return -1 if there are none left.
1419 *
1420 * We are more or less interrupt-safe, so don't block interrupts.
1421 */
1422static int
1423twe_dequeue_aen(struct twe_softc *sc)
1424{
1425    int		result;
1426
1427    debug_called(4);
1428
1429    if (sc->twe_aen_tail == sc->twe_aen_head) {
1430	result = TWE_AEN_QUEUE_EMPTY;
1431    } else {
1432	result = sc->twe_aen_queue[sc->twe_aen_tail];
1433	sc->twe_aen_tail = ((sc->twe_aen_tail + 1) % TWE_Q_LENGTH);
1434    }
1435    return(result);
1436}
1437
1438/********************************************************************************
1439 * Check to see if the requested AEN is in the queue.
1440 *
1441 * XXX we could probably avoid masking interrupts here
1442 */
1443static int
1444twe_find_aen(struct twe_softc *sc, u_int16_t aen)
1445{
1446    int		i, s, missing;
1447
1448    missing = 1;
1449    s = splbio();
1450    for (i = sc->twe_aen_tail; (i != sc->twe_aen_head) && missing; i = (i + 1) % TWE_Q_LENGTH) {
1451	if (sc->twe_aen_queue[i] == aen)
1452	    missing = 0;
1453    }
1454    splx(s);
1455    return(missing);
1456}
1457
1458
1459#if 0	/* currently unused */
1460/********************************************************************************
1461 * Sleep waiting for at least (timeout) seconds until we see (aen) as
1462 * requested.  Returns nonzero on timeout or failure.
1463 *
1464 * XXX: this should not be used in cases where there may be more than one sleeper
1465 *      without a mechanism for registering multiple sleepers.
1466 */
1467static int
1468twe_wait_aen(struct twe_softc *sc, int aen, int timeout)
1469{
1470    time_t	expiry;
1471    int		found, s;
1472
1473    debug_called(4);
1474
1475    expiry = time_second + timeout;
1476    found = 0;
1477
1478    s = splbio();
1479    sc->twe_wait_aen = aen;
1480    do {
1481	twe_fetch_aen(sc);
1482	tsleep(&sc->twe_wait_aen, PZERO, "twewaen", hz);
1483	if (sc->twe_wait_aen == -1)
1484	    found = 1;
1485    } while ((time_second <= expiry) && !found);
1486    splx(s);
1487    return(!found);
1488}
1489#endif
1490
1491/********************************************************************************
1492 ********************************************************************************
1493                                                        Command Buffer Management
1494 ********************************************************************************
1495 ********************************************************************************/
1496
1497/********************************************************************************
1498 * Get a new command buffer.
1499 *
1500 * This will return NULL if all command buffers are in use.
1501 */
1502static int
1503twe_get_request(struct twe_softc *sc, struct twe_request **tr)
1504{
1505    debug_called(4);
1506
1507    /* try to reuse an old buffer */
1508    *tr = twe_dequeue_free(sc);
1509
1510    /* initialise some fields to their defaults */
1511    if (*tr != NULL) {
1512	(*tr)->tr_data = NULL;
1513	(*tr)->tr_private = NULL;
1514	(*tr)->tr_status = TWE_CMD_SETUP;		/* command is in setup phase */
1515	(*tr)->tr_flags = 0;
1516	(*tr)->tr_complete = NULL;
1517	(*tr)->tr_command.generic.status = 0;		/* before submission to controller */
1518	(*tr)->tr_command.generic.flags = 0;		/* not used */
1519    }
1520    return(*tr == NULL);
1521}
1522
1523/********************************************************************************
1524 * Release a command buffer for reuse.
1525 *
1526 */
1527static void
1528twe_release_request(struct twe_request *tr)
1529{
1530    debug_called(4);
1531
1532    if (tr->tr_private != NULL)
1533	twe_panic(tr->tr_sc, "tr_private != NULL");
1534    twe_enqueue_free(tr);
1535}
1536
1537/********************************************************************************
1538 ********************************************************************************
1539                                                                        Debugging
1540 ********************************************************************************
1541 ********************************************************************************/
1542
1543/********************************************************************************
1544 * Print some information about the controller
1545 */
1546void
1547twe_describe_controller(struct twe_softc *sc)
1548{
1549    TWE_Param		*p[6];
1550    u_int8_t		ports;
1551    u_int32_t		size;
1552    int			i;
1553
1554    debug_called(2);
1555
1556    /* get the port count */
1557    twe_get_param_1(sc, TWE_PARAM_CONTROLLER, TWE_PARAM_CONTROLLER_PortCount, &ports);
1558
1559    /* get version strings */
1560    p[0] = twe_get_param(sc, TWE_PARAM_VERSION, TWE_PARAM_VERSION_Mon,  16, NULL);
1561    p[1] = twe_get_param(sc, TWE_PARAM_VERSION, TWE_PARAM_VERSION_FW,   16, NULL);
1562    p[2] = twe_get_param(sc, TWE_PARAM_VERSION, TWE_PARAM_VERSION_BIOS, 16, NULL);
1563    p[3] = twe_get_param(sc, TWE_PARAM_VERSION, TWE_PARAM_VERSION_PCB,  8, NULL);
1564    p[4] = twe_get_param(sc, TWE_PARAM_VERSION, TWE_PARAM_VERSION_ATA,  8, NULL);
1565    p[5] = twe_get_param(sc, TWE_PARAM_VERSION, TWE_PARAM_VERSION_PCI,  8, NULL);
1566
1567    twe_printf(sc, "%d ports, Firmware %.16s, BIOS %.16s\n", ports, p[1]->data, p[2]->data);
1568    if (bootverbose)
1569	twe_printf(sc, "Monitor %.16s, PCB %.8s, Achip %.8s, Pchip %.8s\n", p[0]->data, p[3]->data,
1570		   p[4]->data, p[5]->data);
1571    free(p[0], M_DEVBUF);
1572    free(p[1], M_DEVBUF);
1573    free(p[2], M_DEVBUF);
1574    free(p[3], M_DEVBUF);
1575    free(p[4], M_DEVBUF);
1576    free(p[5], M_DEVBUF);
1577
1578    /* print attached drives */
1579    if (bootverbose) {
1580	p[0] = twe_get_param(sc, TWE_PARAM_DRIVESUMMARY, TWE_PARAM_DRIVESUMMARY_Status, 16, NULL);
1581	for (i = 0; i < ports; i++) {
1582	    if (p[0]->data[i] != TWE_PARAM_DRIVESTATUS_Present)
1583		continue;
1584	    twe_get_param_4(sc, TWE_PARAM_DRIVEINFO + i, TWE_PARAM_DRIVEINFO_Size, &size);
1585	    p[1] = twe_get_param(sc, TWE_PARAM_DRIVEINFO + i, TWE_PARAM_DRIVEINFO_Model, 40, NULL);
1586	    if (p[1] != NULL) {
1587		twe_printf(sc, "port %d: %.40s %dMB\n", i, p[1]->data, size / 2048);
1588		free(p[1], M_DEVBUF);
1589	    } else {
1590		twe_printf(sc, "port %d, drive status unavailable\n", i);
1591	    }
1592	}
1593	free(p[0], M_DEVBUF);
1594    }
1595}
1596
1597/********************************************************************************
1598 * Complain if the status bits aren't what we're expecting.
1599 *
1600 * Rate-limit the complaints to at most one of each every five seconds, but
1601 * always return the correct status.
1602 */
1603static int
1604twe_check_bits(struct twe_softc *sc, u_int32_t status_reg)
1605{
1606    int			result;
1607    static time_t	lastwarn[2] = {0, 0};
1608
1609    /*
1610     * This can be a little problematic, as twe_panic may call twe_reset if
1611     * TWE_DEBUG is not set, which will call us again as part of the soft reset.
1612     */
1613    if ((status_reg & TWE_STATUS_PANIC_BITS) != 0) {
1614	twe_printf(sc, "FATAL STATUS BIT(S) %b\n", status_reg & TWE_STATUS_PANIC_BITS,
1615		   TWE_STATUS_BITS_DESCRIPTION);
1616	twe_panic(sc, "fatal status bits");
1617    }
1618
1619    result = 0;
1620    if ((status_reg & TWE_STATUS_EXPECTED_BITS) != TWE_STATUS_EXPECTED_BITS) {
1621	if (time_second > (lastwarn[0] + 5)) {
1622	    twe_printf(sc, "missing expected status bit(s) %b\n", ~status_reg & TWE_STATUS_EXPECTED_BITS,
1623		       TWE_STATUS_BITS_DESCRIPTION);
1624	    lastwarn[0] = time_second;
1625	}
1626	result = 1;
1627    }
1628
1629    if ((status_reg & TWE_STATUS_UNEXPECTED_BITS) != 0) {
1630	if (time_second > (lastwarn[1] + 5)) {
1631	    twe_printf(sc, "unexpected status bit(s) %b\n", status_reg & TWE_STATUS_UNEXPECTED_BITS,
1632		       TWE_STATUS_BITS_DESCRIPTION);
1633	    lastwarn[1] = time_second;
1634	}
1635	result = 1;
1636	if (status_reg & TWE_STATUS_PCI_PARITY_ERROR) {
1637	    twe_printf(sc, "PCI parity error: Reseat card, move card or buggy device present.");
1638	    twe_clear_pci_parity_error(sc);
1639	}
1640	if (status_reg & TWE_STATUS_PCI_ABORT) {
1641	    twe_printf(sc, "PCI abort, clearing.");
1642	    twe_clear_pci_abort(sc);
1643	}
1644    }
1645
1646    return(result);
1647}
1648
1649/********************************************************************************
1650 * Return a string describing (aen).
1651 *
1652 * The low 8 bits of the aen are the code, the high 8 bits give the unit number
1653 * where an AEN is specific to a unit.
1654 *
1655 * Note that we could expand this routine to handle eg. up/downgrading the status
1656 * of a drive if we had some idea of what the drive's initial status was.
1657 */
1658
1659static char *
1660twe_format_aen(struct twe_softc *sc, u_int16_t aen)
1661{
1662    static char	buf[80];
1663    device_t	child;
1664    char	*code, *msg;
1665
1666    code = twe_describe_code(twe_table_aen, TWE_AEN_CODE(aen));
1667    msg = code + 2;
1668
1669    switch (*code) {
1670    case 'q':
1671	if (!bootverbose)
1672	    return(NULL);
1673	/* FALLTHROUGH */
1674    case 'a':
1675	return(msg);
1676
1677    case 'c':
1678	if ((child = sc->twe_drive[TWE_AEN_UNIT(aen)].td_disk) != NULL) {
1679	    sprintf(buf, "twed%d: %s", device_get_unit(child), msg);
1680	} else {
1681	    sprintf(buf, "twe%d: %s for unknown unit %d", device_get_unit(sc->twe_dev),
1682		    msg, TWE_AEN_UNIT(aen));
1683	}
1684	return(buf);
1685
1686    case 'p':
1687	sprintf(buf, "twe%d: port %d: %s", device_get_unit(sc->twe_dev), TWE_AEN_UNIT(aen),
1688		msg);
1689	return(buf);
1690
1691
1692    case 'x':
1693    default:
1694	break;
1695    }
1696    sprintf(buf, "unknown AEN 0x%x", aen);
1697    return(buf);
1698}
1699
1700/********************************************************************************
1701 * Print a diagnostic if the status of the command warrants it, and return
1702 * either zero (command was ok) or nonzero (command failed).
1703 */
1704static int
1705twe_report_request(struct twe_request *tr)
1706{
1707    struct twe_softc	*sc = tr->tr_sc;
1708    TWE_Command		*cmd = &tr->tr_command;
1709    int			result = 0;
1710
1711    /*
1712     * Check the command status value and handle accordingly.
1713     */
1714    if (cmd->generic.status == TWE_STATUS_RESET) {
1715	/*
1716	 * The status code 0xff requests a controller reset.
1717	 */
1718	twe_printf(sc, "command returned with controller rest request\n");
1719	twe_reset(sc);
1720	result = 1;
1721    } else if (cmd->generic.status > TWE_STATUS_FATAL) {
1722	/*
1723	 * Fatal errors that don't require controller reset.
1724	 *
1725	 * We know a few special flags values.
1726	 */
1727	switch (cmd->generic.flags) {
1728	case 0x1b:
1729	    device_printf(sc->twe_drive[cmd->generic.unit].td_disk,
1730			  "drive timeout");
1731	    break;
1732	case 0x51:
1733	    device_printf(sc->twe_drive[cmd->generic.unit].td_disk,
1734			  "unrecoverable drive error");
1735	    break;
1736	default:
1737	    device_printf(sc->twe_drive[cmd->generic.unit].td_disk,
1738			  "controller error - %s (flags = 0x%x)\n",
1739			  twe_describe_code(twe_table_status, cmd->generic.status),
1740			  cmd->generic.flags);
1741	    result = 1;
1742	}
1743    } else if (cmd->generic.status > TWE_STATUS_WARNING) {
1744	/*
1745	 * Warning level status.
1746	 */
1747	device_printf(sc->twe_drive[cmd->generic.unit].td_disk,
1748		      "warning - %s (flags = 0x%x)\n",
1749		      twe_describe_code(twe_table_status, cmd->generic.status),
1750		      cmd->generic.flags);
1751    } else if (cmd->generic.status > 0x40) {
1752	/*
1753	 * Info level status.
1754	 */
1755	device_printf(sc->twe_drive[cmd->generic.unit].td_disk,
1756		      "attention - %s (flags = 0x%x)\n",
1757		      twe_describe_code(twe_table_status, cmd->generic.status),
1758		      cmd->generic.flags);
1759    }
1760
1761    return(result);
1762}
1763
1764/********************************************************************************
1765 * Print some controller state to aid in debugging error/panic conditions
1766 */
1767void
1768twe_print_controller(struct twe_softc *sc)
1769{
1770    u_int32_t		status_reg;
1771
1772    status_reg = TWE_STATUS(sc);
1773    twe_printf(sc, "status   %b\n", status_reg, TWE_STATUS_BITS_DESCRIPTION);
1774    twe_printf(sc, "          current  max\n");
1775    twe_printf(sc, "free      %04d     %04d\n", sc->twe_qstat[TWEQ_FREE].q_length, sc->twe_qstat[TWEQ_FREE].q_max);
1776    twe_printf(sc, "ready     %04d     %04d\n", sc->twe_qstat[TWEQ_READY].q_length, sc->twe_qstat[TWEQ_READY].q_max);
1777    twe_printf(sc, "busy      %04d     %04d\n", sc->twe_qstat[TWEQ_BUSY].q_length, sc->twe_qstat[TWEQ_BUSY].q_max);
1778    twe_printf(sc, "complete  %04d     %04d\n", sc->twe_qstat[TWEQ_COMPLETE].q_length, sc->twe_qstat[TWEQ_COMPLETE].q_max);
1779    twe_printf(sc, "bioq      %04d     %04d\n", sc->twe_qstat[TWEQ_BIO].q_length, sc->twe_qstat[TWEQ_BIO].q_max);
1780    twe_printf(sc, "AEN queue head %d  tail %d\n", sc->twe_aen_head, sc->twe_aen_tail);
1781}
1782
1783static void
1784twe_panic(struct twe_softc *sc, char *reason)
1785{
1786    twe_print_controller(sc);
1787#ifdef TWE_DEBUG
1788    panic(reason);
1789#else
1790    twe_reset(sc);
1791#endif
1792}
1793
1794#if 0
1795/********************************************************************************
1796 * Print a request/command in human-readable format.
1797 */
1798static void
1799twe_print_request(struct twe_request *tr)
1800{
1801    struct twe_softc	*sc = tr->tr_sc;
1802    TWE_Command	*cmd = &tr->tr_command;
1803    int		i;
1804
1805    twe_printf(sc, "CMD: request_id %d  opcode <%s>  size %d  unit %d  host_id %d\n",
1806	       cmd->generic.request_id, twe_describe_code(twe_table_opcode, cmd->generic.opcode), cmd->generic.size,
1807	       cmd->generic.unit, cmd->generic.host_id);
1808    twe_printf(sc, " status %d  flags 0x%x  count %d  sgl_offset %d\n",
1809	       cmd->generic.status, cmd->generic.flags, cmd->generic.count, cmd->generic.sgl_offset);
1810
1811    switch(cmd->generic.opcode) {	/* XXX add more opcodes? */
1812    case TWE_OP_READ:
1813    case TWE_OP_WRITE:
1814	twe_printf(sc, " lba %d\n", cmd->io.lba);
1815	for (i = 0; (i < TWE_MAX_SGL_LENGTH) && (cmd->io.sgl[i].length != 0); i++)
1816	    twe_printf(sc, "  %d: 0x%x/%d\n",
1817		       i, cmd->io.sgl[i].address, cmd->io.sgl[i].length);
1818	break;
1819
1820    case TWE_OP_GET_PARAM:
1821    case TWE_OP_SET_PARAM:
1822	for (i = 0; (i < TWE_MAX_SGL_LENGTH) && (cmd->param.sgl[i].length != 0); i++)
1823	    twe_printf(sc, "  %d: 0x%x/%d\n",
1824		       i, cmd->param.sgl[i].address, cmd->param.sgl[i].length);
1825	break;
1826
1827    case TWE_OP_INIT_CONNECTION:
1828	twe_printf(sc, " response queue pointer 0x%x\n",
1829		   cmd->initconnection.response_queue_pointer);
1830	break;
1831
1832    default:
1833	break;
1834    }
1835    twe_printf(sc, " tr_command %p/0x%x  tr_data %p/0x%x,%d\n",
1836	       tr, tr->tr_cmdphys, tr->tr_data, tr->tr_dataphys, tr->tr_length);
1837    twe_printf(sc, " tr_status %d  tr_flags 0x%x  tr_complete %p  tr_private %p\n",
1838	       tr->tr_status, tr->tr_flags, tr->tr_complete, tr->tr_private);
1839}
1840
1841#endif
1842