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