1 /* $NetBSD: twe.c,v 1.89 2009/05/06 10:34:33 cegger Exp $ */
4 * Copyright (c) 2000, 2001, 2002, 2003, 2004 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran; and by Jason R. Thorpe of Wasabi Systems, Inc.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 * Copyright (c) 2000 Michael Smith
34 * Copyright (c) 2000 BSDi
35 * All rights reserved.
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution.
46 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
47 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
50 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
51 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
52 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * from FreeBSD: twe.c,v 1.1 2000/05/24 23:35:23 msmith Exp
62 * Driver for the 3ware Escalade family of RAID controllers.
65 #include <sys/cdefs.h>
66 __KERNEL_RCSID(0, "$NetBSD: twe.c,v 1.89 2009/05/06 10:34:33 cegger Exp $");
68 #include <sys/param.h>
69 #include <sys/systm.h>
70 #include <sys/kernel.h>
71 #include <sys/device.h>
72 #include <sys/queue.h>
75 #include <sys/endian.h>
76 #include <sys/malloc.h>
79 #include <sys/sysctl.h>
80 #include <sys/syslog.h>
81 #include <sys/kauth.h>
83 #include <uvm/uvm_extern.h>
85 #include <sys/bswap.h>
88 #include <dev/pci/pcireg.h>
89 #include <dev/pci/pcivar.h>
90 #include <dev/pci/pcidevs.h>
91 #include <dev/pci/twereg.h>
92 #include <dev/pci/twevar.h>
93 #include <dev/pci/tweio.h>
99 static int twe_aen_get(struct twe_softc
*, uint16_t *);
100 static void twe_aen_handler(struct twe_ccb
*, int);
101 static void twe_aen_enqueue(struct twe_softc
*sc
, uint16_t, int);
102 static uint16_t twe_aen_dequeue(struct twe_softc
*);
104 static void twe_attach(device_t
, device_t
, void *);
105 static int twe_init_connection(struct twe_softc
*);
106 static int twe_intr(void *);
107 static int twe_match(device_t
, cfdata_t
, void *);
108 static int twe_param_set(struct twe_softc
*, int, int, size_t, void *);
109 static void twe_poll(struct twe_softc
*);
110 static int twe_print(void *, const char *);
111 static int twe_reset(struct twe_softc
*);
112 static int twe_status_check(struct twe_softc
*, u_int
);
113 static int twe_status_wait(struct twe_softc
*, u_int
, int);
114 static void twe_describe_controller(struct twe_softc
*);
115 static void twe_clear_pci_abort(struct twe_softc
*sc
);
116 static void twe_clear_pci_parity_error(struct twe_softc
*sc
);
118 static int twe_add_unit(struct twe_softc
*, int);
119 static int twe_del_unit(struct twe_softc
*, int);
120 static int twe_init_connection(struct twe_softc
*);
122 static inline u_int32_t
twe_inl(struct twe_softc
*, int);
123 static inline void twe_outl(struct twe_softc
*, int, u_int32_t
);
125 extern struct cfdriver twe_cd
;
127 CFATTACH_DECL(twe
, sizeof(struct twe_softc
),
128 twe_match
, twe_attach
, NULL
, NULL
);
130 /* FreeBSD driver revision for sysctl expected by the 3ware cli */
131 const char twever
[] = "1.50.01.002";
134 * Tables to convert numeric codes to strings.
136 const struct twe_code_table twe_table_status
[] = {
137 { 0x00, "successful completion" },
140 { 0x42, "command in progress" },
141 { 0x6c, "retrying interface CRC error from UDMA command" },
144 { 0x81, "redundant/inconsequential request ignored" },
145 { 0x8e, "failed to write zeroes to LBA 0" },
146 { 0x8f, "failed to profile TwinStor zones" },
149 { 0xc1, "aborted due to system command or reconfiguration" },
151 { 0xc5, "access error" },
152 { 0xc6, "access violation" },
153 { 0xc7, "device failure" }, /* high byte may be port # */
154 { 0xc8, "controller error" },
155 { 0xc9, "timed out" },
156 { 0xcb, "invalid unit number" },
157 { 0xcf, "unit not available" },
158 { 0xd2, "undefined opcode" },
159 { 0xdb, "request incompatible with unit" },
160 { 0xdc, "invalid request" },
161 { 0xff, "firmware error, reset requested" },
166 const struct twe_code_table twe_table_unitstate
[] = {
167 { TWE_PARAM_UNITSTATUS_Normal
, "Normal" },
168 { TWE_PARAM_UNITSTATUS_Initialising
, "Initializing" },
169 { TWE_PARAM_UNITSTATUS_Degraded
, "Degraded" },
170 { TWE_PARAM_UNITSTATUS_Rebuilding
, "Rebuilding" },
171 { TWE_PARAM_UNITSTATUS_Verifying
, "Verifying" },
172 { TWE_PARAM_UNITSTATUS_Corrupt
, "Corrupt" },
173 { TWE_PARAM_UNITSTATUS_Missing
, "Missing" },
178 const struct twe_code_table twe_table_unittype
[] = {
179 /* array descriptor configuration */
180 { TWE_AD_CONFIG_RAID0
, "RAID0" },
181 { TWE_AD_CONFIG_RAID1
, "RAID1" },
182 { TWE_AD_CONFIG_TwinStor
, "TwinStor" },
183 { TWE_AD_CONFIG_RAID5
, "RAID5" },
184 { TWE_AD_CONFIG_RAID10
, "RAID10" },
185 { TWE_UD_CONFIG_JBOD
, "JBOD" },
190 const struct twe_code_table twe_table_stripedepth
[] = {
191 { TWE_AD_STRIPE_4k
, "4K" },
192 { TWE_AD_STRIPE_8k
, "8K" },
193 { TWE_AD_STRIPE_16k
, "16K" },
194 { TWE_AD_STRIPE_32k
, "32K" },
195 { TWE_AD_STRIPE_64k
, "64K" },
196 { TWE_AD_STRIPE_128k
, "128K" },
197 { TWE_AD_STRIPE_256k
, "256K" },
198 { TWE_AD_STRIPE_512k
, "512K" },
199 { TWE_AD_STRIPE_1024k
, "1024K" },
205 * Asynchronous event notification messages are qualified:
206 * a - not unit/port specific
210 * They are further qualified with a severity:
219 * blank - just use printf
221 const struct twe_code_table twe_table_aen
[] = {
222 { 0x00, "a queue empty" },
223 { 0x01, "a soft reset" },
224 { 0x02, "uc degraded mode" },
225 { 0x03, "aa controller error" },
226 { 0x04, "uE rebuild fail" },
227 { 0x05, "un rebuild done" },
228 { 0x06, "ue incomplete unit" },
229 { 0x07, "un initialization done" },
230 { 0x08, "uw unclean shutdown detected" },
231 { 0x09, "pe drive timeout" },
232 { 0x0a, "pc drive error" },
233 { 0x0b, "un rebuild started" },
234 { 0x0c, "un initialization started" },
235 { 0x0d, "ui logical unit deleted" },
236 { 0x0f, "pc SMART threshold exceeded" },
237 { 0x15, "a table undefined" }, /* XXX: Not in FreeBSD's table */
238 { 0x21, "pe ATA UDMA downgrade" },
239 { 0x22, "pi ATA UDMA upgrade" },
240 { 0x23, "pw sector repair occurred" },
241 { 0x24, "aa SBUF integrity check failure" },
242 { 0x25, "pa lost cached write" },
243 { 0x26, "pa drive ECC error detected" },
244 { 0x27, "pe DCB checksum error" },
245 { 0x28, "pn DCB unsupported version" },
246 { 0x29, "ui verify started" },
247 { 0x2a, "ua verify failed" },
248 { 0x2b, "ui verify complete" },
249 { 0x2c, "pw overwrote bad sector during rebuild" },
250 { 0x2d, "pa encountered bad sector during rebuild" },
251 { 0x2e, "pe replacement drive too small" },
252 { 0x2f, "ue array not previously initialized" },
253 { 0x30, "p drive not supported" },
254 { 0xff, "a aen queue full" },
260 twe_describe_code(const struct twe_code_table
*table
, uint32_t code
)
263 for (; table
->string
!= NULL
; table
++) {
264 if (table
->code
== code
)
265 return (table
->string
);
270 static inline u_int32_t
271 twe_inl(struct twe_softc
*sc
, int off
)
274 bus_space_barrier(sc
->sc_iot
, sc
->sc_ioh
, off
, 4,
275 BUS_SPACE_BARRIER_WRITE
| BUS_SPACE_BARRIER_READ
);
276 return (bus_space_read_4(sc
->sc_iot
, sc
->sc_ioh
, off
));
280 twe_outl(struct twe_softc
*sc
, int off
, u_int32_t val
)
283 bus_space_write_4(sc
->sc_iot
, sc
->sc_ioh
, off
, val
);
284 bus_space_barrier(sc
->sc_iot
, sc
->sc_ioh
, off
, 4,
285 BUS_SPACE_BARRIER_WRITE
);
289 * Match a supported board.
292 twe_match(device_t parent
, cfdata_t cfdata
, void *aux
)
294 struct pci_attach_args
*pa
;
298 return (PCI_VENDOR(pa
->pa_id
) == PCI_VENDOR_3WARE
&&
299 (PCI_PRODUCT(pa
->pa_id
) == PCI_PRODUCT_3WARE_ESCALADE
||
300 PCI_PRODUCT(pa
->pa_id
) == PCI_PRODUCT_3WARE_ESCALADE_ASIC
));
304 * Attach a supported board.
306 * XXX This doesn't fail gracefully.
309 twe_attach(device_t parent
, device_t self
, void *aux
)
311 struct pci_attach_args
*pa
;
312 struct twe_softc
*sc
;
313 pci_chipset_tag_t pc
;
314 pci_intr_handle_t ih
;
317 int s
, size
, i
, rv
, rseg
;
318 size_t max_segs
, max_xfer
;
319 bus_dma_segment_t seg
;
320 struct ctlname ctlnames
[] = CTL_NAMES
;
321 const struct sysctlnode
*node
;
325 sc
= device_private(self
);
328 sc
->sc_dmat
= pa
->pa_dmat
;
329 SIMPLEQ_INIT(&sc
->sc_ccb_queue
);
330 SLIST_INIT(&sc
->sc_ccb_freelist
);
332 aprint_naive(": RAID controller\n");
333 aprint_normal(": 3ware Escalade\n");
336 if (pci_mapreg_map(pa
, PCI_CBIO
, PCI_MAPREG_TYPE_IO
, 0,
337 &sc
->sc_iot
, &sc
->sc_ioh
, NULL
, NULL
)) {
338 aprint_error_dev(&sc
->sc_dv
, "can't map i/o space\n");
342 /* Enable the device. */
343 csr
= pci_conf_read(pa
->pa_pc
, pa
->pa_tag
, PCI_COMMAND_STATUS_REG
);
344 pci_conf_write(pa
->pa_pc
, pa
->pa_tag
, PCI_COMMAND_STATUS_REG
,
345 csr
| PCI_COMMAND_MASTER_ENABLE
);
347 /* Map and establish the interrupt. */
348 if (pci_intr_map(pa
, &ih
)) {
349 aprint_error_dev(&sc
->sc_dv
, "can't map interrupt\n");
353 intrstr
= pci_intr_string(pc
, ih
);
354 sc
->sc_ih
= pci_intr_establish(pc
, ih
, IPL_BIO
, twe_intr
, sc
);
355 if (sc
->sc_ih
== NULL
) {
356 aprint_error_dev(&sc
->sc_dv
, "can't establish interrupt%s%s\n",
357 (intrstr
) ? " at " : "",
358 (intrstr
) ? intrstr
: "");
363 aprint_normal_dev(&sc
->sc_dv
, "interrupting at %s\n",
367 * Allocate and initialise the command blocks and CCBs.
369 size
= sizeof(struct twe_cmd
) * TWE_MAX_QUEUECNT
;
371 if ((rv
= bus_dmamem_alloc(sc
->sc_dmat
, size
, PAGE_SIZE
, 0, &seg
, 1,
372 &rseg
, BUS_DMA_NOWAIT
)) != 0) {
373 aprint_error_dev(&sc
->sc_dv
, "unable to allocate commands, rv = %d\n", rv
);
377 if ((rv
= bus_dmamem_map(sc
->sc_dmat
, &seg
, rseg
, size
,
378 (void **)&sc
->sc_cmds
,
379 BUS_DMA_NOWAIT
| BUS_DMA_COHERENT
)) != 0) {
380 aprint_error_dev(&sc
->sc_dv
, "unable to map commands, rv = %d\n", rv
);
384 if ((rv
= bus_dmamap_create(sc
->sc_dmat
, size
, size
, 1, 0,
385 BUS_DMA_NOWAIT
, &sc
->sc_dmamap
)) != 0) {
386 aprint_error_dev(&sc
->sc_dv
, "unable to create command DMA map, rv = %d\n", rv
);
390 if ((rv
= bus_dmamap_load(sc
->sc_dmat
, sc
->sc_dmamap
, sc
->sc_cmds
,
391 size
, NULL
, BUS_DMA_NOWAIT
)) != 0) {
392 aprint_error_dev(&sc
->sc_dv
, "unable to load command DMA map, rv = %d\n", rv
);
396 ccb
= malloc(sizeof(*ccb
) * TWE_MAX_QUEUECNT
, M_DEVBUF
, M_NOWAIT
);
398 aprint_error_dev(&sc
->sc_dv
, "unable to allocate memory for ccbs\n");
402 sc
->sc_cmds_paddr
= sc
->sc_dmamap
->dm_segs
[0].ds_addr
;
403 memset(sc
->sc_cmds
, 0, size
);
406 tc
= (struct twe_cmd
*)sc
->sc_cmds
;
407 max_segs
= twe_get_maxsegs();
408 max_xfer
= twe_get_maxxfer(max_segs
);
410 for (i
= 0; i
< TWE_MAX_QUEUECNT
; i
++, tc
++, ccb
++) {
414 rv
= bus_dmamap_create(sc
->sc_dmat
, max_xfer
,
415 max_segs
, PAGE_SIZE
, 0,
416 BUS_DMA_NOWAIT
| BUS_DMA_ALLOCNOW
,
417 &ccb
->ccb_dmamap_xfer
);
419 aprint_error_dev(&sc
->sc_dv
, "can't create dmamap, rv = %d\n", rv
);
423 /* Save the first CCB for AEN retrieval. */
425 SLIST_INSERT_HEAD(&sc
->sc_ccb_freelist
, ccb
,
429 /* Wait for the controller to become ready. */
430 if (twe_status_wait(sc
, TWE_STS_MICROCONTROLLER_READY
, 6)) {
431 aprint_error_dev(&sc
->sc_dv
, "microcontroller not ready\n");
435 twe_outl(sc
, TWE_REG_CTL
, TWE_CTL_DISABLE_INTRS
);
437 /* Reset the controller. */
442 aprint_error_dev(&sc
->sc_dv
, "reset failed\n");
446 /* Initialise connection with controller. */
447 twe_init_connection(sc
);
449 twe_describe_controller(sc
);
451 /* Find and attach RAID array units. */
453 for (i
= 0; i
< TWE_MAX_UNITS
; i
++)
454 (void) twe_add_unit(sc
, i
);
456 /* ...and finally, enable interrupts. */
457 twe_outl(sc
, TWE_REG_CTL
, TWE_CTL_CLEAR_ATTN_INTR
|
458 TWE_CTL_UNMASK_RESP_INTR
|
459 TWE_CTL_ENABLE_INTRS
);
461 /* sysctl set-up for 3ware cli */
462 if (sysctl_createv(NULL
, 0, NULL
, NULL
,
463 CTLFLAG_PERMANENT
, CTLTYPE_NODE
, "hw",
464 NULL
, NULL
, 0, NULL
, 0,
465 CTL_HW
, CTL_EOL
) != 0) {
466 aprint_error_dev(&sc
->sc_dv
, "could not create %s sysctl node\n",
467 ctlnames
[CTL_HW
].ctl_name
);
470 if (sysctl_createv(NULL
, 0, NULL
, &node
,
471 0, CTLTYPE_NODE
, device_xname(&sc
->sc_dv
),
472 SYSCTL_DESCR("twe driver information"),
474 CTL_HW
, CTL_CREATE
, CTL_EOL
) != 0) {
475 aprint_error_dev(&sc
->sc_dv
, "could not create %s.%s sysctl node\n",
476 ctlnames
[CTL_HW
].ctl_name
, device_xname(&sc
->sc_dv
));
479 if ((i
= sysctl_createv(NULL
, 0, NULL
, NULL
,
480 0, CTLTYPE_STRING
, "driver_version",
481 SYSCTL_DESCR("twe0 driver version"),
483 CTL_HW
, node
->sysctl_num
, CTL_CREATE
, CTL_EOL
))
485 aprint_error_dev(&sc
->sc_dv
, "could not create %s.%s.driver_version sysctl\n",
486 ctlnames
[CTL_HW
].ctl_name
, device_xname(&sc
->sc_dv
));
492 twe_register_callbacks(struct twe_softc
*sc
, int unit
,
493 const struct twe_callbacks
*tcb
)
496 sc
->sc_units
[unit
].td_callbacks
= tcb
;
500 twe_recompute_openings(struct twe_softc
*sc
)
502 struct twe_drive
*td
;
505 if (sc
->sc_nunits
!= 0)
506 openings
= (TWE_MAX_QUEUECNT
- 1) / sc
->sc_nunits
;
509 if (openings
== sc
->sc_openings
)
511 sc
->sc_openings
= openings
;
514 printf("%s: %d array%s, %d openings per array\n",
515 device_xname(&sc
->sc_dv
), sc
->sc_nunits
,
516 sc
->sc_nunits
== 1 ? "" : "s", sc
->sc_openings
);
519 for (unit
= 0; unit
< TWE_MAX_UNITS
; unit
++) {
520 td
= &sc
->sc_units
[unit
];
521 if (td
->td_dev
!= NULL
)
522 (*td
->td_callbacks
->tcb_openings
)(td
->td_dev
,
528 twe_add_unit(struct twe_softc
*sc
, int unit
)
530 struct twe_param
*dtp
, *atp
;
531 struct twe_array_descriptor
*ad
;
532 struct twe_drive
*td
;
533 struct twe_attach_args twea
;
537 uint8_t newtype
, newstripe
;
538 int locs
[TWECF_NLOCS
];
540 if (unit
< 0 || unit
>= TWE_MAX_UNITS
)
543 /* Find attached units. */
544 rv
= twe_param_get(sc
, TWE_PARAM_UNITSUMMARY
,
545 TWE_PARAM_UNITSUMMARY_Status
, TWE_MAX_UNITS
, NULL
, &dtp
);
547 aprint_error_dev(&sc
->sc_dv
, "error %d fetching unit summary\n",
552 /* For each detected unit, collect size and store in an array. */
553 td
= &sc
->sc_units
[unit
];
556 if ((dtp
->tp_data
[unit
] & TWE_PARAM_UNITSTATUS_Online
) == 0) {
558 * XXX Should we check to see if a device has been
559 * XXX attached at this index and detach it if it
560 * XXX has? ("rescan" semantics)
566 rv
= twe_param_get_2(sc
, TWE_PARAM_UNITINFO
+ unit
,
567 TWE_PARAM_UNITINFO_DescriptorSize
, &dsize
);
569 aprint_error_dev(&sc
->sc_dv
, "error %d fetching descriptor size "
570 "for unit %d\n", rv
, unit
);
574 rv
= twe_param_get(sc
, TWE_PARAM_UNITINFO
+ unit
,
575 TWE_PARAM_UNITINFO_Descriptor
, dsize
- 3, NULL
, &atp
);
577 aprint_error_dev(&sc
->sc_dv
, "error %d fetching array descriptor "
578 "for unit %d\n", rv
, unit
);
582 ad
= (struct twe_array_descriptor
*)atp
->tp_data
;
583 newtype
= ad
->configuration
;
584 newstripe
= ad
->stripe_size
;
587 rv
= twe_param_get_4(sc
, TWE_PARAM_UNITINFO
+ unit
,
588 TWE_PARAM_UNITINFO_Capacity
, &newsize
);
590 aprint_error_dev(&sc
->sc_dv
,
591 "error %d fetching capacity for unit %d\n",
597 * Have a device, so we need to attach it. If there is currently
598 * something sitting at the slot, and the parameters are different,
599 * then we detach the old device before attaching the new one.
601 if (td
->td_dev
!= NULL
&&
602 td
->td_size
== newsize
&&
603 td
->td_type
== newtype
&&
604 td
->td_stripe
== newstripe
) {
605 /* Same as the old device; just keep using it. */
608 } else if (td
->td_dev
!= NULL
) {
609 /* Detach the old device first. */
610 (void) config_detach(td
->td_dev
, DETACH_FORCE
);
612 } else if (td
->td_size
== 0)
616 * Committed to the new array unit; assign its parameters and
617 * recompute the number of available command openings.
619 td
->td_size
= newsize
;
620 td
->td_type
= newtype
;
621 td
->td_stripe
= newstripe
;
622 twe_recompute_openings(sc
);
624 twea
.twea_unit
= unit
;
626 locs
[TWECF_UNIT
] = unit
;
628 td
->td_dev
= config_found_sm_loc(&sc
->sc_dv
, "twe", locs
, &twea
,
629 twe_print
, config_stdsubmatch
);
638 twe_del_unit(struct twe_softc
*sc
, int unit
)
640 struct twe_drive
*td
;
642 if (unit
< 0 || unit
>= TWE_MAX_UNITS
)
645 td
= &sc
->sc_units
[unit
];
646 if (td
->td_size
!= 0)
651 if (td
->td_dev
!= NULL
) {
652 (void) config_detach(td
->td_dev
, DETACH_FORCE
);
655 twe_recompute_openings(sc
);
660 * Reset the controller.
661 * MUST BE CALLED AT splbio()!
664 twe_reset(struct twe_softc
*sc
)
668 volatile u_int32_t junk
;
671 /* Issue a soft reset. */
672 twe_outl(sc
, TWE_REG_CTL
, TWE_CTL_ISSUE_SOFT_RESET
|
673 TWE_CTL_CLEAR_HOST_INTR
|
674 TWE_CTL_CLEAR_ATTN_INTR
|
675 TWE_CTL_MASK_CMD_INTR
|
676 TWE_CTL_MASK_RESP_INTR
|
677 TWE_CTL_CLEAR_ERROR_STS
|
678 TWE_CTL_DISABLE_INTRS
);
680 /* Wait for attention... */
681 if (twe_status_wait(sc
, TWE_STS_ATTN_INTR
, 30)) {
682 aprint_error_dev(&sc
->sc_dv
, "timeout waiting for attention interrupt\n");
687 twe_outl(sc
, TWE_REG_CTL
, TWE_CTL_CLEAR_ATTN_INTR
);
690 * Pull AENs out of the controller; look for a soft reset AEN.
691 * Open code this, since we want to detect reset even if the
692 * queue for management tools is full.
695 * - interrupts are blocked
696 * - we have reset the controller
697 * - acknowledged the pending ATTENTION
698 * that there is no way a pending asynchronous AEN fetch would
699 * finish, so clear the flag.
701 sc
->sc_flags
&= ~TWEF_AEN
;
703 rv
= twe_aen_get(sc
, &aen
);
705 printf("%s: error %d while draining event queue\n",
706 device_xname(&sc
->sc_dv
), rv
);
707 if (TWE_AEN_CODE(aen
) == TWE_AEN_QUEUE_EMPTY
)
709 if (TWE_AEN_CODE(aen
) == TWE_AEN_SOFT_RESET
)
711 twe_aen_enqueue(sc
, aen
, 1);
715 printf("%s: reset not reported\n", device_xname(&sc
->sc_dv
));
719 /* Check controller status. */
720 status
= twe_inl(sc
, TWE_REG_STS
);
721 if (twe_status_check(sc
, status
)) {
722 printf("%s: controller errors detected\n",
723 device_xname(&sc
->sc_dv
));
727 /* Drain the response queue. */
729 status
= twe_inl(sc
, TWE_REG_STS
);
730 if (twe_status_check(sc
, status
) != 0) {
731 aprint_error_dev(&sc
->sc_dv
, "can't drain response queue\n");
734 if ((status
& TWE_STS_RESP_QUEUE_EMPTY
) != 0)
736 junk
= twe_inl(sc
, TWE_REG_RESP_QUEUE
);
743 * Print autoconfiguration message for a sub-device.
746 twe_print(void *aux
, const char *pnp
)
748 struct twe_attach_args
*twea
;
753 aprint_normal("block device at %s", pnp
);
754 aprint_normal(" unit %d", twea
->twea_unit
);
759 * Interrupt service routine.
764 struct twe_softc
*sc
;
770 status
= twe_inl(sc
, TWE_REG_STS
);
771 twe_status_check(sc
, status
);
773 /* Host interrupts - purpose unknown. */
774 if ((status
& TWE_STS_HOST_INTR
) != 0) {
776 printf("%s: host interrupt\n", device_xname(&sc
->sc_dv
));
778 twe_outl(sc
, TWE_REG_CTL
, TWE_CTL_CLEAR_HOST_INTR
);
783 * Attention interrupts, signalled when a controller or child device
784 * state change has occurred.
786 if ((status
& TWE_STS_ATTN_INTR
) != 0) {
787 rv
= twe_aen_get(sc
, NULL
);
789 aprint_error_dev(&sc
->sc_dv
, "unable to retrieve AEN (%d)\n", rv
);
791 twe_outl(sc
, TWE_REG_CTL
, TWE_CTL_CLEAR_ATTN_INTR
);
796 * Command interrupts, signalled when the controller can accept more
797 * commands. We don't use this; instead, we try to submit commands
798 * when we receive them, and when other commands have completed.
799 * Mask it so we don't get another one.
801 if ((status
& TWE_STS_CMD_INTR
) != 0) {
803 printf("%s: command interrupt\n", device_xname(&sc
->sc_dv
));
805 twe_outl(sc
, TWE_REG_CTL
, TWE_CTL_MASK_CMD_INTR
);
809 if ((status
& TWE_STS_RESP_INTR
) != 0) {
818 * Fetch an AEN. Even though this is really like parameter
819 * retrieval, we handle this specially, because we issue this
820 * AEN retrieval command from interrupt context, and thus
821 * reserve a CCB for it to avoid resource shortage.
823 * XXX There are still potential resource shortages we could
824 * XXX encounter. Consider pre-allocating all AEN-related
827 * MUST BE CALLED AT splbio()!
830 twe_aen_get(struct twe_softc
*sc
, uint16_t *aenp
)
834 struct twe_param
*tp
;
838 * If we're already retrieving an AEN, just wait; another
839 * retrieval will be chained after the current one completes.
841 if (sc
->sc_flags
& TWEF_AEN
) {
843 * It is a fatal software programming error to attempt
844 * to fetch an AEN synchronously when an AEN fetch is
847 KASSERT(aenp
== NULL
);
851 tp
= malloc(TWE_SECTOR_SIZE
, M_DEVBUF
, M_NOWAIT
);
855 ccb
= twe_ccb_alloc(sc
,
856 TWE_CCB_AEN
| TWE_CCB_DATA_IN
| TWE_CCB_DATA_OUT
);
857 KASSERT(ccb
!= NULL
);
860 ccb
->ccb_datasize
= TWE_SECTOR_SIZE
;
861 ccb
->ccb_tx
.tx_handler
= (aenp
== NULL
) ? twe_aen_handler
: NULL
;
862 ccb
->ccb_tx
.tx_context
= tp
;
863 ccb
->ccb_tx
.tx_dv
= &sc
->sc_dv
;
867 tc
->tc_opcode
= TWE_OP_GET_PARAM
| (tc
->tc_size
<< 5);
869 tc
->tc_count
= htole16(1);
871 /* Fill in the outbound parameter data. */
872 tp
->tp_table_id
= htole16(TWE_PARAM_AEN
);
873 tp
->tp_param_id
= TWE_PARAM_AEN_UnitCode
;
874 tp
->tp_param_size
= 2;
876 /* Map the transfer. */
877 if ((rv
= twe_ccb_map(sc
, ccb
)) != 0) {
878 twe_ccb_free(sc
, ccb
);
882 /* Enqueue the command and wait. */
884 rv
= twe_ccb_poll(sc
, ccb
, 5);
885 twe_ccb_unmap(sc
, ccb
);
886 twe_ccb_free(sc
, ccb
);
888 *aenp
= le16toh(*(uint16_t *)tp
->tp_data
);
891 sc
->sc_flags
|= TWEF_AEN
;
892 twe_ccb_enqueue(sc
, ccb
);
901 * Handle an AEN returned by the controller.
902 * MUST BE CALLED AT splbio()!
905 twe_aen_handler(struct twe_ccb
*ccb
, int error
)
907 struct twe_softc
*sc
;
908 struct twe_param
*tp
;
912 sc
= device_private(ccb
->ccb_tx
.tx_dv
);
913 tp
= ccb
->ccb_tx
.tx_context
;
914 twe_ccb_unmap(sc
, ccb
);
916 sc
->sc_flags
&= ~TWEF_AEN
;
919 aprint_error_dev(&sc
->sc_dv
, "error retrieving AEN\n");
920 aen
= TWE_AEN_QUEUE_EMPTY
;
922 aen
= le16toh(*(u_int16_t
*)tp
->tp_data
);
924 twe_ccb_free(sc
, ccb
);
926 if (TWE_AEN_CODE(aen
) == TWE_AEN_QUEUE_EMPTY
) {
927 twe_outl(sc
, TWE_REG_CTL
, TWE_CTL_CLEAR_ATTN_INTR
);
931 twe_aen_enqueue(sc
, aen
, 0);
934 * Chain another retrieval in case interrupts have been
937 rv
= twe_aen_get(sc
, NULL
);
939 aprint_error_dev(&sc
->sc_dv
, "unable to retrieve AEN (%d)\n", rv
);
943 twe_aen_enqueue(struct twe_softc
*sc
, uint16_t aen
, int quiet
)
945 const char *str
, *msg
;
946 int s
, next
, nextnext
, level
;
949 * First report the AEN on the console. Maybe.
952 str
= twe_describe_code(twe_table_aen
, TWE_AEN_CODE(aen
));
954 aprint_error_dev(&sc
->sc_dv
, "unknown AEN 0x%04x\n", aen
);
958 case 'E': level
= LOG_EMERG
; break;
959 case 'a': level
= LOG_ALERT
; break;
960 case 'c': level
= LOG_CRIT
; break;
961 case 'e': level
= LOG_ERR
; break;
962 case 'w': level
= LOG_WARNING
; break;
963 case 'n': level
= LOG_NOTICE
; break;
964 case 'i': level
= LOG_INFO
; break;
965 case 'd': level
= LOG_DEBUG
; break;
967 /* Don't use syslog. */
975 printf("%s: %s %d: %s\n",
976 device_xname(&sc
->sc_dv
),
977 str
[0] == 'u' ? "unit" : "port",
978 TWE_AEN_UNIT(aen
), msg
);
983 device_xname(&sc
->sc_dv
), msg
);
989 log(level
, "%s: %s %d: %s\n",
990 device_xname(&sc
->sc_dv
),
991 str
[0] == 'u' ? "unit" : "port",
992 TWE_AEN_UNIT(aen
), msg
);
996 log(level
, "%s: %s\n",
997 device_xname(&sc
->sc_dv
), msg
);
1003 /* Now enqueue the AEN for mangement tools. */
1006 next
= (sc
->sc_aen_head
+ 1) % TWE_AEN_Q_LENGTH
;
1007 nextnext
= (sc
->sc_aen_head
+ 2) % TWE_AEN_Q_LENGTH
;
1010 * If this is the last free slot, then queue up a "queue
1013 if (nextnext
== sc
->sc_aen_tail
)
1014 aen
= TWE_AEN_QUEUE_FULL
;
1016 if (next
!= sc
->sc_aen_tail
) {
1017 sc
->sc_aen_queue
[sc
->sc_aen_head
] = aen
;
1018 sc
->sc_aen_head
= next
;
1021 if (sc
->sc_flags
& TWEF_AENQ_WAIT
) {
1022 sc
->sc_flags
&= ~TWEF_AENQ_WAIT
;
1023 wakeup(&sc
->sc_aen_queue
);
1029 /* NOTE: Must be called at splbio(). */
1031 twe_aen_dequeue(struct twe_softc
*sc
)
1035 if (sc
->sc_aen_tail
== sc
->sc_aen_head
)
1036 aen
= TWE_AEN_QUEUE_EMPTY
;
1038 aen
= sc
->sc_aen_queue
[sc
->sc_aen_tail
];
1039 sc
->sc_aen_tail
= (sc
->sc_aen_tail
+ 1) % TWE_AEN_Q_LENGTH
;
1046 * These are short-hand functions that execute TWE_OP_GET_PARAM to
1047 * fetch 1, 2, and 4 byte parameter values, respectively.
1050 twe_param_get_1(struct twe_softc
*sc
, int table_id
, int param_id
,
1053 struct twe_param
*tp
;
1056 rv
= twe_param_get(sc
, table_id
, param_id
, 1, NULL
, &tp
);
1059 *valp
= *(uint8_t *)tp
->tp_data
;
1065 twe_param_get_2(struct twe_softc
*sc
, int table_id
, int param_id
,
1068 struct twe_param
*tp
;
1071 rv
= twe_param_get(sc
, table_id
, param_id
, 2, NULL
, &tp
);
1074 *valp
= le16toh(*(uint16_t *)tp
->tp_data
);
1080 twe_param_get_4(struct twe_softc
*sc
, int table_id
, int param_id
,
1083 struct twe_param
*tp
;
1086 rv
= twe_param_get(sc
, table_id
, param_id
, 4, NULL
, &tp
);
1089 *valp
= le32toh(*(uint32_t *)tp
->tp_data
);
1095 * Execute a TWE_OP_GET_PARAM command. If a callback function is provided,
1096 * it will be called with generated context when the command has completed.
1097 * If no callback is provided, the command will be executed synchronously
1098 * and a pointer to a buffer containing the data returned.
1100 * The caller or callback is responsible for freeing the buffer.
1102 * NOTE: We assume we can sleep here to wait for a CCB to become available.
1105 twe_param_get(struct twe_softc
*sc
, int table_id
, int param_id
, size_t size
,
1106 void (*func
)(struct twe_ccb
*, int), struct twe_param
**pbuf
)
1108 struct twe_ccb
*ccb
;
1110 struct twe_param
*tp
;
1113 tp
= malloc(TWE_SECTOR_SIZE
, M_DEVBUF
, M_NOWAIT
);
1117 ccb
= twe_ccb_alloc_wait(sc
, TWE_CCB_DATA_IN
| TWE_CCB_DATA_OUT
);
1118 KASSERT(ccb
!= NULL
);
1121 ccb
->ccb_datasize
= TWE_SECTOR_SIZE
;
1122 ccb
->ccb_tx
.tx_handler
= func
;
1123 ccb
->ccb_tx
.tx_context
= tp
;
1124 ccb
->ccb_tx
.tx_dv
= &sc
->sc_dv
;
1128 tc
->tc_opcode
= TWE_OP_GET_PARAM
| (tc
->tc_size
<< 5);
1130 tc
->tc_count
= htole16(1);
1132 /* Fill in the outbound parameter data. */
1133 tp
->tp_table_id
= htole16(table_id
);
1134 tp
->tp_param_id
= param_id
;
1135 tp
->tp_param_size
= size
;
1137 /* Map the transfer. */
1138 if ((rv
= twe_ccb_map(sc
, ccb
)) != 0) {
1139 twe_ccb_free(sc
, ccb
);
1143 /* Submit the command and either wait or let the callback handle it. */
1146 rv
= twe_ccb_poll(sc
, ccb
, 5);
1147 twe_ccb_unmap(sc
, ccb
);
1148 twe_ccb_free(sc
, ccb
);
1153 panic("both func and pbuf defined");
1155 twe_ccb_enqueue(sc
, ccb
);
1160 if (pbuf
== NULL
|| rv
!= 0)
1162 else if (pbuf
!= NULL
&& rv
== 0)
1168 * Execute a TWE_OP_SET_PARAM command.
1170 * NOTE: We assume we can sleep here to wait for a CCB to become available.
1173 twe_param_set(struct twe_softc
*sc
, int table_id
, int param_id
, size_t size
,
1176 struct twe_ccb
*ccb
;
1178 struct twe_param
*tp
;
1181 tp
= malloc(TWE_SECTOR_SIZE
, M_DEVBUF
, M_NOWAIT
);
1185 ccb
= twe_ccb_alloc_wait(sc
, TWE_CCB_DATA_IN
| TWE_CCB_DATA_OUT
);
1186 KASSERT(ccb
!= NULL
);
1189 ccb
->ccb_datasize
= TWE_SECTOR_SIZE
;
1190 ccb
->ccb_tx
.tx_handler
= 0;
1191 ccb
->ccb_tx
.tx_context
= tp
;
1192 ccb
->ccb_tx
.tx_dv
= &sc
->sc_dv
;
1196 tc
->tc_opcode
= TWE_OP_SET_PARAM
| (tc
->tc_size
<< 5);
1198 tc
->tc_count
= htole16(1);
1200 /* Fill in the outbound parameter data. */
1201 tp
->tp_table_id
= htole16(table_id
);
1202 tp
->tp_param_id
= param_id
;
1203 tp
->tp_param_size
= size
;
1204 memcpy(tp
->tp_data
, sbuf
, size
);
1206 /* Map the transfer. */
1207 if ((rv
= twe_ccb_map(sc
, ccb
)) != 0) {
1208 twe_ccb_free(sc
, ccb
);
1212 /* Submit the command and wait. */
1214 rv
= twe_ccb_poll(sc
, ccb
, 5);
1215 twe_ccb_unmap(sc
, ccb
);
1216 twe_ccb_free(sc
, ccb
);
1224 * Execute a TWE_OP_INIT_CONNECTION command. Return non-zero on error.
1225 * Must be called with interrupts blocked.
1228 twe_init_connection(struct twe_softc
*sc
)
1230 struct twe_ccb
*ccb
;
1234 if ((ccb
= twe_ccb_alloc(sc
, 0)) == NULL
)
1237 /* Build the command. */
1240 tc
->tc_opcode
= TWE_OP_INIT_CONNECTION
;
1242 tc
->tc_count
= htole16(TWE_MAX_CMDS
);
1243 tc
->tc_args
.init_connection
.response_queue_pointer
= 0;
1245 /* Submit the command for immediate execution. */
1246 rv
= twe_ccb_poll(sc
, ccb
, 5);
1247 twe_ccb_free(sc
, ccb
);
1252 * Poll the controller for completed commands. Must be called with
1253 * interrupts blocked.
1256 twe_poll(struct twe_softc
*sc
)
1258 struct twe_ccb
*ccb
;
1260 u_int status
, cmdid
;
1265 status
= twe_inl(sc
, TWE_REG_STS
);
1266 twe_status_check(sc
, status
);
1268 if ((status
& TWE_STS_RESP_QUEUE_EMPTY
))
1272 cmdid
= twe_inl(sc
, TWE_REG_RESP_QUEUE
);
1273 cmdid
= (cmdid
& TWE_RESP_MASK
) >> TWE_RESP_SHIFT
;
1274 if (cmdid
>= TWE_MAX_QUEUECNT
) {
1275 aprint_error_dev(&sc
->sc_dv
, "bad cmdid %d\n", cmdid
);
1279 ccb
= sc
->sc_ccbs
+ cmdid
;
1280 if ((ccb
->ccb_flags
& TWE_CCB_ACTIVE
) == 0) {
1281 printf("%s: CCB for cmdid %d not active\n",
1282 device_xname(&sc
->sc_dv
), cmdid
);
1285 ccb
->ccb_flags
^= TWE_CCB_COMPLETE
| TWE_CCB_ACTIVE
;
1287 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_dmamap
,
1288 (char *)ccb
->ccb_cmd
- (char *)sc
->sc_cmds
,
1289 sizeof(struct twe_cmd
),
1290 BUS_DMASYNC_POSTREAD
| BUS_DMASYNC_POSTWRITE
);
1292 /* Pass notification to upper layers. */
1293 if (ccb
->ccb_tx
.tx_handler
!= NULL
)
1294 (*ccb
->ccb_tx
.tx_handler
)(ccb
,
1295 ccb
->ccb_cmd
->tc_status
!= 0 ? EIO
: 0);
1298 /* If any commands have completed, run the software queue. */
1300 twe_ccb_enqueue(sc
, NULL
);
1304 * Wait for `status' to be set in the controller status register. Return
1305 * zero if found, non-zero if the operation timed out.
1308 twe_status_wait(struct twe_softc
*sc
, u_int32_t status
, int timo
)
1311 for (timo
*= 10; timo
!= 0; timo
--) {
1312 if ((twe_inl(sc
, TWE_REG_STS
) & status
) == status
)
1321 * Clear a PCI parity error.
1324 twe_clear_pci_parity_error(struct twe_softc
*sc
)
1326 bus_space_write_4(sc
->sc_iot
, sc
->sc_ioh
, 0x0, TWE_CTL_CLEAR_PARITY_ERROR
);
1328 //FreeBSD: pci_write_config(sc->twe_dev, PCIR_STATUS, TWE_PCI_CLEAR_PARITY_ERROR, 2);
1333 * Clear a PCI abort.
1336 twe_clear_pci_abort(struct twe_softc
*sc
)
1338 bus_space_write_4(sc
->sc_iot
, sc
->sc_ioh
, 0x0, TWE_CTL_CLEAR_PCI_ABORT
);
1340 //FreeBSD: pci_write_config(sc->twe_dev, PCIR_STATUS, TWE_PCI_CLEAR_PCI_ABORT, 2);
1344 * Complain if the status bits aren't what we expect.
1347 twe_status_check(struct twe_softc
*sc
, u_int status
)
1353 if ((status
& TWE_STS_EXPECTED_BITS
) != TWE_STS_EXPECTED_BITS
) {
1354 aprint_error_dev(&sc
->sc_dv
, "missing status bits: 0x%08x\n",
1355 status
& ~TWE_STS_EXPECTED_BITS
);
1359 if ((status
& TWE_STS_UNEXPECTED_BITS
) != 0) {
1360 aprint_error_dev(&sc
->sc_dv
, "unexpected status bits: 0x%08x\n",
1361 status
& TWE_STS_UNEXPECTED_BITS
);
1363 if (status
& TWE_STS_PCI_PARITY_ERROR
) {
1364 aprint_error_dev(&sc
->sc_dv
, "PCI parity error: Reseat card, move card "
1365 "or buggy device present.\n");
1366 twe_clear_pci_parity_error(sc
);
1368 if (status
& TWE_STS_PCI_ABORT
) {
1369 aprint_error_dev(&sc
->sc_dv
, "PCI abort, clearing.\n");
1370 twe_clear_pci_abort(sc
);
1378 * Allocate and initialise a CCB.
1381 twe_ccb_init(struct twe_softc
*sc
, struct twe_ccb
*ccb
, int flags
)
1385 ccb
->ccb_tx
.tx_handler
= NULL
;
1386 ccb
->ccb_flags
= flags
;
1390 tc
->tc_cmdid
= ccb
->ccb_cmdid
;
1394 twe_ccb_alloc(struct twe_softc
*sc
, int flags
)
1396 struct twe_ccb
*ccb
;
1400 if (__predict_false((flags
& TWE_CCB_AEN
) != 0)) {
1401 /* Use the reserved CCB. */
1404 /* Allocate a CCB and command block. */
1405 if (__predict_false((ccb
=
1406 SLIST_FIRST(&sc
->sc_ccb_freelist
)) == NULL
)) {
1410 SLIST_REMOVE_HEAD(&sc
->sc_ccb_freelist
, ccb_chain
.slist
);
1413 if ((long)(ccb
- sc
->sc_ccbs
) == 0 && (flags
& TWE_CCB_AEN
) == 0)
1414 panic("twe_ccb_alloc: got reserved CCB for non-AEN");
1415 if ((ccb
->ccb_flags
& TWE_CCB_ALLOCED
) != 0)
1416 panic("twe_ccb_alloc: CCB %ld already allocated",
1417 (long)(ccb
- sc
->sc_ccbs
));
1418 flags
|= TWE_CCB_ALLOCED
;
1422 twe_ccb_init(sc
, ccb
, flags
);
1427 twe_ccb_alloc_wait(struct twe_softc
*sc
, int flags
)
1429 struct twe_ccb
*ccb
;
1432 KASSERT((flags
& TWE_CCB_AEN
) == 0);
1435 while (__predict_false((ccb
=
1436 SLIST_FIRST(&sc
->sc_ccb_freelist
)) == NULL
)) {
1437 sc
->sc_flags
|= TWEF_WAIT_CCB
;
1438 (void) tsleep(&sc
->sc_ccb_freelist
, PRIBIO
, "tweccb", 0);
1440 SLIST_REMOVE_HEAD(&sc
->sc_ccb_freelist
, ccb_chain
.slist
);
1442 if ((ccb
->ccb_flags
& TWE_CCB_ALLOCED
) != 0)
1443 panic("twe_ccb_alloc_wait: CCB %ld already allocated",
1444 (long)(ccb
- sc
->sc_ccbs
));
1445 flags
|= TWE_CCB_ALLOCED
;
1449 twe_ccb_init(sc
, ccb
, flags
);
1457 twe_ccb_free(struct twe_softc
*sc
, struct twe_ccb
*ccb
)
1462 if ((ccb
->ccb_flags
& TWE_CCB_AEN
) == 0) {
1463 SLIST_INSERT_HEAD(&sc
->sc_ccb_freelist
, ccb
, ccb_chain
.slist
);
1464 if (__predict_false((sc
->sc_flags
& TWEF_WAIT_CCB
) != 0)) {
1465 sc
->sc_flags
&= ~TWEF_WAIT_CCB
;
1466 wakeup(&sc
->sc_ccb_freelist
);
1474 * Map the specified CCB's command block and data buffer (if any) into
1475 * controller visible space. Perform DMA synchronisation.
1478 twe_ccb_map(struct twe_softc
*sc
, struct twe_ccb
*ccb
)
1481 int flags
, nsegs
, i
, s
, rv
;
1485 * The data as a whole must be 512-byte aligned.
1487 if (((u_long
)ccb
->ccb_data
& (TWE_ALIGNMENT
- 1)) != 0) {
1490 ccb
->ccb_abuf
= uvm_km_alloc(kmem_map
,
1491 ccb
->ccb_datasize
, 0, UVM_KMF_NOWAIT
|UVM_KMF_WIRED
);
1493 data
= (void *)ccb
->ccb_abuf
;
1494 if ((ccb
->ccb_flags
& TWE_CCB_DATA_OUT
) != 0)
1495 memcpy(data
, ccb
->ccb_data
, ccb
->ccb_datasize
);
1497 ccb
->ccb_abuf
= (vaddr_t
)0;
1498 data
= ccb
->ccb_data
;
1502 * Map the data buffer into bus space and build the S/G list.
1504 rv
= bus_dmamap_load(sc
->sc_dmat
, ccb
->ccb_dmamap_xfer
, data
,
1505 ccb
->ccb_datasize
, NULL
, BUS_DMA_NOWAIT
| BUS_DMA_STREAMING
|
1506 ((ccb
->ccb_flags
& TWE_CCB_DATA_IN
) ?
1507 BUS_DMA_READ
: BUS_DMA_WRITE
));
1509 if (ccb
->ccb_abuf
!= (vaddr_t
)0) {
1512 uvm_km_free(kmem_map
, ccb
->ccb_abuf
,
1513 ccb
->ccb_datasize
, UVM_KMF_WIRED
);
1519 nsegs
= ccb
->ccb_dmamap_xfer
->dm_nsegs
;
1521 tc
->tc_size
+= 2 * nsegs
;
1523 /* The location of the S/G list is dependant upon command type. */
1524 switch (tc
->tc_opcode
>> 5) {
1526 for (i
= 0; i
< nsegs
; i
++) {
1527 tc
->tc_args
.param
.sgl
[i
].tsg_address
=
1528 htole32(ccb
->ccb_dmamap_xfer
->dm_segs
[i
].ds_addr
);
1529 tc
->tc_args
.param
.sgl
[i
].tsg_length
=
1530 htole32(ccb
->ccb_dmamap_xfer
->dm_segs
[i
].ds_len
);
1533 for (; i
< TWE_SG_SIZE
; i
++) {
1534 tc
->tc_args
.param
.sgl
[i
].tsg_address
= 0;
1535 tc
->tc_args
.param
.sgl
[i
].tsg_length
= 0;
1539 for (i
= 0; i
< nsegs
; i
++) {
1540 tc
->tc_args
.io
.sgl
[i
].tsg_address
=
1541 htole32(ccb
->ccb_dmamap_xfer
->dm_segs
[i
].ds_addr
);
1542 tc
->tc_args
.io
.sgl
[i
].tsg_length
=
1543 htole32(ccb
->ccb_dmamap_xfer
->dm_segs
[i
].ds_len
);
1546 for (; i
< TWE_SG_SIZE
; i
++) {
1547 tc
->tc_args
.io
.sgl
[i
].tsg_address
= 0;
1548 tc
->tc_args
.io
.sgl
[i
].tsg_length
= 0;
1553 * In all likelihood, this is a command passed from
1554 * management tools in userspace where no S/G list is
1555 * necessary because no data is being passed.
1560 if ((ccb
->ccb_flags
& TWE_CCB_DATA_IN
) != 0)
1561 flags
= BUS_DMASYNC_PREREAD
;
1564 if ((ccb
->ccb_flags
& TWE_CCB_DATA_OUT
) != 0)
1565 flags
|= BUS_DMASYNC_PREWRITE
;
1567 bus_dmamap_sync(sc
->sc_dmat
, ccb
->ccb_dmamap_xfer
, 0,
1568 ccb
->ccb_datasize
, flags
);
1573 * Unmap the specified CCB's command block and data buffer (if any) and
1574 * perform DMA synchronisation.
1577 twe_ccb_unmap(struct twe_softc
*sc
, struct twe_ccb
*ccb
)
1581 if ((ccb
->ccb_flags
& TWE_CCB_DATA_IN
) != 0)
1582 flags
= BUS_DMASYNC_POSTREAD
;
1585 if ((ccb
->ccb_flags
& TWE_CCB_DATA_OUT
) != 0)
1586 flags
|= BUS_DMASYNC_POSTWRITE
;
1588 bus_dmamap_sync(sc
->sc_dmat
, ccb
->ccb_dmamap_xfer
, 0,
1589 ccb
->ccb_datasize
, flags
);
1590 bus_dmamap_unload(sc
->sc_dmat
, ccb
->ccb_dmamap_xfer
);
1592 if (ccb
->ccb_abuf
!= (vaddr_t
)0) {
1593 if ((ccb
->ccb_flags
& TWE_CCB_DATA_IN
) != 0)
1594 memcpy(ccb
->ccb_data
, (void *)ccb
->ccb_abuf
,
1598 uvm_km_free(kmem_map
, ccb
->ccb_abuf
, ccb
->ccb_datasize
,
1605 * Submit a command to the controller and poll on completion. Return
1606 * non-zero on timeout (but don't check status, as some command types don't
1607 * return status). Must be called with interrupts blocked.
1610 twe_ccb_poll(struct twe_softc
*sc
, struct twe_ccb
*ccb
, int timo
)
1614 if ((rv
= twe_ccb_submit(sc
, ccb
)) != 0)
1617 for (timo
*= 1000; timo
!= 0; timo
--) {
1619 if ((ccb
->ccb_flags
& TWE_CCB_COMPLETE
) != 0)
1628 * If a CCB is specified, enqueue it. Pull CCBs off the software queue in
1629 * the order that they were enqueued and try to submit their command blocks
1630 * to the controller for execution.
1633 twe_ccb_enqueue(struct twe_softc
*sc
, struct twe_ccb
*ccb
)
1640 SIMPLEQ_INSERT_TAIL(&sc
->sc_ccb_queue
, ccb
, ccb_chain
.simpleq
);
1642 while ((ccb
= SIMPLEQ_FIRST(&sc
->sc_ccb_queue
)) != NULL
) {
1643 if (twe_ccb_submit(sc
, ccb
))
1645 SIMPLEQ_REMOVE_HEAD(&sc
->sc_ccb_queue
, ccb_chain
.simpleq
);
1652 * Submit the command block associated with the specified CCB to the
1653 * controller for execution. Must be called with interrupts blocked.
1656 twe_ccb_submit(struct twe_softc
*sc
, struct twe_ccb
*ccb
)
1662 /* Check to see if we can post a command. */
1663 status
= twe_inl(sc
, TWE_REG_STS
);
1664 twe_status_check(sc
, status
);
1666 if ((status
& TWE_STS_CMD_QUEUE_FULL
) == 0) {
1667 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_dmamap
,
1668 (char *)ccb
->ccb_cmd
- (char *)sc
->sc_cmds
,
1669 sizeof(struct twe_cmd
),
1670 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1672 if ((ccb
->ccb_flags
& TWE_CCB_ALLOCED
) == 0)
1673 panic("%s: CCB %ld not ALLOCED\n",
1674 device_xname(&sc
->sc_dv
), (long)(ccb
- sc
->sc_ccbs
));
1676 ccb
->ccb_flags
|= TWE_CCB_ACTIVE
;
1677 pa
= sc
->sc_cmds_paddr
+
1678 ccb
->ccb_cmdid
* sizeof(struct twe_cmd
);
1679 twe_outl(sc
, TWE_REG_CMD_QUEUE
, (u_int32_t
)pa
);
1689 * Accept an open operation on the control device.
1692 tweopen(dev_t dev
, int flag
, int mode
, struct lwp
*l
)
1694 struct twe_softc
*twe
;
1696 if ((twe
= device_lookup_private(&twe_cd
, minor(dev
))) == NULL
)
1698 if ((twe
->sc_flags
& TWEF_OPEN
) != 0)
1701 twe
->sc_flags
|= TWEF_OPEN
;
1706 * Accept the last close on the control device.
1709 tweclose(dev_t dev
, int flag
, int mode
,
1712 struct twe_softc
*twe
;
1714 twe
= device_lookup_private(&twe_cd
, minor(dev
));
1715 twe
->sc_flags
&= ~TWEF_OPEN
;
1720 twe_ccb_wait_handler(struct twe_ccb
*ccb
, int error
)
1723 /* Just wake up the sleeper. */
1728 * Handle control operations.
1731 tweioctl(dev_t dev
, u_long cmd
, void *data
, int flag
,
1734 struct twe_softc
*twe
;
1735 struct twe_ccb
*ccb
;
1736 struct twe_param
*param
;
1737 struct twe_usercommand
*tu
;
1738 struct twe_paramcommand
*tp
;
1739 struct twe_drivecommand
*td
;
1744 twe
= device_lookup_private(&twe_cd
, minor(dev
));
1745 tu
= (struct twe_usercommand
*)data
;
1746 tp
= (struct twe_paramcommand
*)data
;
1747 td
= (struct twe_drivecommand
*)data
;
1749 /* This is intended to be compatible with the FreeBSD interface. */
1752 error
= kauth_authorize_device_passthru(l
->l_cred
, dev
,
1753 KAUTH_REQ_DEVICE_RAWIO_PASSTHRU_ALL
, data
);
1758 if (tu
->tu_size
> 0) {
1760 * XXX Handle > TWE_SECTOR_SIZE? Let's see if
1761 * it's really necessary, first.
1763 if (tu
->tu_size
> TWE_SECTOR_SIZE
) {
1765 printf("%s: TWEIO_COMMAND: tu_size = %d\n",
1766 device_xname(&twe
->sc_dv
), tu
->tu_size
);
1770 pdata
= malloc(TWE_SECTOR_SIZE
, M_DEVBUF
, M_WAITOK
);
1771 error
= copyin(tu
->tu_data
, pdata
, tu
->tu_size
);
1774 ccb
= twe_ccb_alloc_wait(twe
,
1775 TWE_CCB_DATA_IN
| TWE_CCB_DATA_OUT
);
1776 KASSERT(ccb
!= NULL
);
1777 ccb
->ccb_data
= pdata
;
1778 ccb
->ccb_datasize
= TWE_SECTOR_SIZE
;
1780 ccb
= twe_ccb_alloc_wait(twe
, 0);
1781 KASSERT(ccb
!= NULL
);
1784 ccb
->ccb_tx
.tx_handler
= twe_ccb_wait_handler
;
1785 ccb
->ccb_tx
.tx_context
= NULL
;
1786 ccb
->ccb_tx
.tx_dv
= &twe
->sc_dv
;
1788 cmdid
= ccb
->ccb_cmdid
;
1789 memcpy(ccb
->ccb_cmd
, &tu
->tu_cmd
, sizeof(struct twe_cmd
));
1790 ccb
->ccb_cmd
->tc_cmdid
= cmdid
;
1792 /* Map the transfer. */
1793 if ((error
= twe_ccb_map(twe
, ccb
)) != 0) {
1794 twe_ccb_free(twe
, ccb
);
1798 /* Submit the command and wait up to 1 minute. */
1800 twe_ccb_enqueue(twe
, ccb
);
1802 while ((ccb
->ccb_flags
& TWE_CCB_COMPLETE
) == 0)
1803 if ((error
= tsleep(ccb
, PRIBIO
, "tweioctl",
1808 /* Copy the command back to the ioctl argument. */
1809 memcpy(&tu
->tu_cmd
, ccb
->ccb_cmd
, sizeof(struct twe_cmd
));
1811 printf("%s: TWEIO_COMMAND: tc_opcode = 0x%02x, "
1812 "tc_status = 0x%02x\n", device_xname(&twe
->sc_dv
),
1813 tu
->tu_cmd
.tc_opcode
, tu
->tu_cmd
.tc_status
);
1817 twe_ccb_free(twe
, ccb
);
1820 if (tu
->tu_size
> 0)
1821 error
= copyout(pdata
, tu
->tu_data
, tu
->tu_size
);
1827 case TWEIO_AEN_POLL
:
1829 *(u_int
*)data
= twe_aen_dequeue(twe
);
1833 case TWEIO_AEN_WAIT
:
1835 while ((*(u_int
*)data
=
1836 twe_aen_dequeue(twe
)) == TWE_AEN_QUEUE_EMPTY
) {
1837 twe
->sc_flags
|= TWEF_AENQ_WAIT
;
1838 error
= tsleep(&twe
->sc_aen_queue
, PRIBIO
| PCATCH
,
1840 if (error
== EINTR
) {
1848 case TWEIO_GET_PARAM
:
1849 error
= twe_param_get(twe
, tp
->tp_table_id
, tp
->tp_param_id
,
1850 tp
->tp_size
, 0, ¶m
);
1853 if (param
->tp_param_size
> tp
->tp_size
) {
1857 error
= copyout(param
->tp_data
, tp
->tp_data
,
1858 param
->tp_param_size
);
1859 free(param
, M_DEVBUF
);
1862 case TWEIO_SET_PARAM
:
1863 pdata
= malloc(tp
->tp_size
, M_DEVBUF
, M_WAITOK
);
1864 if ((error
= copyin(tp
->tp_data
, pdata
, tp
->tp_size
)) != 0)
1866 error
= twe_param_set(twe
, tp
->tp_table_id
, tp
->tp_param_id
,
1867 tp
->tp_size
, pdata
);
1876 case TWEIO_ADD_UNIT
:
1878 return (twe_add_unit(twe
, td
->td_unit
));
1880 case TWEIO_DEL_UNIT
:
1882 return (twe_del_unit(twe
, td
->td_unit
));
1889 free(pdata
, M_DEVBUF
);
1893 const struct cdevsw twe_cdevsw
= {
1894 tweopen
, tweclose
, noread
, nowrite
, tweioctl
,
1895 nostop
, notty
, nopoll
, nommap
, nokqfilter
, D_OTHER
,
1899 * Print some information about the controller
1902 twe_describe_controller(struct twe_softc
*sc
)
1904 struct twe_param
*p
[6];
1911 /* get the port count */
1912 rv
|= twe_param_get_1(sc
, TWE_PARAM_CONTROLLER
,
1913 TWE_PARAM_CONTROLLER_PortCount
, &ports
);
1915 /* get version strings */
1916 rv
|= twe_param_get(sc
, TWE_PARAM_VERSION
, TWE_PARAM_VERSION_Mon
,
1918 rv
|= twe_param_get(sc
, TWE_PARAM_VERSION
, TWE_PARAM_VERSION_FW
,
1920 rv
|= twe_param_get(sc
, TWE_PARAM_VERSION
, TWE_PARAM_VERSION_BIOS
,
1922 rv
|= twe_param_get(sc
, TWE_PARAM_VERSION
, TWE_PARAM_VERSION_PCB
,
1924 rv
|= twe_param_get(sc
, TWE_PARAM_VERSION
, TWE_PARAM_VERSION_ATA
,
1926 rv
|= twe_param_get(sc
, TWE_PARAM_VERSION
, TWE_PARAM_VERSION_PCI
,
1930 /* some error occurred */
1931 aprint_error_dev(&sc
->sc_dv
, "failed to fetch version information\n");
1935 aprint_normal_dev(&sc
->sc_dv
, "%d ports, Firmware %.16s, BIOS %.16s\n",
1936 ports
, p
[1]->tp_data
, p
[2]->tp_data
);
1938 aprint_verbose_dev(&sc
->sc_dv
, "Monitor %.16s, PCB %.8s, Achip %.8s, Pchip %.8s\n",
1939 p
[0]->tp_data
, p
[3]->tp_data
,
1940 p
[4]->tp_data
, p
[5]->tp_data
);
1942 free(p
[0], M_DEVBUF
);
1943 free(p
[1], M_DEVBUF
);
1944 free(p
[2], M_DEVBUF
);
1945 free(p
[3], M_DEVBUF
);
1946 free(p
[4], M_DEVBUF
);
1947 free(p
[5], M_DEVBUF
);
1949 rv
= twe_param_get(sc
, TWE_PARAM_DRIVESUMMARY
,
1950 TWE_PARAM_DRIVESUMMARY_Status
, 16, NULL
, &p
[0]);
1952 aprint_error_dev(&sc
->sc_dv
, "failed to get drive status summary\n");
1955 for (i
= 0; i
< ports
; i
++) {
1956 if (p
[0]->tp_data
[i
] != TWE_PARAM_DRIVESTATUS_Present
)
1958 rv
= twe_param_get_4(sc
, TWE_PARAM_DRIVEINFO
+ i
,
1959 TWE_PARAM_DRIVEINFO_Size
, &dsize
);
1961 aprint_error_dev(&sc
->sc_dv
,
1962 "unable to get drive size for port %d\n", i
);
1965 rv
= twe_param_get(sc
, TWE_PARAM_DRIVEINFO
+ i
,
1966 TWE_PARAM_DRIVEINFO_Model
, 40, NULL
, &p
[1]);
1968 aprint_error_dev(&sc
->sc_dv
,
1969 "unable to get drive model for port %d\n", i
);
1972 aprint_verbose_dev(&sc
->sc_dv
, "port %d: %.40s %d MB\n",
1973 i
, p
[1]->tp_data
, dsize
/ 2048);
1974 free(p
[1], M_DEVBUF
);
1976 free(p
[0], M_DEVBUF
);