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