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