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/11.1/sys/dev/ips/ips.c 298955 2016-05-03 03:41:25Z pfg $");
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 bus_generic_detach(sc->dev);
290 return 0;
291 }
292
293 /* ips_timeout is periodically called to make sure no commands sent
294 * to the card have become stuck. If it finds a stuck command, it
295 * sets a flag so the driver won't start any more commands and then
296 * is periodically called to see if all outstanding commands have
297 * either finished or timed out. Once timed out, an attempt to
298 * reinitialize the card is made. If that fails, the driver gives
299 * up and declares the card dead. */
300 static void ips_timeout(void *arg)
301 {
302 ips_softc_t *sc = arg;
303 int i, state = 0;
304 ips_command_t *command;
305
306 mtx_assert(&sc->queue_mtx, MA_OWNED);
307 command = &sc->commandarray[0];
308 for(i = 0; i < sc->max_cmds; i++){
309 if(!command[i].timeout){
310 continue;
311 }
312 command[i].timeout--;
313 if(!command[i].timeout){
314 if(!(sc->state & IPS_TIMEOUT)){
315 sc->state |= IPS_TIMEOUT;
316 device_printf(sc->dev, "WARNING: command timeout. Adapter is in toaster mode, resetting to known state\n");
317 }
318 ips_set_error(&command[i], ETIMEDOUT);
319 command[i].callback(&command[i]);
320 /* hmm, this should be enough cleanup */
321 } else
322 state = 1;
323 }
324 if(!state && (sc->state & IPS_TIMEOUT)){
325 if(sc->ips_adapter_reinit(sc, 1)){
326 device_printf(sc->dev, "AIEE! adapter reset failed, giving up and going home! Have a nice day.\n");
327 sc->state |= IPS_OFFLINE;
328 sc->state &= ~IPS_TIMEOUT;
329 /* Grr, I hate this solution. I run waiting commands
330 one at a time and error them out just before they
331 would go to the card. This sucks. */
332 } else
333 sc->state &= ~IPS_TIMEOUT;
334 }
335 if (sc->state != IPS_OFFLINE)
336 callout_reset(&sc->timer, 10 * hz, ips_timeout, sc);
337 }
338
339 /* check card and initialize it */
340 int ips_adapter_init(ips_softc_t *sc)
341 {
342 int i;
343 DEVICE_PRINTF(1,sc->dev, "initializing\n");
344
345 if (bus_dma_tag_create( /* parent */ sc->adapter_dmatag,
346 /* alignemnt */ 1,
347 /* boundary */ 0,
348 /* lowaddr */ BUS_SPACE_MAXADDR_32BIT,
349 /* highaddr */ BUS_SPACE_MAXADDR,
350 /* filter */ NULL,
351 /* filterarg */ NULL,
352 /* maxsize */ IPS_COMMAND_LEN +
353 IPS_MAX_SG_LEN,
354 /* numsegs */ 1,
355 /* maxsegsize*/ IPS_COMMAND_LEN +
356 IPS_MAX_SG_LEN,
357 /* flags */ 0,
358 /* lockfunc */ NULL,
359 /* lockarg */ NULL,
360 &sc->command_dmatag) != 0) {
361 device_printf(sc->dev, "can't alloc command dma tag\n");
362 goto error;
363 }
364 if (bus_dma_tag_create( /* parent */ sc->adapter_dmatag,
365 /* alignemnt */ 1,
366 /* boundary */ 0,
367 /* lowaddr */ BUS_SPACE_MAXADDR_32BIT,
368 /* highaddr */ BUS_SPACE_MAXADDR,
369 /* filter */ NULL,
370 /* filterarg */ NULL,
371 /* maxsize */ IPS_MAX_IOBUF_SIZE,
372 /* numsegs */ IPS_MAX_SG_ELEMENTS,
373 /* maxsegsize*/ IPS_MAX_IOBUF_SIZE,
374 /* flags */ 0,
375 /* lockfunc */ busdma_lock_mutex,
376 /* lockarg */ &sc->queue_mtx,
377 &sc->sg_dmatag) != 0) {
378 device_printf(sc->dev, "can't alloc SG dma tag\n");
379 goto error;
380 }
381 /* create one command buffer until we know how many commands this card
382 can handle */
383 sc->max_cmds = 1;
384 ips_cmdqueue_init(sc);
385
386 if(sc->ips_adapter_reinit(sc, 0))
387 goto error;
388
389 /* initialize ffdc values */
390 microtime(&sc->ffdc_resettime);
391 sc->ffdc_resetcount = 1;
392 if ((i = ips_ffdc_reset(sc)) != 0) {
393 device_printf(sc->dev, "failed to send ffdc reset to device (%d)\n", i);
394 goto error;
395 }
396 if ((i = ips_get_adapter_info(sc)) != 0) {
397 device_printf(sc->dev, "failed to get adapter configuration data from device (%d)\n", i);
398 goto error;
399 }
400 ips_update_nvram(sc); /* no error check as failure doesn't matter */
401 if(sc->adapter_type > 0 && sc->adapter_type <= IPS_ADAPTER_MAX_T){
402 device_printf(sc->dev, "adapter type: %s\n", ips_adapter_name[sc->adapter_type]);
403 }
404 if ((i = ips_get_drive_info(sc)) != 0) {
405 device_printf(sc->dev, "failed to get drive configuration data from device (%d)\n", i);
406 goto error;
407 }
408
409 ips_cmdqueue_free(sc);
410 if(sc->adapter_info.max_concurrent_cmds)
411 sc->max_cmds = min(128, sc->adapter_info.max_concurrent_cmds);
412 else
413 sc->max_cmds = 32;
414 if(ips_cmdqueue_init(sc)){
415 device_printf(sc->dev, "failed to initialize command buffers\n");
416 goto error;
417 }
418 sc->device_file = make_dev(&ips_cdevsw, device_get_unit(sc->dev), UID_ROOT, GID_OPERATOR,
419 S_IRUSR | S_IWUSR, "ips%d", device_get_unit(sc->dev));
420 sc->device_file->si_drv1 = sc;
421 ips_diskdev_init(sc);
422 callout_reset(&sc->timer, 10 * hz, ips_timeout, sc);
423 return 0;
424
425 error:
426 ips_adapter_free(sc);
427 return ENXIO;
428 }
429
430 /* see if we should reinitialize the card and wait for it to timeout or complete initialization */
431 int ips_morpheus_reinit(ips_softc_t *sc, int force)
432 {
433 u_int32_t tmp;
434 int i;
435
436 tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
437 if(!force && (ips_read_4(sc, MORPHEUS_REG_OMR0) >= IPS_POST1_OK) &&
438 (ips_read_4(sc, MORPHEUS_REG_OMR1) != 0xdeadbeef) && !tmp){
439 ips_write_4(sc, MORPHEUS_REG_OIMR, 0);
440 return 0;
441 }
442 ips_write_4(sc, MORPHEUS_REG_OIMR, 0xff);
443 ips_read_4(sc, MORPHEUS_REG_OIMR);
444
445 device_printf(sc->dev, "resetting adapter, this may take up to 5 minutes\n");
446 ips_write_4(sc, MORPHEUS_REG_IDR, 0x80000000);
447 DELAY(5000000);
448 ips_read_4(sc, MORPHEUS_REG_OIMR);
449
450 tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
451 for(i = 0; i < 45 && !(tmp & MORPHEUS_BIT_POST1); i++){
452 DELAY(1000000);
453 DEVICE_PRINTF(2, sc->dev, "post1: %d\n", i);
454 tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
455 }
456 if(tmp & MORPHEUS_BIT_POST1)
457 ips_write_4(sc, MORPHEUS_REG_OISR, MORPHEUS_BIT_POST1);
458
459 if( i == 45 || ips_read_4(sc, MORPHEUS_REG_OMR0) < IPS_POST1_OK){
460 device_printf(sc->dev,"Adapter error during initialization.\n");
461 return 1;
462 }
463 for(i = 0; i < 240 && !(tmp & MORPHEUS_BIT_POST2); i++){
464 DELAY(1000000);
465 DEVICE_PRINTF(2, sc->dev, "post2: %d\n", i);
466 tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
467 }
468 if(tmp & MORPHEUS_BIT_POST2)
469 ips_write_4(sc, MORPHEUS_REG_OISR, MORPHEUS_BIT_POST2);
470
471 if(i == 240 || !ips_read_4(sc, MORPHEUS_REG_OMR1)){
472 device_printf(sc->dev, "adapter failed config check\n");
473 return 1;
474 }
475 ips_write_4(sc, MORPHEUS_REG_OIMR, 0);
476 if(force && ips_clear_adapter(sc)){
477 device_printf(sc->dev, "adapter clear failed\n");
478 return 1;
479 }
480 return 0;
481 }
482
483 /* clean up so we can unload the driver. */
484 int ips_adapter_free(ips_softc_t *sc)
485 {
486 int error = 0;
487 if(sc->state & IPS_DEV_OPEN)
488 return EBUSY;
489 if((error = ips_diskdev_free(sc)))
490 return error;
491 if(ips_cmdqueue_free(sc)){
492 device_printf(sc->dev,
493 "trying to exit when command queue is not empty!\n");
494 return EBUSY;
495 }
496 DEVICE_PRINTF(1, sc->dev, "free\n");
497 callout_drain(&sc->timer);
498
499 if(sc->sg_dmatag)
500 bus_dma_tag_destroy(sc->sg_dmatag);
501 if(sc->command_dmatag)
502 bus_dma_tag_destroy(sc->command_dmatag);
503 if(sc->device_file)
504 destroy_dev(sc->device_file);
505 return 0;
506 }
507
508 static __inline int ips_morpheus_check_intr(ips_softc_t *sc)
509 {
510 int cmdnumber;
511 ips_cmd_status_t status;
512 ips_command_t *command;
513 int found = 0;
514 u_int32_t oisr;
515
516 oisr = ips_read_4(sc, MORPHEUS_REG_OISR);
517 PRINTF(9, "interrupt registers out:%x\n", oisr);
518 if(!(oisr & MORPHEUS_BIT_CMD_IRQ)){
519 DEVICE_PRINTF(2,sc->dev, "got a non-command irq\n");
520 return (0);
521 }
522 while((status.value = ips_read_4(sc, MORPHEUS_REG_OQPR)) != 0xffffffff){
523 cmdnumber = status.fields.command_id;
524 command = &sc->commandarray[cmdnumber];
525 command->status.value = status.value;
526 command->timeout = 0;
527 command->callback(command);
528
529 found = 1;
530 }
531 return (found);
532 }
533
534 void ips_morpheus_intr(void *void_sc)
535 {
536 ips_softc_t *sc = void_sc;
537
538 mtx_lock(&sc->queue_mtx);
539 ips_morpheus_check_intr(sc);
540 mtx_unlock(&sc->queue_mtx);
541 }
542
543 void ips_morpheus_poll(ips_command_t *command)
544 {
545 uint32_t ts;
546
547 /*
548 * Locks are not used here because this is only called during
549 * crashdumps.
550 */
551 ts = time_second + command->timeout;
552 while ((command->timeout != 0)
553 && (ips_morpheus_check_intr(command->sc) == 0)
554 && (ts > time_second))
555 DELAY(1000);
556 }
557
558 void ips_issue_morpheus_cmd(ips_command_t *command)
559 {
560 /* hmmm, is there a cleaner way to do this? */
561 if(command->sc->state & IPS_OFFLINE){
562 ips_set_error(command, EINVAL);
563 command->callback(command);
564 return;
565 }
566 command->timeout = 10;
567 ips_write_4(command->sc, MORPHEUS_REG_IQPR, command->command_phys_addr);
568 }
569
570 static void ips_copperhead_queue_callback(void *queueptr, bus_dma_segment_t *segments,int segnum, int error)
571 {
572 ips_copper_queue_t *queue = queueptr;
573 if(error){
574 return;
575 }
576 queue->base_phys_addr = segments[0].ds_addr;
577 }
578
579 static int ips_copperhead_queue_init(ips_softc_t *sc)
580 {
581 int error;
582 bus_dma_tag_t dmatag;
583 bus_dmamap_t dmamap;
584 if (bus_dma_tag_create( /* parent */ sc->adapter_dmatag,
585 /* alignemnt */ 1,
586 /* boundary */ 0,
587 /* lowaddr */ BUS_SPACE_MAXADDR_32BIT,
588 /* highaddr */ BUS_SPACE_MAXADDR,
589 /* filter */ NULL,
590 /* filterarg */ NULL,
591 /* maxsize */ sizeof(ips_copper_queue_t),
592 /* numsegs */ 1,
593 /* maxsegsize*/ sizeof(ips_copper_queue_t),
594 /* flags */ 0,
595 /* lockfunc */ NULL,
596 /* lockarg */ NULL,
597 &dmatag) != 0) {
598 device_printf(sc->dev, "can't alloc dma tag for statue queue\n");
599 error = ENOMEM;
600 return error;
601 }
602 if(bus_dmamem_alloc(dmatag, (void *)&(sc->copper_queue),
603 BUS_DMA_NOWAIT, &dmamap)){
604 error = ENOMEM;
605 goto exit;
606 }
607 bzero(sc->copper_queue, sizeof(ips_copper_queue_t));
608 sc->copper_queue->dmatag = dmatag;
609 sc->copper_queue->dmamap = dmamap;
610 sc->copper_queue->nextstatus = 1;
611 bus_dmamap_load(dmatag, dmamap,
612 &(sc->copper_queue->status[0]), IPS_MAX_CMD_NUM * 4,
613 ips_copperhead_queue_callback, sc->copper_queue,
614 BUS_DMA_NOWAIT);
615 if(sc->copper_queue->base_phys_addr == 0){
616 error = ENOMEM;
617 goto exit;
618 }
619 ips_write_4(sc, COPPER_REG_SQSR, sc->copper_queue->base_phys_addr);
620 ips_write_4(sc, COPPER_REG_SQER, sc->copper_queue->base_phys_addr +
621 IPS_MAX_CMD_NUM * 4);
622 ips_write_4(sc, COPPER_REG_SQHR, sc->copper_queue->base_phys_addr + 4);
623 ips_write_4(sc, COPPER_REG_SQTR, sc->copper_queue->base_phys_addr);
624
625
626 return 0;
627 exit:
628 if (sc->copper_queue != NULL)
629 bus_dmamem_free(dmatag, sc->copper_queue, dmamap);
630 bus_dma_tag_destroy(dmatag);
631 return error;
632 }
633
634 /* see if we should reinitialize the card and wait for it to timeout or complete initialization FIXME */
635 int ips_copperhead_reinit(ips_softc_t *sc, int force)
636 {
637 int i, j;
638 u_int32_t postcode = 0, configstatus = 0;
639 ips_write_1(sc, COPPER_REG_SCPR, 0x80);
640 ips_write_1(sc, COPPER_REG_SCPR, 0);
641 device_printf(sc->dev, "reinitializing adapter, this could take several minutes.\n");
642 for(j = 0; j < 2; j++){
643 postcode <<= 8;
644 for(i = 0; i < 45; i++){
645 if(ips_read_1(sc, COPPER_REG_HISR) & COPPER_GHI_BIT){
646 postcode |= ips_read_1(sc, COPPER_REG_ISPR);
647 ips_write_1(sc, COPPER_REG_HISR,
648 COPPER_GHI_BIT);
649 break;
650 } else
651 DELAY(1000000);
652 }
653 if(i == 45)
654 return 1;
655 }
656 for(j = 0; j < 2; j++){
657 configstatus <<= 8;
658 for(i = 0; i < 240; i++){
659 if(ips_read_1(sc, COPPER_REG_HISR) & COPPER_GHI_BIT){
660 configstatus |= ips_read_1(sc, COPPER_REG_ISPR);
661 ips_write_1(sc, COPPER_REG_HISR,
662 COPPER_GHI_BIT);
663 break;
664 } else
665 DELAY(1000000);
666 }
667 if(i == 240)
668 return 1;
669 }
670 for(i = 0; i < 240; i++){
671 if(!(ips_read_1(sc, COPPER_REG_CBSP) & COPPER_OP_BIT)){
672 break;
673 } else
674 DELAY(1000000);
675 }
676 if(i == 240)
677 return 1;
678 ips_write_2(sc, COPPER_REG_CCCR, 0x1000 | COPPER_ILE_BIT);
679 ips_write_1(sc, COPPER_REG_SCPR, COPPER_EBM_BIT);
680 ips_copperhead_queue_init(sc);
681 ips_write_1(sc, COPPER_REG_HISR, COPPER_GHI_BIT);
682 i = ips_read_1(sc, COPPER_REG_SCPR);
683 ips_write_1(sc, COPPER_REG_HISR, COPPER_EI_BIT);
684 if(!configstatus){
685 device_printf(sc->dev, "adapter initialization failed\n");
686 return 1;
687 }
688 if(force && ips_clear_adapter(sc)){
689 device_printf(sc->dev, "adapter clear failed\n");
690 return 1;
691 }
692 return 0;
693 }
694 static u_int32_t ips_copperhead_cmd_status(ips_softc_t *sc)
695 {
696 u_int32_t value;
697 int statnum = sc->copper_queue->nextstatus++;
698 if(sc->copper_queue->nextstatus == IPS_MAX_CMD_NUM)
699 sc->copper_queue->nextstatus = 0;
700 value = sc->copper_queue->status[statnum];
701 ips_write_4(sc, COPPER_REG_SQTR, sc->copper_queue->base_phys_addr +
702 4 * statnum);
703 return value;
704 }
705
706
707 void ips_copperhead_intr(void *void_sc)
708 {
709 ips_softc_t *sc = (ips_softc_t *)void_sc;
710 int cmdnumber;
711 ips_cmd_status_t status;
712
713 mtx_lock(&sc->queue_mtx);
714 while(ips_read_1(sc, COPPER_REG_HISR) & COPPER_SCE_BIT){
715 status.value = ips_copperhead_cmd_status(sc);
716 cmdnumber = status.fields.command_id;
717 sc->commandarray[cmdnumber].status.value = status.value;
718 sc->commandarray[cmdnumber].timeout = 0;
719 sc->commandarray[cmdnumber].callback(&(sc->commandarray[cmdnumber]));
720 PRINTF(9, "ips: got command %d\n", cmdnumber);
721 }
722 mtx_unlock(&sc->queue_mtx);
723 return;
724 }
725
726 void ips_issue_copperhead_cmd(ips_command_t *command)
727 {
728 int i;
729 /* hmmm, is there a cleaner way to do this? */
730 if(command->sc->state & IPS_OFFLINE){
731 ips_set_error(command, EINVAL);
732 command->callback(command);
733 return;
734 }
735 command->timeout = 10;
736 for(i = 0; ips_read_4(command->sc, COPPER_REG_CCCR) & COPPER_SEM_BIT;
737 i++ ){
738 if( i == 20){
739 printf("sem bit still set, can't send a command\n");
740 return;
741 }
742 DELAY(500);/* need to do a delay here */
743 }
744 ips_write_4(command->sc, COPPER_REG_CCSAR, command->command_phys_addr);
745 ips_write_2(command->sc, COPPER_REG_CCCR, COPPER_CMD_START);
746 }
747
748 void ips_copperhead_poll(ips_command_t *command)
749 {
750
751 printf("ips: cmd polling not implemented for copperhead devices\n");
752 }
Cache object: 998f969624b1144dad60b7b4ee3f3b3e
|