LCOV - code coverage report
Current view: top level - drivers/pcmcia - pcmcia_resource.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 412 0.0 %
Date: 2022-03-28 13:20:08 Functions: 0 20 0.0 %
Branches: 0 191 0.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0-only
       2                 :            : /*
       3                 :            :  * PCMCIA 16-bit resource management functions
       4                 :            :  *
       5                 :            :  * The initial developer of the original code is David A. Hinds
       6                 :            :  * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
       7                 :            :  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
       8                 :            :  *
       9                 :            :  * Copyright (C) 1999        David A. Hinds
      10                 :            :  * Copyright (C) 2004-2010   Dominik Brodowski
      11                 :            :  */
      12                 :            : 
      13                 :            : #include <linux/module.h>
      14                 :            : #include <linux/kernel.h>
      15                 :            : #include <linux/interrupt.h>
      16                 :            : #include <linux/delay.h>
      17                 :            : #include <linux/pci.h>
      18                 :            : #include <linux/device.h>
      19                 :            : #include <linux/netdevice.h>
      20                 :            : #include <linux/slab.h>
      21                 :            : 
      22                 :            : #include <asm/irq.h>
      23                 :            : 
      24                 :            : #include <pcmcia/ss.h>
      25                 :            : #include <pcmcia/cistpl.h>
      26                 :            : #include <pcmcia/cisreg.h>
      27                 :            : #include <pcmcia/ds.h>
      28                 :            : 
      29                 :            : #include "cs_internal.h"
      30                 :            : 
      31                 :            : 
      32                 :            : /* Access speed for IO windows */
      33                 :            : static int io_speed;
      34                 :            : module_param(io_speed, int, 0444);
      35                 :            : 
      36                 :            : 
      37                 :          0 : int pcmcia_validate_mem(struct pcmcia_socket *s)
      38                 :            : {
      39         [ #  # ]:          0 :         if (s->resource_ops->validate_mem)
      40                 :          0 :                 return s->resource_ops->validate_mem(s);
      41                 :            :         /* if there is no callback, we can assume that everything is OK */
      42                 :            :         return 0;
      43                 :            : }
      44                 :            : 
      45                 :          0 : struct resource *pcmcia_find_mem_region(u_long base, u_long num, u_long align,
      46                 :            :                                  int low, struct pcmcia_socket *s)
      47                 :            : {
      48         [ #  # ]:          0 :         if (s->resource_ops->find_mem)
      49                 :          0 :                 return s->resource_ops->find_mem(base, num, align, low, s);
      50                 :            :         return NULL;
      51                 :            : }
      52                 :            : 
      53                 :            : 
      54                 :            : /**
      55                 :            :  * release_io_space() - release IO ports allocated with alloc_io_space()
      56                 :            :  * @s: pcmcia socket
      57                 :            :  * @res: resource to release
      58                 :            :  *
      59                 :            :  */
      60                 :          0 : static void release_io_space(struct pcmcia_socket *s, struct resource *res)
      61                 :            : {
      62                 :          0 :         resource_size_t num = resource_size(res);
      63                 :          0 :         int i;
      64                 :            : 
      65                 :          0 :         dev_dbg(&s->dev, "release_io_space for %pR\n", res);
      66                 :            : 
      67         [ #  # ]:          0 :         for (i = 0; i < MAX_IO_WIN; i++) {
      68         [ #  # ]:          0 :                 if (!s->io[i].res)
      69                 :          0 :                         continue;
      70         [ #  # ]:          0 :                 if ((s->io[i].res->start <= res->start) &&
      71         [ #  # ]:          0 :                     (s->io[i].res->end >= res->end)) {
      72                 :          0 :                         s->io[i].InUse -= num;
      73         [ #  # ]:          0 :                         if (res->parent)
      74                 :          0 :                                 release_resource(res);
      75                 :          0 :                         res->start = res->end = 0;
      76                 :          0 :                         res->flags = IORESOURCE_IO;
      77                 :            :                         /* Free the window if no one else is using it */
      78         [ #  # ]:          0 :                         if (s->io[i].InUse == 0) {
      79                 :          0 :                                 release_resource(s->io[i].res);
      80                 :          0 :                                 kfree(s->io[i].res);
      81                 :          0 :                                 s->io[i].res = NULL;
      82                 :            :                         }
      83                 :            :                 }
      84                 :            :         }
      85                 :          0 : }
      86                 :            : 
      87                 :            : 
      88                 :            : /**
      89                 :            :  * alloc_io_space() - allocate IO ports for use by a PCMCIA device
      90                 :            :  * @s: pcmcia socket
      91                 :            :  * @res: resource to allocate (begin: begin, end: size)
      92                 :            :  * @lines: number of IO lines decoded by the PCMCIA card
      93                 :            :  *
      94                 :            :  * Special stuff for managing IO windows, because they are scarce
      95                 :            :  */
      96                 :          0 : static int alloc_io_space(struct pcmcia_socket *s, struct resource *res,
      97                 :            :                         unsigned int lines)
      98                 :            : {
      99                 :          0 :         unsigned int align;
     100                 :          0 :         unsigned int base = res->start;
     101                 :          0 :         unsigned int num = res->end;
     102                 :          0 :         int ret;
     103                 :            : 
     104                 :          0 :         res->flags |= IORESOURCE_IO;
     105                 :            : 
     106                 :          0 :         dev_dbg(&s->dev, "alloc_io_space request for %pR, %d lines\n",
     107                 :            :                 res, lines);
     108                 :            : 
     109   [ #  #  #  # ]:          0 :         align = base ? (lines ? 1<<lines : 0) : 1;
     110         [ #  # ]:          0 :         if (align && (align < num)) {
     111         [ #  # ]:          0 :                 if (base) {
     112                 :            :                         dev_dbg(&s->dev, "odd IO request\n");
     113                 :            :                         align = 0;
     114                 :            :                 } else
     115         [ #  # ]:          0 :                         while (align && (align < num))
     116                 :          0 :                                 align <<= 1;
     117                 :            :         }
     118         [ #  # ]:          0 :         if (base & ~(align-1)) {
     119                 :          0 :                 dev_dbg(&s->dev, "odd IO request\n");
     120                 :          0 :                 align = 0;
     121                 :            :         }
     122                 :            : 
     123                 :          0 :         ret = s->resource_ops->find_io(s, res->flags, &base, num, align,
     124                 :            :                                 &res->parent);
     125         [ #  # ]:          0 :         if (ret) {
     126                 :            :                 dev_dbg(&s->dev, "alloc_io_space request failed (%d)\n", ret);
     127                 :            :                 return -EINVAL;
     128                 :            :         }
     129                 :            : 
     130                 :          0 :         res->start = base;
     131                 :          0 :         res->end = res->start + num - 1;
     132                 :            : 
     133         [ #  # ]:          0 :         if (res->parent) {
     134                 :          0 :                 ret = request_resource(res->parent, res);
     135         [ #  # ]:          0 :                 if (ret) {
     136                 :          0 :                         dev_warn(&s->dev,
     137                 :            :                                 "request_resource %pR failed: %d\n", res, ret);
     138                 :          0 :                         res->parent = NULL;
     139                 :          0 :                         release_io_space(s, res);
     140                 :            :                 }
     141                 :            :         }
     142                 :            :         dev_dbg(&s->dev, "alloc_io_space request result %d: %pR\n", ret, res);
     143                 :            :         return ret;
     144                 :            : }
     145                 :            : 
     146                 :            : 
     147                 :            : /**
     148                 :            :  * pcmcia_access_config() - read or write card configuration registers
     149                 :            :  *
     150                 :            :  * pcmcia_access_config() reads and writes configuration registers in
     151                 :            :  * attribute memory.  Memory window 0 is reserved for this and the tuple
     152                 :            :  * reading services. Drivers must use pcmcia_read_config_byte() or
     153                 :            :  * pcmcia_write_config_byte().
     154                 :            :  */
     155                 :          0 : static int pcmcia_access_config(struct pcmcia_device *p_dev,
     156                 :            :                                 off_t where, u8 *val,
     157                 :            :                                 int (*accessf) (struct pcmcia_socket *s,
     158                 :            :                                                 int attr, unsigned int addr,
     159                 :            :                                                 unsigned int len, void *ptr))
     160                 :            : {
     161                 :          0 :         struct pcmcia_socket *s;
     162                 :          0 :         config_t *c;
     163                 :          0 :         int addr;
     164                 :          0 :         int ret = 0;
     165                 :            : 
     166                 :          0 :         s = p_dev->socket;
     167                 :            : 
     168                 :          0 :         mutex_lock(&s->ops_mutex);
     169                 :          0 :         c = p_dev->function_config;
     170                 :            : 
     171         [ #  # ]:          0 :         if (!(c->state & CONFIG_LOCKED)) {
     172                 :          0 :                 dev_dbg(&p_dev->dev, "Configuration isn't locked\n");
     173                 :          0 :                 mutex_unlock(&s->ops_mutex);
     174                 :          0 :                 return -EACCES;
     175                 :            :         }
     176                 :            : 
     177                 :          0 :         addr = (p_dev->config_base + where) >> 1;
     178                 :            : 
     179                 :          0 :         ret = accessf(s, 1, addr, 1, val);
     180                 :            : 
     181                 :          0 :         mutex_unlock(&s->ops_mutex);
     182                 :            : 
     183                 :          0 :         return ret;
     184                 :            : }
     185                 :            : 
     186                 :            : 
     187                 :            : /**
     188                 :            :  * pcmcia_read_config_byte() - read a byte from a card configuration register
     189                 :            :  *
     190                 :            :  * pcmcia_read_config_byte() reads a byte from a configuration register in
     191                 :            :  * attribute memory.
     192                 :            :  */
     193                 :          0 : int pcmcia_read_config_byte(struct pcmcia_device *p_dev, off_t where, u8 *val)
     194                 :            : {
     195                 :          0 :         return pcmcia_access_config(p_dev, where, val, pcmcia_read_cis_mem);
     196                 :            : }
     197                 :            : EXPORT_SYMBOL(pcmcia_read_config_byte);
     198                 :            : 
     199                 :            : 
     200                 :            : /**
     201                 :            :  * pcmcia_write_config_byte() - write a byte to a card configuration register
     202                 :            :  *
     203                 :            :  * pcmcia_write_config_byte() writes a byte to a configuration register in
     204                 :            :  * attribute memory.
     205                 :            :  */
     206                 :          0 : int pcmcia_write_config_byte(struct pcmcia_device *p_dev, off_t where, u8 val)
     207                 :            : {
     208                 :          0 :         return pcmcia_access_config(p_dev, where, &val, pcmcia_write_cis_mem);
     209                 :            : }
     210                 :            : EXPORT_SYMBOL(pcmcia_write_config_byte);
     211                 :            : 
     212                 :            : 
     213                 :            : /**
     214                 :            :  * pcmcia_map_mem_page() - modify iomem window to point to a different offset
     215                 :            :  * @p_dev: pcmcia device
     216                 :            :  * @res: iomem resource already enabled by pcmcia_request_window()
     217                 :            :  * @offset: card_offset to map
     218                 :            :  *
     219                 :            :  * pcmcia_map_mem_page() modifies what can be read and written by accessing
     220                 :            :  * an iomem range previously enabled by pcmcia_request_window(), by setting
     221                 :            :  * the card_offset value to @offset.
     222                 :            :  */
     223                 :          0 : int pcmcia_map_mem_page(struct pcmcia_device *p_dev, struct resource *res,
     224                 :            :                         unsigned int offset)
     225                 :            : {
     226                 :          0 :         struct pcmcia_socket *s = p_dev->socket;
     227                 :          0 :         unsigned int w;
     228                 :          0 :         int ret;
     229                 :            : 
     230                 :          0 :         w = ((res->flags & IORESOURCE_BITS & WIN_FLAGS_REQ) >> 2) - 1;
     231         [ #  # ]:          0 :         if (w >= MAX_WIN)
     232                 :            :                 return -EINVAL;
     233                 :            : 
     234                 :          0 :         mutex_lock(&s->ops_mutex);
     235                 :          0 :         s->win[w].card_start = offset;
     236                 :          0 :         ret = s->ops->set_mem_map(s, &s->win[w]);
     237         [ #  # ]:          0 :         if (ret)
     238                 :          0 :                 dev_warn(&p_dev->dev, "failed to set_mem_map\n");
     239                 :          0 :         mutex_unlock(&s->ops_mutex);
     240                 :          0 :         return ret;
     241                 :            : }
     242                 :            : EXPORT_SYMBOL(pcmcia_map_mem_page);
     243                 :            : 
     244                 :            : 
     245                 :            : /**
     246                 :            :  * pcmcia_fixup_iowidth() - reduce io width to 8bit
     247                 :            :  * @p_dev: pcmcia device
     248                 :            :  *
     249                 :            :  * pcmcia_fixup_iowidth() allows a PCMCIA device driver to reduce the
     250                 :            :  * IO width to 8bit after having called pcmcia_enable_device()
     251                 :            :  * previously.
     252                 :            :  */
     253                 :          0 : int pcmcia_fixup_iowidth(struct pcmcia_device *p_dev)
     254                 :            : {
     255                 :          0 :         struct pcmcia_socket *s = p_dev->socket;
     256                 :          0 :         pccard_io_map io_off = { 0, 0, 0, 0, 1 };
     257                 :          0 :         pccard_io_map io_on;
     258                 :          0 :         int i, ret = 0;
     259                 :            : 
     260                 :          0 :         mutex_lock(&s->ops_mutex);
     261                 :            : 
     262                 :          0 :         dev_dbg(&p_dev->dev, "fixup iowidth to 8bit\n");
     263                 :            : 
     264         [ #  # ]:          0 :         if (!(s->state & SOCKET_PRESENT) ||
     265         [ #  # ]:          0 :                 !(p_dev->function_config->state & CONFIG_LOCKED)) {
     266                 :          0 :                 dev_dbg(&p_dev->dev, "No card? Config not locked?\n");
     267                 :          0 :                 ret = -EACCES;
     268                 :          0 :                 goto unlock;
     269                 :            :         }
     270                 :            : 
     271                 :          0 :         io_on.speed = io_speed;
     272         [ #  # ]:          0 :         for (i = 0; i < MAX_IO_WIN; i++) {
     273         [ #  # ]:          0 :                 if (!s->io[i].res)
     274                 :          0 :                         continue;
     275                 :          0 :                 io_off.map = i;
     276                 :          0 :                 io_on.map = i;
     277                 :            : 
     278                 :          0 :                 io_on.flags = MAP_ACTIVE | IO_DATA_PATH_WIDTH_8;
     279                 :          0 :                 io_on.start = s->io[i].res->start;
     280                 :          0 :                 io_on.stop = s->io[i].res->end;
     281                 :            : 
     282                 :          0 :                 s->ops->set_io_map(s, &io_off);
     283                 :          0 :                 msleep(40);
     284                 :          0 :                 s->ops->set_io_map(s, &io_on);
     285                 :            :         }
     286                 :          0 : unlock:
     287                 :          0 :         mutex_unlock(&s->ops_mutex);
     288                 :            : 
     289                 :          0 :         return ret;
     290                 :            : }
     291                 :            : EXPORT_SYMBOL(pcmcia_fixup_iowidth);
     292                 :            : 
     293                 :            : 
     294                 :            : /**
     295                 :            :  * pcmcia_fixup_vpp() - set Vpp to a new voltage level
     296                 :            :  * @p_dev: pcmcia device
     297                 :            :  * @new_vpp: new Vpp voltage
     298                 :            :  *
     299                 :            :  * pcmcia_fixup_vpp() allows a PCMCIA device driver to set Vpp to
     300                 :            :  * a new voltage level between calls to pcmcia_enable_device()
     301                 :            :  * and pcmcia_disable_device().
     302                 :            :  */
     303                 :          0 : int pcmcia_fixup_vpp(struct pcmcia_device *p_dev, unsigned char new_vpp)
     304                 :            : {
     305                 :          0 :         struct pcmcia_socket *s = p_dev->socket;
     306                 :          0 :         int ret = 0;
     307                 :            : 
     308                 :          0 :         mutex_lock(&s->ops_mutex);
     309                 :            : 
     310                 :          0 :         dev_dbg(&p_dev->dev, "fixup Vpp to %d\n", new_vpp);
     311                 :            : 
     312         [ #  # ]:          0 :         if (!(s->state & SOCKET_PRESENT) ||
     313         [ #  # ]:          0 :                 !(p_dev->function_config->state & CONFIG_LOCKED)) {
     314                 :          0 :                 dev_dbg(&p_dev->dev, "No card? Config not locked?\n");
     315                 :          0 :                 ret = -EACCES;
     316                 :          0 :                 goto unlock;
     317                 :            :         }
     318                 :            : 
     319                 :          0 :         s->socket.Vpp = new_vpp;
     320         [ #  # ]:          0 :         if (s->ops->set_socket(s, &s->socket)) {
     321                 :          0 :                 dev_warn(&p_dev->dev, "Unable to set VPP\n");
     322                 :          0 :                 ret = -EIO;
     323                 :          0 :                 goto unlock;
     324                 :            :         }
     325                 :          0 :         p_dev->vpp = new_vpp;
     326                 :            : 
     327                 :          0 : unlock:
     328                 :          0 :         mutex_unlock(&s->ops_mutex);
     329                 :            : 
     330                 :          0 :         return ret;
     331                 :            : }
     332                 :            : EXPORT_SYMBOL(pcmcia_fixup_vpp);
     333                 :            : 
     334                 :            : 
     335                 :            : /**
     336                 :            :  * pcmcia_release_configuration() - physically disable a PCMCIA device
     337                 :            :  * @p_dev: pcmcia device
     338                 :            :  *
     339                 :            :  * pcmcia_release_configuration() is the 1:1 counterpart to
     340                 :            :  * pcmcia_enable_device(): If a PCMCIA device is no longer used by any
     341                 :            :  * driver, the Vpp voltage is set to 0, IRQs will no longer be generated,
     342                 :            :  * and I/O ranges will be disabled. As pcmcia_release_io() and
     343                 :            :  * pcmcia_release_window() still need to be called, device drivers are
     344                 :            :  * expected to call pcmcia_disable_device() instead.
     345                 :            :  */
     346                 :          0 : int pcmcia_release_configuration(struct pcmcia_device *p_dev)
     347                 :            : {
     348                 :          0 :         pccard_io_map io = { 0, 0, 0, 0, 1 };
     349                 :          0 :         struct pcmcia_socket *s = p_dev->socket;
     350                 :          0 :         config_t *c;
     351                 :          0 :         int i;
     352                 :            : 
     353                 :          0 :         mutex_lock(&s->ops_mutex);
     354                 :          0 :         c = p_dev->function_config;
     355         [ #  # ]:          0 :         if (p_dev->_locked) {
     356                 :          0 :                 p_dev->_locked = 0;
     357         [ #  # ]:          0 :                 if (--(s->lock_count) == 0) {
     358                 :          0 :                         s->socket.flags = SS_OUTPUT_ENA; /* Is this correct? */
     359                 :          0 :                         s->socket.Vpp = 0;
     360                 :          0 :                         s->socket.io_irq = 0;
     361                 :          0 :                         s->ops->set_socket(s, &s->socket);
     362                 :            :                 }
     363                 :            :         }
     364         [ #  # ]:          0 :         if (c->state & CONFIG_LOCKED) {
     365                 :          0 :                 c->state &= ~CONFIG_LOCKED;
     366         [ #  # ]:          0 :                 if (c->state & CONFIG_IO_REQ)
     367         [ #  # ]:          0 :                         for (i = 0; i < MAX_IO_WIN; i++) {
     368         [ #  # ]:          0 :                                 if (!s->io[i].res)
     369                 :          0 :                                         continue;
     370                 :          0 :                                 s->io[i].Config--;
     371         [ #  # ]:          0 :                                 if (s->io[i].Config != 0)
     372                 :          0 :                                         continue;
     373                 :          0 :                                 io.map = i;
     374                 :          0 :                                 s->ops->set_io_map(s, &io);
     375                 :            :                         }
     376                 :            :         }
     377                 :          0 :         mutex_unlock(&s->ops_mutex);
     378                 :            : 
     379                 :          0 :         return 0;
     380                 :            : }
     381                 :            : 
     382                 :            : 
     383                 :            : /**
     384                 :            :  * pcmcia_release_io() - release I/O allocated by a PCMCIA device
     385                 :            :  * @p_dev: pcmcia device
     386                 :            :  *
     387                 :            :  * pcmcia_release_io() releases the I/O ranges allocated by a PCMCIA
     388                 :            :  * device.  This may be invoked some time after a card ejection has
     389                 :            :  * already dumped the actual socket configuration, so if the client is
     390                 :            :  * "stale", we don't bother checking the port ranges against the
     391                 :            :  * current socket values.
     392                 :            :  */
     393                 :          0 : static int pcmcia_release_io(struct pcmcia_device *p_dev)
     394                 :            : {
     395                 :          0 :         struct pcmcia_socket *s = p_dev->socket;
     396                 :          0 :         int ret = -EINVAL;
     397                 :          0 :         config_t *c;
     398                 :            : 
     399                 :          0 :         mutex_lock(&s->ops_mutex);
     400         [ #  # ]:          0 :         if (!p_dev->_io)
     401                 :          0 :                 goto out;
     402                 :            : 
     403                 :          0 :         c = p_dev->function_config;
     404                 :            : 
     405                 :          0 :         release_io_space(s, &c->io[0]);
     406                 :            : 
     407         [ #  # ]:          0 :         if (c->io[1].end)
     408                 :          0 :                 release_io_space(s, &c->io[1]);
     409                 :            : 
     410                 :          0 :         p_dev->_io = 0;
     411                 :          0 :         c->state &= ~CONFIG_IO_REQ;
     412                 :            : 
     413                 :          0 : out:
     414                 :          0 :         mutex_unlock(&s->ops_mutex);
     415                 :            : 
     416                 :          0 :         return ret;
     417                 :            : } /* pcmcia_release_io */
     418                 :            : 
     419                 :            : 
     420                 :            : /**
     421                 :            :  * pcmcia_release_window() - release reserved iomem for PCMCIA devices
     422                 :            :  * @p_dev: pcmcia device
     423                 :            :  * @res: iomem resource to release
     424                 :            :  *
     425                 :            :  * pcmcia_release_window() releases &struct resource *res which was
     426                 :            :  * previously reserved by calling pcmcia_request_window().
     427                 :            :  */
     428                 :          0 : int pcmcia_release_window(struct pcmcia_device *p_dev, struct resource *res)
     429                 :            : {
     430                 :          0 :         struct pcmcia_socket *s = p_dev->socket;
     431                 :          0 :         pccard_mem_map *win;
     432                 :          0 :         unsigned int w;
     433                 :            : 
     434                 :          0 :         dev_dbg(&p_dev->dev, "releasing window %pR\n", res);
     435                 :            : 
     436                 :          0 :         w = ((res->flags & IORESOURCE_BITS & WIN_FLAGS_REQ) >> 2) - 1;
     437         [ #  # ]:          0 :         if (w >= MAX_WIN)
     438                 :            :                 return -EINVAL;
     439                 :            : 
     440                 :          0 :         mutex_lock(&s->ops_mutex);
     441                 :          0 :         win = &s->win[w];
     442                 :            : 
     443         [ #  # ]:          0 :         if (!(p_dev->_win & CLIENT_WIN_REQ(w))) {
     444                 :          0 :                 dev_dbg(&p_dev->dev, "not releasing unknown window\n");
     445                 :          0 :                 mutex_unlock(&s->ops_mutex);
     446                 :          0 :                 return -EINVAL;
     447                 :            :         }
     448                 :            : 
     449                 :            :         /* Shut down memory window */
     450                 :          0 :         win->flags &= ~MAP_ACTIVE;
     451                 :          0 :         s->ops->set_mem_map(s, win);
     452                 :          0 :         s->state &= ~SOCKET_WIN_REQ(w);
     453                 :            : 
     454                 :            :         /* Release system memory */
     455         [ #  # ]:          0 :         if (win->res) {
     456                 :          0 :                 release_resource(res);
     457                 :          0 :                 release_resource(win->res);
     458                 :          0 :                 kfree(win->res);
     459                 :          0 :                 win->res = NULL;
     460                 :            :         }
     461                 :          0 :         res->start = res->end = 0;
     462                 :          0 :         res->flags = IORESOURCE_MEM;
     463                 :          0 :         p_dev->_win &= ~CLIENT_WIN_REQ(w);
     464                 :          0 :         mutex_unlock(&s->ops_mutex);
     465                 :            : 
     466                 :          0 :         return 0;
     467                 :            : } /* pcmcia_release_window */
     468                 :            : EXPORT_SYMBOL(pcmcia_release_window);
     469                 :            : 
     470                 :            : 
     471                 :            : /**
     472                 :            :  * pcmcia_enable_device() - set up and activate a PCMCIA device
     473                 :            :  * @p_dev: the associated PCMCIA device
     474                 :            :  *
     475                 :            :  * pcmcia_enable_device() physically enables a PCMCIA device. It parses
     476                 :            :  * the flags passed to in @flags and stored in @p_dev->flags and sets up
     477                 :            :  * the Vpp voltage, enables the speaker line, I/O ports and store proper
     478                 :            :  * values to configuration registers.
     479                 :            :  */
     480                 :          0 : int pcmcia_enable_device(struct pcmcia_device *p_dev)
     481                 :            : {
     482                 :          0 :         int i;
     483                 :          0 :         unsigned int base;
     484                 :          0 :         struct pcmcia_socket *s = p_dev->socket;
     485                 :          0 :         config_t *c;
     486                 :          0 :         pccard_io_map iomap;
     487                 :          0 :         unsigned char status = 0;
     488                 :          0 :         unsigned char ext_status = 0;
     489                 :          0 :         unsigned char option = 0;
     490                 :          0 :         unsigned int flags = p_dev->config_flags;
     491                 :            : 
     492         [ #  # ]:          0 :         if (!(s->state & SOCKET_PRESENT))
     493                 :            :                 return -ENODEV;
     494                 :            : 
     495                 :          0 :         mutex_lock(&s->ops_mutex);
     496                 :          0 :         c = p_dev->function_config;
     497         [ #  # ]:          0 :         if (c->state & CONFIG_LOCKED) {
     498                 :          0 :                 mutex_unlock(&s->ops_mutex);
     499                 :          0 :                 dev_dbg(&p_dev->dev, "Configuration is locked\n");
     500                 :          0 :                 return -EACCES;
     501                 :            :         }
     502                 :            : 
     503                 :            :         /* Do power control.  We don't allow changes in Vcc. */
     504                 :          0 :         s->socket.Vpp = p_dev->vpp;
     505         [ #  # ]:          0 :         if (s->ops->set_socket(s, &s->socket)) {
     506                 :          0 :                 mutex_unlock(&s->ops_mutex);
     507                 :          0 :                 dev_warn(&p_dev->dev, "Unable to set socket state\n");
     508                 :          0 :                 return -EINVAL;
     509                 :            :         }
     510                 :            : 
     511                 :            :         /* Pick memory or I/O card, DMA mode, interrupt */
     512   [ #  #  #  # ]:          0 :         if (p_dev->_io || flags & CONF_ENABLE_IRQ)
     513                 :          0 :                 flags |= CONF_ENABLE_IOCARD;
     514         [ #  # ]:          0 :         if (flags & CONF_ENABLE_IOCARD)
     515                 :          0 :                 s->socket.flags |= SS_IOCARD;
     516         [ #  # ]:          0 :         if (flags & CONF_ENABLE_ZVCARD)
     517                 :          0 :                 s->socket.flags |= SS_ZVCARD | SS_IOCARD;
     518         [ #  # ]:          0 :         if (flags & CONF_ENABLE_SPKR) {
     519                 :          0 :                 s->socket.flags |= SS_SPKR_ENA;
     520                 :          0 :                 status = CCSR_AUDIO_ENA;
     521         [ #  # ]:          0 :                 if (!(p_dev->config_regs & PRESENT_STATUS))
     522                 :          0 :                         dev_warn(&p_dev->dev, "speaker requested, but "
     523                 :            :                                               "PRESENT_STATUS not set!\n");
     524                 :            :         }
     525         [ #  # ]:          0 :         if (flags & CONF_ENABLE_IRQ)
     526                 :          0 :                 s->socket.io_irq = s->pcmcia_irq;
     527                 :            :         else
     528                 :          0 :                 s->socket.io_irq = 0;
     529         [ #  # ]:          0 :         if (flags & CONF_ENABLE_ESR) {
     530                 :          0 :                 p_dev->config_regs |= PRESENT_EXT_STATUS;
     531                 :          0 :                 ext_status = ESR_REQ_ATTN_ENA;
     532                 :            :         }
     533                 :          0 :         s->ops->set_socket(s, &s->socket);
     534                 :          0 :         s->lock_count++;
     535                 :            : 
     536                 :          0 :         dev_dbg(&p_dev->dev,
     537                 :            :                 "enable_device: V %d, flags %x, base %x, regs %x, idx %x\n",
     538                 :            :                 p_dev->vpp, flags, p_dev->config_base, p_dev->config_regs,
     539                 :            :                 p_dev->config_index);
     540                 :            : 
     541                 :            :         /* Set up CIS configuration registers */
     542                 :          0 :         base = p_dev->config_base;
     543         [ #  # ]:          0 :         if (p_dev->config_regs & PRESENT_COPY) {
     544                 :          0 :                 u16 tmp = 0;
     545                 :          0 :                 dev_dbg(&p_dev->dev, "clearing CISREG_SCR\n");
     546                 :          0 :                 pcmcia_write_cis_mem(s, 1, (base + CISREG_SCR)>>1, 1, &tmp);
     547                 :            :         }
     548         [ #  # ]:          0 :         if (p_dev->config_regs & PRESENT_PIN_REPLACE) {
     549                 :          0 :                 u16 tmp = 0;
     550                 :          0 :                 dev_dbg(&p_dev->dev, "clearing CISREG_PRR\n");
     551                 :          0 :                 pcmcia_write_cis_mem(s, 1, (base + CISREG_PRR)>>1, 1, &tmp);
     552                 :            :         }
     553         [ #  # ]:          0 :         if (p_dev->config_regs & PRESENT_OPTION) {
     554         [ #  # ]:          0 :                 if (s->functions == 1) {
     555                 :          0 :                         option = p_dev->config_index & COR_CONFIG_MASK;
     556                 :            :                 } else {
     557                 :          0 :                         option = p_dev->config_index & COR_MFC_CONFIG_MASK;
     558                 :          0 :                         option |= COR_FUNC_ENA|COR_IREQ_ENA;
     559         [ #  # ]:          0 :                         if (p_dev->config_regs & PRESENT_IOBASE_0)
     560                 :          0 :                                 option |= COR_ADDR_DECODE;
     561                 :            :                 }
     562         [ #  # ]:          0 :                 if ((flags & CONF_ENABLE_IRQ) &&
     563                 :            :                         !(flags & CONF_ENABLE_PULSE_IRQ))
     564                 :          0 :                         option |= COR_LEVEL_REQ;
     565                 :          0 :                 pcmcia_write_cis_mem(s, 1, (base + CISREG_COR)>>1, 1, &option);
     566                 :          0 :                 msleep(40);
     567                 :            :         }
     568         [ #  # ]:          0 :         if (p_dev->config_regs & PRESENT_STATUS)
     569                 :          0 :                 pcmcia_write_cis_mem(s, 1, (base + CISREG_CCSR)>>1, 1, &status);
     570                 :            : 
     571         [ #  # ]:          0 :         if (p_dev->config_regs & PRESENT_EXT_STATUS)
     572                 :          0 :                 pcmcia_write_cis_mem(s, 1, (base + CISREG_ESR)>>1, 1,
     573                 :            :                                         &ext_status);
     574                 :            : 
     575         [ #  # ]:          0 :         if (p_dev->config_regs & PRESENT_IOBASE_0) {
     576                 :          0 :                 u8 b = c->io[0].start & 0xff;
     577                 :          0 :                 pcmcia_write_cis_mem(s, 1, (base + CISREG_IOBASE_0)>>1, 1, &b);
     578                 :          0 :                 b = (c->io[0].start >> 8) & 0xff;
     579                 :          0 :                 pcmcia_write_cis_mem(s, 1, (base + CISREG_IOBASE_1)>>1, 1, &b);
     580                 :            :         }
     581         [ #  # ]:          0 :         if (p_dev->config_regs & PRESENT_IOSIZE) {
     582                 :          0 :                 u8 b = resource_size(&c->io[0]) + resource_size(&c->io[1]) - 1;
     583                 :          0 :                 pcmcia_write_cis_mem(s, 1, (base + CISREG_IOSIZE)>>1, 1, &b);
     584                 :            :         }
     585                 :            : 
     586                 :            :         /* Configure I/O windows */
     587         [ #  # ]:          0 :         if (c->state & CONFIG_IO_REQ) {
     588                 :          0 :                 iomap.speed = io_speed;
     589         [ #  # ]:          0 :                 for (i = 0; i < MAX_IO_WIN; i++)
     590         [ #  # ]:          0 :                         if (s->io[i].res) {
     591                 :          0 :                                 iomap.map = i;
     592                 :          0 :                                 iomap.flags = MAP_ACTIVE;
     593      [ #  #  # ]:          0 :                                 switch (s->io[i].res->flags & IO_DATA_PATH_WIDTH) {
     594                 :          0 :                                 case IO_DATA_PATH_WIDTH_16:
     595                 :          0 :                                         iomap.flags |= MAP_16BIT; break;
     596                 :          0 :                                 case IO_DATA_PATH_WIDTH_AUTO:
     597                 :          0 :                                         iomap.flags |= MAP_AUTOSZ; break;
     598                 :            :                                 default:
     599                 :            :                                         break;
     600                 :            :                                 }
     601                 :          0 :                                 iomap.start = s->io[i].res->start;
     602                 :          0 :                                 iomap.stop = s->io[i].res->end;
     603                 :          0 :                                 s->ops->set_io_map(s, &iomap);
     604                 :          0 :                                 s->io[i].Config++;
     605                 :            :                         }
     606                 :            :         }
     607                 :            : 
     608                 :          0 :         c->state |= CONFIG_LOCKED;
     609                 :          0 :         p_dev->_locked = 1;
     610                 :          0 :         mutex_unlock(&s->ops_mutex);
     611                 :          0 :         return 0;
     612                 :            : } /* pcmcia_enable_device */
     613                 :            : EXPORT_SYMBOL(pcmcia_enable_device);
     614                 :            : 
     615                 :            : 
     616                 :            : /**
     617                 :            :  * pcmcia_request_io() - attempt to reserve port ranges for PCMCIA devices
     618                 :            :  * @p_dev: the associated PCMCIA device
     619                 :            :  *
     620                 :            :  * pcmcia_request_io() attempts to reserve the IO port ranges specified in
     621                 :            :  * &struct pcmcia_device @p_dev->resource[0] and @p_dev->resource[1]. The
     622                 :            :  * "start" value is the requested start of the IO port resource; "end"
     623                 :            :  * reflects the number of ports requested. The number of IO lines requested
     624                 :            :  * is specified in &struct pcmcia_device @p_dev->io_lines.
     625                 :            :  */
     626                 :          0 : int pcmcia_request_io(struct pcmcia_device *p_dev)
     627                 :            : {
     628                 :          0 :         struct pcmcia_socket *s = p_dev->socket;
     629                 :          0 :         config_t *c = p_dev->function_config;
     630                 :          0 :         int ret = -EINVAL;
     631                 :            : 
     632                 :          0 :         mutex_lock(&s->ops_mutex);
     633                 :          0 :         dev_dbg(&p_dev->dev, "pcmcia_request_io: %pR , %pR",
     634                 :            :                 &c->io[0], &c->io[1]);
     635                 :            : 
     636         [ #  # ]:          0 :         if (!(s->state & SOCKET_PRESENT)) {
     637                 :          0 :                 dev_dbg(&p_dev->dev, "pcmcia_request_io: No card present\n");
     638                 :          0 :                 goto out;
     639                 :            :         }
     640                 :            : 
     641         [ #  # ]:          0 :         if (c->state & CONFIG_LOCKED) {
     642                 :          0 :                 dev_dbg(&p_dev->dev, "Configuration is locked\n");
     643                 :          0 :                 goto out;
     644                 :            :         }
     645         [ #  # ]:          0 :         if (c->state & CONFIG_IO_REQ) {
     646                 :          0 :                 dev_dbg(&p_dev->dev, "IO already configured\n");
     647                 :          0 :                 goto out;
     648                 :            :         }
     649                 :            : 
     650                 :          0 :         ret = alloc_io_space(s, &c->io[0], p_dev->io_lines);
     651         [ #  # ]:          0 :         if (ret)
     652                 :          0 :                 goto out;
     653                 :            : 
     654         [ #  # ]:          0 :         if (c->io[1].end) {
     655                 :          0 :                 ret = alloc_io_space(s, &c->io[1], p_dev->io_lines);
     656         [ #  # ]:          0 :                 if (ret) {
     657                 :          0 :                         struct resource tmp = c->io[0];
     658                 :            :                         /* release the previously allocated resource */
     659                 :          0 :                         release_io_space(s, &c->io[0]);
     660                 :            :                         /* but preserve the settings, for they worked... */
     661                 :          0 :                         c->io[0].end = resource_size(&tmp);
     662                 :          0 :                         c->io[0].start = tmp.start;
     663                 :          0 :                         c->io[0].flags = tmp.flags;
     664                 :          0 :                         goto out;
     665                 :            :                 }
     666                 :            :         } else
     667                 :          0 :                 c->io[1].start = 0;
     668                 :            : 
     669                 :          0 :         c->state |= CONFIG_IO_REQ;
     670                 :          0 :         p_dev->_io = 1;
     671                 :            : 
     672                 :          0 :         dev_dbg(&p_dev->dev, "pcmcia_request_io succeeded: %pR , %pR",
     673                 :            :                 &c->io[0], &c->io[1]);
     674                 :          0 : out:
     675                 :          0 :         mutex_unlock(&s->ops_mutex);
     676                 :            : 
     677                 :          0 :         return ret;
     678                 :            : } /* pcmcia_request_io */
     679                 :            : EXPORT_SYMBOL(pcmcia_request_io);
     680                 :            : 
     681                 :            : 
     682                 :            : /**
     683                 :            :  * pcmcia_request_irq() - attempt to request a IRQ for a PCMCIA device
     684                 :            :  * @p_dev: the associated PCMCIA device
     685                 :            :  * @handler: IRQ handler to register
     686                 :            :  *
     687                 :            :  * pcmcia_request_irq() is a wrapper around request_irq() which allows
     688                 :            :  * the PCMCIA core to clean up the registration in pcmcia_disable_device().
     689                 :            :  * Drivers are free to use request_irq() directly, but then they need to
     690                 :            :  * call free_irq() themselfves, too. Also, only %IRQF_SHARED capable IRQ
     691                 :            :  * handlers are allowed.
     692                 :            :  */
     693                 :          0 : int __must_check pcmcia_request_irq(struct pcmcia_device *p_dev,
     694                 :            :                                     irq_handler_t handler)
     695                 :            : {
     696                 :          0 :         int ret;
     697                 :            : 
     698         [ #  # ]:          0 :         if (!p_dev->irq)
     699                 :            :                 return -EINVAL;
     700                 :            : 
     701                 :          0 :         ret = request_irq(p_dev->irq, handler, IRQF_SHARED,
     702                 :          0 :                         p_dev->devname, p_dev->priv);
     703         [ #  # ]:          0 :         if (!ret)
     704                 :          0 :                 p_dev->_irq = 1;
     705                 :            : 
     706                 :            :         return ret;
     707                 :            : }
     708                 :            : EXPORT_SYMBOL(pcmcia_request_irq);
     709                 :            : 
     710                 :            : 
     711                 :            : #ifdef CONFIG_PCMCIA_PROBE
     712                 :            : 
     713                 :            : /* mask of IRQs already reserved by other cards, we should avoid using them */
     714                 :            : static u8 pcmcia_used_irq[32];
     715                 :            : 
     716                 :            : static irqreturn_t test_action(int cpl, void *dev_id)
     717                 :            : {
     718                 :            :         return IRQ_NONE;
     719                 :            : }
     720                 :            : 
     721                 :            : /**
     722                 :            :  * pcmcia_setup_isa_irq() - determine whether an ISA IRQ can be used
     723                 :            :  * @p_dev - the associated PCMCIA device
     724                 :            :  *
     725                 :            :  * locking note: must be called with ops_mutex locked.
     726                 :            :  */
     727                 :            : static int pcmcia_setup_isa_irq(struct pcmcia_device *p_dev, int type)
     728                 :            : {
     729                 :            :         struct pcmcia_socket *s = p_dev->socket;
     730                 :            :         unsigned int try, irq;
     731                 :            :         u32 mask = s->irq_mask;
     732                 :            :         int ret = -ENODEV;
     733                 :            : 
     734                 :            :         for (try = 0; try < 64; try++) {
     735                 :            :                 irq = try % 32;
     736                 :            : 
     737                 :            :                 if (irq > NR_IRQS)
     738                 :            :                         continue;
     739                 :            : 
     740                 :            :                 /* marked as available by driver, not blocked by userspace? */
     741                 :            :                 if (!((mask >> irq) & 1))
     742                 :            :                         continue;
     743                 :            : 
     744                 :            :                 /* avoid an IRQ which is already used by another PCMCIA card */
     745                 :            :                 if ((try < 32) && pcmcia_used_irq[irq])
     746                 :            :                         continue;
     747                 :            : 
     748                 :            :                 /* register the correct driver, if possible, to check whether
     749                 :            :                  * registering a dummy handle works, i.e. if the IRQ isn't
     750                 :            :                  * marked as used by the kernel resource management core */
     751                 :            :                 ret = request_irq(irq, test_action, type, p_dev->devname,
     752                 :            :                                   p_dev);
     753                 :            :                 if (!ret) {
     754                 :            :                         free_irq(irq, p_dev);
     755                 :            :                         p_dev->irq = s->pcmcia_irq = irq;
     756                 :            :                         pcmcia_used_irq[irq]++;
     757                 :            :                         break;
     758                 :            :                 }
     759                 :            :         }
     760                 :            : 
     761                 :            :         return ret;
     762                 :            : }
     763                 :            : 
     764                 :            : void pcmcia_cleanup_irq(struct pcmcia_socket *s)
     765                 :            : {
     766                 :            :         pcmcia_used_irq[s->pcmcia_irq]--;
     767                 :            :         s->pcmcia_irq = 0;
     768                 :            : }
     769                 :            : 
     770                 :            : #else /* CONFIG_PCMCIA_PROBE */
     771                 :            : 
     772                 :          0 : static int pcmcia_setup_isa_irq(struct pcmcia_device *p_dev, int type)
     773                 :            : {
     774                 :          0 :         return -EINVAL;
     775                 :            : }
     776                 :            : 
     777                 :          0 : void pcmcia_cleanup_irq(struct pcmcia_socket *s)
     778                 :            : {
     779                 :          0 :         s->pcmcia_irq = 0;
     780                 :          0 :         return;
     781                 :            : }
     782                 :            : 
     783                 :            : #endif  /* CONFIG_PCMCIA_PROBE */
     784                 :            : 
     785                 :            : 
     786                 :            : /**
     787                 :            :  * pcmcia_setup_irq() - determine IRQ to be used for device
     788                 :            :  * @p_dev - the associated PCMCIA device
     789                 :            :  *
     790                 :            :  * locking note: must be called with ops_mutex locked.
     791                 :            :  */
     792                 :          0 : int pcmcia_setup_irq(struct pcmcia_device *p_dev)
     793                 :            : {
     794                 :          0 :         struct pcmcia_socket *s = p_dev->socket;
     795                 :            : 
     796         [ #  # ]:          0 :         if (p_dev->irq)
     797                 :            :                 return 0;
     798                 :            : 
     799                 :            :         /* already assigned? */
     800         [ #  # ]:          0 :         if (s->pcmcia_irq) {
     801                 :          0 :                 p_dev->irq = s->pcmcia_irq;
     802                 :          0 :                 return 0;
     803                 :            :         }
     804                 :            : 
     805                 :            :         /* prefer an exclusive ISA irq */
     806                 :          0 :         if (!pcmcia_setup_isa_irq(p_dev, 0))
     807                 :            :                 return 0;
     808                 :            : 
     809                 :            :         /* but accept a shared ISA irq */
     810                 :          0 :         if (!pcmcia_setup_isa_irq(p_dev, IRQF_SHARED))
     811                 :            :                 return 0;
     812                 :            : 
     813                 :            :         /* but use the PCI irq otherwise */
     814         [ #  # ]:          0 :         if (s->pci_irq) {
     815                 :          0 :                 p_dev->irq = s->pcmcia_irq = s->pci_irq;
     816                 :          0 :                 return 0;
     817                 :            :         }
     818                 :            : 
     819                 :            :         return -EINVAL;
     820                 :            : }
     821                 :            : 
     822                 :            : 
     823                 :            : /**
     824                 :            :  * pcmcia_request_window() - attempt to reserve iomem for PCMCIA devices
     825                 :            :  * @p_dev: the associated PCMCIA device
     826                 :            :  * @res: &struct resource pointing to p_dev->resource[2..5]
     827                 :            :  * @speed: access speed
     828                 :            :  *
     829                 :            :  * pcmcia_request_window() attepts to reserve an iomem ranges specified in
     830                 :            :  * &struct resource @res pointing to one of the entries in
     831                 :            :  * &struct pcmcia_device @p_dev->resource[2..5]. The "start" value is the
     832                 :            :  * requested start of the IO mem resource; "end" reflects the size
     833                 :            :  * requested.
     834                 :            :  */
     835                 :          0 : int pcmcia_request_window(struct pcmcia_device *p_dev, struct resource *res,
     836                 :            :                         unsigned int speed)
     837                 :            : {
     838                 :          0 :         struct pcmcia_socket *s = p_dev->socket;
     839                 :          0 :         pccard_mem_map *win;
     840                 :          0 :         u_long align;
     841                 :          0 :         int w;
     842                 :            : 
     843                 :          0 :         dev_dbg(&p_dev->dev, "request_window %pR %d\n", res, speed);
     844                 :            : 
     845         [ #  # ]:          0 :         if (!(s->state & SOCKET_PRESENT)) {
     846                 :            :                 dev_dbg(&p_dev->dev, "No card present\n");
     847                 :            :                 return -ENODEV;
     848                 :            :         }
     849                 :            : 
     850                 :            :         /* Window size defaults to smallest available */
     851         [ #  # ]:          0 :         if (res->end == 0)
     852                 :          0 :                 res->end = s->map_size;
     853         [ #  # ]:          0 :         align = (s->features & SS_CAP_MEM_ALIGN) ? res->end : s->map_size;
     854         [ #  # ]:          0 :         if (res->end & (s->map_size-1)) {
     855                 :            :                 dev_dbg(&p_dev->dev, "invalid map size\n");
     856                 :            :                 return -EINVAL;
     857                 :            :         }
     858   [ #  #  #  # ]:          0 :         if ((res->start && (s->features & SS_CAP_STATIC_MAP)) ||
     859         [ #  # ]:          0 :             (res->start & (align-1))) {
     860                 :            :                 dev_dbg(&p_dev->dev, "invalid base address\n");
     861                 :            :                 return -EINVAL;
     862                 :            :         }
     863         [ #  # ]:          0 :         if (res->start)
     864                 :          0 :                 align = 0;
     865                 :            : 
     866                 :            :         /* Allocate system memory window */
     867                 :          0 :         mutex_lock(&s->ops_mutex);
     868         [ #  # ]:          0 :         for (w = 0; w < MAX_WIN; w++)
     869         [ #  # ]:          0 :                 if (!(s->state & SOCKET_WIN_REQ(w)))
     870                 :            :                         break;
     871         [ #  # ]:          0 :         if (w == MAX_WIN) {
     872                 :          0 :                 dev_dbg(&p_dev->dev, "all windows are used already\n");
     873                 :          0 :                 mutex_unlock(&s->ops_mutex);
     874                 :          0 :                 return -EINVAL;
     875                 :            :         }
     876                 :            : 
     877                 :          0 :         win = &s->win[w];
     878                 :            : 
     879         [ #  # ]:          0 :         if (!(s->features & SS_CAP_STATIC_MAP)) {
     880         [ #  # ]:          0 :                 win->res = pcmcia_find_mem_region(res->start, res->end, align,
     881                 :            :                                                 0, s);
     882         [ #  # ]:          0 :                 if (!win->res) {
     883                 :          0 :                         dev_dbg(&p_dev->dev, "allocating mem region failed\n");
     884                 :          0 :                         mutex_unlock(&s->ops_mutex);
     885                 :          0 :                         return -EINVAL;
     886                 :            :                 }
     887                 :            :         }
     888                 :          0 :         p_dev->_win |= CLIENT_WIN_REQ(w);
     889                 :            : 
     890                 :            :         /* Configure the socket controller */
     891                 :          0 :         win->map = w+1;
     892                 :          0 :         win->flags = res->flags & WIN_FLAGS_MAP;
     893                 :          0 :         win->speed = speed;
     894                 :          0 :         win->card_start = 0;
     895                 :            : 
     896         [ #  # ]:          0 :         if (s->ops->set_mem_map(s, win) != 0) {
     897                 :          0 :                 dev_dbg(&p_dev->dev, "failed to set memory mapping\n");
     898                 :          0 :                 mutex_unlock(&s->ops_mutex);
     899                 :          0 :                 return -EIO;
     900                 :            :         }
     901                 :          0 :         s->state |= SOCKET_WIN_REQ(w);
     902                 :            : 
     903                 :            :         /* Return window handle */
     904         [ #  # ]:          0 :         if (s->features & SS_CAP_STATIC_MAP)
     905                 :          0 :                 res->start = win->static_start;
     906                 :            :         else
     907                 :          0 :                 res->start = win->res->start;
     908                 :            : 
     909                 :            :         /* convert to new-style resources */
     910                 :          0 :         res->end += res->start - 1;
     911                 :          0 :         res->flags &= ~WIN_FLAGS_REQ;
     912                 :          0 :         res->flags |= (win->map << 2) | IORESOURCE_MEM;
     913                 :          0 :         res->parent = win->res;
     914         [ #  # ]:          0 :         if (win->res)
     915                 :          0 :                 request_resource(&iomem_resource, res);
     916                 :            : 
     917                 :          0 :         dev_dbg(&p_dev->dev, "request_window results in %pR\n", res);
     918                 :            : 
     919                 :          0 :         mutex_unlock(&s->ops_mutex);
     920                 :            : 
     921                 :          0 :         return 0;
     922                 :            : } /* pcmcia_request_window */
     923                 :            : EXPORT_SYMBOL(pcmcia_request_window);
     924                 :            : 
     925                 :            : 
     926                 :            : /**
     927                 :            :  * pcmcia_disable_device() - disable and clean up a PCMCIA device
     928                 :            :  * @p_dev: the associated PCMCIA device
     929                 :            :  *
     930                 :            :  * pcmcia_disable_device() is the driver-callable counterpart to
     931                 :            :  * pcmcia_enable_device(): If a PCMCIA device is no longer used,
     932                 :            :  * drivers are expected to clean up and disable the device by calling
     933                 :            :  * this function. Any I/O ranges (iomem and ioports) will be released,
     934                 :            :  * the Vpp voltage will be set to 0, and IRQs will no longer be
     935                 :            :  * generated -- at least if there is no other card function (of
     936                 :            :  * multifunction devices) being used.
     937                 :            :  */
     938                 :          0 : void pcmcia_disable_device(struct pcmcia_device *p_dev)
     939                 :            : {
     940                 :          0 :         int i;
     941                 :            : 
     942                 :          0 :         dev_dbg(&p_dev->dev, "disabling device\n");
     943                 :            : 
     944         [ #  # ]:          0 :         for (i = 0; i < MAX_WIN; i++) {
     945                 :          0 :                 struct resource *res = p_dev->resource[MAX_IO_WIN + i];
     946         [ #  # ]:          0 :                 if (res->flags & WIN_FLAGS_REQ)
     947                 :          0 :                         pcmcia_release_window(p_dev, res);
     948                 :            :         }
     949                 :            : 
     950                 :          0 :         pcmcia_release_configuration(p_dev);
     951                 :          0 :         pcmcia_release_io(p_dev);
     952         [ #  # ]:          0 :         if (p_dev->_irq) {
     953                 :          0 :                 free_irq(p_dev->irq, p_dev->priv);
     954                 :          0 :                 p_dev->_irq = 0;
     955                 :            :         }
     956                 :          0 : }
     957                 :            : EXPORT_SYMBOL(pcmcia_disable_device);

Generated by: LCOV version 1.14