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