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