The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ips/ips.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

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

Cache object: db2c8edb64753f2e67792c9cbaff6222


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.