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