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