twa.c revision 1.9.2.2 1 /* $NetBSD: twa.c,v 1.9.2.2 2006/07/31 12:35:23 tron Exp $ */
2 /* $wasabi: twa.c,v 1.27 2006/07/28 18:17:21 wrstuden Exp $ */
3
4 /*-
5 * Copyright (c) 2004 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jordan Rhody of Wasabi Systems, Inc.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the NetBSD
22 * Foundation, Inc. and its contributors.
23 * 4. Neither the name of The NetBSD Foundation nor the names of its
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40 /*-
41 * Copyright (c) 2003-04 3ware, Inc.
42 * Copyright (c) 2000 Michael Smith
43 * Copyright (c) 2000 BSDi
44 * All rights reserved.
45 *
46 * Redistribution and use in source and binary forms, with or without
47 * modification, are permitted provided that the following conditions
48 * are met:
49 * 1. Redistributions of source code must retain the above copyright
50 * notice, this list of conditions and the following disclaimer.
51 * 2. Redistributions in binary form must reproduce the above copyright
52 * notice, this list of conditions and the following disclaimer in the
53 * documentation and/or other materials provided with the distribution.
54 *
55 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
56 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
57 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
58 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
59 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
60 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
61 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
62 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
63 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
64 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
65 * SUCH DAMAGE.
66 *
67 * $FreeBSD: src/sys/dev/twa/twa.c,v 1.2 2004/04/02 15:09:57 des Exp $
68 */
69
70 /*
71 * 3ware driver for 9000 series storage controllers.
72 *
73 * Author: Vinod Kashyap
74 */
75
76 #include <sys/cdefs.h>
77 __KERNEL_RCSID(0, "$NetBSD: twa.c,v 1.9.2.2 2006/07/31 12:35:23 tron Exp $");
78
79 #include <sys/param.h>
80 #include <sys/systm.h>
81 #include <sys/kernel.h>
82 #include <sys/device.h>
83 #include <sys/queue.h>
84 #include <sys/proc.h>
85 #include <sys/bswap.h>
86 #include <sys/buf.h>
87 #include <sys/bufq.h>
88 #include <sys/endian.h>
89 #include <sys/malloc.h>
90 #include <sys/conf.h>
91 #include <sys/disk.h>
92 #include <sys/syslog.h>
93
94 #include <uvm/uvm_extern.h>
95
96 #include <machine/bus.h>
97
98 #include <dev/pci/pcireg.h>
99 #include <dev/pci/pcivar.h>
100 #include <dev/pci/pcidevs.h>
101 #include <dev/pci/twareg.h>
102 #include <dev/pci/twavar.h>
103 #include <dev/pci/twaio.h>
104
105 #include <dev/scsipi/scsipi_all.h>
106 #include <dev/scsipi/scsipi_disk.h>
107 #include <dev/scsipi/scsipiconf.h>
108 #include <dev/scsipi/scsi_spc.h>
109
110 #include <dev/ldvar.h>
111
112 #include "locators.h"
113
114 #define PCI_CBIO 0x10
115
116 static int twa_fetch_aen(struct twa_softc *);
117 static void twa_aen_callback(struct twa_request *);
118 static int twa_find_aen(struct twa_softc *sc, uint16_t);
119 static uint16_t twa_enqueue_aen(struct twa_softc *sc,
120 struct twa_command_header *);
121
122 static void twa_attach(struct device *, struct device *, void *);
123 static void twa_shutdown(void *);
124 static int twa_init_connection(struct twa_softc *, uint16_t, uint32_t,
125 uint16_t, uint16_t, uint16_t, uint16_t, uint16_t *,
126 uint16_t *, uint16_t *, uint16_t *, uint32_t *);
127 static int twa_intr(void *);
128 static int twa_match(struct device *, struct cfdata *, void *);
129 static int twa_submatch(struct device *, struct cfdata *,
130 const locdesc_t *, void *);
131 static int twa_reset(struct twa_softc *);
132
133 static int twa_print(void *, const char *);
134 static int twa_soft_reset(struct twa_softc *);
135
136 static int twa_check_ctlr_state(struct twa_softc *, uint32_t);
137 static int twa_get_param(struct twa_softc *, int, int, size_t,
138 void (* callback)(struct twa_request *),
139 struct twa_param_9k **);
140 static int twa_set_param(struct twa_softc *, int, int, int, void *,
141 void (* callback)(struct twa_request *));
142 static void twa_describe_controller(struct twa_softc *);
143 static int twa_wait_status(struct twa_softc *, uint32_t, uint32_t);
144 static int twa_done(struct twa_softc *);
145 #if 0
146 static int twa_flash_firmware(struct twa_softc *sc);
147 static int twa_hard_reset(struct twa_softc *sc);
148 #endif
149
150 extern struct cfdriver twa_cd;
151 extern uint32_t twa_fw_img_size;
152 extern uint8_t twa_fw_img[];
153
154 CFATTACH_DECL(twa, sizeof(struct twa_softc),
155 twa_match, twa_attach, NULL, NULL);
156
157 /* AEN messages. */
158 static const struct twa_message twa_aen_table[] = {
159 {0x0000, "AEN queue empty"},
160 {0x0001, "Controller reset occurred"},
161 {0x0002, "Degraded unit detected"},
162 {0x0003, "Controller error occured"},
163 {0x0004, "Background rebuild failed"},
164 {0x0005, "Background rebuild done"},
165 {0x0006, "Incomplete unit detected"},
166 {0x0007, "Background initialize done"},
167 {0x0008, "Unclean shutdown detected"},
168 {0x0009, "Drive timeout detected"},
169 {0x000A, "Drive error detected"},
170 {0x000B, "Rebuild started"},
171 {0x000C, "Background initialize started"},
172 {0x000D, "Entire logical unit was deleted"},
173 {0x000E, "Background initialize failed"},
174 {0x000F, "SMART attribute exceeded threshold"},
175 {0x0010, "Power supply reported AC under range"},
176 {0x0011, "Power supply reported DC out of range"},
177 {0x0012, "Power supply reported a malfunction"},
178 {0x0013, "Power supply predicted malfunction"},
179 {0x0014, "Battery charge is below threshold"},
180 {0x0015, "Fan speed is below threshold"},
181 {0x0016, "Temperature sensor is above threshold"},
182 {0x0017, "Power supply was removed"},
183 {0x0018, "Power supply was inserted"},
184 {0x0019, "Drive was removed from a bay"},
185 {0x001A, "Drive was inserted into a bay"},
186 {0x001B, "Drive bay cover door was opened"},
187 {0x001C, "Drive bay cover door was closed"},
188 {0x001D, "Product case was opened"},
189 {0x0020, "Prepare for shutdown (power-off)"},
190 {0x0021, "Downgrade UDMA mode to lower speed"},
191 {0x0022, "Upgrade UDMA mode to higher speed"},
192 {0x0023, "Sector repair completed"},
193 {0x0024, "Sbuf memory test failed"},
194 {0x0025, "Error flushing cached write data to disk"},
195 {0x0026, "Drive reported data ECC error"},
196 {0x0027, "DCB has checksum error"},
197 {0x0028, "DCB version is unsupported"},
198 {0x0029, "Background verify started"},
199 {0x002A, "Background verify failed"},
200 {0x002B, "Background verify done"},
201 {0x002C, "Bad sector overwritten during rebuild"},
202 {0x002E, "Replace failed because replacement drive too small"},
203 {0x002F, "Verify failed because array was never initialized"},
204 {0x0030, "Unsupported ATA drive"},
205 {0x0031, "Synchronize host/controller time"},
206 {0x0032, "Spare capacity is inadequate for some units"},
207 {0x0033, "Background migration started"},
208 {0x0034, "Background migration failed"},
209 {0x0035, "Background migration done"},
210 {0x0036, "Verify detected and fixed data/parity mismatch"},
211 {0x0037, "SO-DIMM incompatible"},
212 {0x0038, "SO-DIMM not detected"},
213 {0x0039, "Corrected Sbuf ECC error"},
214 {0x003A, "Drive power on reset detected"},
215 {0x003B, "Background rebuild paused"},
216 {0x003C, "Background initialize paused"},
217 {0x003D, "Background verify paused"},
218 {0x003E, "Background migration paused"},
219 {0x003F, "Corrupt flash file system detected"},
220 {0x0040, "Flash file system repaired"},
221 {0x0041, "Unit number assignments were lost"},
222 {0x0042, "Error during read of primary DCB"},
223 {0x0043, "Latent error found in backup DCB"},
224 {0x0044, "Battery voltage is normal"},
225 {0x0045, "Battery voltage is low"},
226 {0x0046, "Battery voltage is high"},
227 {0x0047, "Battery voltage is too low"},
228 {0x0048, "Battery voltage is too high"},
229 {0x0049, "Battery temperature is normal"},
230 {0x004A, "Battery temperature is low"},
231 {0x004B, "Battery temperature is high"},
232 {0x004C, "Battery temperature is too low"},
233 {0x004D, "Battery temperature is too high"},
234 {0x004E, "Battery capacity test started"},
235 {0x004F, "Cache synchronization skipped"},
236 {0x0050, "Battery capacity test completed"},
237 {0x0051, "Battery health check started"},
238 {0x0052, "Battery health check completed"},
239 {0x0053, "Need to do a capacity test"},
240 {0x0054, "Charge termination voltage is at high level"},
241 {0x0055, "Battery charging started"},
242 {0x0056, "Battery charging completed"},
243 {0x0057, "Battery charging fault"},
244 {0x0058, "Battery capacity is below warning level"},
245 {0x0059, "Battery capacity is below error level"},
246 {0x005A, "Battery is present"},
247 {0x005B, "Battery is not present"},
248 {0x005C, "Battery is weak"},
249 {0x005D, "Battery health check failed"},
250 {0x005E, "Cache synchronized after power fail"},
251 {0x005F, "Cache synchronization failed; some data lost"},
252 {0x0060, "Bad cache meta data checksum"},
253 {0x0061, "Bad cache meta data signature"},
254 {0x0062, "Cache meta data restore failed"},
255 {0x0063, "BBU not found after power fail"},
256 {0x00FC, "Recovered/finished array membership update"},
257 {0x00FD, "Handler lockup"},
258 {0x00FE, "Retrying PCI transfer"},
259 {0x00FF, "AEN queue is full"},
260 {0xFFFFFFFF, (char *)NULL}
261 };
262
263 /* AEN severity table. */
264 static const char *twa_aen_severity_table[] = {
265 "None",
266 "ERROR",
267 "WARNING",
268 "INFO",
269 "DEBUG",
270 (char *)NULL
271 };
272
273 /* Error messages. */
274 static const struct twa_message twa_error_table[] = {
275 {0x0100, "SGL entry contains zero data"},
276 {0x0101, "Invalid command opcode"},
277 {0x0102, "SGL entry has unaligned address"},
278 {0x0103, "SGL size does not match command"},
279 {0x0104, "SGL entry has illegal length"},
280 {0x0105, "Command packet is not aligned"},
281 {0x0106, "Invalid request ID"},
282 {0x0107, "Duplicate request ID"},
283 {0x0108, "ID not locked"},
284 {0x0109, "LBA out of range"},
285 {0x010A, "Logical unit not supported"},
286 {0x010B, "Parameter table does not exist"},
287 {0x010C, "Parameter index does not exist"},
288 {0x010D, "Invalid field in CDB"},
289 {0x010E, "Specified port has invalid drive"},
290 {0x010F, "Parameter item size mismatch"},
291 {0x0110, "Failed memory allocation"},
292 {0x0111, "Memory request too large"},
293 {0x0112, "Out of memory segments"},
294 {0x0113, "Invalid address to deallocate"},
295 {0x0114, "Out of memory"},
296 {0x0115, "Out of heap"},
297 {0x0120, "Double degrade"},
298 {0x0121, "Drive not degraded"},
299 {0x0122, "Reconstruct error"},
300 {0x0123, "Replace not accepted"},
301 {0x0124, "Replace drive capacity too small"},
302 {0x0125, "Sector count not allowed"},
303 {0x0126, "No spares left"},
304 {0x0127, "Reconstruct error"},
305 {0x0128, "Unit is offline"},
306 {0x0129, "Cannot update status to DCB"},
307 {0x0130, "Invalid stripe handle"},
308 {0x0131, "Handle that was not locked"},
309 {0x0132, "Handle that was not empy"},
310 {0x0133, "Handle has different owner"},
311 {0x0140, "IPR has parent"},
312 {0x0150, "Illegal Pbuf address alignment"},
313 {0x0151, "Illegal Pbuf transfer length"},
314 {0x0152, "Illegal Sbuf address alignment"},
315 {0x0153, "Illegal Sbuf transfer length"},
316 {0x0160, "Command packet too large"},
317 {0x0161, "SGL exceeds maximum length"},
318 {0x0162, "SGL has too many entries"},
319 {0x0170, "Insufficient resources for rebuilder"},
320 {0x0171, "Verify error (data != parity)"},
321 {0x0180, "Requested segment not in directory of this DCB"},
322 {0x0181, "DCB segment has unsupported version"},
323 {0x0182, "DCB segment has checksum error"},
324 {0x0183, "DCB support (settings) segment invalid"},
325 {0x0184, "DCB UDB (unit descriptor block) segment invalid"},
326 {0x0185, "DCB GUID (globally unique identifier) segment invalid"},
327 {0x01A0, "Could not clear Sbuf"},
328 {0x01C0, "Flash identify failed"},
329 {0x01C1, "Flash out of bounds"},
330 {0x01C2, "Flash verify error"},
331 {0x01C3, "Flash file object not found"},
332 {0x01C4, "Flash file already present"},
333 {0x01C5, "Flash file system full"},
334 {0x01C6, "Flash file not present"},
335 {0x01C7, "Flash file size error"},
336 {0x01C8, "Bad flash file checksum"},
337 {0x01CA, "Corrupt flash file system detected"},
338 {0x01D0, "Invalid field in parameter list"},
339 {0x01D1, "Parameter list length error"},
340 {0x01D2, "Parameter item is not changeable"},
341 {0x01D3, "Parameter item is not saveable"},
342 {0x0200, "UDMA CRC error"},
343 {0x0201, "Internal CRC error"},
344 {0x0202, "Data ECC error"},
345 {0x0203, "ADP level 1 error"},
346 {0x0204, "Port timeout"},
347 {0x0205, "Drive power on reset"},
348 {0x0206, "ADP level 2 error"},
349 {0x0207, "Soft reset failed"},
350 {0x0208, "Drive not ready"},
351 {0x0209, "Unclassified port error"},
352 {0x020A, "Drive aborted command"},
353 {0x0210, "Internal CRC error"},
354 {0x0211, "Host PCI bus abort"},
355 {0x0212, "Host PCI parity error"},
356 {0x0213, "Port handler error"},
357 {0x0214, "Token interrupt count error"},
358 {0x0215, "Timeout waiting for PCI transfer"},
359 {0x0216, "Corrected buffer ECC"},
360 {0x0217, "Uncorrected buffer ECC"},
361 {0x0230, "Unsupported command during flash recovery"},
362 {0x0231, "Next image buffer expected"},
363 {0x0232, "Binary image architecture incompatible"},
364 {0x0233, "Binary image has no signature"},
365 {0x0234, "Binary image has bad checksum"},
366 {0x0235, "Image downloaded overflowed buffer"},
367 {0x0240, "I2C device not found"},
368 {0x0241, "I2C transaction aborted"},
369 {0x0242, "SO-DIMM parameter(s) incompatible using defaults"},
370 {0x0243, "SO-DIMM unsupported"},
371 {0x0248, "SPI transfer status error"},
372 {0x0249, "SPI transfer timeout error"},
373 {0x0250, "Invalid unit descriptor size in CreateUnit"},
374 {0x0251, "Unit descriptor size exceeds data buffer in CreateUnit"},
375 {0x0252, "Invalid value in CreateUnit descriptor"},
376 {0x0253, "Inadequate disk space to support descriptor in CreateUnit"},
377 {0x0254, "Unable to create data channel for this unit descriptor"},
378 {0x0255, "CreateUnit descriptor specifies a drive already in use"},
379 {0x0256, "Unable to write configuration to all disks during CreateUnit"},
380 {0x0257, "CreateUnit does not support this descriptor version"},
381 {0x0258, "Invalid subunit for RAID 0 or 5 in CreateUnit"},
382 {0x0259, "Too many descriptors in CreateUnit"},
383 {0x025A, "Invalid configuration specified in CreateUnit descriptor"},
384 {0x025B, "Invalid LBA offset specified in CreateUnit descriptor"},
385 {0x025C, "Invalid stripelet size specified in CreateUnit descriptor"},
386 {0x0260, "SMART attribute exceeded threshold"},
387 {0xFFFFFFFF, (char *)NULL}
388 };
389
390 struct twa_pci_identity {
391 uint32_t vendor_id;
392 uint32_t product_id;
393 const char *name;
394 };
395
396 static const struct twa_pci_identity pci_twa_products[] = {
397 { PCI_VENDOR_3WARE,
398 PCI_PRODUCT_3WARE_9000,
399 "3ware 9000 series",
400 },
401 { PCI_VENDOR_3WARE,
402 PCI_PRODUCT_3WARE_9550,
403 "3ware 9550SX series",
404 },
405 { 0,
406 0,
407 NULL,
408 },
409 };
410
411
412 static inline void
413 twa_outl(struct twa_softc *sc, int off, uint32_t val)
414 {
415
416 bus_space_write_4(sc->twa_bus_iot, sc->twa_bus_ioh, off, val);
417 bus_space_barrier(sc->twa_bus_iot, sc->twa_bus_ioh, off, 4,
418 BUS_SPACE_BARRIER_WRITE);
419 }
420
421 static inline uint32_t twa_inl(struct twa_softc *sc, int off)
422 {
423
424 bus_space_barrier(sc->twa_bus_iot, sc->twa_bus_ioh, off, 4,
425 BUS_SPACE_BARRIER_WRITE | BUS_SPACE_BARRIER_READ);
426 return (bus_space_read_4(sc->twa_bus_iot, sc->twa_bus_ioh, off));
427 }
428
429 void
430 twa_request_wait_handler(struct twa_request *tr)
431 {
432
433 wakeup(tr);
434 }
435
436 static int
437 twa_match(struct device *parent, struct cfdata *cfdata, void *aux)
438 {
439 int i;
440 struct pci_attach_args *pa = aux;
441 const struct twa_pci_identity *entry = 0;
442
443 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_3WARE) {
444 for (i = 0; (pci_twa_products[i].product_id); i++) {
445 entry = &pci_twa_products[i];
446 if (entry->product_id == PCI_PRODUCT(pa->pa_id)) {
447 aprint_normal("%s: (rev. 0x%02x)\n",
448 entry->name, PCI_REVISION(pa->pa_class));
449 return (1);
450 }
451 }
452 }
453 return (0);
454 }
455
456 static const char *
457 twa_find_msg_string(const struct twa_message *table, uint16_t code)
458 {
459 int i;
460
461 for (i = 0; table[i].message != NULL; i++)
462 if (table[i].code == code)
463 return(table[i].message);
464
465 return(table[i].message);
466 }
467
468 void
469 twa_release_request(struct twa_request *tr)
470 {
471 int s;
472 struct twa_softc *sc;
473
474 sc = tr->tr_sc;
475
476 if ((tr->tr_flags & TWA_CMD_AEN) == 0) {
477 s = splbio();
478 TAILQ_INSERT_TAIL(&tr->tr_sc->twa_free, tr, tr_link);
479 splx(s);
480 if (__predict_false((tr->tr_sc->twa_sc_flags &
481 TWA_STATE_REQUEST_WAIT) != 0)) {
482 tr->tr_sc->twa_sc_flags &= ~TWA_STATE_REQUEST_WAIT;
483 wakeup(&sc->twa_free);
484 }
485 } else
486 tr->tr_flags &= ~TWA_CMD_AEN_BUSY;
487 }
488
489 static void
490 twa_unmap_request(struct twa_request *tr)
491 {
492 struct twa_softc *sc = tr->tr_sc;
493 uint8_t cmd_status;
494 int s;
495
496 /* If the command involved data, unmap that too. */
497 if (tr->tr_data != NULL) {
498 if (tr->tr_cmd_pkt_type & TWA_CMD_PKT_TYPE_9K)
499 cmd_status = tr->tr_command->command.cmd_pkt_9k.status;
500 else
501 cmd_status =
502 tr->tr_command->command.cmd_pkt_7k.generic.status;
503
504 if (tr->tr_flags & TWA_CMD_DATA_OUT) {
505 bus_dmamap_sync(tr->tr_sc->twa_dma_tag, tr->tr_dma_map,
506 0, tr->tr_length, BUS_DMASYNC_POSTREAD);
507 /*
508 * If we are using a bounce buffer, and we are reading
509 * data, copy the real data in.
510 */
511 if (tr->tr_flags & TWA_CMD_DATA_COPY_NEEDED)
512 if (cmd_status == 0)
513 memcpy(tr->tr_real_data, tr->tr_data,
514 tr->tr_real_length);
515 }
516 if (tr->tr_flags & TWA_CMD_DATA_IN)
517 bus_dmamap_sync(tr->tr_sc->twa_dma_tag, tr->tr_dma_map,
518 0, tr->tr_length, BUS_DMASYNC_POSTWRITE);
519
520 bus_dmamap_unload(sc->twa_dma_tag, tr->tr_dma_map);
521 }
522
523 /* Free alignment buffer if it was used. */
524 if (tr->tr_flags & TWA_CMD_DATA_COPY_NEEDED) {
525 s = splvm();
526 uvm_km_free(kmem_map, (vaddr_t)tr->tr_data,
527 tr->tr_length);
528 splx(s);
529 tr->tr_data = tr->tr_real_data;
530 tr->tr_length = tr->tr_real_length;
531 }
532 }
533
534 /*
535 * Function name: twa_wait_request
536 * Description: Sends down a firmware cmd, and waits for the completion,
537 * but NOT in a tight loop.
538 *
539 * Input: tr -- ptr to request pkt
540 * timeout -- max # of seconds to wait before giving up
541 * Output: None
542 * Return value: 0 -- success
543 * non-zero-- failure
544 */
545 static int
546 twa_wait_request(struct twa_request *tr, uint32_t timeout)
547 {
548 time_t end_time;
549 struct timeval t1;
550 int s, rv;
551
552 tr->tr_flags |= TWA_CMD_SLEEP_ON_REQUEST;
553 tr->tr_callback = twa_request_wait_handler;
554 tr->tr_status = TWA_CMD_BUSY;
555
556 rv = twa_map_request(tr);
557
558 if (rv != 0)
559 return (rv);
560
561 microtime(&t1);
562 end_time = t1.tv_usec +
563 (timeout * 1000 * 100);
564
565 while (tr->tr_status != TWA_CMD_COMPLETE) {
566 rv = tr->tr_error;
567 if (rv != 0)
568 return(rv);
569 if ((rv = tsleep(tr, PRIBIO, "twawait", timeout * hz)) == 0)
570 break;
571
572 if (rv == EWOULDBLOCK) {
573 /*
574 * We will reset the controller only if the request has
575 * already been submitted, so as to not lose the
576 * request packet. If a busy request timed out, the
577 * reset will take care of freeing resources. If a
578 * pending request timed out, we will free resources
579 * for that request, right here. So, the caller is
580 * expected to NOT cleanup when ETIMEDOUT is returned.
581 */
582 if (tr->tr_status == TWA_CMD_BUSY)
583 twa_reset(tr->tr_sc);
584 else {
585 /* Request was never submitted. Clean up. */
586 s = splbio();
587 TAILQ_REMOVE(&tr->tr_sc->twa_pending, tr,
588 tr_link);
589 splx(s);
590
591 twa_unmap_request(tr);
592 if (tr->tr_data)
593 free(tr->tr_data, M_DEVBUF);
594
595 twa_release_request(tr);
596 }
597 return(ETIMEDOUT);
598 }
599 /*
600 * Either the request got completed, or we were woken up by a
601 * signal. Calculate the new timeout, in case it was the
602 * latter.
603 */
604 microtime(&t1);
605
606 timeout = (end_time - t1.tv_usec) / (1000 * 100);
607 }
608 return(rv);
609 }
610
611 /*
612 * Function name: twa_immediate_request
613 * Description: Sends down a firmware cmd, and waits for the completion
614 * in a tight loop.
615 *
616 * Input: tr -- ptr to request pkt
617 * timeout -- max # of seconds to wait before giving up
618 * Output: None
619 * Return value: 0 -- success
620 * non-zero-- failure
621 */
622 static int
623 twa_immediate_request(struct twa_request *tr, uint32_t timeout)
624 {
625 struct timeval t1;
626 int s = 0, rv = 0;
627
628 rv = twa_map_request(tr);
629
630 if (rv != 0)
631 return(rv);
632
633 timeout = (timeout * 10000 * 10);
634
635 microtime(&t1);
636
637 timeout += t1.tv_usec;
638
639 do {
640 rv = tr->tr_error;
641 if (rv != 0)
642 return(rv);
643 s = splbio();
644 twa_done(tr->tr_sc);
645 splx(s);
646 if (tr->tr_status == TWA_CMD_COMPLETE)
647 return(rv);
648 microtime(&t1);
649 } while (t1.tv_usec <= timeout);
650
651 /*
652 * We will reset the controller only if the request has
653 * already been submitted, so as to not lose the
654 * request packet. If a busy request timed out, the
655 * reset will take care of freeing resources. If a
656 * pending request timed out, we will free resources
657 * for that request, right here. So, the caller is
658 * expected to NOT cleanup when ETIMEDOUT is returned.
659 */
660 rv = ETIMEDOUT;
661
662 if (tr->tr_status == TWA_CMD_BUSY)
663 twa_reset(tr->tr_sc);
664 else {
665 /* Request was never submitted. Clean up. */
666 s = splbio();
667 TAILQ_REMOVE(&tr->tr_sc->twa_pending, tr, tr_link);
668 splx(s);
669 twa_unmap_request(tr);
670 if (tr->tr_data)
671 free(tr->tr_data, M_DEVBUF);
672
673 twa_release_request(tr);
674 }
675 return (rv);
676 }
677
678 static int
679 twa_inquiry(struct twa_request *tr, int lunid)
680 {
681 int error;
682 struct twa_command_9k *tr_9k_cmd;
683
684 if (tr->tr_data == NULL)
685 return (ENOMEM);
686
687 memset(tr->tr_data, 0, TWA_SECTOR_SIZE);
688
689 tr->tr_length = TWA_SECTOR_SIZE;
690 tr->tr_cmd_pkt_type = TWA_CMD_PKT_TYPE_9K;
691 tr->tr_flags |= TWA_CMD_DATA_IN;
692
693 tr_9k_cmd = &tr->tr_command->command.cmd_pkt_9k;
694
695 tr_9k_cmd->command.opcode = TWA_OP_EXECUTE_SCSI_COMMAND;
696 tr_9k_cmd->unit = lunid;
697 tr_9k_cmd->request_id = tr->tr_request_id;
698 tr_9k_cmd->status = 0;
699 tr_9k_cmd->sgl_offset = 16;
700 tr_9k_cmd->sgl_entries = 1;
701 /* create the CDB here */
702 tr_9k_cmd->cdb[0] = INQUIRY;
703 tr_9k_cmd->cdb[1] = ((lunid << 5) & 0x0e);
704 tr_9k_cmd->cdb[4] = 255;
705
706 /* XXXX setup page data no lun device
707 * it seems 9000 series does not indicate
708 * NOTPRESENT - need more investigation
709 */
710 ((struct scsipi_inquiry_data *)tr->tr_data)->device =
711 SID_QUAL_LU_NOTPRESENT;
712
713 error = twa_immediate_request(tr, TWA_REQUEST_TIMEOUT_PERIOD);
714
715 if (error != 0)
716 return (error);
717
718 if (((struct scsipi_inquiry_data *)tr->tr_data)->device ==
719 SID_QUAL_LU_NOTPRESENT)
720 error = 1;
721
722 return (error);
723 }
724
725 static int
726 twa_print_inquiry_data(struct twa_softc *sc, struct scsipi_inquiry_data *scsipi)
727 {
728
729 printf("%s: %s\n", sc->twa_dv.dv_xname, scsipi->vendor);
730
731 return (1);
732 }
733
734
735 static uint64_t
736 twa_read_capacity(struct twa_request *tr, int lunid)
737 {
738 int error;
739 struct twa_command_9k *tr_9k_cmd;
740 uint64_t array_size = 0LL;
741
742 if (tr->tr_data == NULL)
743 return (ENOMEM);
744
745 memset(tr->tr_data, 0, TWA_SECTOR_SIZE);
746
747 tr->tr_length = TWA_SECTOR_SIZE;
748 tr->tr_cmd_pkt_type = TWA_CMD_PKT_TYPE_9K;
749 tr->tr_flags |= TWA_CMD_DATA_OUT;
750
751 tr_9k_cmd = &tr->tr_command->command.cmd_pkt_9k;
752
753 tr_9k_cmd->command.opcode = TWA_OP_EXECUTE_SCSI_COMMAND;
754 tr_9k_cmd->unit = lunid;
755 tr_9k_cmd->request_id = tr->tr_request_id;
756 tr_9k_cmd->status = 0;
757 tr_9k_cmd->sgl_offset = 16;
758 tr_9k_cmd->sgl_entries = 1;
759 /* create the CDB here */
760 tr_9k_cmd->cdb[0] = READ_CAPACITY_16;
761 tr_9k_cmd->cdb[1] = ((lunid << 5) & 0x0e) | SRC16_SERVICE_ACTION;
762
763 error = twa_immediate_request(tr, TWA_REQUEST_TIMEOUT_PERIOD);
764
765 if (error == 0) {
766 #if BYTE_ORDER == BIG_ENDIAN
767 array_size = bswap64(_8btol(
768 ((struct scsipi_read_capacity_16_data *)tr->tr_data->addr) + 1);
769 #else
770 array_size = _8btol(((struct scsipi_read_capacity_16_data *)
771 tr->tr_data)->addr) + 1;
772 #endif
773 }
774 return (array_size);
775 }
776
777 static int
778 twa_request_sense(struct twa_request *tr, int lunid)
779 {
780 int error = 1;
781 struct twa_command_9k *tr_9k_cmd;
782
783 if (tr->tr_data == NULL)
784 return (error);
785
786 memset(tr->tr_data, 0, TWA_SECTOR_SIZE);
787
788 tr->tr_length = TWA_SECTOR_SIZE;
789 tr->tr_cmd_pkt_type = TWA_CMD_PKT_TYPE_9K;
790 tr->tr_flags |= TWA_CMD_DATA_OUT;
791
792 tr_9k_cmd = &tr->tr_command->command.cmd_pkt_9k;
793
794 tr_9k_cmd->command.opcode = TWA_OP_EXECUTE_SCSI_COMMAND;
795 tr_9k_cmd->unit = lunid;
796 tr_9k_cmd->request_id = tr->tr_request_id;
797 tr_9k_cmd->status = 0;
798 tr_9k_cmd->sgl_offset = 16;
799 tr_9k_cmd->sgl_entries = 1;
800 /* create the CDB here */
801 tr_9k_cmd->cdb[0] = SCSI_REQUEST_SENSE;
802 tr_9k_cmd->cdb[1] = ((lunid << 5) & 0x0e);
803 tr_9k_cmd->cdb[4] = 255;
804
805 /*XXX AEN notification called in interrupt context
806 * so just queue the request. Return as quickly
807 * as possible from interrupt
808 */
809 if ((tr->tr_flags & TWA_CMD_AEN) != 0)
810 error = twa_map_request(tr);
811 else
812 error = twa_immediate_request(tr, TWA_REQUEST_TIMEOUT_PERIOD);
813
814 return (error);
815 }
816
817 static int
818 twa_alloc_req_pkts(struct twa_softc *sc, int num_reqs)
819 {
820 struct twa_request *tr;
821 struct twa_command_packet *tc;
822 bus_dma_segment_t seg;
823 size_t max_segs, max_xfer;
824 int i, rv, rseg, size;
825
826 if ((sc->twa_req_buf = malloc(num_reqs * sizeof(struct twa_request),
827 M_DEVBUF, M_NOWAIT)) == NULL)
828 return(ENOMEM);
829
830 size = num_reqs * sizeof(struct twa_command_packet);
831
832 /* Allocate memory for cmd pkts. */
833 if ((rv = bus_dmamem_alloc(sc->twa_dma_tag,
834 size, PAGE_SIZE, 0, &seg,
835 1, &rseg, BUS_DMA_NOWAIT)) != 0){
836 aprint_error("%s: unable to allocate "
837 "command packets, rv = %d\n",
838 sc->twa_dv.dv_xname, rv);
839 return (ENOMEM);
840 }
841
842 if ((rv = bus_dmamem_map(sc->twa_dma_tag,
843 &seg, rseg, size, (caddr_t *)&sc->twa_cmds,
844 BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) {
845 aprint_error("%s: unable to map commands, rv = %d\n",
846 sc->twa_dv.dv_xname, rv);
847 return (1);
848 }
849
850 if ((rv = bus_dmamap_create(sc->twa_dma_tag,
851 size, num_reqs, size,
852 0, BUS_DMA_NOWAIT, &sc->twa_cmd_map)) != 0) {
853 aprint_error("%s: unable to create command DMA map, "
854 "rv = %d\n", sc->twa_dv.dv_xname, rv);
855 return (ENOMEM);
856 }
857
858 if ((rv = bus_dmamap_load(sc->twa_dma_tag, sc->twa_cmd_map,
859 sc->twa_cmds, size, NULL,
860 BUS_DMA_NOWAIT)) != 0) {
861 aprint_error("%s: unable to load command DMA map, "
862 "rv = %d\n", sc->twa_dv.dv_xname, rv);
863 return (1);
864 }
865
866 if ((uintptr_t)sc->twa_cmds % TWA_ALIGNMENT) {
867 aprint_error("%s: DMA map memory not aligned on %d boundary\n",
868 sc->twa_dv.dv_xname, TWA_ALIGNMENT);
869
870 return (1);
871 }
872 tc = sc->twa_cmd_pkt_buf = (struct twa_command_packet *)sc->twa_cmds;
873 sc->twa_cmd_pkt_phys = sc->twa_cmd_map->dm_segs[0].ds_addr;
874
875 memset(sc->twa_req_buf, 0, num_reqs * sizeof(struct twa_request));
876 memset(sc->twa_cmd_pkt_buf, 0,
877 num_reqs * sizeof(struct twa_command_packet));
878
879 sc->sc_twa_request = sc->twa_req_buf;
880 max_segs = twa_get_maxsegs();
881 max_xfer = twa_get_maxxfer(max_segs);
882
883 for (i = 0; i < num_reqs; i++, tc++) {
884 tr = &(sc->twa_req_buf[i]);
885 tr->tr_command = tc;
886 tr->tr_cmd_phys = sc->twa_cmd_pkt_phys +
887 (i * sizeof(struct twa_command_packet));
888 tr->tr_request_id = i;
889 tr->tr_sc = sc;
890
891 /*
892 * Create a map for data buffers. maxsize (256 * 1024) used in
893 * bus_dma_tag_create above should suffice the bounce page needs
894 * for data buffers, since the max I/O size we support is 128KB.
895 * If we supported I/O's bigger than 256KB, we would have to
896 * create a second dma_tag, with the appropriate maxsize.
897 */
898 if ((rv = bus_dmamap_create(sc->twa_dma_tag,
899 max_xfer, max_segs, 1, 0, BUS_DMA_NOWAIT,
900 &tr->tr_dma_map)) != 0) {
901 aprint_error("%s: unable to create command "
902 "DMA map, rv = %d\n",
903 sc->twa_dv.dv_xname, rv);
904 return (ENOMEM);
905 }
906 /* Insert request into the free queue. */
907 if (i != 0) {
908 sc->twa_lookup[i] = tr;
909 twa_release_request(tr);
910 } else
911 tr->tr_flags |= TWA_CMD_AEN;
912 }
913 return(0);
914 }
915
916 static void
917 twa_recompute_openings(struct twa_softc *sc)
918 {
919 struct twa_drive *td;
920 int unit;
921 int openings;
922
923 if (sc->sc_nunits != 0)
924 openings = ((TWA_Q_LENGTH / 2) / sc->sc_nunits);
925 else
926 openings = 0;
927 if (openings == sc->sc_openings)
928 return;
929 sc->sc_openings = openings;
930
931 #ifdef TWA_DEBUG
932 printf("%s: %d array%s, %d openings per array\n",
933 sc->sc_twa.dv_xname, sc->sc_nunits,
934 sc->sc_nunits == 1 ? "" : "s", sc->sc_openings);
935 #endif
936 for (unit = 0; unit < TWA_MAX_UNITS; unit++) {
937 td = &sc->sc_units[unit];
938 if (td->td_dev != NULL)
939 (*td->td_callbacks->tcb_openings)(td->td_dev,
940 sc->sc_openings);
941 }
942 }
943
944 static int
945 twa_request_bus_scan(struct twa_softc *sc)
946 {
947 struct twa_drive *td;
948 struct twa_request *tr;
949 struct twa_attach_args twaa;
950 int help[2];
951 locdesc_t *ldesc = (void *)help; /* XXX */
952 int s, unit;
953
954 s = splbio();
955 for (unit = 0; unit < TWA_MAX_UNITS; unit++) {
956
957 if ((tr = twa_get_request(sc, 0)) == NULL) {
958 splx(s);
959 return (EIO);
960 }
961
962 tr->tr_cmd_pkt_type |= TWA_CMD_PKT_TYPE_INTERNAL;
963
964 tr->tr_data = malloc(TWA_SECTOR_SIZE, M_DEVBUF, M_NOWAIT);
965
966 if (tr->tr_data == NULL) {
967 twa_release_request(tr);
968 splx(s);
969 return (ENOMEM);
970 }
971 td = &sc->sc_units[unit];
972
973 if (twa_inquiry(tr, unit) == 0) {
974 if (td->td_dev == NULL) {
975 twa_print_inquiry_data(sc,
976 ((struct scsipi_inquiry_data *)tr->tr_data));
977
978 sc->sc_nunits++;
979
980 sc->sc_units[unit].td_size =
981 twa_read_capacity(tr, unit);
982
983 twaa.twaa_unit = unit;
984
985 twa_recompute_openings(sc);
986
987 ldesc->len = 1;
988 ldesc->locs[TWACF_UNIT] = unit;
989
990 sc->sc_units[unit].td_dev =
991 config_found_sm_loc(&sc->twa_dv, "twa",
992 ldesc, &twaa, twa_print, twa_submatch);
993 }
994 } else {
995 if (td->td_dev != NULL) {
996 sc->sc_nunits--;
997
998 (void) config_detach(td->td_dev, DETACH_FORCE);
999 td->td_dev = NULL;
1000 td->td_size = 0;
1001
1002 twa_recompute_openings(sc);
1003 }
1004 }
1005 free(tr->tr_data, M_DEVBUF);
1006
1007 twa_release_request(tr);
1008 }
1009 splx(s);
1010
1011 return (0);
1012 }
1013
1014 /*
1015 * Match a sub-device.
1016 */
1017 static int
1018 twa_submatch(struct device *parent, struct cfdata *cf,
1019 const locdesc_t *ldesc, void *aux)
1020 {
1021
1022 if (cf->cf_loc[TWACF_UNIT] != TWACF_UNIT_DEFAULT &&
1023 cf->cf_loc[TWACF_UNIT] != ldesc->locs[TWACF_UNIT])
1024 return (0);
1025
1026 return (config_match(parent, cf, aux));
1027 }
1028
1029
1030
1031 #ifdef DIAGNOSTIC
1032 static inline void
1033 twa_check_busy_q(struct twa_request *tr)
1034 {
1035 struct twa_request *rq;
1036 struct twa_softc *sc = tr->tr_sc;
1037
1038 TAILQ_FOREACH(rq, &sc->twa_busy, tr_link) {
1039 if (tr->tr_request_id == rq->tr_request_id) {
1040 panic("cannot submit same request more than once");
1041 } else if (tr->bp == rq->bp && tr->bp != 0) {
1042 /* XXX A check for 0 for the buf ptr is needed to
1043 * guard against ioctl requests with a buf ptr of
1044 * 0 and also aen notifications. Looking for
1045 * external cmds only.
1046 */
1047 panic("cannot submit same buf more than once");
1048 } else {
1049 /* Empty else statement */
1050 }
1051 }
1052 }
1053 #endif
1054
1055 static int
1056 twa_start(struct twa_request *tr)
1057 {
1058 struct twa_softc *sc = tr->tr_sc;
1059 uint32_t status_reg;
1060 int s;
1061 int error;
1062
1063 s = splbio();
1064 /* Check to see if we can post a command. */
1065 status_reg = twa_inl(sc, TWA_STATUS_REGISTER_OFFSET);
1066 if ((error = twa_check_ctlr_state(sc, status_reg)))
1067 goto out;
1068
1069 if (status_reg & TWA_STATUS_COMMAND_QUEUE_FULL) {
1070 if (tr->tr_status != TWA_CMD_PENDING) {
1071 tr->tr_status = TWA_CMD_PENDING;
1072 TAILQ_INSERT_TAIL(&tr->tr_sc->twa_pending,
1073 tr, tr_link);
1074 }
1075 twa_outl(sc, TWA_CONTROL_REGISTER_OFFSET,
1076 TWA_CONTROL_UNMASK_COMMAND_INTERRUPT);
1077 error = EBUSY;
1078 } else {
1079 bus_dmamap_sync(sc->twa_dma_tag, sc->twa_cmd_map,
1080 (caddr_t)tr->tr_command - sc->twa_cmds,
1081 sizeof(struct twa_command_packet),
1082 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1083
1084 /* Cmd queue is not full. Post the command. */
1085 TWA_WRITE_COMMAND_QUEUE(sc, tr->tr_cmd_phys +
1086 sizeof(struct twa_command_header));
1087
1088 /* Mark the request as currently being processed. */
1089 tr->tr_status = TWA_CMD_BUSY;
1090
1091 #ifdef DIAGNOSTIC
1092 twa_check_busy_q(tr);
1093 #endif
1094
1095 /* Move the request into the busy queue. */
1096 TAILQ_INSERT_TAIL(&tr->tr_sc->twa_busy, tr, tr_link);
1097 }
1098 out:
1099 splx(s);
1100 return(error);
1101 }
1102
1103 static int
1104 twa_drain_response_queue(struct twa_softc *sc)
1105 {
1106 union twa_response_queue rq;
1107 uint32_t status_reg;
1108
1109 for (;;) {
1110 status_reg = twa_inl(sc, TWA_STATUS_REGISTER_OFFSET);
1111 if (twa_check_ctlr_state(sc, status_reg))
1112 return(1);
1113 if (status_reg & TWA_STATUS_RESPONSE_QUEUE_EMPTY)
1114 return(0); /* no more response queue entries */
1115 rq = (union twa_response_queue)twa_inl(sc,
1116 TWA_RESPONSE_QUEUE_OFFSET);
1117 }
1118 }
1119
1120 static void
1121 twa_drain_busy_queue(struct twa_softc *sc)
1122 {
1123 struct twa_request *tr;
1124
1125 /* Walk the busy queue. */
1126
1127 while ((tr = TAILQ_FIRST(&sc->twa_busy)) != NULL) {
1128 TAILQ_REMOVE(&sc->twa_busy, tr, tr_link);
1129
1130 twa_unmap_request(tr);
1131 if ((tr->tr_cmd_pkt_type & TWA_CMD_PKT_TYPE_INTERNAL) ||
1132 (tr->tr_cmd_pkt_type & TWA_CMD_PKT_TYPE_IOCTL)) {
1133 /* It's an internal/ioctl request. Simply free it. */
1134 if (tr->tr_data)
1135 free(tr->tr_data, M_DEVBUF);
1136 twa_release_request(tr);
1137 } else {
1138 /* It's a SCSI request. Complete it. */
1139 tr->tr_command->command.cmd_pkt_9k.status = EIO;
1140 if (tr->tr_callback)
1141 tr->tr_callback(tr);
1142 }
1143 }
1144 }
1145
1146 static int
1147 twa_drain_pending_queue(struct twa_softc *sc)
1148 {
1149 struct twa_request *tr;
1150 int s, error = 0;
1151
1152 /*
1153 * Pull requests off the pending queue, and submit them.
1154 */
1155 s = splbio();
1156 while ((tr = TAILQ_FIRST(&sc->twa_pending)) != NULL) {
1157 TAILQ_REMOVE(&sc->twa_pending, tr, tr_link);
1158
1159 if ((error = twa_start(tr))) {
1160 if (error == EBUSY) {
1161 tr->tr_status = TWA_CMD_PENDING;
1162
1163 /* queue at the head */
1164 TAILQ_INSERT_HEAD(&tr->tr_sc->twa_pending,
1165 tr, tr_link);
1166 error = 0;
1167 break;
1168 } else {
1169 if (tr->tr_flags & TWA_CMD_SLEEP_ON_REQUEST) {
1170 tr->tr_error = error;
1171 tr->tr_callback(tr);
1172 error = EIO;
1173 }
1174 }
1175 }
1176 }
1177 splx(s);
1178
1179 return(error);
1180 }
1181
1182 static int
1183 twa_drain_aen_queue(struct twa_softc *sc)
1184 {
1185 int s, error = 0;
1186 struct twa_request *tr;
1187 struct twa_command_header *cmd_hdr;
1188 struct timeval t1;
1189 uint32_t timeout;
1190
1191 for (;;) {
1192 if ((tr = twa_get_request(sc, 0)) == NULL) {
1193 error = EIO;
1194 break;
1195 }
1196 tr->tr_cmd_pkt_type |= TWA_CMD_PKT_TYPE_INTERNAL;
1197 tr->tr_callback = NULL;
1198
1199 tr->tr_data = malloc(TWA_SECTOR_SIZE, M_DEVBUF, M_NOWAIT);
1200
1201 if (tr->tr_data == NULL) {
1202 error = 1;
1203 goto out;
1204 }
1205
1206 if (twa_request_sense(tr, 0) != 0) {
1207 error = 1;
1208 break;
1209 }
1210
1211 timeout = (1000/*ms*/ * 100/*us*/ * TWA_REQUEST_TIMEOUT_PERIOD);
1212
1213 microtime(&t1);
1214
1215 timeout += t1.tv_usec;
1216
1217 do {
1218 s = splbio();
1219 twa_done(tr->tr_sc);
1220 splx(s);
1221 if (tr->tr_status != TWA_CMD_BUSY)
1222 break;
1223 microtime(&t1);
1224 } while (t1.tv_usec <= timeout);
1225
1226 if (tr->tr_status != TWA_CMD_COMPLETE) {
1227 error = ETIMEDOUT;
1228 break;
1229 }
1230
1231 if ((error = tr->tr_command->command.cmd_pkt_9k.status))
1232 break;
1233
1234 cmd_hdr = (struct twa_command_header *)(tr->tr_data);
1235 if ((cmd_hdr->status_block.error) /* aen_code */
1236 == TWA_AEN_QUEUE_EMPTY)
1237 break;
1238 (void)twa_enqueue_aen(sc, cmd_hdr);
1239
1240 free(tr->tr_data, M_DEVBUF);
1241 twa_release_request(tr);
1242 }
1243 out:
1244 if (tr) {
1245 if (tr->tr_data)
1246 free(tr->tr_data, M_DEVBUF);
1247
1248 twa_release_request(tr);
1249 }
1250 return(error);
1251 }
1252
1253
1254 #ifdef DIAGNOSTIC
1255 static void
1256 twa_check_response_q(struct twa_request *tr, int clear)
1257 {
1258 int j;
1259 static int i = 0;
1260 static struct twa_request *req = 0;
1261 static struct buf *hist[255];
1262
1263
1264 if (clear) {
1265 i = 0;
1266 for (j = 0; j < 255; j++)
1267 hist[j] = 0;
1268 return;
1269 }
1270
1271 if (req == 0)
1272 req = tr;
1273
1274 if ((tr->tr_cmd_pkt_type & TWA_CMD_PKT_TYPE_EXTERNAL) != 0) {
1275 if (req->tr_request_id == tr->tr_request_id)
1276 panic("req id: %d on controller queue twice",
1277 tr->tr_request_id);
1278
1279 for (j = 0; j < i; j++)
1280 if (tr->bp == hist[j])
1281 panic("req id: %d buf found twice",
1282 tr->tr_request_id);
1283 }
1284 req = tr;
1285
1286 hist[i++] = req->bp;
1287 }
1288 #endif
1289
1290 static int
1291 twa_done(struct twa_softc *sc)
1292 {
1293 union twa_response_queue rq;
1294 struct twa_request *tr;
1295 int rv = 0;
1296 uint32_t status_reg;
1297
1298 for (;;) {
1299 status_reg = twa_inl(sc, TWA_STATUS_REGISTER_OFFSET);
1300 if ((rv = twa_check_ctlr_state(sc, status_reg)))
1301 break;
1302 if (status_reg & TWA_STATUS_RESPONSE_QUEUE_EMPTY)
1303 break;
1304 /* Response queue is not empty. */
1305 rq = (union twa_response_queue)twa_inl(sc,
1306 TWA_RESPONSE_QUEUE_OFFSET);
1307 tr = sc->sc_twa_request + rq.u.response_id;
1308 #ifdef DIAGNOSTIC
1309 twa_check_response_q(tr, 0);
1310 #endif
1311 /* Unmap the command packet, and any associated data buffer. */
1312 twa_unmap_request(tr);
1313
1314 tr->tr_status = TWA_CMD_COMPLETE;
1315 TAILQ_REMOVE(&tr->tr_sc->twa_busy, tr, tr_link);
1316
1317 if (tr->tr_callback)
1318 tr->tr_callback(tr);
1319 }
1320 (void)twa_drain_pending_queue(sc);
1321
1322 #ifdef DIAGNOSTIC
1323 twa_check_response_q(NULL, 1);
1324 #endif
1325 return(rv);
1326 }
1327
1328 /*
1329 * Function name: twa_init_ctlr
1330 * Description: Establishes a logical connection with the controller.
1331 * If bundled with firmware, determines whether or not
1332 * to flash firmware, based on arch_id, fw SRL (Spec.
1333 * Revision Level), branch & build #'s. Also determines
1334 * whether or not the driver is compatible with the
1335 * firmware on the controller, before proceeding to work
1336 * with it.
1337 *
1338 * Input: sc -- ptr to per ctlr structure
1339 * Output: None
1340 * Return value: 0 -- success
1341 * non-zero-- failure
1342 */
1343 static int
1344 twa_init_ctlr(struct twa_softc *sc)
1345 {
1346 uint16_t fw_on_ctlr_srl = 0;
1347 uint16_t fw_on_ctlr_arch_id = 0;
1348 uint16_t fw_on_ctlr_branch = 0;
1349 uint16_t fw_on_ctlr_build = 0;
1350 uint32_t init_connect_result = 0;
1351 int error = 0;
1352 #if 0
1353 int8_t fw_flashed = FALSE;
1354 int8_t fw_flash_failed = FALSE;
1355 #endif
1356
1357 /* Wait for the controller to become ready. */
1358 if (twa_wait_status(sc, TWA_STATUS_MICROCONTROLLER_READY,
1359 TWA_REQUEST_TIMEOUT_PERIOD)) {
1360 return(ENXIO);
1361 }
1362 /* Drain the response queue. */
1363 if (twa_drain_response_queue(sc))
1364 return(1);
1365
1366 /* Establish a logical connection with the controller. */
1367 if ((error = twa_init_connection(sc, TWA_INIT_MESSAGE_CREDITS,
1368 TWA_EXTENDED_INIT_CONNECT, TWA_CURRENT_FW_SRL,
1369 TWA_9000_ARCH_ID, TWA_CURRENT_FW_BRANCH,
1370 TWA_CURRENT_FW_BUILD, &fw_on_ctlr_srl,
1371 &fw_on_ctlr_arch_id, &fw_on_ctlr_branch,
1372 &fw_on_ctlr_build, &init_connect_result))) {
1373 return(error);
1374 }
1375 #if 0
1376 if ((init_connect_result & TWA_BUNDLED_FW_SAFE_TO_FLASH) &&
1377 (init_connect_result & TWA_CTLR_FW_RECOMMENDS_FLASH)) {
1378 /*
1379 * The bundled firmware is safe to flash, and the firmware
1380 * on the controller recommends a flash. So, flash!
1381 */
1382 printf("%s: flashing bundled firmware...\n",
1383 sc->twa_dv.dv_xname);
1384
1385 if ((error = twa_flash_firmware(sc))) {
1386 fw_flash_failed = TRUE;
1387
1388 printf("%s: unable to flash bundled firmware.\n",
1389 sc->twa_dv.dv_xname);
1390 } else {
1391 printf("%s: successfully flashed bundled firmware.\n",
1392 sc->twa_dv.dv_xname);
1393 fw_flashed = TRUE;
1394 }
1395 }
1396 if (fw_flashed) {
1397 /* The firmware was flashed. Have the new image loaded */
1398 error = twa_hard_reset(sc);
1399 if (error == 0)
1400 error = twa_init_ctlr(sc);
1401 /*
1402 * If hard reset of controller failed, we need to return.
1403 * Otherwise, the above recursive call to twa_init_ctlr will
1404 * have completed the rest of the initialization (starting
1405 * from twa_drain_aen_queue below). Don't do it again.
1406 * Just return.
1407 */
1408 return(error);
1409 } else {
1410 /*
1411 * Either we are not bundled with a firmware image, or
1412 * the bundled firmware is not safe to flash,
1413 * or flash failed for some reason. See if we can at
1414 * least work with the firmware on the controller in the
1415 * current mode.
1416 */
1417 if (init_connect_result & TWA_CTLR_FW_COMPATIBLE) {
1418 /* Yes, we can. Make note of the operating mode. */
1419 sc->working_srl = TWA_CURRENT_FW_SRL;
1420 sc->working_branch = TWA_CURRENT_FW_BRANCH;
1421 sc->working_build = TWA_CURRENT_FW_BUILD;
1422 } else {
1423 /*
1424 * No, we can't. See if we can at least work with
1425 * it in the base mode. We should never come here
1426 * if firmware has just been flashed.
1427 */
1428 printf("%s: Driver/Firmware mismatch. Negotiating "
1429 "for base level.\n", sc->twa_dv.dv_xname);
1430 if ((error = twa_init_connection(sc,
1431 TWA_INIT_MESSAGE_CREDITS,
1432 TWA_EXTENDED_INIT_CONNECT, TWA_BASE_FW_SRL,
1433 TWA_9000_ARCH_ID, TWA_BASE_FW_BRANCH,
1434 TWA_BASE_FW_BUILD, &fw_on_ctlr_srl,
1435 &fw_on_ctlr_arch_id, &fw_on_ctlr_branch,
1436 &fw_on_ctlr_build, &init_connect_result))) {
1437 printf("%s: can't initialize connection in "
1438 "base mode.\n", sc->twa_dv.dv_xname);
1439 return(error);
1440 }
1441 if (!(init_connect_result & TWA_CTLR_FW_COMPATIBLE)) {
1442 /*
1443 * The firmware on the controller is not even
1444 * compatible with our base mode. We cannot
1445 * work with it. Bail...
1446 */
1447 printf("Incompatible firmware on controller\n");
1448 #ifdef TWA_FLASH_FIRMWARE
1449 if (fw_flash_failed)
1450 printf("...and could not flash bundled "
1451 "firmware.\n");
1452 else
1453 printf("...and bundled firmware not "
1454 "safe to flash.\n");
1455 #endif /* TWA_FLASH_FIRMWARE */
1456 return(1);
1457 }
1458 /*
1459 * We can work with this firmware, but only in
1460 * base mode.
1461 */
1462 sc->working_srl = TWA_BASE_FW_SRL;
1463 sc->working_branch = TWA_BASE_FW_BRANCH;
1464 sc->working_build = TWA_BASE_FW_BUILD;
1465 sc->twa_operating_mode = TWA_BASE_MODE;
1466 }
1467 }
1468 #endif
1469 twa_drain_aen_queue(sc);
1470
1471 /* Set controller state to initialized. */
1472 sc->twa_state &= ~TWA_STATE_SHUTDOWN;
1473 return(0);
1474 }
1475
1476 static int
1477 twa_setup(struct twa_softc *sc)
1478 {
1479 struct tw_cl_event_packet *aen_queue;
1480 uint32_t i = 0;
1481 int error = 0;
1482
1483 /* Initialize request queues. */
1484 TAILQ_INIT(&sc->twa_free);
1485 TAILQ_INIT(&sc->twa_busy);
1486 TAILQ_INIT(&sc->twa_pending);
1487
1488 sc->sc_nunits = 0;
1489 sc->twa_sc_flags = 0;
1490
1491 if (twa_alloc_req_pkts(sc, TWA_Q_LENGTH)) {
1492
1493 return(ENOMEM);
1494 }
1495
1496 /* Allocate memory for the AEN queue. */
1497 if ((aen_queue = malloc(sizeof(struct tw_cl_event_packet) *
1498 TWA_Q_LENGTH, M_DEVBUF, M_WAITOK)) == NULL) {
1499 /*
1500 * This should not cause us to return error. We will only be
1501 * unable to support AEN's. But then, we will have to check
1502 * time and again to see if we can support AEN's, if we
1503 * continue. So, we will just return error.
1504 */
1505 return (ENOMEM);
1506 }
1507 /* Initialize the aen queue. */
1508 memset(aen_queue, 0, sizeof(struct tw_cl_event_packet) * TWA_Q_LENGTH);
1509
1510 for (i = 0; i < TWA_Q_LENGTH; i++)
1511 sc->twa_aen_queue[i] = &(aen_queue[i]);
1512
1513 twa_outl(sc, TWA_CONTROL_REGISTER_OFFSET,
1514 TWA_CONTROL_DISABLE_INTERRUPTS);
1515
1516 /* Initialize the controller. */
1517 if ((error = twa_init_ctlr(sc))) {
1518 /* Soft reset the controller, and try one more time. */
1519
1520 printf("%s: controller initialization failed. "
1521 "Retrying initialization\n", sc->twa_dv.dv_xname);
1522
1523 if ((error = twa_soft_reset(sc)) == 0)
1524 error = twa_init_ctlr(sc);
1525 }
1526
1527 twa_describe_controller(sc);
1528
1529 error = twa_request_bus_scan(sc);
1530
1531 twa_outl(sc, TWA_CONTROL_REGISTER_OFFSET,
1532 TWA_CONTROL_CLEAR_ATTENTION_INTERRUPT |
1533 TWA_CONTROL_UNMASK_RESPONSE_INTERRUPT |
1534 TWA_CONTROL_ENABLE_INTERRUPTS);
1535
1536 return (error);
1537 }
1538
1539 void *twa_sdh;
1540
1541 static void
1542 twa_attach(struct device *parent, struct device *self, void *aux)
1543 {
1544 struct pci_attach_args *pa;
1545 struct twa_softc *sc;
1546 pci_chipset_tag_t pc;
1547 pcireg_t csr;
1548 pci_intr_handle_t ih;
1549 const char *intrstr;
1550
1551 sc = (struct twa_softc *)self;
1552
1553 pa = aux;
1554 pc = pa->pa_pc;
1555 sc->pc = pa->pa_pc;
1556 sc->tag = pa->pa_tag;
1557 sc->twa_dma_tag = pa->pa_dmat;
1558
1559 aprint_naive(": RAID controller\n");
1560 aprint_normal(": 3ware Apache\n");
1561
1562 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_3WARE_9000) {
1563 if (pci_mapreg_map(pa, PCI_MAPREG_START, PCI_MAPREG_TYPE_IO, 0,
1564 &sc->twa_bus_iot, &sc->twa_bus_ioh, NULL, NULL)) {
1565 aprint_error("%s: can't map i/o space\n",
1566 sc->twa_dv.dv_xname);
1567 return;
1568 }
1569 } else if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_3WARE_9550) {
1570 if (pci_mapreg_map(pa, PCI_MAPREG_START + 0x08,
1571 PCI_MAPREG_MEM_TYPE_64BIT, 0, &sc->twa_bus_iot,
1572 &sc->twa_bus_ioh, NULL, NULL)) {
1573 aprint_error("%s: can't map mem space\n",
1574 sc->twa_dv.dv_xname);
1575 return;
1576 }
1577 } else {
1578 aprint_error("%s: product id 0x%02x not recognized\n",
1579 sc->twa_dv.dv_xname, PCI_PRODUCT(pa->pa_id));
1580 return;
1581 }
1582 /* Enable the device. */
1583 csr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
1584
1585 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
1586 csr | PCI_COMMAND_MASTER_ENABLE);
1587
1588 /* Map and establish the interrupt. */
1589 if (pci_intr_map(pa, &ih)) {
1590 aprint_error("%s: can't map interrupt\n", sc->twa_dv.dv_xname);
1591 return;
1592 }
1593 intrstr = pci_intr_string(pc, ih);
1594
1595 sc->twa_ih = pci_intr_establish(pc, ih, IPL_BIO, twa_intr, sc);
1596 if (sc->twa_ih == NULL) {
1597 aprint_error("%s: can't establish interrupt%s%s\n",
1598 sc->twa_dv.dv_xname,
1599 (intrstr) ? " at " : "",
1600 (intrstr) ? intrstr : "");
1601 return;
1602 }
1603
1604 if (intrstr != NULL)
1605 aprint_normal("%s: interrupting at %s\n",
1606 sc->twa_dv.dv_xname, intrstr);
1607
1608 twa_setup(sc);
1609
1610 if (twa_sdh == NULL)
1611 twa_sdh = shutdownhook_establish(twa_shutdown, NULL);
1612
1613 return;
1614 }
1615
1616 static void
1617 twa_shutdown(void *arg)
1618 {
1619 extern struct cfdriver twa_cd;
1620 struct twa_softc *sc;
1621 int i, rv, unit;
1622
1623 for (i = 0; i < twa_cd.cd_ndevs; i++) {
1624 if ((sc = device_lookup(&twa_cd, i)) == NULL)
1625 continue;
1626
1627 for (unit = 0; unit < TWA_MAX_UNITS; unit++)
1628 if (sc->sc_units[unit].td_dev != NULL)
1629 (void) config_detach(sc->sc_units[unit].td_dev,
1630 DETACH_FORCE | DETACH_QUIET);
1631
1632 twa_outl(sc, TWA_CONTROL_REGISTER_OFFSET,
1633 TWA_CONTROL_DISABLE_INTERRUPTS);
1634
1635 /* Let the controller know that we are going down. */
1636 rv = twa_init_connection(sc, TWA_SHUTDOWN_MESSAGE_CREDITS,
1637 0, 0, 0, 0, 0,
1638 NULL, NULL, NULL, NULL, NULL);
1639 }
1640 }
1641
1642 void
1643 twa_register_callbacks(struct twa_softc *sc, int unit,
1644 const struct twa_callbacks *tcb)
1645 {
1646
1647 sc->sc_units[unit].td_callbacks = tcb;
1648 }
1649
1650 /*
1651 * Print autoconfiguration message for a sub-device
1652 */
1653 static int
1654 twa_print(void *aux, const char *pnp)
1655 {
1656 struct twa_attach_args *twaa;
1657
1658 twaa = aux;
1659
1660 if (pnp !=NULL)
1661 aprint_normal("block device at %s\n", pnp);
1662 aprint_normal(" unit %d\n", twaa->twaa_unit);
1663 return (UNCONF);
1664 }
1665
1666 static void
1667 twa_fillin_sgl(struct twa_sg *sgl, bus_dma_segment_t *segs, int nsegments)
1668 {
1669 int i;
1670 for (i = 0; i < nsegments; i++) {
1671 sgl[i].address = segs[i].ds_addr;
1672 sgl[i].length = (uint32_t)(segs[i].ds_len);
1673 }
1674 }
1675
1676 static int
1677 twa_submit_io(struct twa_request *tr)
1678 {
1679 int error;
1680
1681 if ((error = twa_start(tr))) {
1682 if (error == EBUSY)
1683 error = 0; /* request is in the pending queue */
1684 else {
1685 tr->tr_error = error;
1686 }
1687 }
1688 return(error);
1689 }
1690
1691 /*
1692 * Function name: twa_setup_data_dmamap
1693 * Description: Callback of bus_dmamap_load for the buffer associated
1694 * with data. Updates the cmd pkt (size/sgl_entries
1695 * fields, as applicable) to reflect the number of sg
1696 * elements.
1697 *
1698 * Input: arg -- ptr to request pkt
1699 * segs -- ptr to a list of segment descriptors
1700 * nsegments--# of segments
1701 * error -- 0 if no errors encountered before callback,
1702 * non-zero if errors were encountered
1703 * Output: None
1704 * Return value: None
1705 */
1706 static int
1707 twa_setup_data_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments,
1708 int error)
1709 {
1710 struct twa_request *tr = (struct twa_request *)arg;
1711 struct twa_command_packet *cmdpkt = tr->tr_command;
1712 struct twa_command_9k *cmd9k;
1713 union twa_command_7k *cmd7k;
1714 uint8_t sgl_offset;
1715
1716 if (error == EFBIG) {
1717 tr->tr_error = error;
1718 goto out;
1719 }
1720
1721 if (tr->tr_cmd_pkt_type & TWA_CMD_PKT_TYPE_9K) {
1722 cmd9k = &(cmdpkt->command.cmd_pkt_9k);
1723 twa_fillin_sgl(&(cmd9k->sg_list[0]), segs, nsegments);
1724 cmd9k->sgl_entries += nsegments - 1;
1725 } else {
1726 /* It's a 7000 command packet. */
1727 cmd7k = &(cmdpkt->command.cmd_pkt_7k);
1728 if ((sgl_offset = cmdpkt->command.cmd_pkt_7k.generic.sgl_offset))
1729 twa_fillin_sgl((struct twa_sg *)
1730 (((uint32_t *)cmd7k) + sgl_offset),
1731 segs, nsegments);
1732 /* Modify the size field, based on sg address size. */
1733 cmd7k->generic.size +=
1734 ((TWA_64BIT_ADDRESSES ? 3 : 2) * nsegments);
1735 }
1736
1737 if (tr->tr_flags & TWA_CMD_DATA_IN)
1738 bus_dmamap_sync(tr->tr_sc->twa_dma_tag, tr->tr_dma_map, 0,
1739 tr->tr_length, BUS_DMASYNC_PREREAD);
1740 if (tr->tr_flags & TWA_CMD_DATA_OUT) {
1741 /*
1742 * If we're using an alignment buffer, and we're
1743 * writing data, copy the real data out.
1744 */
1745 if (tr->tr_flags & TWA_CMD_DATA_COPY_NEEDED)
1746 memcpy(tr->tr_data, tr->tr_real_data,
1747 tr->tr_real_length);
1748 bus_dmamap_sync(tr->tr_sc->twa_dma_tag, tr->tr_dma_map, 0,
1749 tr->tr_length, BUS_DMASYNC_PREWRITE);
1750 }
1751 error = twa_submit_io(tr);
1752
1753 out:
1754 if (error) {
1755 twa_unmap_request(tr);
1756 /*
1757 * If the caller had been returned EINPROGRESS, and he has
1758 * registered a callback for handling completion, the callback
1759 * will never get called because we were unable to submit the
1760 * request. So, free up the request right here.
1761 */
1762 if ((tr->tr_flags & TWA_CMD_IN_PROGRESS) && (tr->tr_callback))
1763 twa_release_request(tr);
1764 }
1765 return (error);
1766 }
1767
1768 /*
1769 * Function name: twa_map_request
1770 * Description: Maps a cmd pkt and data associated with it, into
1771 * DMA'able memory.
1772 *
1773 * Input: tr -- ptr to request pkt
1774 * Output: None
1775 * Return value: 0 -- success
1776 * non-zero-- failure
1777 */
1778 int
1779 twa_map_request(struct twa_request *tr)
1780 {
1781 struct twa_softc *sc = tr->tr_sc;
1782 int s, rv, error = 0;
1783
1784 /* If the command involves data, map that too. */
1785 if (tr->tr_data != NULL) {
1786
1787 if (((u_long)tr->tr_data & (511)) != 0) {
1788 tr->tr_flags |= TWA_CMD_DATA_COPY_NEEDED;
1789 tr->tr_real_data = tr->tr_data;
1790 tr->tr_real_length = tr->tr_length;
1791 s = splvm();
1792 tr->tr_data = (void *)uvm_km_kmemalloc1(kmem_map,
1793 NULL, tr->tr_length, 512, UVM_UNKNOWN_OFFSET,
1794 UVM_KMF_NOWAIT);
1795 splx(s);
1796
1797 if (tr->tr_data == NULL) {
1798 tr->tr_data = tr->tr_real_data;
1799 tr->tr_length = tr->tr_real_length;
1800 return(ENOMEM);
1801 }
1802 if ((tr->tr_flags & TWA_CMD_DATA_IN) != 0)
1803 memcpy(tr->tr_data, tr->tr_real_data,
1804 tr->tr_length);
1805 }
1806
1807 /*
1808 * Map the data buffer into bus space and build the S/G list.
1809 */
1810 rv = bus_dmamap_load(sc->twa_dma_tag, tr->tr_dma_map,
1811 tr->tr_data, tr->tr_length, NULL, BUS_DMA_NOWAIT |
1812 BUS_DMA_STREAMING | (tr->tr_flags & TWA_CMD_DATA_OUT) ?
1813 BUS_DMA_READ : BUS_DMA_WRITE);
1814
1815 if (rv != 0) {
1816 if ((tr->tr_flags & TWA_CMD_DATA_COPY_NEEDED) != 0) {
1817 s = splvm();
1818 uvm_km_free(kmem_map, (vaddr_t)tr->tr_data,
1819 tr->tr_length);
1820 splx(s);
1821 }
1822 return (rv);
1823 }
1824
1825 if ((rv = twa_setup_data_dmamap(tr,
1826 tr->tr_dma_map->dm_segs,
1827 tr->tr_dma_map->dm_nsegs, error))) {
1828
1829 if (tr->tr_flags & TWA_CMD_DATA_COPY_NEEDED) {
1830 s = splvm();
1831 uvm_km_free(kmem_map, (vaddr_t)tr->tr_data,
1832 tr->tr_length);
1833 splx(s);
1834 tr->tr_data = tr->tr_real_data;
1835 tr->tr_length = tr->tr_real_length;
1836 }
1837 } else
1838 error = tr->tr_error;
1839
1840 } else
1841 if ((rv = twa_submit_io(tr)))
1842 twa_unmap_request(tr);
1843
1844 return (rv);
1845 }
1846
1847 #if 0
1848 /*
1849 * Function name: twa_flash_firmware
1850 * Description: Flashes bundled firmware image onto controller.
1851 *
1852 * Input: sc -- ptr to per ctlr structure
1853 * Output: None
1854 * Return value: 0 -- success
1855 * non-zero-- failure
1856 */
1857 static int
1858 twa_flash_firmware(struct twa_softc *sc)
1859 {
1860 struct twa_request *tr;
1861 struct twa_command_download_firmware *cmd;
1862 uint32_t count;
1863 uint32_t fw_img_chunk_size;
1864 uint32_t this_chunk_size = 0;
1865 uint32_t remaining_img_size = 0;
1866 int s, error = 0;
1867 int i;
1868
1869 if ((tr = twa_get_request(sc, 0)) == NULL) {
1870 /* No free request packets available. Can't proceed. */
1871 error = EIO;
1872 goto out;
1873 }
1874
1875 count = (twa_fw_img_size / 65536);
1876
1877 count += ((twa_fw_img_size % 65536) != 0) ? 1 : 0;
1878
1879 tr->tr_cmd_pkt_type |= TWA_CMD_PKT_TYPE_INTERNAL;
1880 /* Allocate sufficient memory to hold a chunk of the firmware image. */
1881 fw_img_chunk_size = ((twa_fw_img_size / count) + 511) & ~511;
1882
1883 s = splvm();
1884 tr->tr_data = (void *)uvm_km_kmemalloc1(kmem_map, NULL,
1885 fw_img_chunk_size, 512, UVM_UNKNOWN_OFFSET, UVM_KMF_NOWAIT);
1886 splx(s);
1887
1888 if (tr->tr_data == NULL) {
1889 error = ENOMEM;
1890 goto out;
1891 }
1892
1893 remaining_img_size = twa_fw_img_size;
1894 cmd = &(tr->tr_command->command.cmd_pkt_7k.download_fw);
1895
1896 for (i = 0; i < count; i++) {
1897 /* Build a cmd pkt for downloading firmware. */
1898 memset(tr->tr_command, 0, sizeof(struct twa_command_packet));
1899
1900 tr->tr_command->cmd_hdr.header_desc.size_header = 128;
1901
1902 cmd->opcode = TWA_OP_DOWNLOAD_FIRMWARE;
1903 cmd->sgl_offset = 2; /* offset in dwords, to the beginning
1904 of sg list */
1905 cmd->size = 2; /* this field will be updated at data
1906 map time */
1907 cmd->request_id = tr->tr_request_id;
1908 cmd->unit = 0;
1909 cmd->status = 0;
1910 cmd->flags = 0;
1911 cmd->param = 8; /* prom image */
1912
1913 if (i != (count - 1))
1914 this_chunk_size = fw_img_chunk_size;
1915 else /* last chunk */
1916 this_chunk_size = remaining_img_size;
1917
1918 remaining_img_size -= this_chunk_size;
1919
1920 memset(tr->tr_data, fw_img_chunk_size, 0);
1921
1922 memcpy(tr->tr_data, twa_fw_img + (i * fw_img_chunk_size),
1923 this_chunk_size);
1924 /*
1925 * The next line will effect only the last chunk.
1926 */
1927 tr->tr_length = (this_chunk_size + 511) & ~511;
1928
1929 tr->tr_flags |= TWA_CMD_DATA_OUT;
1930
1931 error = twa_immediate_request(tr, TWA_REQUEST_TIMEOUT_PERIOD);
1932
1933 if (error) {
1934 if (error == ETIMEDOUT)
1935 /* clean-up done by twa_immediate_request */
1936 return(error);
1937 break;
1938 }
1939 error = cmd->status;
1940
1941 if (i != (count - 1)) {
1942
1943 /*
1944 * XXX FreeBSD code doesn't check for no error condition
1945 * but based on observation, error seems to return 0
1946 */
1947 if ((error =
1948 tr->tr_command->cmd_hdr.status_block.error) == 0) {
1949 continue;
1950 } else if ((error =
1951 tr->tr_command->cmd_hdr.status_block.error) ==
1952 TWA_ERROR_MORE_DATA) {
1953 continue;
1954 } else {
1955 twa_hard_reset(sc);
1956 break;
1957 }
1958 } else /* last chunk */
1959 if (error) {
1960 printf("%s: firmware flash request failed. "
1961 "error = 0x%x\n", sc->twa_dv.dv_xname,
1962 error);
1963 twa_hard_reset(sc);
1964 }
1965 }
1966
1967 if (tr->tr_data) {
1968 s = splvm();
1969 uvm_km_free(kmem_map, (vaddr_t)tr->tr_data,
1970 fw_img_chunk_size);
1971 splx(s);
1972 }
1973 out:
1974 if (tr)
1975 twa_release_request(tr);
1976 return(error);
1977 }
1978
1979 /*
1980 * Function name: twa_hard_reset
1981 * Description: Hard reset the controller.
1982 *
1983 * Input: sc -- ptr to per ctlr structure
1984 * Output: None
1985 * Return value: 0 -- success
1986 * non-zero-- failure
1987 */
1988 static int
1989 twa_hard_reset(struct twa_softc *sc)
1990 {
1991 struct twa_request *tr;
1992 struct twa_command_reset_firmware *cmd;
1993 int error;
1994
1995 if ((tr = twa_get_request(sc, 0)) == NULL)
1996 return(EIO);
1997 tr->tr_cmd_pkt_type |= TWA_CMD_PKT_TYPE_INTERNAL;
1998 /* Build a cmd pkt for sending down the hard reset command. */
1999 tr->tr_command->cmd_hdr.header_desc.size_header = 128;
2000
2001 cmd = &(tr->tr_command->command.cmd_pkt_7k.reset_fw);
2002 cmd->opcode = TWA_OP_RESET_FIRMWARE;
2003 cmd->size = 2; /* this field will be updated at data map time */
2004 cmd->request_id = tr->tr_request_id;
2005 cmd->unit = 0;
2006 cmd->status = 0;
2007 cmd->flags = 0;
2008 cmd->param = 0; /* don't reload FPGA logic */
2009
2010 tr->tr_data = NULL;
2011 tr->tr_length = 0;
2012
2013 error = twa_immediate_request(tr, TWA_REQUEST_TIMEOUT_PERIOD);
2014 if (error) {
2015 printf("%s: hard reset request could not be posted. "
2016 "error = 0x%x\n", sc->twa_dv.dv_xname, error);
2017 if (error == ETIMEDOUT)
2018 /* clean-up done by twa_immediate_request */
2019 return(error);
2020 goto out;
2021 }
2022 if ((error = cmd->status)) {
2023 printf("%s: hard reset request failed. error = 0x%x\n",
2024 sc->twa_dv.dv_xname, error);
2025 }
2026
2027 out:
2028 if (tr)
2029 twa_release_request(tr);
2030 return(error);
2031 }
2032 #endif
2033
2034 /*
2035 * Function name: twa_intr
2036 * Description: Interrupt handler. Determines the kind of interrupt,
2037 * and calls the appropriate handler.
2038 *
2039 * Input: sc -- ptr to per ctlr structure
2040 * Output: None
2041 * Return value: None
2042 */
2043
2044 static int
2045 twa_intr(void *arg)
2046 {
2047 int caught, s, rv;
2048 struct twa_softc *sc;
2049 uint32_t status_reg;
2050 sc = (struct twa_softc *)arg;
2051
2052 caught = 0;
2053 /* Collect current interrupt status. */
2054 status_reg = twa_inl(sc, TWA_STATUS_REGISTER_OFFSET);
2055 if (twa_check_ctlr_state(sc, status_reg)) {
2056 caught = 1;
2057 goto bail;
2058 }
2059 /* Dispatch based on the kind of interrupt. */
2060 if (status_reg & TWA_STATUS_HOST_INTERRUPT) {
2061 twa_outl(sc, TWA_CONTROL_REGISTER_OFFSET,
2062 TWA_CONTROL_CLEAR_HOST_INTERRUPT);
2063 caught = 1;
2064 }
2065 if ((status_reg & TWA_STATUS_ATTENTION_INTERRUPT) != 0) {
2066 twa_outl(sc, TWA_CONTROL_REGISTER_OFFSET,
2067 TWA_CONTROL_CLEAR_ATTENTION_INTERRUPT);
2068 rv = twa_fetch_aen(sc);
2069 #ifdef DIAGNOSTIC
2070 if (rv != 0)
2071 printf("%s: unable to retrieve AEN (%d)\n",
2072 sc->twa_dv.dv_xname, rv);
2073 #endif
2074 caught = 1;
2075 }
2076 if (status_reg & TWA_STATUS_COMMAND_INTERRUPT) {
2077 /* Start any requests that might be in the pending queue. */
2078 twa_outl(sc, TWA_CONTROL_REGISTER_OFFSET,
2079 TWA_CONTROL_MASK_COMMAND_INTERRUPT);
2080 (void)twa_drain_pending_queue(sc);
2081 caught = 1;
2082 }
2083 if (status_reg & TWA_STATUS_RESPONSE_INTERRUPT) {
2084 s = splbio();
2085 twa_done(sc);
2086 splx(s);
2087 caught = 1;
2088 }
2089 bail:
2090 return (caught);
2091 }
2092
2093 /*
2094 * Accept an open operation on the control device.
2095 */
2096 static int
2097 twaopen(dev_t dev, int flag, int mode, struct proc *p)
2098 {
2099 struct twa_softc *twa;
2100
2101 if ((twa = device_lookup(&twa_cd, minor(dev))) == NULL)
2102 return (ENXIO);
2103 if ((twa->twa_sc_flags & TWA_STATE_OPEN) != 0)
2104 return (EBUSY);
2105
2106 twa->twa_sc_flags |= TWA_STATE_OPEN;
2107
2108 return (0);
2109 }
2110
2111 /*
2112 * Accept the last close on the control device.
2113 */
2114 static int
2115 twaclose(dev_t dev, int flag, int mode, struct proc *p)
2116 {
2117 struct twa_softc *twa;
2118
2119 twa = device_lookup(&twa_cd, minor(dev));
2120 twa->twa_sc_flags &= ~TWA_STATE_OPEN;
2121 return (0);
2122 }
2123
2124 /*
2125 * Function name: twaioctl
2126 * Description: ioctl handler.
2127 *
2128 * Input: sc -- ptr to per ctlr structure
2129 * cmd -- ioctl cmd
2130 * buf -- ptr to buffer in kernel memory, which is
2131 * a copy of the input buffer in user-space
2132 * Output: buf -- ptr to buffer in kernel memory, which will
2133 * be copied of the output buffer in user-space
2134 * Return value: 0 -- success
2135 * non-zero-- failure
2136 */
2137 static int
2138 twaioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
2139 {
2140 struct twa_softc *sc;
2141 struct twa_ioctl_9k *user_buf = (struct twa_ioctl_9k *)data;
2142 struct tw_cl_event_packet event_buf;
2143 struct twa_request *tr = 0;
2144 int32_t event_index = 0;
2145 int32_t start_index;
2146 int s, error = 0;
2147
2148 sc = device_lookup(&twa_cd, minor(dev));
2149
2150 switch (cmd) {
2151 case TW_OSL_IOCTL_FIRMWARE_PASS_THROUGH:
2152 {
2153 struct twa_command_packet *cmdpkt;
2154 uint32_t data_buf_size_adjusted;
2155
2156 /* Get a request packet */
2157 tr = twa_get_request_wait(sc, 0);
2158 KASSERT(tr != NULL);
2159 /*
2160 * Make sure that the data buffer sent to firmware is a
2161 * 512 byte multiple in size.
2162 */
2163 data_buf_size_adjusted =
2164 (user_buf->twa_drvr_pkt.buffer_length + 511) & ~511;
2165
2166 if ((tr->tr_length = data_buf_size_adjusted)) {
2167 if ((tr->tr_data = malloc(data_buf_size_adjusted,
2168 M_DEVBUF, M_WAITOK)) == NULL) {
2169 error = ENOMEM;
2170 goto fw_passthru_done;
2171 }
2172 /* Copy the payload. */
2173 if ((error = copyin((void *) (user_buf->pdata),
2174 (void *) (tr->tr_data),
2175 user_buf->twa_drvr_pkt.buffer_length)) != 0) {
2176 goto fw_passthru_done;
2177 }
2178 tr->tr_flags |= TWA_CMD_DATA_IN | TWA_CMD_DATA_OUT;
2179 }
2180 tr->tr_cmd_pkt_type |= TWA_CMD_PKT_TYPE_IOCTL;
2181 cmdpkt = tr->tr_command;
2182
2183 /* Copy the command packet. */
2184 memcpy(cmdpkt, &(user_buf->twa_cmd_pkt),
2185 sizeof(struct twa_command_packet));
2186 cmdpkt->command.cmd_pkt_7k.generic.request_id =
2187 tr->tr_request_id;
2188
2189 /* Send down the request, and wait for it to complete. */
2190 if ((error = twa_wait_request(tr, TWA_REQUEST_TIMEOUT_PERIOD))) {
2191 if (error == ETIMEDOUT)
2192 break; /* clean-up done by twa_wait_request */
2193 goto fw_passthru_done;
2194 }
2195
2196 /* Copy the command packet back into user space. */
2197 memcpy(&user_buf->twa_cmd_pkt, cmdpkt,
2198 sizeof(struct twa_command_packet));
2199
2200 /* If there was a payload, copy it back too. */
2201 if (tr->tr_length)
2202 error = copyout(tr->tr_data, user_buf->pdata,
2203 user_buf->twa_drvr_pkt.buffer_length);
2204 fw_passthru_done:
2205 /* Free resources. */
2206 if (tr->tr_data)
2207 free(tr->tr_data, M_DEVBUF);
2208
2209 if (tr)
2210 twa_release_request(tr);
2211 break;
2212 }
2213
2214 case TW_OSL_IOCTL_SCAN_BUS:
2215 twa_request_bus_scan(sc);
2216 break;
2217
2218 case TW_CL_IOCTL_GET_FIRST_EVENT:
2219 if (sc->twa_aen_queue_wrapped) {
2220 if (sc->twa_aen_queue_overflow) {
2221 /*
2222 * The aen queue has wrapped, even before some
2223 * events have been retrieved. Let the caller
2224 * know that he missed out on some AEN's.
2225 */
2226 user_buf->twa_drvr_pkt.status =
2227 TWA_ERROR_AEN_OVERFLOW;
2228 sc->twa_aen_queue_overflow = FALSE;
2229 } else
2230 user_buf->twa_drvr_pkt.status = 0;
2231 event_index = sc->twa_aen_head;
2232 } else {
2233 if (sc->twa_aen_head == sc->twa_aen_tail) {
2234 user_buf->twa_drvr_pkt.status =
2235 TWA_ERROR_AEN_NO_EVENTS;
2236 break;
2237 }
2238 user_buf->twa_drvr_pkt.status = 0;
2239 event_index = sc->twa_aen_tail; /* = 0 */
2240 }
2241 if ((error = copyout(sc->twa_aen_queue[event_index],
2242 user_buf->pdata, sizeof(struct tw_cl_event_packet))) != 0)
2243 (sc->twa_aen_queue[event_index])->retrieved =
2244 TWA_AEN_RETRIEVED;
2245 break;
2246
2247 case TW_CL_IOCTL_GET_LAST_EVENT:
2248 if (sc->twa_aen_queue_wrapped) {
2249 if (sc->twa_aen_queue_overflow) {
2250 /*
2251 * The aen queue has wrapped, even before some
2252 * events have been retrieved. Let the caller
2253 * know that he missed out on some AEN's.
2254 */
2255 user_buf->twa_drvr_pkt.status =
2256 TWA_ERROR_AEN_OVERFLOW;
2257 sc->twa_aen_queue_overflow = FALSE;
2258 } else
2259 user_buf->twa_drvr_pkt.status = 0;
2260 } else {
2261 if (sc->twa_aen_head == sc->twa_aen_tail) {
2262 user_buf->twa_drvr_pkt.status =
2263 TWA_ERROR_AEN_NO_EVENTS;
2264 break;
2265 }
2266 user_buf->twa_drvr_pkt.status = 0;
2267 }
2268 event_index =
2269 (sc->twa_aen_head - 1 + TWA_Q_LENGTH) % TWA_Q_LENGTH;
2270 if ((error = copyout(sc->twa_aen_queue[event_index],
2271 user_buf->pdata, sizeof(struct tw_cl_event_packet))) != 0)
2272 (sc->twa_aen_queue[event_index])->retrieved =
2273 TWA_AEN_RETRIEVED;
2274 break;
2275
2276 case TW_CL_IOCTL_GET_NEXT_EVENT:
2277 user_buf->twa_drvr_pkt.status = 0;
2278 if (sc->twa_aen_queue_wrapped) {
2279
2280 if (sc->twa_aen_queue_overflow) {
2281 /*
2282 * The aen queue has wrapped, even before some
2283 * events have been retrieved. Let the caller
2284 * know that he missed out on some AEN's.
2285 */
2286 user_buf->twa_drvr_pkt.status =
2287 TWA_ERROR_AEN_OVERFLOW;
2288 sc->twa_aen_queue_overflow = FALSE;
2289 }
2290 start_index = sc->twa_aen_head;
2291 } else {
2292 if (sc->twa_aen_head == sc->twa_aen_tail) {
2293 user_buf->twa_drvr_pkt.status =
2294 TWA_ERROR_AEN_NO_EVENTS;
2295 break;
2296 }
2297 start_index = sc->twa_aen_tail; /* = 0 */
2298 }
2299 error = copyin(user_buf->pdata, &event_buf,
2300 sizeof(struct tw_cl_event_packet));
2301
2302 event_index = (start_index + event_buf.sequence_id -
2303 (sc->twa_aen_queue[start_index])->sequence_id + 1)
2304 % TWA_Q_LENGTH;
2305
2306 if (!((sc->twa_aen_queue[event_index])->sequence_id >
2307 event_buf.sequence_id)) {
2308 if (user_buf->twa_drvr_pkt.status ==
2309 TWA_ERROR_AEN_OVERFLOW)
2310 /* so we report the overflow next time */
2311 sc->twa_aen_queue_overflow = TRUE;
2312 user_buf->twa_drvr_pkt.status = TWA_ERROR_AEN_NO_EVENTS;
2313 break;
2314 }
2315 if ((error = copyout(sc->twa_aen_queue[event_index],
2316 user_buf->pdata, sizeof(struct tw_cl_event_packet))) != 0)
2317 (sc->twa_aen_queue[event_index])->retrieved =
2318 TWA_AEN_RETRIEVED;
2319 break;
2320
2321 case TW_CL_IOCTL_GET_PREVIOUS_EVENT:
2322 user_buf->twa_drvr_pkt.status = 0;
2323 if (sc->twa_aen_queue_wrapped) {
2324 if (sc->twa_aen_queue_overflow) {
2325 /*
2326 * The aen queue has wrapped, even before some
2327 * events have been retrieved. Let the caller
2328 * know that he missed out on some AEN's.
2329 */
2330 user_buf->twa_drvr_pkt.status =
2331 TWA_ERROR_AEN_OVERFLOW;
2332 sc->twa_aen_queue_overflow = FALSE;
2333 }
2334 start_index = sc->twa_aen_head;
2335 } else {
2336 if (sc->twa_aen_head == sc->twa_aen_tail) {
2337 user_buf->twa_drvr_pkt.status =
2338 TWA_ERROR_AEN_NO_EVENTS;
2339 break;
2340 }
2341 start_index = sc->twa_aen_tail; /* = 0 */
2342 }
2343 if ((error = copyin(user_buf->pdata, &event_buf,
2344 sizeof(struct tw_cl_event_packet))) != 0)
2345
2346 event_index = (start_index + event_buf.sequence_id -
2347 (sc->twa_aen_queue[start_index])->sequence_id - 1)
2348 % TWA_Q_LENGTH;
2349 if (!((sc->twa_aen_queue[event_index])->sequence_id <
2350 event_buf.sequence_id)) {
2351 if (user_buf->twa_drvr_pkt.status ==
2352 TWA_ERROR_AEN_OVERFLOW)
2353 /* so we report the overflow next time */
2354 sc->twa_aen_queue_overflow = TRUE;
2355 user_buf->twa_drvr_pkt.status =
2356 TWA_ERROR_AEN_NO_EVENTS;
2357 break;
2358 }
2359 if ((error = copyout(sc->twa_aen_queue [event_index],
2360 user_buf->pdata, sizeof(struct tw_cl_event_packet))) != 0)
2361 aprint_error("%s: get_previous: Could not copyout to "
2362 "event_buf. error = %x\n", sc->twa_dv.dv_xname,
2363 error);
2364 (sc->twa_aen_queue[event_index])->retrieved = TWA_AEN_RETRIEVED;
2365 break;
2366
2367 case TW_CL_IOCTL_GET_LOCK:
2368 {
2369 struct tw_cl_lock_packet twa_lock;
2370
2371 copyin(user_buf->pdata, &twa_lock,
2372 sizeof(struct tw_cl_lock_packet));
2373 s = splbio();
2374 if ((sc->twa_ioctl_lock.lock == TWA_LOCK_FREE) ||
2375 (twa_lock.force_flag) ||
2376 (time.tv_sec >= sc->twa_ioctl_lock.timeout)) {
2377
2378 sc->twa_ioctl_lock.lock = TWA_LOCK_HELD;
2379 sc->twa_ioctl_lock.timeout = time.tv_sec +
2380 (twa_lock.timeout_msec / 1000);
2381 twa_lock.time_remaining_msec = twa_lock.timeout_msec;
2382 user_buf->twa_drvr_pkt.status = 0;
2383 } else {
2384 twa_lock.time_remaining_msec =
2385 (sc->twa_ioctl_lock.timeout - time.tv_sec) *
2386 1000;
2387 user_buf->twa_drvr_pkt.status =
2388 TWA_ERROR_IOCTL_LOCK_ALREADY_HELD;
2389 }
2390 splx(s);
2391 copyout(&twa_lock, user_buf->pdata,
2392 sizeof(struct tw_cl_lock_packet));
2393 break;
2394 }
2395
2396 case TW_CL_IOCTL_RELEASE_LOCK:
2397 s = splbio();
2398 if (sc->twa_ioctl_lock.lock == TWA_LOCK_FREE) {
2399 user_buf->twa_drvr_pkt.status =
2400 TWA_ERROR_IOCTL_LOCK_NOT_HELD;
2401 } else {
2402 sc->twa_ioctl_lock.lock = TWA_LOCK_FREE;
2403 user_buf->twa_drvr_pkt.status = 0;
2404 }
2405 splx(s);
2406 break;
2407
2408 case TW_CL_IOCTL_GET_COMPATIBILITY_INFO:
2409 {
2410 struct tw_cl_compatibility_packet comp_pkt;
2411
2412 memcpy(comp_pkt.driver_version, TWA_DRIVER_VERSION_STRING,
2413 sizeof(TWA_DRIVER_VERSION_STRING));
2414 comp_pkt.working_srl = sc->working_srl;
2415 comp_pkt.working_branch = sc->working_branch;
2416 comp_pkt.working_build = sc->working_build;
2417 user_buf->twa_drvr_pkt.status = 0;
2418
2419 /* Copy compatibility information to user space. */
2420 copyout(&comp_pkt, user_buf->pdata,
2421 min(sizeof(struct tw_cl_compatibility_packet),
2422 user_buf->twa_drvr_pkt.buffer_length));
2423 break;
2424 }
2425
2426 case TWA_IOCTL_GET_UNITNAME: /* WASABI EXTENSION */
2427 {
2428 struct twa_unitname *tn;
2429 struct twa_drive *tdr;
2430
2431 tn = (struct twa_unitname *)data;
2432 /* XXX mutex */
2433 if (tn->tn_unit < 0 || tn->tn_unit >= TWA_MAX_UNITS)
2434 return (EINVAL);
2435 tdr = &sc->sc_units[tn->tn_unit];
2436 if (tdr->td_dev == NULL)
2437 tn->tn_name[0] = '\0';
2438 else
2439 strlcpy(tn->tn_name, tdr->td_dev->dv_xname,
2440 sizeof(tn->tn_name));
2441 return (0);
2442 }
2443
2444 default:
2445 /* Unknown opcode. */
2446 error = ENOTTY;
2447 }
2448
2449 return(error);
2450 }
2451
2452 const struct cdevsw twa_cdevsw = {
2453 twaopen, twaclose, noread, nowrite, twaioctl,
2454 nostop, notty, nopoll, nommap,
2455 };
2456
2457 /*
2458 * Function name: twa_get_param
2459 * Description: Get a firmware parameter.
2460 *
2461 * Input: sc -- ptr to per ctlr structure
2462 * table_id -- parameter table #
2463 * param_id -- index of the parameter in the table
2464 * param_size -- size of the parameter in bytes
2465 * callback -- ptr to function, if any, to be called
2466 * back on completion; NULL if no callback.
2467 * Output: None
2468 * Return value: ptr to param structure -- success
2469 * NULL -- failure
2470 */
2471 static int
2472 twa_get_param(struct twa_softc *sc, int table_id, int param_id,
2473 size_t param_size, void (* callback)(struct twa_request *tr),
2474 struct twa_param_9k **param)
2475 {
2476 int rv = 0;
2477 struct twa_request *tr;
2478 union twa_command_7k *cmd;
2479
2480 /* Get a request packet. */
2481 if ((tr = twa_get_request(sc, 0)) == NULL) {
2482 rv = EAGAIN;
2483 goto out;
2484 }
2485
2486 tr->tr_cmd_pkt_type |= TWA_CMD_PKT_TYPE_INTERNAL;
2487
2488 /* Allocate memory to read data into. */
2489 if ((*param = (struct twa_param_9k *)
2490 malloc(TWA_SECTOR_SIZE, M_DEVBUF, M_NOWAIT)) == NULL) {
2491 rv = ENOMEM;
2492 goto out;
2493 }
2494
2495 memset(*param, 0, sizeof(struct twa_param_9k) - 1 + param_size);
2496 tr->tr_data = *param;
2497 tr->tr_length = TWA_SECTOR_SIZE;
2498 tr->tr_flags = TWA_CMD_DATA_IN | TWA_CMD_DATA_OUT;
2499
2500 /* Build the cmd pkt. */
2501 cmd = &(tr->tr_command->command.cmd_pkt_7k);
2502
2503 tr->tr_command->cmd_hdr.header_desc.size_header = 128;
2504
2505 cmd->param.opcode = TWA_OP_GET_PARAM;
2506 cmd->param.sgl_offset = 2;
2507 cmd->param.size = 2;
2508 cmd->param.request_id = tr->tr_request_id;
2509 cmd->param.unit = 0;
2510 cmd->param.param_count = 1;
2511
2512 /* Specify which parameter we need. */
2513 (*param)->table_id = table_id | TWA_9K_PARAM_DESCRIPTOR;
2514 (*param)->parameter_id = param_id;
2515 (*param)->parameter_size_bytes = param_size;
2516
2517 /* Submit the command. */
2518 if (callback == NULL) {
2519 /* There's no call back; wait till the command completes. */
2520 rv = twa_immediate_request(tr, TWA_REQUEST_TIMEOUT_PERIOD);
2521
2522 if (rv != 0)
2523 goto out;
2524
2525 if ((rv = cmd->param.status) != 0) {
2526 /* twa_drain_complete_queue will have done the unmapping */
2527 goto out;
2528 }
2529 twa_release_request(tr);
2530 return (rv);
2531 } else {
2532 /* There's a call back. Simply submit the command. */
2533 tr->tr_callback = callback;
2534 rv = twa_map_request(tr);
2535 return (rv);
2536 }
2537 out:
2538 if (tr)
2539 twa_release_request(tr);
2540 return(rv);
2541 }
2542
2543 /*
2544 * Function name: twa_set_param
2545 * Description: Set a firmware parameter.
2546 *
2547 * Input: sc -- ptr to per ctlr structure
2548 * table_id -- parameter table #
2549 * param_id -- index of the parameter in the table
2550 * param_size -- size of the parameter in bytes
2551 * callback -- ptr to function, if any, to be called
2552 * back on completion; NULL if no callback.
2553 * Output: None
2554 * Return value: 0 -- success
2555 * non-zero-- failure
2556 */
2557 static int
2558 twa_set_param(struct twa_softc *sc, int table_id, int param_id, int param_size,
2559 void *data, void (* callback)(struct twa_request *tr))
2560 {
2561 struct twa_request *tr;
2562 union twa_command_7k *cmd;
2563 struct twa_param_9k *param = NULL;
2564 int error = ENOMEM;
2565
2566 tr = twa_get_request(sc, 0);
2567 if (tr == NULL)
2568 return (EAGAIN);
2569
2570 tr->tr_cmd_pkt_type |= TWA_CMD_PKT_TYPE_INTERNAL;
2571
2572 /* Allocate memory to send data using. */
2573 if ((param = (struct twa_param_9k *)
2574 malloc(TWA_SECTOR_SIZE, M_DEVBUF, M_NOWAIT)) == NULL)
2575 goto out;
2576 memset(param, 0, sizeof(struct twa_param_9k) - 1 + param_size);
2577 tr->tr_data = param;
2578 tr->tr_length = TWA_SECTOR_SIZE;
2579 tr->tr_flags = TWA_CMD_DATA_IN | TWA_CMD_DATA_OUT;
2580
2581 /* Build the cmd pkt. */
2582 cmd = &(tr->tr_command->command.cmd_pkt_7k);
2583
2584 tr->tr_command->cmd_hdr.header_desc.size_header = 128;
2585
2586 cmd->param.opcode = TWA_OP_SET_PARAM;
2587 cmd->param.sgl_offset = 2;
2588 cmd->param.size = 2;
2589 cmd->param.request_id = tr->tr_request_id;
2590 cmd->param.unit = 0;
2591 cmd->param.param_count = 1;
2592
2593 /* Specify which parameter we want to set. */
2594 param->table_id = table_id | TWA_9K_PARAM_DESCRIPTOR;
2595 param->parameter_id = param_id;
2596 param->parameter_size_bytes = param_size;
2597 memcpy(param->data, data, param_size);
2598
2599 /* Submit the command. */
2600 if (callback == NULL) {
2601 /* There's no call back; wait till the command completes. */
2602 error = twa_immediate_request(tr, TWA_REQUEST_TIMEOUT_PERIOD);
2603 if (error == ETIMEDOUT)
2604 /* clean-up done by twa_immediate_request */
2605 return(error);
2606 if (error)
2607 goto out;
2608 if ((error = cmd->param.status)) {
2609 /*
2610 * twa_drain_complete_queue will have done the
2611 * unmapping.
2612 */
2613 goto out;
2614 }
2615 free(param, M_DEVBUF);
2616 twa_release_request(tr);
2617 return(error);
2618 } else {
2619 /* There's a call back. Simply submit the command. */
2620 tr->tr_callback = callback;
2621 if ((error = twa_map_request(tr)))
2622 goto out;
2623
2624 return (0);
2625 }
2626 out:
2627 if (param)
2628 free(param, M_DEVBUF);
2629 if (tr)
2630 twa_release_request(tr);
2631 return(error);
2632 }
2633
2634 /*
2635 * Function name: twa_init_connection
2636 * Description: Send init_connection cmd to firmware
2637 *
2638 * Input: sc -- ptr to per ctlr structure
2639 * message_credits -- max # of requests that we might send
2640 * down simultaneously. This will be
2641 * typically set to 256 at init-time or
2642 * after a reset, and to 1 at shutdown-time
2643 * set_features -- indicates if we intend to use 64-bit
2644 * sg, also indicates if we want to do a
2645 * basic or an extended init_connection;
2646 *
2647 * Note: The following input/output parameters are valid, only in case of an
2648 * extended init_connection:
2649 *
2650 * current_fw_srl -- srl of fw we are bundled
2651 * with, if any; 0 otherwise
2652 * current_fw_arch_id -- arch_id of fw we are bundled
2653 * with, if any; 0 otherwise
2654 * current_fw_branch -- branch # of fw we are bundled
2655 * with, if any; 0 otherwise
2656 * current_fw_build -- build # of fw we are bundled
2657 * with, if any; 0 otherwise
2658 * Output: fw_on_ctlr_srl -- srl of fw on ctlr
2659 * fw_on_ctlr_arch_id -- arch_id of fw on ctlr
2660 * fw_on_ctlr_branch -- branch # of fw on ctlr
2661 * fw_on_ctlr_build -- build # of fw on ctlr
2662 * init_connect_result -- result bitmap of fw response
2663 * Return value: 0 -- success
2664 * non-zero-- failure
2665 */
2666 static int
2667 twa_init_connection(struct twa_softc *sc, uint16_t message_credits,
2668 uint32_t set_features, uint16_t current_fw_srl,
2669 uint16_t current_fw_arch_id, uint16_t current_fw_branch,
2670 uint16_t current_fw_build, uint16_t *fw_on_ctlr_srl,
2671 uint16_t *fw_on_ctlr_arch_id, uint16_t *fw_on_ctlr_branch,
2672 uint16_t *fw_on_ctlr_build, uint32_t *init_connect_result)
2673 {
2674 struct twa_request *tr;
2675 struct twa_command_init_connect *init_connect;
2676 int error = 1;
2677
2678 /* Get a request packet. */
2679 if ((tr = twa_get_request(sc, 0)) == NULL)
2680 goto out;
2681 tr->tr_cmd_pkt_type |= TWA_CMD_PKT_TYPE_INTERNAL;
2682 /* Build the cmd pkt. */
2683 init_connect = &(tr->tr_command->command.cmd_pkt_7k.init_connect);
2684
2685 tr->tr_command->cmd_hdr.header_desc.size_header = 128;
2686
2687 init_connect->opcode = TWA_OP_INIT_CONNECTION;
2688 init_connect->request_id = tr->tr_request_id;
2689 init_connect->message_credits = message_credits;
2690 init_connect->features = set_features;
2691 if (TWA_64BIT_ADDRESSES) {
2692 printf("64 bit addressing supported for scatter/gather list\n");
2693 init_connect->features |= TWA_64BIT_SG_ADDRESSES;
2694 }
2695 if (set_features & TWA_EXTENDED_INIT_CONNECT) {
2696 /*
2697 * Fill in the extra fields needed for
2698 * an extended init_connect.
2699 */
2700 init_connect->size = 6;
2701 init_connect->fw_srl = current_fw_srl;
2702 init_connect->fw_arch_id = current_fw_arch_id;
2703 init_connect->fw_branch = current_fw_branch;
2704 } else
2705 init_connect->size = 3;
2706
2707 /* Submit the command, and wait for it to complete. */
2708 error = twa_immediate_request(tr, TWA_REQUEST_TIMEOUT_PERIOD);
2709 if (error == ETIMEDOUT)
2710 return(error); /* clean-up done by twa_immediate_request */
2711 if (error)
2712 goto out;
2713 if ((error = init_connect->status)) {
2714 /* twa_drain_complete_queue will have done the unmapping */
2715 goto out;
2716 }
2717 if (set_features & TWA_EXTENDED_INIT_CONNECT) {
2718 *fw_on_ctlr_srl = init_connect->fw_srl;
2719 *fw_on_ctlr_arch_id = init_connect->fw_arch_id;
2720 *fw_on_ctlr_branch = init_connect->fw_branch;
2721 *fw_on_ctlr_build = init_connect->fw_build;
2722 *init_connect_result = init_connect->result;
2723 }
2724 twa_release_request(tr);
2725 return(error);
2726
2727 out:
2728 if (tr)
2729 twa_release_request(tr);
2730 return(error);
2731 }
2732
2733 static int
2734 twa_reset(struct twa_softc *sc)
2735 {
2736 int s;
2737 int error = 0;
2738
2739 /*
2740 * Disable interrupts from the controller, and mask any
2741 * accidental entry into our interrupt handler.
2742 */
2743 twa_outl(sc, TWA_CONTROL_REGISTER_OFFSET,
2744 TWA_CONTROL_DISABLE_INTERRUPTS);
2745
2746 s = splbio();
2747
2748 /* Soft reset the controller. */
2749 if ((error = twa_soft_reset(sc)))
2750 goto out;
2751
2752 /* Re-establish logical connection with the controller. */
2753 if ((error = twa_init_connection(sc, TWA_INIT_MESSAGE_CREDITS,
2754 0, 0, 0, 0, 0,
2755 NULL, NULL, NULL, NULL, NULL))) {
2756 goto out;
2757 }
2758 /*
2759 * Complete all requests in the complete queue; error back all requests
2760 * in the busy queue. Any internal requests will be simply freed.
2761 * Re-submit any requests in the pending queue.
2762 */
2763 twa_drain_busy_queue(sc);
2764
2765 out:
2766 splx(s);
2767 /*
2768 * Enable interrupts, and also clear attention and response interrupts.
2769 */
2770 twa_outl(sc, TWA_CONTROL_REGISTER_OFFSET,
2771 TWA_CONTROL_CLEAR_ATTENTION_INTERRUPT |
2772 TWA_CONTROL_UNMASK_RESPONSE_INTERRUPT |
2773 TWA_CONTROL_ENABLE_INTERRUPTS);
2774 return(error);
2775 }
2776
2777 static int
2778 twa_soft_reset(struct twa_softc *sc)
2779 {
2780 uint32_t status_reg;
2781
2782 twa_outl(sc, TWA_CONTROL_REGISTER_OFFSET,
2783 TWA_CONTROL_ISSUE_SOFT_RESET |
2784 TWA_CONTROL_CLEAR_HOST_INTERRUPT |
2785 TWA_CONTROL_CLEAR_ATTENTION_INTERRUPT |
2786 TWA_CONTROL_MASK_COMMAND_INTERRUPT |
2787 TWA_CONTROL_MASK_RESPONSE_INTERRUPT |
2788 TWA_CONTROL_DISABLE_INTERRUPTS);
2789
2790 if (twa_wait_status(sc, TWA_STATUS_MICROCONTROLLER_READY |
2791 TWA_STATUS_ATTENTION_INTERRUPT, 30)) {
2792 aprint_error("%s: no attention interrupt after reset.\n",
2793 sc->twa_dv.dv_xname);
2794 return(1);
2795 }
2796 twa_outl(sc, TWA_CONTROL_REGISTER_OFFSET,
2797 TWA_CONTROL_CLEAR_ATTENTION_INTERRUPT);
2798
2799 if (twa_drain_response_queue(sc)) {
2800 aprint_error("%s: cannot drain response queue.\n",
2801 sc->twa_dv.dv_xname);
2802 return(1);
2803 }
2804 if (twa_drain_aen_queue(sc)) {
2805 aprint_error("%s: cannot drain AEN queue.\n",
2806 sc->twa_dv.dv_xname);
2807 return(1);
2808 }
2809 if (twa_find_aen(sc, TWA_AEN_SOFT_RESET)) {
2810 aprint_error("%s: reset not reported by controller.\n",
2811 sc->twa_dv.dv_xname);
2812 return(1);
2813 }
2814 status_reg = twa_inl(sc, TWA_STATUS_REGISTER_OFFSET);
2815 if (TWA_STATUS_ERRORS(status_reg) ||
2816 twa_check_ctlr_state(sc, status_reg)) {
2817 aprint_error("%s: controller errors detected.\n",
2818 sc->twa_dv.dv_xname);
2819 return(1);
2820 }
2821 return(0);
2822 }
2823
2824 static int
2825 twa_wait_status(struct twa_softc *sc, uint32_t status, uint32_t timeout)
2826 {
2827 struct timeval t1;
2828 time_t end_time;
2829 uint32_t status_reg;
2830
2831 timeout = (timeout * 1000 * 100);
2832
2833 microtime(&t1);
2834
2835 end_time = t1.tv_usec + timeout;
2836
2837 do {
2838 status_reg = twa_inl(sc, TWA_STATUS_REGISTER_OFFSET);
2839 /* got the required bit(s)? */
2840 if ((status_reg & status) == status)
2841 return(0);
2842 DELAY(100000);
2843 microtime(&t1);
2844 } while (t1.tv_usec <= end_time);
2845
2846 return(1);
2847 }
2848
2849 static int
2850 twa_fetch_aen(struct twa_softc *sc)
2851 {
2852 struct twa_request *tr;
2853 int s, error = 0;
2854
2855 s = splbio();
2856
2857 if ((tr = twa_get_request(sc, TWA_CMD_AEN)) == NULL) {
2858 splx(s);
2859 return(EIO);
2860 }
2861 tr->tr_cmd_pkt_type |= TWA_CMD_PKT_TYPE_INTERNAL;
2862 tr->tr_callback = twa_aen_callback;
2863 tr->tr_data = malloc(TWA_SECTOR_SIZE, M_DEVBUF, M_NOWAIT);
2864 if (twa_request_sense(tr, 0) != 0) {
2865 if (tr->tr_data)
2866 free(tr->tr_data, M_DEVBUF);
2867 twa_release_request(tr);
2868 error = 1;
2869 }
2870 splx(s);
2871
2872 return(error);
2873 }
2874
2875 /*
2876 * Function name: twa_aen_callback
2877 * Description: Callback for requests to fetch AEN's.
2878 *
2879 * Input: tr -- ptr to completed request pkt
2880 * Output: None
2881 * Return value: None
2882 */
2883 static void
2884 twa_aen_callback(struct twa_request *tr)
2885 {
2886 int i;
2887 int fetch_more_aens = 0;
2888 struct twa_softc *sc = tr->tr_sc;
2889 struct twa_command_header *cmd_hdr =
2890 (struct twa_command_header *)(tr->tr_data);
2891 struct twa_command_9k *cmd =
2892 &(tr->tr_command->command.cmd_pkt_9k);
2893
2894 if (! cmd->status) {
2895 if ((tr->tr_cmd_pkt_type & TWA_CMD_PKT_TYPE_9K) &&
2896 (cmd->cdb[0] == 0x3 /* REQUEST_SENSE */))
2897 if (twa_enqueue_aen(sc, cmd_hdr)
2898 != TWA_AEN_QUEUE_EMPTY)
2899 fetch_more_aens = 1;
2900 } else {
2901 cmd_hdr->err_specific_desc[sizeof(cmd_hdr->err_specific_desc) - 1] = '\0';
2902 for (i = 0; i < 18; i++)
2903 printf("%x\t", tr->tr_command->cmd_hdr.sense_data[i]);
2904
2905 printf(""); /* print new line */
2906
2907 for (i = 0; i < 128; i++)
2908 printf("%x\t", ((int8_t *)(tr->tr_data))[i]);
2909 }
2910 if (tr->tr_data)
2911 free(tr->tr_data, M_DEVBUF);
2912 twa_release_request(tr);
2913
2914 if (fetch_more_aens)
2915 twa_fetch_aen(sc);
2916 }
2917
2918 /*
2919 * Function name: twa_enqueue_aen
2920 * Description: Queues AEN's to be supplied to user-space tools on request.
2921 *
2922 * Input: sc -- ptr to per ctlr structure
2923 * cmd_hdr -- ptr to hdr of fw cmd pkt, from where the AEN
2924 * details can be retrieved.
2925 * Output: None
2926 * Return value: None
2927 */
2928 static uint16_t
2929 twa_enqueue_aen(struct twa_softc *sc, struct twa_command_header *cmd_hdr)
2930 {
2931 int rv, s;
2932 struct tw_cl_event_packet *event;
2933 uint16_t aen_code;
2934 unsigned long sync_time;
2935
2936 s = splbio();
2937 aen_code = cmd_hdr->status_block.error;
2938
2939 switch (aen_code) {
2940 case TWA_AEN_SYNC_TIME_WITH_HOST:
2941
2942 sync_time = (time.tv_sec - (3 * 86400)) % 604800;
2943 rv = twa_set_param(sc, TWA_PARAM_TIME_TABLE,
2944 TWA_PARAM_TIME_SchedulerTime, 4,
2945 &sync_time, twa_aen_callback);
2946 #ifdef DIAGNOSTIC
2947 if (rv != 0)
2948 printf("%s: unable to sync time with ctlr\n",
2949 sc->twa_dv.dv_xname);
2950 #endif
2951 break;
2952
2953 case TWA_AEN_QUEUE_EMPTY:
2954 break;
2955
2956 default:
2957 /* Queue the event. */
2958 event = sc->twa_aen_queue[sc->twa_aen_head];
2959 if (event->retrieved == TWA_AEN_NOT_RETRIEVED)
2960 sc->twa_aen_queue_overflow = TRUE;
2961 event->severity =
2962 cmd_hdr->status_block.substatus_block.severity;
2963 event->time_stamp_sec = time.tv_sec;
2964 event->aen_code = aen_code;
2965 event->retrieved = TWA_AEN_NOT_RETRIEVED;
2966 event->sequence_id = ++(sc->twa_current_sequence_id);
2967 cmd_hdr->err_specific_desc[sizeof(cmd_hdr->err_specific_desc) - 1] = '\0';
2968 event->parameter_len = strlen(cmd_hdr->err_specific_desc);
2969 memcpy(event->parameter_data, cmd_hdr->err_specific_desc,
2970 event->parameter_len);
2971
2972 if (event->severity < TWA_AEN_SEVERITY_DEBUG) {
2973 printf("%s: AEN 0x%04X: %s: %s: %s\n",
2974 sc->twa_dv.dv_xname,
2975 aen_code,
2976 twa_aen_severity_table[event->severity],
2977 twa_find_msg_string(twa_aen_table, aen_code),
2978 event->parameter_data);
2979 }
2980
2981 if ((sc->twa_aen_head + 1) == TWA_Q_LENGTH)
2982 sc->twa_aen_queue_wrapped = TRUE;
2983 sc->twa_aen_head = (sc->twa_aen_head + 1) % TWA_Q_LENGTH;
2984 break;
2985 } /* switch */
2986 splx(s);
2987
2988 return (aen_code);
2989 }
2990
2991 /*
2992 * Function name: twa_find_aen
2993 * Description: Reports whether a given AEN ever occurred.
2994 *
2995 * Input: sc -- ptr to per ctlr structure
2996 * aen_code-- AEN to look for
2997 * Output: None
2998 * Return value: 0 -- success
2999 * non-zero-- failure
3000 */
3001 static int
3002 twa_find_aen(struct twa_softc *sc, uint16_t aen_code)
3003 {
3004 uint32_t last_index;
3005 int s;
3006 int i;
3007
3008 s = splbio();
3009
3010 if (sc->twa_aen_queue_wrapped)
3011 last_index = sc->twa_aen_head;
3012 else
3013 last_index = 0;
3014
3015 i = sc->twa_aen_head;
3016 do {
3017 i = (i + TWA_Q_LENGTH - 1) % TWA_Q_LENGTH;
3018 if ((sc->twa_aen_queue[i])->aen_code == aen_code) {
3019 splx(s);
3020 return(0);
3021 }
3022 } while (i != last_index);
3023
3024 splx(s);
3025 return(1);
3026 }
3027
3028 static void inline
3029 twa_request_init(struct twa_request *tr, int flags)
3030 {
3031 tr->tr_data = NULL;
3032 tr->tr_real_data = NULL;
3033 tr->tr_length = 0;
3034 tr->tr_real_length = 0;
3035 tr->tr_status = TWA_CMD_SETUP;/* command is in setup phase */
3036 tr->tr_flags = flags;
3037 tr->tr_error = 0;
3038 tr->tr_callback = NULL;
3039 tr->tr_cmd_pkt_type = 0;
3040 tr->bp = 0;
3041
3042 /*
3043 * Look at the status field in the command packet to see how
3044 * it completed the last time it was used, and zero out only
3045 * the portions that might have changed. Note that we don't
3046 * care to zero out the sglist.
3047 */
3048 if (tr->tr_command->command.cmd_pkt_9k.status)
3049 memset(tr->tr_command, 0,
3050 sizeof(struct twa_command_header) + 28);
3051 else
3052 memset(&(tr->tr_command->command), 0, 28);
3053 }
3054
3055 struct twa_request *
3056 twa_get_request_wait(struct twa_softc *sc, int flags)
3057 {
3058 struct twa_request *tr;
3059 int s;
3060
3061 KASSERT((flags & TWA_CMD_AEN) == 0);
3062
3063 s = splbio();
3064 while ((tr = TAILQ_FIRST(&sc->twa_free)) == NULL) {
3065 sc->twa_sc_flags |= TWA_STATE_REQUEST_WAIT;
3066 (void) tsleep(&sc->twa_free, PRIBIO, "twaccb", hz);
3067 }
3068 TAILQ_REMOVE(&sc->twa_free, tr, tr_link);
3069
3070 splx(s);
3071
3072 twa_request_init(tr, flags);
3073
3074 return(tr);
3075 }
3076
3077 struct twa_request *
3078 twa_get_request(struct twa_softc *sc, int flags)
3079 {
3080 int s;
3081 struct twa_request *tr;
3082
3083 /* Get a free request packet. */
3084 s = splbio();
3085 if (__predict_false((flags & TWA_CMD_AEN) != 0)) {
3086
3087 if ((sc->sc_twa_request->tr_flags & TWA_CMD_AEN_BUSY) == 0) {
3088 tr = sc->sc_twa_request;
3089 flags |= TWA_CMD_AEN_BUSY;
3090 } else {
3091 splx(s);
3092 return (NULL);
3093 }
3094 } else {
3095 if (__predict_false((tr =
3096 TAILQ_FIRST(&sc->twa_free)) == NULL)) {
3097 splx(s);
3098 return (NULL);
3099 }
3100 TAILQ_REMOVE(&sc->twa_free, tr, tr_link);
3101 }
3102 splx(s);
3103
3104 twa_request_init(tr, flags);
3105
3106 return(tr);
3107 }
3108
3109 /*
3110 * Print some information about the controller
3111 */
3112 static void
3113 twa_describe_controller(struct twa_softc *sc)
3114 {
3115 struct twa_param_9k *p[10];
3116 int i, rv = 0;
3117 uint32_t dsize;
3118 uint8_t ports;
3119
3120 memset(p, sizeof(struct twa_param_9k *), 10);
3121
3122 /* Get the port count. */
3123 rv |= twa_get_param(sc, TWA_PARAM_CONTROLLER,
3124 TWA_PARAM_CONTROLLER_PortCount, 1, NULL, &p[0]);
3125
3126 /* get version strings */
3127 rv |= twa_get_param(sc, TWA_PARAM_VERSION, TWA_PARAM_VERSION_FW,
3128 16, NULL, &p[1]);
3129 rv |= twa_get_param(sc, TWA_PARAM_VERSION, TWA_PARAM_VERSION_BIOS,
3130 16, NULL, &p[2]);
3131 rv |= twa_get_param(sc, TWA_PARAM_VERSION, TWA_PARAM_VERSION_Mon,
3132 16, NULL, &p[3]);
3133 rv |= twa_get_param(sc, TWA_PARAM_VERSION, TWA_PARAM_VERSION_PCBA,
3134 8, NULL, &p[4]);
3135 rv |= twa_get_param(sc, TWA_PARAM_VERSION, TWA_PARAM_VERSION_ATA,
3136 8, NULL, &p[5]);
3137 rv |= twa_get_param(sc, TWA_PARAM_VERSION, TWA_PARAM_VERSION_PCI,
3138 8, NULL, &p[6]);
3139 rv |= twa_get_param(sc, TWA_PARAM_DRIVESUMMARY, TWA_PARAM_DRIVESTATUS,
3140 16, NULL, &p[7]);
3141
3142 if (rv) {
3143 /* some error occurred */
3144 aprint_error("%s: failed to fetch version information\n",
3145 sc->twa_dv.dv_xname);
3146 goto bail;
3147 }
3148
3149 ports = *(uint8_t *)(p[0]->data);
3150
3151 aprint_normal("%s: %d ports, Firmware %.16s, BIOS %.16s\n",
3152 sc->twa_dv.dv_xname, ports,
3153 p[1]->data, p[2]->data);
3154
3155 aprint_verbose("%s: Monitor %.16s, PCB %.8s, Achip %.8s, Pchip %.8s\n",
3156 sc->twa_dv.dv_xname,
3157 p[3]->data, p[4]->data,
3158 p[5]->data, p[6]->data);
3159
3160 for (i = 0; i < ports; i++) {
3161
3162 if ((*((char *)(p[7]->data + i)) & TWA_DRIVE_DETECTED) == 0)
3163 continue;
3164
3165 rv = twa_get_param(sc, TWA_PARAM_DRIVE_TABLE,
3166 TWA_PARAM_DRIVEMODELINDEX,
3167 TWA_PARAM_DRIVEMODEL_LENGTH, NULL, &p[8]);
3168
3169 if (rv != 0) {
3170 aprint_error("%s: unable to get drive model for port"
3171 " %d\n", sc->twa_dv.dv_xname, i);
3172 continue;
3173 }
3174
3175 rv = twa_get_param(sc, TWA_PARAM_DRIVE_TABLE,
3176 TWA_PARAM_DRIVESIZEINDEX,
3177 TWA_PARAM_DRIVESIZE_LENGTH, NULL, &p[9]);
3178
3179 if (rv != 0) {
3180 aprint_error("%s: unable to get drive size"
3181 " for port %d\n", sc->twa_dv.dv_xname,
3182 i);
3183 free(p[8], M_DEVBUF);
3184 continue;
3185 }
3186
3187 dsize = *(uint32_t *)(p[9]->data);
3188
3189 aprint_verbose("%s: port %d: %.40s %d MB\n",
3190 sc->twa_dv.dv_xname, i, p[8]->data, dsize / 2048);
3191
3192 if (p[8])
3193 free(p[8], M_DEVBUF);
3194 if (p[9])
3195 free(p[9], M_DEVBUF);
3196 }
3197 bail:
3198 if (p[0])
3199 free(p[0], M_DEVBUF);
3200 if (p[1])
3201 free(p[1], M_DEVBUF);
3202 if (p[2])
3203 free(p[2], M_DEVBUF);
3204 if (p[3])
3205 free(p[3], M_DEVBUF);
3206 if (p[4])
3207 free(p[4], M_DEVBUF);
3208 if (p[5])
3209 free(p[5], M_DEVBUF);
3210 if (p[6])
3211 free(p[6], M_DEVBUF);
3212 }
3213
3214 /*
3215 * Function name: twa_check_ctlr_state
3216 * Description: Makes sure that the fw status register reports a
3217 * proper status.
3218 *
3219 * Input: sc -- ptr to per ctlr structure
3220 * status_reg -- value in the status register
3221 * Output: None
3222 * Return value: 0 -- no errors
3223 * non-zero-- errors
3224 */
3225 static int
3226 twa_check_ctlr_state(struct twa_softc *sc, uint32_t status_reg)
3227 {
3228 int result = 0;
3229 struct timeval t1;
3230 static time_t last_warning[2] = {0, 0};
3231
3232 /* Check if the 'micro-controller ready' bit is not set. */
3233 if ((status_reg & TWA_STATUS_EXPECTED_BITS) !=
3234 TWA_STATUS_EXPECTED_BITS) {
3235
3236 microtime(&t1);
3237
3238 last_warning[0] += (5 * 1000 * 100);
3239
3240 if (t1.tv_usec > last_warning[0]) {
3241 microtime(&t1);
3242 last_warning[0] = t1.tv_usec;
3243 }
3244 result = 1;
3245 }
3246
3247 /* Check if any error bits are set. */
3248 if ((status_reg & TWA_STATUS_UNEXPECTED_BITS) != 0) {
3249
3250 microtime(&t1);
3251 last_warning[1] += (5 * 1000 * 100);
3252 if (t1.tv_usec > last_warning[1]) {
3253 microtime(&t1);
3254 last_warning[1] = t1.tv_usec;
3255 }
3256 if (status_reg & TWA_STATUS_PCI_PARITY_ERROR_INTERRUPT) {
3257 aprint_error("%s: clearing PCI parity error "
3258 "re-seat/move/replace card.\n",
3259 sc->twa_dv.dv_xname);
3260 twa_outl(sc, TWA_CONTROL_REGISTER_OFFSET,
3261 TWA_CONTROL_CLEAR_PARITY_ERROR);
3262 pci_conf_write(sc->pc, sc->tag,
3263 PCI_COMMAND_STATUS_REG,
3264 TWA_PCI_CONFIG_CLEAR_PARITY_ERROR);
3265 result = 1;
3266 }
3267 if (status_reg & TWA_STATUS_PCI_ABORT_INTERRUPT) {
3268 aprint_error("%s: clearing PCI abort\n",
3269 sc->twa_dv.dv_xname);
3270 twa_outl(sc, TWA_CONTROL_REGISTER_OFFSET,
3271 TWA_CONTROL_CLEAR_PCI_ABORT);
3272 pci_conf_write(sc->pc, sc->tag,
3273 PCI_COMMAND_STATUS_REG,
3274 TWA_PCI_CONFIG_CLEAR_PCI_ABORT);
3275 result = 1;
3276 }
3277 if (status_reg & TWA_STATUS_QUEUE_ERROR_INTERRUPT) {
3278 aprint_error("%s: clearing controller queue error\n",
3279 sc->twa_dv.dv_xname);
3280 twa_outl(sc, TWA_CONTROL_REGISTER_OFFSET,
3281 TWA_CONTROL_CLEAR_PCI_ABORT);
3282 result = 1;
3283 }
3284 if (status_reg & TWA_STATUS_SBUF_WRITE_ERROR) {
3285 aprint_error("%s: clearing SBUF write error\n",
3286 sc->twa_dv.dv_xname);
3287 twa_outl(sc, TWA_CONTROL_REGISTER_OFFSET,
3288 TWA_CONTROL_CLEAR_SBUF_WRITE_ERROR);
3289 result = 1;
3290 }
3291 if (status_reg & TWA_STATUS_MICROCONTROLLER_ERROR) {
3292 aprint_error("%s: micro-controller error\n",
3293 sc->twa_dv.dv_xname);
3294 result = 1;
3295 }
3296 }
3297 return(result);
3298 }
3299