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