pcmcia_resource.c (9a457a524762edc1bb1ded65b7a75c01738632d5) pcmcia_resource.c (cdb138080b78146d1cdadba9f5dadbeb97445b91)
1/*
2 * PCMCIA 16-bit resource management functions
3 *
4 * The initial developer of the original code is David A. Hinds
5 * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
6 * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
7 *
8 * Copyright (C) 1999 David A. Hinds

--- 190 unchanged lines hidden (view full) ---

199 */
200int pcmcia_write_config_byte(struct pcmcia_device *p_dev, off_t where, u8 val)
201{
202 return pcmcia_access_config(p_dev, where, &val, pcmcia_write_cis_mem);
203}
204EXPORT_SYMBOL(pcmcia_write_config_byte);
205
206
1/*
2 * PCMCIA 16-bit resource management functions
3 *
4 * The initial developer of the original code is David A. Hinds
5 * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
6 * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
7 *
8 * Copyright (C) 1999 David A. Hinds

--- 190 unchanged lines hidden (view full) ---

199 */
200int pcmcia_write_config_byte(struct pcmcia_device *p_dev, off_t where, u8 val)
201{
202 return pcmcia_access_config(p_dev, where, &val, pcmcia_write_cis_mem);
203}
204EXPORT_SYMBOL(pcmcia_write_config_byte);
205
206
207int pcmcia_map_mem_page(struct pcmcia_device *p_dev, window_handle_t wh,
207int pcmcia_map_mem_page(struct pcmcia_device *p_dev, struct resource *res,
208 unsigned int offset)
209{
210 struct pcmcia_socket *s = p_dev->socket;
208 unsigned int offset)
209{
210 struct pcmcia_socket *s = p_dev->socket;
211 struct resource *res = wh;
212 unsigned int w;
213 int ret;
214
215 w = ((res->flags & IORESOURCE_BITS & WIN_FLAGS_REQ) >> 2) - 1;
216 if (w >= MAX_WIN)
217 return -EINVAL;
218
219 mutex_lock(&s->ops_mutex);

--- 161 unchanged lines hidden (view full) ---

381 c->state &= ~CONFIG_IO_REQ;
382
383out:
384 mutex_unlock(&s->ops_mutex);
385
386 return ret;
387} /* pcmcia_release_io */
388
211 unsigned int w;
212 int ret;
213
214 w = ((res->flags & IORESOURCE_BITS & WIN_FLAGS_REQ) >> 2) - 1;
215 if (w >= MAX_WIN)
216 return -EINVAL;
217
218 mutex_lock(&s->ops_mutex);

--- 161 unchanged lines hidden (view full) ---

380 c->state &= ~CONFIG_IO_REQ;
381
382out:
383 mutex_unlock(&s->ops_mutex);
384
385 return ret;
386} /* pcmcia_release_io */
387
389
388/**
389 * pcmcia_release_window() - release reserved iomem for PCMCIA devices
390 *
391 * pcmcia_release_window() releases struct resource *res which was
392 * previously reserved by calling pcmcia_request_window().
393 */
390int pcmcia_release_window(struct pcmcia_device *p_dev, struct resource *res)
391{
392 struct pcmcia_socket *s = p_dev->socket;
393 pccard_mem_map *win;
394 unsigned int w;
395
396 dev_dbg(&p_dev->dev, "releasing window %pR\n", res);
397

--- 17 unchanged lines hidden (view full) ---

415
416 /* Release system memory */
417 if (win->res) {
418 release_resource(res);
419 release_resource(win->res);
420 kfree(win->res);
421 win->res = NULL;
422 }
394int pcmcia_release_window(struct pcmcia_device *p_dev, struct resource *res)
395{
396 struct pcmcia_socket *s = p_dev->socket;
397 pccard_mem_map *win;
398 unsigned int w;
399
400 dev_dbg(&p_dev->dev, "releasing window %pR\n", res);
401

--- 17 unchanged lines hidden (view full) ---

419
420 /* Release system memory */
421 if (win->res) {
422 release_resource(res);
423 release_resource(win->res);
424 kfree(win->res);
425 win->res = NULL;
426 }
427 res->start = res->end = 0;
428 res->flags = IORESOURCE_MEM;
423 p_dev->_win &= ~CLIENT_WIN_REQ(w);
424 mutex_unlock(&s->ops_mutex);
425
426 return 0;
427} /* pcmcia_release_window */
428EXPORT_SYMBOL(pcmcia_release_window);
429
430

--- 359 unchanged lines hidden (view full) ---

790 p_dev->irq = s->pcmcia_irq = s->pci_irq;
791 return 0;
792 }
793
794 return -EINVAL;
795}
796
797
429 p_dev->_win &= ~CLIENT_WIN_REQ(w);
430 mutex_unlock(&s->ops_mutex);
431
432 return 0;
433} /* pcmcia_release_window */
434EXPORT_SYMBOL(pcmcia_release_window);
435
436

--- 359 unchanged lines hidden (view full) ---

796 p_dev->irq = s->pcmcia_irq = s->pci_irq;
797 return 0;
798 }
799
800 return -EINVAL;
801}
802
803
798/** pcmcia_request_window
804/**
805 * pcmcia_request_window() - attempt to reserve iomem for PCMCIA devices
799 *
806 *
800 * Request_window() establishes a mapping between card memory space
801 * and system memory space.
807 * pcmcia_request_window() attepts to reserve an iomem ranges specified in
808 * struct resource *res pointing to one of the entries in
809 * struct pcmcia_device *p_dev->resource[2..5]. The "start" value is the
810 * requested start of the IO mem resource; "end" reflects the size
811 * requested.
802 */
812 */
803int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_handle_t *wh)
813int pcmcia_request_window(struct pcmcia_device *p_dev, struct resource *res,
814 unsigned int speed)
804{
805 struct pcmcia_socket *s = p_dev->socket;
806 pccard_mem_map *win;
807 u_long align;
815{
816 struct pcmcia_socket *s = p_dev->socket;
817 pccard_mem_map *win;
818 u_long align;
808 struct resource *res;
809 int w;
810
811 if (!(s->state & SOCKET_PRESENT)) {
812 dev_dbg(&p_dev->dev, "No card present\n");
813 return -ENODEV;
814 }
815
816 /* Window size defaults to smallest available */
819 int w;
820
821 if (!(s->state & SOCKET_PRESENT)) {
822 dev_dbg(&p_dev->dev, "No card present\n");
823 return -ENODEV;
824 }
825
826 /* Window size defaults to smallest available */
817 if (req->Size == 0)
818 req->Size = s->map_size;
819 align = (s->features & SS_CAP_MEM_ALIGN) ? req->Size : s->map_size;
820 if (req->Size & (s->map_size-1)) {
827 if (res->end == 0)
828 res->end = s->map_size;
829 align = (s->features & SS_CAP_MEM_ALIGN) ? res->end : s->map_size;
830 if (res->end & (s->map_size-1)) {
821 dev_dbg(&p_dev->dev, "invalid map size\n");
822 return -EINVAL;
823 }
831 dev_dbg(&p_dev->dev, "invalid map size\n");
832 return -EINVAL;
833 }
824 if ((req->Base && (s->features & SS_CAP_STATIC_MAP)) ||
825 (req->Base & (align-1))) {
834 if ((res->start && (s->features & SS_CAP_STATIC_MAP)) ||
835 (res->start & (align-1))) {
826 dev_dbg(&p_dev->dev, "invalid base address\n");
827 return -EINVAL;
828 }
836 dev_dbg(&p_dev->dev, "invalid base address\n");
837 return -EINVAL;
838 }
829 if (req->Base)
839 if (res->start)
830 align = 0;
831
832 /* Allocate system memory window */
833 mutex_lock(&s->ops_mutex);
834 for (w = 0; w < MAX_WIN; w++)
835 if (!(s->state & SOCKET_WIN_REQ(w)))
836 break;
837 if (w == MAX_WIN) {
838 dev_dbg(&p_dev->dev, "all windows are used already\n");
839 mutex_unlock(&s->ops_mutex);
840 return -EINVAL;
841 }
842
843 win = &s->win[w];
844
845 if (!(s->features & SS_CAP_STATIC_MAP)) {
840 align = 0;
841
842 /* Allocate system memory window */
843 mutex_lock(&s->ops_mutex);
844 for (w = 0; w < MAX_WIN; w++)
845 if (!(s->state & SOCKET_WIN_REQ(w)))
846 break;
847 if (w == MAX_WIN) {
848 dev_dbg(&p_dev->dev, "all windows are used already\n");
849 mutex_unlock(&s->ops_mutex);
850 return -EINVAL;
851 }
852
853 win = &s->win[w];
854
855 if (!(s->features & SS_CAP_STATIC_MAP)) {
846 win->res = pcmcia_find_mem_region(req->Base, req->Size, align,
856 win->res = pcmcia_find_mem_region(res->start, res->end, align,
847 0, s);
848 if (!win->res) {
849 dev_dbg(&p_dev->dev, "allocating mem region failed\n");
850 mutex_unlock(&s->ops_mutex);
851 return -EINVAL;
852 }
853 }
854 p_dev->_win |= CLIENT_WIN_REQ(w);
855
856 /* Configure the socket controller */
857 win->map = w+1;
857 0, s);
858 if (!win->res) {
859 dev_dbg(&p_dev->dev, "allocating mem region failed\n");
860 mutex_unlock(&s->ops_mutex);
861 return -EINVAL;
862 }
863 }
864 p_dev->_win |= CLIENT_WIN_REQ(w);
865
866 /* Configure the socket controller */
867 win->map = w+1;
858 win->flags = req->Attributes;
859 win->speed = req->AccessSpeed;
868 win->flags = res->flags & WIN_FLAGS_MAP;
869 win->speed = speed;
860 win->card_start = 0;
861
862 if (s->ops->set_mem_map(s, win) != 0) {
863 dev_dbg(&p_dev->dev, "failed to set memory mapping\n");
864 mutex_unlock(&s->ops_mutex);
865 return -EIO;
866 }
867 s->state |= SOCKET_WIN_REQ(w);
868
869 /* Return window handle */
870 if (s->features & SS_CAP_STATIC_MAP)
870 win->card_start = 0;
871
872 if (s->ops->set_mem_map(s, win) != 0) {
873 dev_dbg(&p_dev->dev, "failed to set memory mapping\n");
874 mutex_unlock(&s->ops_mutex);
875 return -EIO;
876 }
877 s->state |= SOCKET_WIN_REQ(w);
878
879 /* Return window handle */
880 if (s->features & SS_CAP_STATIC_MAP)
871 req->Base = win->static_start;
881 res->start = win->static_start;
872 else
882 else
873 req->Base = win->res->start;
883 res->start = win->res->start;
874
875 /* convert to new-style resources */
884
885 /* convert to new-style resources */
876 res = p_dev->resource[w + MAX_IO_WIN];
877 res->start = req->Base;
878 res->end = req->Base + req->Size - 1;
879 res->flags &= ~IORESOURCE_BITS;
880 res->flags |= (req->Attributes & WIN_FLAGS_MAP) | (win->map << 2);
881 res->flags |= IORESOURCE_MEM;
886 res->end += res->start - 1;
887 res->flags &= ~WIN_FLAGS_REQ;
888 res->flags |= (win->map << 2) | IORESOURCE_MEM;
882 res->parent = win->res;
883 if (win->res)
884 request_resource(&iomem_resource, res);
885
886 dev_dbg(&p_dev->dev, "request_window results in %pR\n", res);
887
888 mutex_unlock(&s->ops_mutex);
889 res->parent = win->res;
890 if (win->res)
891 request_resource(&iomem_resource, res);
892
893 dev_dbg(&p_dev->dev, "request_window results in %pR\n", res);
894
895 mutex_unlock(&s->ops_mutex);
889 *wh = res;
890
891 return 0;
892} /* pcmcia_request_window */
893EXPORT_SYMBOL(pcmcia_request_window);
894
895void pcmcia_disable_device(struct pcmcia_device *p_dev)
896{
897 int i;

--- 14 unchanged lines hidden ---
896
897 return 0;
898} /* pcmcia_request_window */
899EXPORT_SYMBOL(pcmcia_request_window);
900
901void pcmcia_disable_device(struct pcmcia_device *p_dev)
902{
903 int i;

--- 14 unchanged lines hidden ---