1 /*-
2 * Written by: David Jeffery
3 * Copyright (c) 2002 Adaptec Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * $FreeBSD: src/sys/dev/ips/ips.c,v 1.12 2004/05/30 04:01:29 scottl Exp $
28 */
29
30 #include <dev/raid/ips/ips.h>
31 #include <sys/stat.h>
32 #include <sys/time.h>
33 #include <sys/thread2.h>
34 #include <sys/udev.h>
35 #include <machine/clock.h>
36
37 static d_open_t ips_open;
38 static d_close_t ips_close;
39 static d_ioctl_t ips_ioctl;
40
41 MALLOC_DEFINE(M_IPSBUF, "ipsbuf", "IPS driver buffer");
42
43 static struct dev_ops ips_ops = {
44 { "ips", 0, D_DISK },
45 .d_open = ips_open,
46 .d_close = ips_close,
47 .d_ioctl = ips_ioctl,
48 };
49
50 static const char *ips_adapter_name[] = {
51 "N/A",
52 "ServeRAID (copperhead)",
53 "ServeRAID II (copperhead refresh)",
54 "ServeRAID onboard (copperhead)",
55 "ServeRAID onboard (copperhead)",
56 "ServeRAID 3H (clarinet)",
57 "ServeRAID 3L (clarinet lite)",
58 "ServeRAID 4H (trombone)",
59 "ServeRAID 4M (morpheus)",
60 "ServeRAID 4L (morpheus lite)",
61 "ServeRAID 4Mx (neo)",
62 "ServeRAID 4Lx (neo lite)",
63 "ServeRAID 5i II (sarasota)",
64 "ServeRAID 5i (sarasota)",
65 "ServeRAID 6M (marco)",
66 "ServeRAID 6i (sebring)",
67 "ServeRAID 7t",
68 "ServeRAID 7k",
69 "ServeRAID 7M",
70 };
71
72
73 static int
ips_open(struct dev_open_args * ap)74 ips_open(struct dev_open_args *ap)
75 {
76 cdev_t dev = ap->a_head.a_dev;
77 ips_softc_t *sc = dev->si_drv1;
78
79 sc->state |= IPS_DEV_OPEN;
80 return 0;
81 }
82
83 static int
ips_close(struct dev_close_args * ap)84 ips_close(struct dev_close_args *ap)
85 {
86 cdev_t dev = ap->a_head.a_dev;
87 ips_softc_t *sc = dev->si_drv1;
88
89 sc->state &= ~IPS_DEV_OPEN;
90 return 0;
91 }
92
93 static int
ips_ioctl(struct dev_ioctl_args * ap)94 ips_ioctl(struct dev_ioctl_args *ap)
95 {
96 ips_softc_t *sc;
97
98 sc = ap->a_head.a_dev->si_drv1;
99 return ips_ioctl_request(sc, ap->a_cmd, ap->a_data, ap->a_fflag);
100 }
101
102 static void
ips_cmd_dmaload(void * cmdptr,bus_dma_segment_t * segments,int segnum,int error)103 ips_cmd_dmaload(void *cmdptr, bus_dma_segment_t *segments, int segnum,
104 int error)
105 {
106 ips_command_t *command = cmdptr;
107
108 PRINTF(10, "ips: in ips_cmd_dmaload\n");
109 if (!error)
110 command->command_phys_addr = segments[0].ds_addr;
111
112 }
113
114 /* is locking needed? what locking guarentees are there on removal? */
115 static int
ips_cmdqueue_free(ips_softc_t * sc)116 ips_cmdqueue_free(ips_softc_t *sc)
117 {
118 int i, error = -1;
119 ips_command_t *command;
120
121 crit_enter();
122 if (sc->used_commands == 0) {
123 for (i = 0; i < sc->max_cmds; i++) {
124 command = &sc->commandarray[i];
125 if (command->command_phys_addr == 0)
126 continue;
127 bus_dmamap_unload(sc->command_dmatag,
128 command->command_dmamap);
129 bus_dmamem_free(sc->command_dmatag,
130 command->command_buffer,
131 command->command_dmamap);
132 if (command->data_dmamap != NULL)
133 bus_dmamap_destroy(command->data_dmatag,
134 command->data_dmamap);
135 }
136 error = 0;
137 sc->state |= IPS_OFFLINE;
138 }
139 sc->staticcmd = NULL;
140 kfree(sc->commandarray, M_IPSBUF);
141 crit_exit();
142 return error;
143 }
144
145 /*
146 * Places all ips command structs on the free command queue.
147 * The first slot is used exclusively for static commands
148 * No locking as if someone else tries to access this during init,
149 * we have bigger problems
150 */
151 static int
ips_cmdqueue_init(ips_softc_t * sc)152 ips_cmdqueue_init(ips_softc_t *sc)
153 {
154 int i;
155 ips_command_t *command;
156
157 sc->commandarray = kmalloc(sizeof(sc->commandarray[0]) * sc->max_cmds,
158 M_IPSBUF, M_INTWAIT | M_ZERO);
159 SLIST_INIT(&sc->free_cmd_list);
160 for (i = 0; i < sc->max_cmds; i++) {
161 command = &sc->commandarray[i];
162 command->id = i;
163 command->sc = sc;
164 if (bus_dmamem_alloc(sc->command_dmatag,
165 &command->command_buffer, BUS_DMA_NOWAIT,
166 &command->command_dmamap))
167 goto error;
168 bus_dmamap_load(sc->command_dmatag, command->command_dmamap,
169 command->command_buffer, IPS_COMMAND_LEN, ips_cmd_dmaload,
170 command, BUS_DMA_NOWAIT);
171 if (command->command_phys_addr == 0) {
172 bus_dmamem_free(sc->command_dmatag,
173 command->command_buffer, command->command_dmamap);
174 goto error;
175 }
176
177 if (i == 0)
178 sc->staticcmd = command;
179 else {
180 command->data_dmatag = sc->sg_dmatag;
181 if (bus_dmamap_create(command->data_dmatag, 0,
182 &command->data_dmamap))
183 goto error;
184 SLIST_INSERT_HEAD(&sc->free_cmd_list, command, next);
185 }
186 }
187 sc->state &= ~IPS_OFFLINE;
188 return 0;
189 error:
190 ips_cmdqueue_free(sc);
191 return ENOMEM;
192 }
193
194 /*
195 * returns a free command struct if one is available.
196 * It also blanks out anything that may be a wild pointer/value.
197 * Also, command buffers are not freed. They are
198 * small so they are saved and kept dmamapped and loaded.
199 */
200 int
ips_get_free_cmd(ips_softc_t * sc,ips_command_t ** cmd,unsigned long flags)201 ips_get_free_cmd(ips_softc_t *sc, ips_command_t **cmd, unsigned long flags)
202 {
203 ips_command_t *command = NULL;
204 int error = 0;
205
206 crit_enter();
207 if (sc->state & IPS_OFFLINE) {
208 error = EIO;
209 goto bail;
210 }
211 if ((flags & IPS_STATIC_FLAG) != 0) {
212 if (sc->state & IPS_STATIC_BUSY) {
213 error = EAGAIN;
214 goto bail;
215 }
216 command = sc->staticcmd;
217 sc->state |= IPS_STATIC_BUSY;
218 } else {
219 command = SLIST_FIRST(&sc->free_cmd_list);
220 if (!command || (sc->state & IPS_TIMEOUT)) {
221 error = EBUSY;
222 goto bail;
223 }
224 SLIST_REMOVE_HEAD(&sc->free_cmd_list, next);
225 sc->used_commands++;
226 }
227 bail:
228 crit_exit();
229 if (error != 0)
230 return error;
231
232 bzero(&command->status, (char *)(command + 1) - (char *)(&command->status));
233 bzero(command->command_buffer, IPS_COMMAND_LEN);
234 *cmd = command;
235 return 0;
236 }
237
238 /* adds a command back to the free command queue */
239 void
ips_insert_free_cmd(ips_softc_t * sc,ips_command_t * command)240 ips_insert_free_cmd(ips_softc_t *sc, ips_command_t *command)
241 {
242 crit_enter();
243 if (command == sc->staticcmd)
244 sc->state &= ~IPS_STATIC_BUSY;
245 else {
246 SLIST_INSERT_HEAD(&sc->free_cmd_list, command, next);
247 sc->used_commands--;
248 }
249 crit_exit();
250 }
251
252 static const char *
ips_diskdev_statename(u_int8_t state)253 ips_diskdev_statename(u_int8_t state)
254 {
255 static char statebuf[20];
256
257 switch(state) {
258 case IPS_LD_OFFLINE:
259 return("OFFLINE");
260 break;
261 case IPS_LD_OKAY:
262 return("OK");
263 break;
264 case IPS_LD_DEGRADED:
265 return("DEGRADED");
266 break;
267 case IPS_LD_FREE:
268 return("FREE");
269 break;
270 case IPS_LD_SYS:
271 return("SYS");
272 break;
273 case IPS_LD_CRS:
274 return("CRS");
275 break;
276 }
277 ksprintf(statebuf, "UNKNOWN(0x%02x)", state);
278 return (statebuf);
279 }
280
281 static int
ips_diskdev_init(ips_softc_t * sc)282 ips_diskdev_init(ips_softc_t *sc)
283 {
284 int i;
285
286 for (i = 0; i < IPS_MAX_NUM_DRIVES; i++) {
287 if (sc->drives[i].state == IPS_LD_FREE)
288 continue;
289 device_printf(sc->dev,
290 "Logical Drive %d: RAID%d sectors: %u, state %s\n", i,
291 sc->drives[i].raid_lvl, sc->drives[i].sector_count,
292 ips_diskdev_statename(sc->drives[i].state));
293 if (sc->drives[i].state == IPS_LD_OKAY ||
294 sc->drives[i].state == IPS_LD_DEGRADED) {
295 sc->diskdev[i] = device_add_child(sc->dev, NULL, -1);
296 device_set_ivars(sc->diskdev[i], (void *)(uintptr_t)i);
297 }
298 }
299 if (bus_generic_attach(sc->dev))
300 device_printf(sc->dev, "Attaching bus failed\n");
301 return 0;
302 }
303
304 static int
ips_diskdev_free(ips_softc_t * sc)305 ips_diskdev_free(ips_softc_t *sc)
306 {
307 int i;
308 int error = 0;
309
310 for (i = 0; i < IPS_MAX_NUM_DRIVES; i++) {
311 if (sc->diskdev[i] != NULL) {
312 error = device_delete_child(sc->dev, sc->diskdev[i]);
313 if (error)
314 return error;
315 }
316 }
317 bus_generic_detach(sc->dev);
318 return 0;
319 }
320
321 /*
322 * ips_timeout is periodically called to make sure no commands sent
323 * to the card have become stuck. If it finds a stuck command, it
324 * sets a flag so the driver won't start any more commands and then
325 * is periodically called to see if all outstanding commands have
326 * either finished or timed out. Once timed out, an attempt to
327 * reinitialize the card is made. If that fails, the driver gives
328 * up and declares the card dead.
329 */
330 static void
ips_timeout(void * arg)331 ips_timeout(void *arg)
332 {
333 ips_command_t *command;
334 ips_softc_t *sc = arg;
335 int i, state = 0;
336
337 lockmgr(&sc->queue_lock, LK_EXCLUSIVE|LK_RETRY);
338 command = &sc->commandarray[0];
339 for (i = 0; i < sc->max_cmds; i++) {
340 if (!command[i].timeout)
341 continue;
342 command[i].timeout--;
343 if (command[i].timeout == 0) {
344 if (!(sc->state & IPS_TIMEOUT)) {
345 sc->state |= IPS_TIMEOUT;
346 device_printf(sc->dev, "WARNING: command timeout. Adapter is in toaster mode, resetting to known state\n");
347 }
348 command[i].status.value = IPS_ERROR_STATUS;
349 command[i].callback(&command[i]);
350 /* hmm, this should be enough cleanup */
351 } else
352 state = 1;
353 }
354 if (!state && (sc->state & IPS_TIMEOUT)) {
355 if (sc->ips_adapter_reinit(sc, 1)) {
356 device_printf(sc->dev, "AIEE! adapter reset failed, "
357 "giving up and going home! Have a nice day.\n");
358 sc->state |= IPS_OFFLINE;
359 sc->state &= ~IPS_TIMEOUT;
360 /*
361 * Grr, I hate this solution. I run waiting commands
362 * one at a time and error them out just before they
363 * would go to the card. This sucks.
364 */
365 } else
366 sc->state &= ~IPS_TIMEOUT;
367 }
368 if (sc->state != IPS_OFFLINE)
369 callout_reset(&sc->timer, 10 * hz, ips_timeout, sc);
370 lockmgr(&sc->queue_lock, LK_RELEASE);
371 }
372
373 /* check card and initialize it */
374 int
ips_adapter_init(ips_softc_t * sc)375 ips_adapter_init(ips_softc_t *sc)
376 {
377 int i;
378 cdev_t dev;
379
380 DEVICE_PRINTF(1, sc->dev, "initializing\n");
381 if (bus_dma_tag_create( /* parent */ sc->adapter_dmatag,
382 /* alignemnt */ 1,
383 /* boundary */ 0,
384 /* lowaddr */ BUS_SPACE_MAXADDR_32BIT,
385 /* highaddr */ BUS_SPACE_MAXADDR,
386 /* maxsize */ IPS_COMMAND_LEN +
387 IPS_MAX_SG_LEN,
388 /* numsegs */ 1,
389 /* maxsegsize*/ IPS_COMMAND_LEN +
390 IPS_MAX_SG_LEN,
391 /* flags */ 0,
392 &sc->command_dmatag) != 0) {
393 device_printf(sc->dev, "can't alloc command dma tag\n");
394 goto error;
395 }
396 if (bus_dma_tag_create( /* parent */ sc->adapter_dmatag,
397 /* alignemnt */ 1,
398 /* boundary */ 0,
399 /* lowaddr */ BUS_SPACE_MAXADDR_32BIT,
400 /* highaddr */ BUS_SPACE_MAXADDR,
401 /* maxsize */ IPS_MAX_IOBUF_SIZE,
402 /* numsegs */ IPS_MAX_SG_ELEMENTS,
403 /* maxsegsize*/ IPS_MAX_IOBUF_SIZE,
404 /* flags */ 0,
405 &sc->sg_dmatag) != 0) {
406 device_printf(sc->dev, "can't alloc SG dma tag\n");
407 goto error;
408 }
409 /*
410 * create one command buffer until we know how many commands this card
411 * can handle
412 */
413 sc->max_cmds = 1;
414 ips_cmdqueue_init(sc);
415 callout_init(&sc->timer);
416 if (sc->ips_adapter_reinit(sc, 0))
417 goto error;
418 /* initialize ffdc values */
419 microtime(&sc->ffdc_resettime);
420 sc->ffdc_resetcount = 1;
421 if ((i = ips_ffdc_reset(sc)) != 0) {
422 device_printf(sc->dev,
423 "failed to send ffdc reset to device (%d)\n", i);
424 goto error;
425 }
426 if ((i = ips_get_adapter_info(sc)) != 0) {
427 device_printf(sc->dev, "failed to get adapter configuration "
428 "data from device (%d)\n", i);
429 goto error;
430 }
431 /* no error check as failure doesn't matter */
432 ips_update_nvram(sc);
433 if (sc->adapter_type > 0 && sc->adapter_type <= IPS_ADAPTER_MAX_T) {
434 device_printf(sc->dev, "adapter type: %s\n",
435 ips_adapter_name[sc->adapter_type]);
436 }
437 if ((i = ips_get_drive_info(sc)) != 0) {
438 device_printf(sc->dev, "failed to get drive "
439 "configuration data from device (%d)\n", i);
440 goto error;
441 }
442 ips_cmdqueue_free(sc);
443 if (sc->adapter_info.max_concurrent_cmds)
444 sc->max_cmds = min(128, sc->adapter_info.max_concurrent_cmds);
445 else
446 sc->max_cmds = 32;
447 if (ips_cmdqueue_init(sc)) {
448 device_printf(sc->dev,
449 "failed to initialize command buffers\n");
450 goto error;
451 }
452 dev = make_dev(&ips_ops, device_get_unit(sc->dev),
453 UID_ROOT, GID_OPERATOR, S_IRUSR | S_IWUSR,
454 "ips%d", device_get_unit(sc->dev));
455 dev->si_drv1 = sc;
456 udev_dict_set_cstr(dev, "subsystem", "raid");
457 udev_dict_set_cstr(dev, "disk-type", "raid");
458 ips_diskdev_init(sc);
459 callout_reset(&sc->timer, 10 * hz, ips_timeout, sc);
460 return 0;
461 error:
462 ips_adapter_free(sc);
463 return ENXIO;
464 }
465
466 /*
467 * see if we should reinitialize the card and wait for it to timeout
468 * or complete initialization
469 */
470 int
ips_morpheus_reinit(ips_softc_t * sc,int force)471 ips_morpheus_reinit(ips_softc_t *sc, int force)
472 {
473 u_int32_t tmp;
474 int i;
475
476 tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
477 if (!force && (ips_read_4(sc, MORPHEUS_REG_OMR0) >= IPS_POST1_OK) &&
478 (ips_read_4(sc, MORPHEUS_REG_OMR1) != 0xdeadbeef) && !tmp) {
479 ips_write_4(sc, MORPHEUS_REG_OIMR, 0);
480 return 0;
481 }
482 ips_write_4(sc, MORPHEUS_REG_OIMR, 0xff);
483 ips_read_4(sc, MORPHEUS_REG_OIMR);
484 device_printf(sc->dev,
485 "resetting adapter, this may take up to 5 minutes\n");
486 ips_write_4(sc, MORPHEUS_REG_IDR, 0x80000000);
487 DELAY(5000000);
488 pci_read_config(sc->dev, 0, 4);
489 tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
490 for (i = 0; i < 45 && !(tmp & MORPHEUS_BIT_POST1); i++) {
491 DELAY(1000000);
492 DEVICE_PRINTF(2, sc->dev, "post1: %d\n", i);
493 tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
494 }
495 if (tmp & MORPHEUS_BIT_POST1)
496 ips_write_4(sc, MORPHEUS_REG_OISR, MORPHEUS_BIT_POST1);
497
498 if (i == 45 || ips_read_4(sc, MORPHEUS_REG_OMR0) < IPS_POST1_OK) {
499 device_printf(sc->dev,
500 "Adapter error during initialization.\n");
501 return 1;
502 }
503 for (i = 0; i < 240 && !(tmp & MORPHEUS_BIT_POST2); i++) {
504 DELAY(1000000);
505 DEVICE_PRINTF(2, sc->dev, "post2: %d\n", i);
506 tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
507 }
508 if (tmp & MORPHEUS_BIT_POST2)
509 ips_write_4(sc, MORPHEUS_REG_OISR, MORPHEUS_BIT_POST2);
510
511 if (i == 240 || !ips_read_4(sc, MORPHEUS_REG_OMR1)) {
512 device_printf(sc->dev, "adapter failed config check\n");
513 return 1;
514 }
515 ips_write_4(sc, MORPHEUS_REG_OIMR, 0);
516 if (force && ips_clear_adapter(sc)) {
517 device_printf(sc->dev, "adapter clear failed\n");
518 return 1;
519 }
520 return 0;
521 }
522
523 /* clean up so we can unload the driver. */
524 int
ips_adapter_free(ips_softc_t * sc)525 ips_adapter_free(ips_softc_t *sc)
526 {
527 int error = 0;
528
529 if (sc->state & IPS_DEV_OPEN)
530 return EBUSY;
531 if ((error = ips_diskdev_free(sc)))
532 return error;
533 if (ips_cmdqueue_free(sc)) {
534 device_printf(sc->dev,
535 "trying to exit when command queue is not empty!\n");
536 return EBUSY;
537 }
538 DEVICE_PRINTF(1, sc->dev, "free\n");
539 crit_enter();
540 callout_stop(&sc->timer);
541 crit_exit();
542 if (sc->sg_dmatag)
543 bus_dma_tag_destroy(sc->sg_dmatag);
544 if (sc->command_dmatag)
545 bus_dma_tag_destroy(sc->command_dmatag);
546 dev_ops_remove_minor(&ips_ops, device_get_unit(sc->dev));
547 return 0;
548 }
549
550 static int
ips_morpheus_check_intr(void * void_sc)551 ips_morpheus_check_intr(void *void_sc)
552 {
553 ips_softc_t *sc = (ips_softc_t *)void_sc;
554 u_int32_t oisr, iisr;
555 ips_cmd_status_t status;
556 ips_command_t *command;
557 int cmdnumber;
558 int found = 0;
559
560 iisr =ips_read_4(sc, MORPHEUS_REG_IISR);
561 oisr =ips_read_4(sc, MORPHEUS_REG_OISR);
562 PRINTF(9, "interrupt registers in:%x out:%x\n", iisr, oisr);
563 if (!(oisr & MORPHEUS_BIT_CMD_IRQ)) {
564 DEVICE_PRINTF(2, sc->dev, "got a non-command irq\n");
565 return(0);
566 }
567 while ((status.value = ips_read_4(sc, MORPHEUS_REG_OQPR))
568 != 0xffffffff) {
569 cmdnumber = status.fields.command_id;
570 command = &sc->commandarray[cmdnumber];
571 command->status.value = status.value;
572 command->timeout = 0;
573 command->callback(command);
574 DEVICE_PRINTF(9, sc->dev, "got command %d\n", cmdnumber);
575 found = 1;
576 }
577 return(found);
578 }
579
580 void
ips_morpheus_intr(void * void_sc)581 ips_morpheus_intr(void *void_sc)
582 {
583 ips_softc_t *sc = void_sc;
584
585 lockmgr(&sc->queue_lock, LK_EXCLUSIVE|LK_RETRY);
586 ips_morpheus_check_intr(sc);
587 lockmgr(&sc->queue_lock, LK_RELEASE);
588 }
589
590 void
ips_issue_morpheus_cmd(ips_command_t * command)591 ips_issue_morpheus_cmd(ips_command_t *command)
592 {
593 crit_enter();
594 /* hmmm, is there a cleaner way to do this? */
595 if (command->sc->state & IPS_OFFLINE) {
596 crit_exit();
597 command->status.value = IPS_ERROR_STATUS;
598 command->callback(command);
599 return;
600 }
601 command->timeout = 10;
602 ips_write_4(command->sc, MORPHEUS_REG_IQPR, command->command_phys_addr);
603 crit_exit();
604 }
605
606 void
ips_morpheus_poll(ips_command_t * command)607 ips_morpheus_poll(ips_command_t *command)
608 {
609 uint32_t ts;
610
611 ts = time_uptime + command->timeout;
612 while (command->timeout != 0 &&
613 ips_morpheus_check_intr(command->sc) == 0 &&
614 (ts > time_uptime))
615 DELAY(1000);
616 }
617
618 static void
ips_copperhead_queue_callback(void * queueptr,bus_dma_segment_t * segments,int segnum,int error)619 ips_copperhead_queue_callback(void *queueptr, bus_dma_segment_t *segments,
620 int segnum, int error)
621 {
622 ips_copper_queue_t *queue = queueptr;
623
624 if (error)
625 return;
626 queue->base_phys_addr = segments[0].ds_addr;
627 }
628
629 static int
ips_copperhead_queue_init(ips_softc_t * sc)630 ips_copperhead_queue_init(ips_softc_t *sc)
631 {
632 bus_dma_tag_t dmatag = NULL;
633 bus_dmamap_t dmamap = NULL;
634 int error;
635
636 if (bus_dma_tag_create( /* parent */ sc->adapter_dmatag,
637 /* alignemnt */ 1,
638 /* boundary */ 0,
639 /* lowaddr */ BUS_SPACE_MAXADDR_32BIT,
640 /* highaddr */ BUS_SPACE_MAXADDR,
641 /* maxsize */ sizeof(ips_copper_queue_t),
642 /* numsegs */ 1,
643 /* maxsegsize*/ sizeof(ips_copper_queue_t),
644 /* flags */ 0,
645 &dmatag) != 0) {
646 device_printf(sc->dev, "can't alloc dma tag for statue queue\n");
647 error = ENOMEM;
648 goto exit;
649 }
650 if (bus_dmamem_alloc(dmatag, (void *)&(sc->copper_queue),
651 BUS_DMA_NOWAIT, &dmamap)) {
652 error = ENOMEM;
653 goto exit;
654 }
655 bzero(sc->copper_queue, sizeof(ips_copper_queue_t));
656 sc->copper_queue->dmatag = dmatag;
657 sc->copper_queue->dmamap = dmamap;
658 sc->copper_queue->nextstatus = 1;
659 bus_dmamap_load(dmatag, dmamap, &(sc->copper_queue->status[0]),
660 IPS_MAX_CMD_NUM * 4, ips_copperhead_queue_callback,
661 sc->copper_queue, BUS_DMA_NOWAIT);
662 if (sc->copper_queue->base_phys_addr == 0) {
663 error = ENOMEM;
664 goto exit;
665 }
666 ips_write_4(sc, COPPER_REG_SQSR, sc->copper_queue->base_phys_addr);
667 ips_write_4(sc, COPPER_REG_SQER, sc->copper_queue->base_phys_addr +
668 IPS_MAX_CMD_NUM * 4);
669 ips_write_4(sc, COPPER_REG_SQHR, sc->copper_queue->base_phys_addr + 4);
670 ips_write_4(sc, COPPER_REG_SQTR, sc->copper_queue->base_phys_addr);
671 return 0;
672 exit:
673 bus_dmamem_free(dmatag, sc->copper_queue, dmamap);
674 bus_dma_tag_destroy(dmatag);
675 return error;
676 }
677
678 /*
679 * see if we should reinitialize the card and wait for it to timeout or
680 * complete initialization FIXME
681 */
682 int
ips_copperhead_reinit(ips_softc_t * sc,int force)683 ips_copperhead_reinit(ips_softc_t *sc, int force)
684 {
685 u_int32_t postcode = 0, configstatus = 0;
686 int i, j;
687
688 ips_write_1(sc, COPPER_REG_SCPR, 0x80);
689 ips_write_1(sc, COPPER_REG_SCPR, 0);
690 device_printf(sc->dev,
691 "reinitializing adapter, this could take several minutes.\n");
692 for (j = 0; j < 2; j++) {
693 postcode <<= 8;
694 for (i = 0; i < 45; i++) {
695 if (ips_read_1(sc, COPPER_REG_HISR) & COPPER_GHI_BIT) {
696 postcode |= ips_read_1(sc, COPPER_REG_ISPR);
697 ips_write_1(sc, COPPER_REG_HISR,
698 COPPER_GHI_BIT);
699 break;
700 } else
701 DELAY(1000000);
702 }
703 if (i == 45)
704 return 1;
705 }
706 for (j = 0; j < 2; j++) {
707 configstatus <<= 8;
708 for (i = 0; i < 240; i++) {
709 if (ips_read_1(sc, COPPER_REG_HISR) & COPPER_GHI_BIT) {
710 configstatus |= ips_read_1(sc, COPPER_REG_ISPR);
711 ips_write_1(sc, COPPER_REG_HISR,
712 COPPER_GHI_BIT);
713 break;
714 } else
715 DELAY(1000000);
716 }
717 if (i == 240)
718 return 1;
719 }
720 for (i = 0; i < 240; i++) {
721 if (!(ips_read_1(sc, COPPER_REG_CBSP) & COPPER_OP_BIT))
722 break;
723 else
724 DELAY(1000000);
725 }
726 if (i == 240)
727 return 1;
728 ips_write_2(sc, COPPER_REG_CCCR, 0x1000 | COPPER_ILE_BIT);
729 ips_write_1(sc, COPPER_REG_SCPR, COPPER_EBM_BIT);
730 ips_copperhead_queue_init(sc);
731 ips_write_1(sc, COPPER_REG_HISR, COPPER_GHI_BIT);
732 i = ips_read_1(sc, COPPER_REG_SCPR);
733 ips_write_1(sc, COPPER_REG_HISR, COPPER_EI_BIT);
734 if (configstatus == 0) {
735 device_printf(sc->dev, "adapter initialization failed\n");
736 return 1;
737 }
738 if (force && ips_clear_adapter(sc)) {
739 device_printf(sc->dev, "adapter clear failed\n");
740 return 1;
741 }
742 return 0;
743 }
744
745 static u_int32_t
ips_copperhead_cmd_status(ips_softc_t * sc)746 ips_copperhead_cmd_status(ips_softc_t *sc)
747 {
748 u_int32_t value;
749 int statnum;
750
751 statnum = sc->copper_queue->nextstatus++;
752 if (sc->copper_queue->nextstatus == IPS_MAX_CMD_NUM)
753 sc->copper_queue->nextstatus = 0;
754 crit_enter();
755 value = sc->copper_queue->status[statnum];
756 ips_write_4(sc, COPPER_REG_SQTR, sc->copper_queue->base_phys_addr +
757 4 * statnum);
758 crit_exit();
759 return value;
760 }
761
762 void
ips_copperhead_intr(void * void_sc)763 ips_copperhead_intr(void *void_sc)
764 {
765 ips_softc_t *sc = (ips_softc_t *)void_sc;
766 ips_cmd_status_t status;
767 int cmdnumber;
768
769 lockmgr(&sc->queue_lock, LK_EXCLUSIVE|LK_RETRY);
770 while (ips_read_1(sc, COPPER_REG_HISR) & COPPER_SCE_BIT) {
771 status.value = ips_copperhead_cmd_status(sc);
772 cmdnumber = status.fields.command_id;
773 sc->commandarray[cmdnumber].status.value = status.value;
774 sc->commandarray[cmdnumber].timeout = 0;
775 sc->commandarray[cmdnumber].callback(&(sc->commandarray[cmdnumber]));
776 PRINTF(9, "ips: got command %d\n", cmdnumber);
777 }
778 lockmgr(&sc->queue_lock, LK_RELEASE);
779 return;
780 }
781
782 void
ips_issue_copperhead_cmd(ips_command_t * command)783 ips_issue_copperhead_cmd(ips_command_t *command)
784 {
785 int i;
786
787 crit_enter();
788 /* hmmm, is there a cleaner way to do this? */
789 if (command->sc->state & IPS_OFFLINE) {
790 crit_exit();
791 command->status.value = IPS_ERROR_STATUS;
792 command->callback(command);
793 return;
794 }
795 command->timeout = 10;
796 for (i = 0; ips_read_4(command->sc, COPPER_REG_CCCR) & COPPER_SEM_BIT;
797 i++) {
798 if (i == 20) {
799 kprintf("sem bit still set, can't send a command\n");
800 crit_exit();
801 return;
802 }
803 DELAY(500); /* need to do a delay here */
804 }
805 ips_write_4(command->sc, COPPER_REG_CCSAR, command->command_phys_addr);
806 ips_write_2(command->sc, COPPER_REG_CCCR, COPPER_CMD_START);
807 crit_exit();
808 }
809
810 void
ips_copperhead_poll(ips_command_t * command)811 ips_copperhead_poll(ips_command_t *command)
812 {
813 kprintf("ips: cmd polling not implemented for copperhead devices\n");
814 }
815