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