1 /*====================================================================== 3 PCMCIA Card Services -- core services 5 cs.c 1.267 2000/08/30 22:07:31 7 The contents of this file are subject to the Mozilla Public 8 License Version 1.1 (the "License"); you may not use this file 9 except in compliance with the License. You may obtain a copy of 10 the License at http://www.mozilla.org/MPL/ 12 Software distributed under the License is distributed on an "AS 13 IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or 14 implied. See the License for the specific language governing 15 rights and limitations under the License. 17 The initial developer of the original code is David A. Hinds 18 <dahinds@users.sourceforge.net>. Portions created by David A. Hinds 19 are Copyright (C) 1999 David A. Hinds. All Rights Reserved. 21 Alternatively, the contents of this file may be used under the 22 terms of the GNU Public License version 2 (the "GPL"), in which 23 case the provisions of the GPL are applicable instead of the 24 above. If you wish to allow the use of your version of this file 25 only under the terms of the GPL and not to allow others to use 26 your version of this file under the MPL, indicate your decision 27 by deleting the provisions above and replace them with the notice 28 and other provisions required by the GPL. If you do not delete 29 the provisions above, a recipient may use your version of this 30 file under either the MPL or the GPL. 32 ======================================================================*/ 34 #include <linux/module.h> 35 #include <linux/init.h> 36 #include <linux/kernel.h> 37 #include <linux/config.h> 38 #include <linux/string.h> 39 #include <linux/major.h> 40 #include <linux/errno.h> 41 #include <linux/malloc.h> 43 #include <linux/sched.h> 44 #include <linux/timer.h> 45 #include <linux/ioport.h> 46 #include <linux/delay.h> 47 #include <linux/proc_fs.h> 49 #include <linux/pci.h> 50 #include <asm/system.h> 53 #define IN_CARD_SERVICES 54 #include <pcmcia/version.h> 55 #include <pcmcia/cs_types.h> 56 #include <pcmcia/ss.h> 57 #include <pcmcia/cs.h> 58 #include <pcmcia/bulkmem.h> 59 #include <pcmcia/cistpl.h> 60 #include <pcmcia/cisreg.h> 61 #include <pcmcia/bus_ops.h> 62 #include"cs_internal.h" 66 int pc_debug
= PCMCIA_DEBUG
; 67 MODULE_PARM(pc_debug
,"i"); 68 static const char*version
= 69 "cs.c 1.267 2000/08/30 22:07:31 (David Hinds)"; 73 #define PCI_OPT" [pci]" 78 #define CB_OPT" [cardbus]" 87 #if !defined(CONFIG_CARDBUS) && !defined(CONFIG_PCI) && !defined(CONFIG_PM) 88 #define OPTIONS" none" 90 #define OPTIONS PCI_OPT CB_OPT PM_OPT 93 static const char*release
="Linux PCMCIA Card Services " CS_RELEASE
; 94 static const char*options
="options: " OPTIONS
; 96 MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>"); 97 MODULE_DESCRIPTION("Linux PCMCIA Card Services " CS_RELEASE
98 "\noptions:" OPTIONS
); 100 /*====================================================================*/ 102 /* Parameters that can be set with 'insmod' */ 104 #define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n,"i") 106 INT_MODULE_PARM(setup_delay
, HZ
/20);/* ticks */ 107 INT_MODULE_PARM(resume_delay
, HZ
/5);/* ticks */ 108 INT_MODULE_PARM(shutdown_delay
, HZ
/40);/* ticks */ 109 INT_MODULE_PARM(vcc_settle
,400);/* msecs */ 110 INT_MODULE_PARM(reset_time
,10);/* usecs */ 111 INT_MODULE_PARM(unreset_delay
,100);/* msecs */ 112 INT_MODULE_PARM(unreset_check
,100);/* msecs */ 113 INT_MODULE_PARM(unreset_limit
,30);/* unreset_check's */ 115 /* Access speed for attribute memory windows */ 116 INT_MODULE_PARM(cis_speed
,300);/* ns */ 118 /* Access speed for IO windows */ 119 INT_MODULE_PARM(io_speed
,0);/* ns */ 121 /* Optional features */ 123 INT_MODULE_PARM(do_apm
,1); 125 INT_MODULE_PARM(do_apm
,0); 128 /*====================================================================*/ 130 socket_state_t dead_socket
= { 134 /* Table of sockets */ 136 socket_info_t
*socket_table
[MAX_SOCK
]; 138 #ifdef CONFIG_PROC_FS 139 struct proc_dir_entry
*proc_pccard
= NULL
; 142 /*====================================================================*/ 144 /* String tables for error messages */ 146 typedefstruct lookup_t
{ 151 static const lookup_t error_table
[] = { 152 { CS_SUCCESS
,"Operation succeeded"}, 153 { CS_BAD_ADAPTER
,"Bad adapter"}, 154 { CS_BAD_ATTRIBUTE
,"Bad attribute", }, 155 { CS_BAD_BASE
,"Bad base address"}, 156 { CS_BAD_EDC
,"Bad EDC"}, 157 { CS_BAD_IRQ
,"Bad IRQ"}, 158 { CS_BAD_OFFSET
,"Bad offset"}, 159 { CS_BAD_PAGE
,"Bad page number"}, 160 { CS_READ_FAILURE
,"Read failure"}, 161 { CS_BAD_SIZE
,"Bad size"}, 162 { CS_BAD_SOCKET
,"Bad socket"}, 163 { CS_BAD_TYPE
,"Bad type"}, 164 { CS_BAD_VCC
,"Bad Vcc"}, 165 { CS_BAD_VPP
,"Bad Vpp"}, 166 { CS_BAD_WINDOW
,"Bad window"}, 167 { CS_WRITE_FAILURE
,"Write failure"}, 168 { CS_NO_CARD
,"No card present"}, 169 { CS_UNSUPPORTED_FUNCTION
,"Usupported function"}, 170 { CS_UNSUPPORTED_MODE
,"Unsupported mode"}, 171 { CS_BAD_SPEED
,"Bad speed"}, 172 { CS_BUSY
,"Resource busy"}, 173 { CS_GENERAL_FAILURE
,"General failure"}, 174 { CS_WRITE_PROTECTED
,"Write protected"}, 175 { CS_BAD_ARG_LENGTH
,"Bad argument length"}, 176 { CS_BAD_ARGS
,"Bad arguments"}, 177 { CS_CONFIGURATION_LOCKED
,"Configuration locked"}, 178 { CS_IN_USE
,"Resource in use"}, 179 { CS_NO_MORE_ITEMS
,"No more items"}, 180 { CS_OUT_OF_RESOURCE
,"Out of resource"}, 181 { CS_BAD_HANDLE
,"Bad handle"}, 182 { CS_BAD_TUPLE
,"Bad CIS tuple"} 184 #define ERROR_COUNT (sizeof(error_table)/sizeof(lookup_t)) 186 static const lookup_t service_table
[] = { 187 { AccessConfigurationRegister
,"AccessConfigurationRegister"}, 188 { AddSocketServices
,"AddSocketServices"}, 189 { AdjustResourceInfo
,"AdjustResourceInfo"}, 190 { CheckEraseQueue
,"CheckEraseQueue"}, 191 { CloseMemory
,"CloseMemory"}, 192 { DeregisterClient
,"DeregisterClient"}, 193 { DeregisterEraseQueue
,"DeregisterEraseQueue"}, 194 { GetCardServicesInfo
,"GetCardServicesInfo"}, 195 { GetClientInfo
,"GetClientInfo"}, 196 { GetConfigurationInfo
,"GetConfigurationInfo"}, 197 { GetEventMask
,"GetEventMask"}, 198 { GetFirstClient
,"GetFirstClient"}, 199 { GetFirstRegion
,"GetFirstRegion"}, 200 { GetFirstTuple
,"GetFirstTuple"}, 201 { GetNextClient
,"GetNextClient"}, 202 { GetNextRegion
,"GetNextRegion"}, 203 { GetNextTuple
,"GetNextTuple"}, 204 { GetStatus
,"GetStatus"}, 205 { GetTupleData
,"GetTupleData"}, 206 { MapMemPage
,"MapMemPage"}, 207 { ModifyConfiguration
,"ModifyConfiguration"}, 208 { ModifyWindow
,"ModifyWindow"}, 209 { OpenMemory
,"OpenMemory"}, 210 { ParseTuple
,"ParseTuple"}, 211 { ReadMemory
,"ReadMemory"}, 212 { RegisterClient
,"RegisterClient"}, 213 { RegisterEraseQueue
,"RegisterEraseQueue"}, 214 { RegisterMTD
,"RegisterMTD"}, 215 { ReleaseConfiguration
,"ReleaseConfiguration"}, 216 { ReleaseIO
,"ReleaseIO"}, 217 { ReleaseIRQ
,"ReleaseIRQ"}, 218 { ReleaseWindow
,"ReleaseWindow"}, 219 { RequestConfiguration
,"RequestConfiguration"}, 220 { RequestIO
,"RequestIO"}, 221 { RequestIRQ
,"RequestIRQ"}, 222 { RequestSocketMask
,"RequestSocketMask"}, 223 { RequestWindow
,"RequestWindow"}, 224 { ResetCard
,"ResetCard"}, 225 { SetEventMask
,"SetEventMask"}, 226 { ValidateCIS
,"ValidateCIS"}, 227 { WriteMemory
,"WriteMemory"}, 228 { BindDevice
,"BindDevice"}, 229 { BindMTD
,"BindMTD"}, 230 { ReportError
,"ReportError"}, 231 { SuspendCard
,"SuspendCard"}, 232 { ResumeCard
,"ResumeCard"}, 233 { EjectCard
,"EjectCard"}, 234 { InsertCard
,"InsertCard"}, 235 { ReplaceCIS
,"ReplaceCIS"} 237 #define SERVICE_COUNT (sizeof(service_table)/sizeof(lookup_t)) 239 /*====================================================================== 241 These functions are just shorthand for the actual low-level drivers 243 ======================================================================*/ 245 static intregister_callback(socket_info_t
*s
,void(*handler
)(void*,unsigned int),void* info
) 247 return s
->ss_entry
->register_callback(s
->sock
, handler
, info
); 250 static intget_socket_status(socket_info_t
*s
,int*val
) 252 return s
->ss_entry
->get_status(s
->sock
, val
); 255 static intset_socket(socket_info_t
*s
, socket_state_t
*state
) 257 return s
->ss_entry
->set_socket(s
->sock
, state
); 260 static intset_io_map(socket_info_t
*s
,struct pccard_io_map
*io
) 262 return s
->ss_entry
->set_io_map(s
->sock
, io
); 265 static intset_mem_map(socket_info_t
*s
,struct pccard_mem_map
*mem
) 267 return s
->ss_entry
->set_mem_map(s
->sock
, mem
); 270 static intsuspend_socket(socket_info_t
*s
) 272 s
->socket
= dead_socket
; 273 return s
->ss_entry
->suspend(s
->sock
); 276 static intinit_socket(socket_info_t
*s
) 278 s
->socket
= dead_socket
; 279 return s
->ss_entry
->init(s
->sock
); 282 /*====================================================================*/ 284 #if defined(CONFIG_PROC_FS) && defined(PCMCIA_DEBUG) 285 static intproc_read_clients(char*buf
,char**start
, off_t pos
, 286 int count
,int*eof
,void*data
) 288 socket_info_t
*s
= data
; 292 for(c
= s
->clients
; c
; c
= c
->next
) 293 p
+=sprintf(p
,"fn %x: '%s' [attr 0x%04x] [state 0x%04x]\n", 294 c
->Function
, c
->dev_info
, c
->Attributes
, c
->state
); 299 /*====================================================================== 301 Low-level PC Card interface drivers need to register with Card 302 Services using these calls. 304 ======================================================================*/ 306 static voidsetup_socket(socket_info_t
*); 307 static voidshutdown_socket(socket_info_t
*); 308 static voidreset_socket(socket_info_t
*); 309 static voidunreset_socket(socket_info_t
*); 310 static voidparse_events(void*info
, u_int events
); 312 socket_info_t
*pcmcia_register_socket(int slot
, 313 struct pccard_operations
* ss_entry
, 319 DEBUG(0,"cs: pcmcia_register_socket(0x%p)\n", ss_entry
); 321 s
=kmalloc(sizeof(struct socket_info_t
), GFP_KERNEL
); 322 memset(s
,0,sizeof(socket_info_t
)); 324 s
->ss_entry
= ss_entry
; 327 /* base address = 0, map = 0 */ 329 s
->cis_mem
.speed
= cis_speed
; 330 s
->use_bus_pm
= use_bus_pm
; 331 s
->erase_busy
.next
= s
->erase_busy
.prev
= &s
->erase_busy
; 332 spin_lock_init(&s
->lock
); 334 for(i
=0; i
< sockets
; i
++) 335 if(socket_table
[i
] == NULL
)break; 337 if(i
== sockets
) sockets
++; 340 ss_entry
->inquire_socket(slot
, &s
->cap
); 341 #ifdef CONFIG_PROC_FS 344 sprintf(name
,"%02d", i
); 345 s
->proc
=proc_mkdir(name
, proc_pccard
); 347 ss_entry
->proc_setup(slot
, s
->proc
); 350 create_proc_read_entry("clients",0, s
->proc
, 351 proc_read_clients
, s
); 356 }/* pcmcia_register_socket */ 358 intregister_ss_entry(int nsock
,struct pccard_operations
* ss_entry
) 362 DEBUG(0,"cs: register_ss_entry(%d, 0x%p)\n", nsock
, ss_entry
); 364 for(ns
=0; ns
< nsock
; ns
++) { 365 pcmcia_register_socket(ns
, ss_entry
,0); 369 }/* register_ss_entry */ 371 /*====================================================================*/ 373 voidpcmcia_unregister_socket(socket_info_t
*s
) 378 for(j
=0; j
< MAX_SOCK
; j
++) 379 if(socket_table
[j
] == s
) { 386 #ifdef CONFIG_PROC_FS 389 sprintf(name
,"%02d", socket
); 391 remove_proc_entry("clients", s
->proc
); 393 remove_proc_entry(name
, proc_pccard
); 401 s
->clients
= s
->clients
->next
; 407 socket_table
[socket
] = NULL
; 408 for(j
= socket
; j
< sockets
-1; j
++) 409 socket_table
[j
] = socket_table
[j
+1]; 411 }/* pcmcia_unregister_socket */ 413 voidunregister_ss_entry(struct pccard_operations
* ss_entry
) 417 for(i
=0; i
< sockets
; i
++) { 418 socket_info_t
*socket
= socket_table
[i
]; 419 if(socket
->ss_entry
== ss_entry
) 420 pcmcia_unregister_socket(socket
); 424 }/* unregister_ss_entry */ 426 /*====================================================================== 428 Shutdown_Socket() and setup_socket() are scheduled using add_timer 429 calls by the main event handler when card insertion and removal 430 events are received. Shutdown_Socket() unconfigures a socket and 431 turns off socket power. Setup_socket() turns on socket power 432 and resets the socket, in two stages. 434 ======================================================================*/ 436 static voidfree_regions(memory_handle_t
*list
) 439 while(*list
!= NULL
) { 441 *list
= tmp
->info
.next
; 442 tmp
->region_magic
=0; 447 static intsend_event(socket_info_t
*s
, event_t event
,int priority
); 449 static voidmsleep(unsigned int msec
) 451 current
->state
= TASK_INTERRUPTIBLE
; 452 schedule_timeout( (msec
* HZ
+999) /1000); 455 static voidshutdown_socket(socket_info_t
*s
) 459 DEBUG(1,"cs: shutdown_socket(%p)\n", s
); 461 /* Blank out the socket state */ 462 s
->state
&= SOCKET_PRESENT
|SOCKET_SETUP_PENDING
; 464 s
->irq
.AssignedIRQ
= s
->irq
.Config
=0; 471 #ifdef CONFIG_CARDBUS 472 cb_release_cis_mem(s
); 480 for(c
= &s
->clients
; *c
; ) { 481 if((*c
)->state
& CLIENT_UNBOUND
) { 489 free_regions(&s
->a_region
); 490 free_regions(&s
->c_region
); 491 }/* shutdown_socket */ 493 static voidsetup_socket(socket_info_t
*s
) 496 int setup_timeout
=100; 498 /* Wait for "not pending" */ 500 get_socket_status(s
, &val
); 501 if(!(val
& SS_PENDING
)) 503 if(--setup_timeout
) { 507 printk(KERN_NOTICE
"cs: socket %p voltage interrogation" 512 if(val
& SS_DETECT
) { 513 DEBUG(1,"cs: setup_socket(%p): applying power\n", s
); 514 s
->state
|= SOCKET_PRESENT
; 517 s
->socket
.Vcc
= s
->socket
.Vpp
=33; 518 else if(!(val
& SS_XVCARD
)) 519 s
->socket
.Vcc
= s
->socket
.Vpp
=50; 521 printk(KERN_NOTICE
"cs: socket %p: unsupported " 525 if(val
& SS_CARDBUS
) { 526 s
->state
|= SOCKET_CARDBUS
; 527 #ifndef CONFIG_CARDBUS 528 printk(KERN_NOTICE
"cs: unsupported card type detected!\n"); 531 set_socket(s
, &s
->socket
); 535 DEBUG(0,"cs: setup_socket(%p): no card!\n", s
); 538 /*====================================================================== 540 Reset_socket() and unreset_socket() handle hard resets. Resets 541 have several causes: card insertion, a call to reset_socket, or 542 recovery from a suspend/resume cycle. Unreset_socket() sends 543 a CS event that matches the cause of the reset. 545 ======================================================================*/ 547 static voidreset_socket(socket_info_t
*s
) 549 DEBUG(1,"cs: resetting socket %p\n", s
); 550 s
->socket
.flags
|= SS_OUTPUT_ENA
| SS_RESET
; 551 set_socket(s
, &s
->socket
); 552 udelay((long)reset_time
); 553 s
->socket
.flags
&= ~SS_RESET
; 554 set_socket(s
, &s
->socket
); 555 msleep(unreset_delay
); 560 (SOCKET_SETUP_PENDING|SOCKET_SUSPEND|SOCKET_RESET_PENDING) 562 static voidunreset_socket(socket_info_t
*s
) 564 int setup_timeout
= unreset_limit
; 567 /* Wait for "ready" */ 569 get_socket_status(s
, &val
); 572 DEBUG(2,"cs: socket %ld not ready yet\n", i
); 573 if(--setup_timeout
) { 574 msleep(unreset_check
); 577 printk(KERN_NOTICE
"cs: socket %p timed out during" 579 s
->state
&= ~EVENT_MASK
; 583 DEBUG(1,"cs: reset done on socket %p\n", s
); 584 if(s
->state
& SOCKET_SUSPEND
) { 585 s
->state
&= ~EVENT_MASK
; 586 if(verify_cis_cache(s
) !=0) 587 parse_events(s
, SS_DETECT
); 589 send_event(s
, CS_EVENT_PM_RESUME
, CS_EVENT_PRI_LOW
); 590 }else if(s
->state
& SOCKET_SETUP_PENDING
) { 591 #ifdef CONFIG_CARDBUS 592 if(s
->state
& SOCKET_CARDBUS
) 595 send_event(s
, CS_EVENT_CARD_INSERTION
, CS_EVENT_PRI_LOW
); 596 s
->state
&= ~SOCKET_SETUP_PENDING
; 598 send_event(s
, CS_EVENT_CARD_RESET
, CS_EVENT_PRI_LOW
); 599 if(s
->reset_handle
) { 600 s
->reset_handle
->event_callback_args
.info
= NULL
; 601 EVENT(s
->reset_handle
, CS_EVENT_RESET_COMPLETE
, 604 s
->state
&= ~EVENT_MASK
; 606 }/* unreset_socket */ 608 /*====================================================================== 610 The central event handler. Send_event() sends an event to all 611 valid clients. Parse_events() interprets the event bits from 612 a card status change report. Do_shotdown() handles the high 613 priority stuff associated with a card removal. 615 ======================================================================*/ 617 static intsend_event(socket_info_t
*s
, event_t event
,int priority
) 619 client_t
*client
= s
->clients
; 621 DEBUG(1,"cs: send_event(sock %d, event %d, pri %d)\n", 622 s
->sock
, event
, priority
); 624 for(; client
; client
= client
->next
) { 625 if(client
->state
& (CLIENT_UNBOUND
|CLIENT_STALE
)) 627 if(client
->EventMask
& event
) { 628 ret
=EVENT(client
, event
, priority
); 636 static voiddo_shutdown(socket_info_t
*s
) 639 if(s
->state
& SOCKET_SHUTDOWN_PENDING
) 641 s
->state
|= SOCKET_SHUTDOWN_PENDING
; 642 send_event(s
, CS_EVENT_CARD_REMOVAL
, CS_EVENT_PRI_HIGH
); 643 for(client
= s
->clients
; client
; client
= client
->next
) 644 if(!(client
->Attributes
& INFO_MASTER_CLIENT
)) 645 client
->state
|= CLIENT_STALE
; 646 if(s
->state
& (SOCKET_SETUP_PENDING
|SOCKET_RESET_PENDING
)) { 647 DEBUG(0,"cs: flushing pending setup\n"); 648 s
->state
&= ~EVENT_MASK
; 650 msleep(shutdown_delay
); 651 s
->state
&= ~SOCKET_PRESENT
; 655 static voidparse_events(void*info
, u_int events
) 657 socket_info_t
*s
= info
; 658 if(events
& SS_DETECT
) { 661 get_socket_status(s
, &status
); 662 if((s
->state
& SOCKET_PRESENT
) && 663 (!(s
->state
& SOCKET_SUSPEND
) || 664 !(status
& SS_DETECT
))) 666 if(status
& SS_DETECT
) { 667 if(s
->state
& SOCKET_SETUP_PENDING
) { 668 DEBUG(1,"cs: delaying pending setup\n"); 671 s
->state
|= SOCKET_SETUP_PENDING
; 672 if(s
->state
& SOCKET_SUSPEND
) 673 msleep(resume_delay
); 679 if(events
& SS_BATDEAD
) 680 send_event(s
, CS_EVENT_BATTERY_DEAD
, CS_EVENT_PRI_LOW
); 681 if(events
& SS_BATWARN
) 682 send_event(s
, CS_EVENT_BATTERY_LOW
, CS_EVENT_PRI_LOW
); 683 if(events
& SS_READY
) { 684 if(!(s
->state
& SOCKET_RESET_PENDING
)) 685 send_event(s
, CS_EVENT_READY_CHANGE
, CS_EVENT_PRI_LOW
); 686 elseDEBUG(1,"cs: ready change during reset\n"); 690 /*====================================================================== 692 Another event handler, for power management events. 694 This does not comply with the latest PC Card spec for handling 695 power management events. 697 ======================================================================*/ 699 voidpcmcia_suspend_socket(socket_info_t
*s
) 701 if((s
->state
& SOCKET_PRESENT
) && !(s
->state
& SOCKET_SUSPEND
)) { 702 send_event(s
, CS_EVENT_PM_SUSPEND
, CS_EVENT_PRI_LOW
); 704 s
->state
|= SOCKET_SUSPEND
; 708 voidpcmcia_resume_socket(socket_info_t
*s
) 712 /* Do this just to reinitialize the socket */ 714 get_socket_status(s
, &stat
); 716 /* If there was or is a card here, we need to do something 717 about it... but parse_events will sort it all out. */ 718 if((s
->state
& SOCKET_PRESENT
) || (stat
& SS_DETECT
)) 719 parse_events(s
, SS_DETECT
); 722 static inthandle_pm_event(struct pm_dev
*dev
, pm_request_t rqst
,void*data
) 727 /* only for busses that don't suspend/resume slots directly */ 731 DEBUG(1,"cs: received suspend notification\n"); 732 for(i
=0; i
< sockets
; i
++) { 733 s
= socket_table
[i
]; 735 pcmcia_suspend_socket(socket_table
[i
]); 739 DEBUG(1,"cs: received resume notification\n"); 740 for(i
=0; i
< sockets
; i
++) { 741 s
= socket_table
[i
]; 743 pcmcia_resume_socket(socket_table
[i
]); 748 }/* handle_pm_event */ 750 /*====================================================================== 752 Special stuff for managing IO windows, because they are scarce. 754 ======================================================================*/ 756 static intalloc_io_space(socket_info_t
*s
, u_int attr
, ioaddr_t
*base
, 757 ioaddr_t num
, u_int lines
,char*name
) 762 align
= (*base
) ? (lines
?1<<lines
:0) :1; 763 if(align
&& (align
< num
)) { 765 DEBUG(0,"odd IO request: num %04x align %04x\n", 769 while(align
&& (align
< num
)) align
<<=1; 771 if(*base
& ~(align
-1)) { 772 DEBUG(0,"odd IO request: base %04x align %04x\n", 776 /* Check for an already-allocated window that must conflict with 777 what was asked for. It is a hack because it does not catch all 778 potential conflicts, just the most obvious ones. */ 779 for(i
=0; i
< MAX_IO_WIN
; i
++) 780 if((s
->io
[i
].NumPorts
!=0) && 781 ((s
->io
[i
].BasePort
& (align
-1)) == *base
)) 783 for(i
=0; i
< MAX_IO_WIN
; i
++) { 784 if(s
->io
[i
].NumPorts
==0) { 785 if(find_io_region(base
, num
, align
, name
) ==0) { 786 s
->io
[i
].Attributes
= attr
; 787 s
->io
[i
].BasePort
= *base
; 788 s
->io
[i
].NumPorts
= s
->io
[i
].InUse
= num
; 792 }else if(s
->io
[i
].Attributes
!= attr
) 794 /* Try to extend top of window */ 795 try= s
->io
[i
].BasePort
+ s
->io
[i
].NumPorts
; 796 if((*base
==0) || (*base
==try)) 797 if(find_io_region(&try, num
,0, name
) ==0) { 799 s
->io
[i
].NumPorts
+= num
; 800 s
->io
[i
].InUse
+= num
; 803 /* Try to extend bottom of window */ 804 try= s
->io
[i
].BasePort
- num
; 805 if((*base
==0) || (*base
==try)) 806 if(find_io_region(&try, num
,0, name
) ==0) { 807 s
->io
[i
].BasePort
= *base
=try; 808 s
->io
[i
].NumPorts
+= num
; 809 s
->io
[i
].InUse
+= num
; 813 return(i
== MAX_IO_WIN
); 814 }/* alloc_io_space */ 816 static voidrelease_io_space(socket_info_t
*s
, ioaddr_t base
, 820 release_region(base
, num
); 821 for(i
=0; i
< MAX_IO_WIN
; i
++) { 822 if((s
->io
[i
].BasePort
<= base
) && 823 (s
->io
[i
].BasePort
+s
->io
[i
].NumPorts
>= base
+num
)) { 824 s
->io
[i
].InUse
-= num
; 825 /* Free the window if no one else is using it */ 826 if(s
->io
[i
].InUse
==0) 827 s
->io
[i
].NumPorts
=0; 832 /*====================================================================== 834 Access_configuration_register() reads and writes configuration 835 registers in attribute memory. Memory window 0 is reserved for 836 this and the tuple reading services. 838 ======================================================================*/ 840 intpcmcia_access_configuration_register(client_handle_t handle
, 848 if(CHECK_HANDLE(handle
)) 849 return CS_BAD_HANDLE
; 851 if(handle
->Function
== BIND_FN_ALL
) { 852 if(reg
->Function
>= s
->functions
) 854 c
= &s
->config
[reg
->Function
]; 857 if(!(c
->state
& CONFIG_LOCKED
)) 858 return CS_CONFIGURATION_LOCKED
; 860 addr
= (c
->ConfigBase
+ reg
->Offset
) >>1; 862 switch(reg
->Action
) { 864 read_cis_mem(s
,1, addr
,1, &val
); 869 write_cis_mem(s
,1, addr
,1, &val
); 876 }/* access_configuration_register */ 878 /*====================================================================== 880 Bind_device() associates a device driver with a particular socket. 881 It is normally called by Driver Services after it has identified 882 a newly inserted card. An instance of that driver will then be 883 eligible to register as a client of this socket. 885 ======================================================================*/ 887 intpcmcia_bind_device(bind_req_t
*req
) 892 if(CHECK_SOCKET(req
->Socket
)) 893 return CS_BAD_SOCKET
; 896 client
= (client_t
*)kmalloc(sizeof(client_t
), GFP_KERNEL
); 897 if(!client
)return CS_OUT_OF_RESOURCE
; 898 memset(client
,'\0',sizeof(client_t
)); 899 client
->client_magic
= CLIENT_MAGIC
; 900 strncpy(client
->dev_info
, (char*)req
->dev_info
, DEV_NAME_LEN
); 901 client
->Socket
= req
->Socket
; 902 client
->Function
= req
->Function
; 903 client
->state
= CLIENT_UNBOUND
; 904 client
->erase_busy
.next
= &client
->erase_busy
; 905 client
->erase_busy
.prev
= &client
->erase_busy
; 906 init_waitqueue_head(&client
->mtd_req
); 907 client
->next
= s
->clients
; 909 DEBUG(1,"cs: bind_device(): client 0x%p, sock %d, dev %s\n", 910 client
, client
->Socket
, client
->dev_info
); 914 /*====================================================================== 916 Bind_mtd() associates a device driver with a particular memory 917 region. It is normally called by Driver Services after it has 918 identified a memory device type. An instance of the corresponding 919 driver will then be able to register to control this region. 921 ======================================================================*/ 923 intpcmcia_bind_mtd(mtd_bind_t
*req
) 926 memory_handle_t region
; 928 if(CHECK_SOCKET(req
->Socket
)) 929 return CS_BAD_SOCKET
; 932 if(req
->Attributes
& REGION_TYPE_AM
) 933 region
= s
->a_region
; 935 region
= s
->c_region
; 938 if(region
->info
.CardOffset
== req
->CardOffset
)break; 939 region
= region
->info
.next
; 941 if(!region
|| (region
->mtd
!= NULL
)) 942 return CS_BAD_OFFSET
; 943 strncpy(region
->dev_info
, (char*)req
->dev_info
, DEV_NAME_LEN
); 945 DEBUG(1,"cs: bind_mtd(): attr 0x%x, offset 0x%x, dev %s\n", 946 req
->Attributes
, req
->CardOffset
, (char*)req
->dev_info
); 950 /*====================================================================*/ 952 intpcmcia_deregister_client(client_handle_t handle
) 956 memory_handle_t region
; 960 DEBUG(1,"cs: deregister_client(%p)\n", handle
); 961 if(CHECK_HANDLE(handle
)) 962 return CS_BAD_HANDLE
; 964 (CLIENT_IRQ_REQ
|CLIENT_IO_REQ
|CLIENT_CONFIG_LOCKED
)) 966 for(i
=0; i
< MAX_WIN
; i
++) 967 if(handle
->state
&CLIENT_WIN_REQ(i
)) 970 /* Disconnect all MTD links */ 972 if(handle
->mtd_count
) { 973 for(region
= s
->a_region
; region
; region
= region
->info
.next
) 974 if(region
->mtd
== handle
) region
->mtd
= NULL
; 975 for(region
= s
->c_region
; region
; region
= region
->info
.next
) 976 if(region
->mtd
== handle
) region
->mtd
= NULL
; 979 sn
= handle
->Socket
; s
= socket_table
[sn
]; 981 if((handle
->state
& CLIENT_STALE
) || 982 (handle
->Attributes
& INFO_MASTER_CLIENT
)) { 983 spin_lock_irqsave(&s
->lock
, flags
); 984 client
= &s
->clients
; 985 while((*client
) && ((*client
) != handle
)) 986 client
= &(*client
)->next
; 987 if(*client
== NULL
) { 988 spin_unlock_irqrestore(&s
->lock
, flags
); 989 return CS_BAD_HANDLE
; 991 *client
= handle
->next
; 992 handle
->client_magic
=0; 994 spin_unlock_irqrestore(&s
->lock
, flags
); 996 handle
->state
= CLIENT_UNBOUND
; 997 handle
->mtd_count
=0; 998 handle
->event_handler
= NULL
; 1001 if(--s
->real_clients
==0) 1002 register_callback(s
, NULL
, NULL
); 1005 }/* deregister_client */ 1007 /*====================================================================*/ 1009 intpcmcia_get_configuration_info(client_handle_t handle
, 1010 config_info_t
*config
) 1015 if(CHECK_HANDLE(handle
)) 1016 return CS_BAD_HANDLE
; 1018 if(!(s
->state
& SOCKET_PRESENT
)) 1021 if(handle
->Function
== BIND_FN_ALL
) { 1022 if(config
->Function
&& (config
->Function
>= s
->functions
)) 1025 config
->Function
= handle
->Function
; 1027 #ifdef CONFIG_CARDBUS 1028 if(s
->state
& SOCKET_CARDBUS
) { 1029 u_char fn
= config
->Function
; 1030 memset(config
,0,sizeof(config_info_t
)); 1031 config
->Function
= fn
; 1032 config
->Vcc
= s
->socket
.Vcc
; 1033 config
->Vpp1
= config
->Vpp2
= s
->socket
.Vpp
; 1034 config
->Option
= s
->cap
.cb_dev
->subordinate
->number
; 1036 config
->Attributes
= CONF_VALID_CLIENT
; 1037 config
->IntType
= INT_CARDBUS
; 1038 config
->AssignedIRQ
= s
->irq
.AssignedIRQ
; 1039 if(config
->AssignedIRQ
) 1040 config
->Attributes
|= CONF_ENABLE_IRQ
; 1041 config
->BasePort1
= s
->io
[0].BasePort
; 1042 config
->NumPorts1
= s
->io
[0].NumPorts
; 1048 c
= (s
->config
!= NULL
) ? &s
->config
[config
->Function
] : NULL
; 1050 if((c
== NULL
) || !(c
->state
& CONFIG_LOCKED
)) { 1051 config
->Attributes
=0; 1052 config
->Vcc
= s
->socket
.Vcc
; 1053 config
->Vpp1
= config
->Vpp2
= s
->socket
.Vpp
; 1057 /* !!! This is a hack !!! */ 1058 memcpy(&config
->Attributes
, &c
->Attributes
,sizeof(config_t
)); 1059 config
->Attributes
|= CONF_VALID_CLIENT
; 1060 config
->CardValues
= c
->CardValues
; 1061 config
->IRQAttributes
= c
->irq
.Attributes
; 1062 config
->AssignedIRQ
= s
->irq
.AssignedIRQ
; 1063 config
->BasePort1
= c
->io
.BasePort1
; 1064 config
->NumPorts1
= c
->io
.NumPorts1
; 1065 config
->Attributes1
= c
->io
.Attributes1
; 1066 config
->BasePort2
= c
->io
.BasePort2
; 1067 config
->NumPorts2
= c
->io
.NumPorts2
; 1068 config
->Attributes2
= c
->io
.Attributes2
; 1069 config
->IOAddrLines
= c
->io
.IOAddrLines
; 1072 }/* get_configuration_info */ 1074 /*====================================================================== 1076 Return information about this version of Card Services. 1078 ======================================================================*/ 1080 intpcmcia_get_card_services_info(servinfo_t
*info
) 1082 info
->Signature
[0] ='C'; 1083 info
->Signature
[1] ='S'; 1084 info
->Count
= sockets
; 1085 info
->Revision
= CS_RELEASE_CODE
; 1086 info
->CSLevel
=0x0210; 1087 info
->VendorString
= (char*)release
; 1089 }/* get_card_services_info */ 1091 /*====================================================================== 1093 Note that get_first_client() *does* recognize the Socket field 1094 in the request structure. 1096 ======================================================================*/ 1098 intpcmcia_get_first_client(client_handle_t
*handle
, client_req_t
*req
) 1101 if(req
->Attributes
& CLIENT_THIS_SOCKET
) 1105 if(CHECK_SOCKET(req
->Socket
)) 1106 return CS_BAD_SOCKET
; 1107 if(socket_table
[s
]->clients
== NULL
) 1108 return CS_NO_MORE_ITEMS
; 1109 *handle
= socket_table
[s
]->clients
; 1111 }/* get_first_client */ 1113 /*====================================================================*/ 1115 intpcmcia_get_next_client(client_handle_t
*handle
, client_req_t
*req
) 1118 if((handle
== NULL
) ||CHECK_HANDLE(*handle
)) 1119 return CS_BAD_HANDLE
; 1120 if((*handle
)->next
== NULL
) { 1121 if(req
->Attributes
& CLIENT_THIS_SOCKET
) 1122 return CS_NO_MORE_ITEMS
; 1124 if(s
->clients
== NULL
) 1125 return CS_NO_MORE_ITEMS
; 1126 *handle
= s
->clients
; 1128 *handle
= (*handle
)->next
; 1130 }/* get_next_client */ 1132 /*====================================================================*/ 1134 intpcmcia_get_window(window_handle_t
*handle
,int idx
, win_req_t
*req
) 1141 s
=SOCKET((client_handle_t
)*handle
); 1143 s
= (*handle
)->sock
; 1144 if(!(s
->state
& SOCKET_PRESENT
)) 1146 for(w
= idx
; w
< MAX_WIN
; w
++) 1147 if(s
->state
&SOCKET_WIN_REQ(w
))break; 1149 return CS_NO_MORE_ITEMS
; 1151 req
->Base
= win
->ctl
.sys_start
; 1152 req
->Size
= win
->ctl
.sys_stop
- win
->ctl
.sys_start
+1; 1153 req
->AccessSpeed
= win
->ctl
.speed
; 1155 if(win
->ctl
.flags
& MAP_ATTRIB
) 1156 req
->Attributes
|= WIN_MEMORY_TYPE_AM
; 1157 if(win
->ctl
.flags
& MAP_ACTIVE
) 1158 req
->Attributes
|= WIN_ENABLE
; 1159 if(win
->ctl
.flags
& MAP_16BIT
) 1160 req
->Attributes
|= WIN_DATA_WIDTH_16
; 1161 if(win
->ctl
.flags
& MAP_USE_WAIT
) 1162 req
->Attributes
|= WIN_USE_WAIT
; 1167 intpcmcia_get_first_window(window_handle_t
*win
, win_req_t
*req
) 1169 if((win
== NULL
) || ((*win
)->magic
!= WINDOW_MAGIC
)) 1170 return CS_BAD_HANDLE
; 1171 returnpcmcia_get_window(win
,0, req
); 1174 intpcmcia_get_next_window(window_handle_t
*win
, win_req_t
*req
) 1176 if((win
== NULL
) || ((*win
)->magic
!= WINDOW_MAGIC
)) 1177 return CS_BAD_HANDLE
; 1178 returnpcmcia_get_window(win
, (*win
)->index
+1, req
); 1181 /*===================================================================== 1183 Return the PCI device associated with a card.. 1185 ======================================================================*/ 1187 #ifdef CONFIG_CARDBUS 1189 struct pci_bus
*pcmcia_lookup_bus(client_handle_t handle
) 1193 if(CHECK_HANDLE(handle
)) 1196 if(!(s
->state
& SOCKET_CARDBUS
)) 1199 return s
->cap
.cb_dev
->subordinate
; 1202 EXPORT_SYMBOL(pcmcia_lookup_bus
); 1206 /*====================================================================== 1208 Get the current socket state bits. We don't support the latched 1209 SocketState yet: I haven't seen any point for it. 1211 ======================================================================*/ 1213 intpcmcia_get_status(client_handle_t handle
, cs_status_t
*status
) 1219 if(CHECK_HANDLE(handle
)) 1220 return CS_BAD_HANDLE
; 1222 get_socket_status(s
, &val
); 1223 status
->CardState
= status
->SocketState
=0; 1224 status
->CardState
|= (val
& SS_DETECT
) ? CS_EVENT_CARD_DETECT
:0; 1225 status
->CardState
|= (val
& SS_CARDBUS
) ? CS_EVENT_CB_DETECT
:0; 1226 status
->CardState
|= (val
& SS_3VCARD
) ? CS_EVENT_3VCARD
:0; 1227 status
->CardState
|= (val
& SS_XVCARD
) ? CS_EVENT_XVCARD
:0; 1228 if(s
->state
& SOCKET_SUSPEND
) 1229 status
->CardState
|= CS_EVENT_PM_SUSPEND
; 1230 if(!(s
->state
& SOCKET_PRESENT
)) 1232 if(s
->state
& SOCKET_SETUP_PENDING
) 1233 status
->CardState
|= CS_EVENT_CARD_INSERTION
; 1235 /* Get info from the PRR, if necessary */ 1236 if(handle
->Function
== BIND_FN_ALL
) { 1237 if(status
->Function
&& (status
->Function
>= s
->functions
)) 1239 c
= (s
->config
!= NULL
) ? &s
->config
[status
->Function
] : NULL
; 1242 if((c
!= NULL
) && (c
->state
& CONFIG_LOCKED
) && 1243 (c
->IntType
& INT_MEMORY_AND_IO
)) { 1245 if(c
->Present
& PRESENT_PIN_REPLACE
) { 1246 read_cis_mem(s
,1, (c
->ConfigBase
+CISREG_PRR
)>>1,1, ®
); 1247 status
->CardState
|= 1248 (reg
& PRR_WP_STATUS
) ? CS_EVENT_WRITE_PROTECT
:0; 1249 status
->CardState
|= 1250 (reg
& PRR_READY_STATUS
) ? CS_EVENT_READY_CHANGE
:0; 1251 status
->CardState
|= 1252 (reg
& PRR_BVD2_STATUS
) ? CS_EVENT_BATTERY_LOW
:0; 1253 status
->CardState
|= 1254 (reg
& PRR_BVD1_STATUS
) ? CS_EVENT_BATTERY_DEAD
:0; 1256 /* No PRR? Then assume we're always ready */ 1257 status
->CardState
|= CS_EVENT_READY_CHANGE
; 1259 if(c
->Present
& PRESENT_EXT_STATUS
) { 1260 read_cis_mem(s
,1, (c
->ConfigBase
+CISREG_ESR
)>>1,1, ®
); 1261 status
->CardState
|= 1262 (reg
& ESR_REQ_ATTN
) ? CS_EVENT_REQUEST_ATTENTION
:0; 1266 status
->CardState
|= 1267 (val
& SS_WRPROT
) ? CS_EVENT_WRITE_PROTECT
:0; 1268 status
->CardState
|= 1269 (val
& SS_BATDEAD
) ? CS_EVENT_BATTERY_DEAD
:0; 1270 status
->CardState
|= 1271 (val
& SS_BATWARN
) ? CS_EVENT_BATTERY_LOW
:0; 1272 status
->CardState
|= 1273 (val
& SS_READY
) ? CS_EVENT_READY_CHANGE
:0; 1277 /*====================================================================== 1279 Change the card address of an already open memory window. 1281 ======================================================================*/ 1283 intpcmcia_get_mem_page(window_handle_t win
, memreq_t
*req
) 1285 if((win
== NULL
) || (win
->magic
!= WINDOW_MAGIC
)) 1286 return CS_BAD_HANDLE
; 1288 req
->CardOffset
= win
->ctl
.card_start
; 1292 intpcmcia_map_mem_page(window_handle_t win
, memreq_t
*req
) 1295 if((win
== NULL
) || (win
->magic
!= WINDOW_MAGIC
)) 1296 return CS_BAD_HANDLE
; 1300 win
->ctl
.card_start
= req
->CardOffset
; 1301 if(set_mem_map(s
, &win
->ctl
) !=0) 1302 return CS_BAD_OFFSET
; 1306 /*====================================================================== 1308 Modify a locked socket configuration 1310 ======================================================================*/ 1312 intpcmcia_modify_configuration(client_handle_t handle
, 1318 if(CHECK_HANDLE(handle
)) 1319 return CS_BAD_HANDLE
; 1320 s
=SOCKET(handle
); c
=CONFIG(handle
); 1321 if(!(s
->state
& SOCKET_PRESENT
)) 1323 if(!(c
->state
& CONFIG_LOCKED
)) 1324 return CS_CONFIGURATION_LOCKED
; 1326 if(mod
->Attributes
& CONF_IRQ_CHANGE_VALID
) { 1327 if(mod
->Attributes
& CONF_ENABLE_IRQ
) { 1328 c
->Attributes
|= CONF_ENABLE_IRQ
; 1329 s
->socket
.io_irq
= s
->irq
.AssignedIRQ
; 1331 c
->Attributes
&= ~CONF_ENABLE_IRQ
; 1332 s
->socket
.io_irq
=0; 1334 set_socket(s
, &s
->socket
); 1337 if(mod
->Attributes
& CONF_VCC_CHANGE_VALID
) 1340 /* We only allow changing Vpp1 and Vpp2 to the same value */ 1341 if((mod
->Attributes
& CONF_VPP1_CHANGE_VALID
) && 1342 (mod
->Attributes
& CONF_VPP2_CHANGE_VALID
)) { 1343 if(mod
->Vpp1
!= mod
->Vpp2
) 1345 c
->Vpp1
= c
->Vpp2
= s
->socket
.Vpp
= mod
->Vpp1
; 1346 if(set_socket(s
, &s
->socket
)) 1348 }else if((mod
->Attributes
& CONF_VPP1_CHANGE_VALID
) || 1349 (mod
->Attributes
& CONF_VPP2_CHANGE_VALID
)) 1353 }/* modify_configuration */ 1355 /*====================================================================== 1357 Modify the attributes of a window returned by RequestWindow. 1359 ======================================================================*/ 1361 intpcmcia_modify_window(window_handle_t win
, modwin_t
*req
) 1363 if((win
== NULL
) || (win
->magic
!= WINDOW_MAGIC
)) 1364 return CS_BAD_HANDLE
; 1366 win
->ctl
.flags
&= ~(MAP_ATTRIB
|MAP_ACTIVE
); 1367 if(req
->Attributes
& WIN_MEMORY_TYPE
) 1368 win
->ctl
.flags
|= MAP_ATTRIB
; 1369 if(req
->Attributes
& WIN_ENABLE
) 1370 win
->ctl
.flags
|= MAP_ACTIVE
; 1371 if(req
->Attributes
& WIN_DATA_WIDTH_16
) 1372 win
->ctl
.flags
|= MAP_16BIT
; 1373 if(req
->Attributes
& WIN_USE_WAIT
) 1374 win
->ctl
.flags
|= MAP_USE_WAIT
; 1375 win
->ctl
.speed
= req
->AccessSpeed
; 1376 set_mem_map(win
->sock
, &win
->ctl
); 1379 }/* modify_window */ 1381 /*====================================================================== 1383 Register_client() uses the dev_info_t handle to match the 1384 caller with a socket. The driver must have already been bound 1385 to a socket with bind_device() -- in fact, bind_device() 1386 allocates the client structure that will be used. 1388 ======================================================================*/ 1390 intpcmcia_register_client(client_handle_t
*handle
, client_reg_t
*req
) 1396 /* Look for unbound client with matching dev_info */ 1398 for(ns
=0; ns
< sockets
; ns
++) { 1399 client
= socket_table
[ns
]->clients
; 1400 while(client
!= NULL
) { 1401 if((strcmp(client
->dev_info
, (char*)req
->dev_info
) ==0) 1402 && (client
->state
& CLIENT_UNBOUND
))break; 1403 client
= client
->next
; 1405 if(client
!= NULL
)break; 1408 return CS_OUT_OF_RESOURCE
; 1410 s
= socket_table
[ns
]; 1411 if(++s
->real_clients
==1) { 1413 register_callback(s
, &parse_events
, s
); 1414 get_socket_status(s
, &status
); 1415 if((status
& SS_DETECT
) && 1416 !(s
->state
& SOCKET_SETUP_PENDING
)) { 1417 s
->state
|= SOCKET_SETUP_PENDING
; 1423 client
->state
&= ~CLIENT_UNBOUND
; 1424 client
->Socket
= ns
; 1425 client
->Attributes
= req
->Attributes
; 1426 client
->EventMask
= req
->EventMask
; 1427 client
->event_handler
= req
->event_handler
; 1428 client
->event_callback_args
= req
->event_callback_args
; 1429 client
->event_callback_args
.client_handle
= client
; 1430 client
->event_callback_args
.bus
= s
->cap
.bus
; 1432 if(s
->state
& SOCKET_CARDBUS
) 1433 client
->state
|= CLIENT_CARDBUS
; 1435 if((!(s
->state
& SOCKET_CARDBUS
)) && (s
->functions
==0) && 1436 (client
->Function
!= BIND_FN_ALL
)) { 1437 cistpl_longlink_mfc_t mfc
; 1438 if(read_tuple(client
, CISTPL_LONGLINK_MFC
, &mfc
) 1440 s
->functions
= mfc
.nfn
; 1443 s
->config
=kmalloc(sizeof(config_t
) * s
->functions
, 1445 memset(s
->config
,0,sizeof(config_t
) * s
->functions
); 1448 DEBUG(1,"cs: register_client(): client 0x%p, sock %d, dev %s\n", 1449 client
, client
->Socket
, client
->dev_info
); 1450 if(client
->EventMask
& CS_EVENT_REGISTRATION_COMPLETE
) 1451 EVENT(client
, CS_EVENT_REGISTRATION_COMPLETE
, CS_EVENT_PRI_LOW
); 1452 if((socket_table
[ns
]->state
& SOCKET_PRESENT
) && 1453 !(socket_table
[ns
]->state
& SOCKET_SETUP_PENDING
)) { 1454 if(client
->EventMask
& CS_EVENT_CARD_INSERTION
) 1455 EVENT(client
, CS_EVENT_CARD_INSERTION
, CS_EVENT_PRI_LOW
); 1457 client
->PendingEvents
|= CS_EVENT_CARD_INSERTION
; 1460 }/* register_client */ 1462 /*====================================================================*/ 1464 intpcmcia_release_configuration(client_handle_t handle
) 1466 pccard_io_map io
= {0,0,0,0,1}; 1470 if(CHECK_HANDLE(handle
) || 1471 !(handle
->state
& CLIENT_CONFIG_LOCKED
)) 1472 return CS_BAD_HANDLE
; 1473 handle
->state
&= ~CLIENT_CONFIG_LOCKED
; 1476 #ifdef CONFIG_CARDBUS 1477 if(handle
->state
& CLIENT_CARDBUS
) { 1484 if(!(handle
->state
& CLIENT_STALE
)) { 1485 config_t
*c
=CONFIG(handle
); 1486 if(--(s
->lock_count
) ==0) { 1487 s
->socket
.flags
= SS_OUTPUT_ENA
; 1489 s
->socket
.io_irq
=0; 1490 set_socket(s
, &s
->socket
); 1492 if(c
->state
& CONFIG_IO_REQ
) 1493 for(i
=0; i
< MAX_IO_WIN
; i
++) { 1494 if(s
->io
[i
].NumPorts
==0) 1497 if(s
->io
[i
].Config
!=0) 1502 c
->state
&= ~CONFIG_LOCKED
; 1506 }/* release_configuration */ 1508 /*====================================================================== 1510 Release_io() releases the I/O ranges allocated by a client. This 1511 may be invoked some time after a card ejection has already dumped 1512 the actual socket configuration, so if the client is "stale", we 1513 don't bother checking the port ranges against the current socket 1516 ======================================================================*/ 1518 intpcmcia_release_io(client_handle_t handle
, io_req_t
*req
) 1522 if(CHECK_HANDLE(handle
) || !(handle
->state
& CLIENT_IO_REQ
)) 1523 return CS_BAD_HANDLE
; 1524 handle
->state
&= ~CLIENT_IO_REQ
; 1527 #ifdef CONFIG_CARDBUS 1528 if(handle
->state
& CLIENT_CARDBUS
) { 1534 if(!(handle
->state
& CLIENT_STALE
)) { 1535 config_t
*c
=CONFIG(handle
); 1536 if(c
->state
& CONFIG_LOCKED
) 1537 return CS_CONFIGURATION_LOCKED
; 1538 if((c
->io
.BasePort1
!= req
->BasePort1
) || 1539 (c
->io
.NumPorts1
!= req
->NumPorts1
) || 1540 (c
->io
.BasePort2
!= req
->BasePort2
) || 1541 (c
->io
.NumPorts2
!= req
->NumPorts2
)) 1543 c
->state
&= ~CONFIG_IO_REQ
; 1546 release_io_space(s
, req
->BasePort1
, req
->NumPorts1
); 1548 release_io_space(s
, req
->BasePort2
, req
->NumPorts2
); 1553 /*====================================================================*/ 1555 intpcmcia_release_irq(client_handle_t handle
, irq_req_t
*req
) 1558 if(CHECK_HANDLE(handle
) || !(handle
->state
& CLIENT_IRQ_REQ
)) 1559 return CS_BAD_HANDLE
; 1560 handle
->state
&= ~CLIENT_IRQ_REQ
; 1563 if(!(handle
->state
& CLIENT_STALE
)) { 1564 config_t
*c
=CONFIG(handle
); 1565 if(c
->state
& CONFIG_LOCKED
) 1566 return CS_CONFIGURATION_LOCKED
; 1567 if(c
->irq
.Attributes
!= req
->Attributes
) 1568 return CS_BAD_ATTRIBUTE
; 1569 if(s
->irq
.AssignedIRQ
!= req
->AssignedIRQ
) 1571 if(--s
->irq
.Config
==0) { 1572 c
->state
&= ~CONFIG_IRQ_REQ
; 1573 s
->irq
.AssignedIRQ
=0; 1577 if(req
->Attributes
& IRQ_HANDLE_PRESENT
) { 1578 bus_free_irq(s
->cap
.bus
, req
->AssignedIRQ
, req
->Instance
); 1582 if(req
->AssignedIRQ
!= s
->cap
.pci_irq
) 1583 undo_irq(req
->Attributes
, req
->AssignedIRQ
); 1587 }/* cs_release_irq */ 1589 /*====================================================================*/ 1591 intpcmcia_release_window(window_handle_t win
) 1595 if((win
== NULL
) || (win
->magic
!= WINDOW_MAGIC
)) 1596 return CS_BAD_HANDLE
; 1598 if(!(win
->handle
->state
&CLIENT_WIN_REQ(win
->index
))) 1599 return CS_BAD_HANDLE
; 1601 /* Shut down memory window */ 1602 win
->ctl
.flags
&= ~MAP_ACTIVE
; 1603 set_mem_map(s
, &win
->ctl
); 1604 s
->state
&= ~SOCKET_WIN_REQ(win
->index
); 1606 /* Release system memory */ 1607 release_mem_region(win
->base
, win
->size
); 1608 win
->handle
->state
&= ~CLIENT_WIN_REQ(win
->index
); 1613 }/* release_window */ 1615 /*====================================================================*/ 1617 intpcmcia_request_configuration(client_handle_t handle
, 1624 pccard_io_map iomap
; 1626 if(CHECK_HANDLE(handle
)) 1627 return CS_BAD_HANDLE
; 1628 i
= handle
->Socket
; s
= socket_table
[i
]; 1629 if(!(s
->state
& SOCKET_PRESENT
)) 1632 #ifdef CONFIG_CARDBUS 1633 if(handle
->state
& CLIENT_CARDBUS
) { 1634 if(!(req
->IntType
& INT_CARDBUS
)) 1635 return CS_UNSUPPORTED_MODE
; 1636 if(s
->lock_count
!=0) 1637 return CS_CONFIGURATION_LOCKED
; 1639 handle
->state
|= CLIENT_CONFIG_LOCKED
; 1645 if(req
->IntType
& INT_CARDBUS
) 1646 return CS_UNSUPPORTED_MODE
; 1648 if(c
->state
& CONFIG_LOCKED
) 1649 return CS_CONFIGURATION_LOCKED
; 1651 /* Do power control. We don't allow changes in Vcc. */ 1652 if(s
->socket
.Vcc
!= req
->Vcc
) 1654 if(req
->Vpp1
!= req
->Vpp2
) 1656 s
->socket
.Vpp
= req
->Vpp1
; 1657 if(set_socket(s
, &s
->socket
)) 1660 c
->Vcc
= req
->Vcc
; c
->Vpp1
= c
->Vpp2
= req
->Vpp1
; 1662 /* Pick memory or I/O card, DMA mode, interrupt */ 1663 c
->IntType
= req
->IntType
; 1664 c
->Attributes
= req
->Attributes
; 1665 if(req
->IntType
& INT_MEMORY_AND_IO
) 1666 s
->socket
.flags
|= SS_IOCARD
; 1667 if(req
->Attributes
& CONF_ENABLE_DMA
) 1668 s
->socket
.flags
|= SS_DMA_MODE
; 1669 if(req
->Attributes
& CONF_ENABLE_SPKR
) 1670 s
->socket
.flags
|= SS_SPKR_ENA
; 1671 if(req
->Attributes
& CONF_ENABLE_IRQ
) 1672 s
->socket
.io_irq
= s
->irq
.AssignedIRQ
; 1674 s
->socket
.io_irq
=0; 1675 set_socket(s
, &s
->socket
); 1678 /* Set up CIS configuration registers */ 1679 base
= c
->ConfigBase
= req
->ConfigBase
; 1680 c
->Present
= c
->CardValues
= req
->Present
; 1681 if(req
->Present
& PRESENT_COPY
) { 1682 c
->Copy
= req
->Copy
; 1683 write_cis_mem(s
,1, (base
+ CISREG_SCR
)>>1,1, &c
->Copy
); 1685 if(req
->Present
& PRESENT_OPTION
) { 1686 if(s
->functions
==1) { 1687 c
->Option
= req
->ConfigIndex
& COR_CONFIG_MASK
; 1689 c
->Option
= req
->ConfigIndex
& COR_MFC_CONFIG_MASK
; 1690 c
->Option
|= COR_FUNC_ENA
|COR_IREQ_ENA
; 1691 if(req
->Present
& PRESENT_IOBASE_0
) 1692 c
->Option
|= COR_ADDR_DECODE
; 1694 if(c
->state
& CONFIG_IRQ_REQ
) 1695 if(!(c
->irq
.Attributes
& IRQ_FORCED_PULSE
)) 1696 c
->Option
|= COR_LEVEL_REQ
; 1697 write_cis_mem(s
,1, (base
+ CISREG_COR
)>>1,1, &c
->Option
); 1700 if(req
->Present
& PRESENT_STATUS
) { 1701 c
->Status
= req
->Status
; 1702 write_cis_mem(s
,1, (base
+ CISREG_CCSR
)>>1,1, &c
->Status
); 1704 if(req
->Present
& PRESENT_PIN_REPLACE
) { 1706 write_cis_mem(s
,1, (base
+ CISREG_PRR
)>>1,1, &c
->Pin
); 1708 if(req
->Present
& PRESENT_EXT_STATUS
) { 1709 c
->ExtStatus
= req
->ExtStatus
; 1710 write_cis_mem(s
,1, (base
+ CISREG_ESR
)>>1,1, &c
->ExtStatus
); 1712 if(req
->Present
& PRESENT_IOBASE_0
) { 1713 i
= c
->io
.BasePort1
&0xff; 1714 write_cis_mem(s
,1, (base
+ CISREG_IOBASE_0
)>>1,1, &i
); 1715 i
= (c
->io
.BasePort1
>>8) &0xff; 1716 write_cis_mem(s
,1, (base
+ CISREG_IOBASE_1
)>>1,1, &i
); 1718 if(req
->Present
& PRESENT_IOSIZE
) { 1719 i
= c
->io
.NumPorts1
+ c
->io
.NumPorts2
-1; 1720 write_cis_mem(s
,1, (base
+ CISREG_IOSIZE
)>>1,1, &i
); 1723 /* Configure I/O windows */ 1724 if(c
->state
& CONFIG_IO_REQ
) { 1725 iomap
.speed
= io_speed
; 1726 for(i
=0; i
< MAX_IO_WIN
; i
++) 1727 if(s
->io
[i
].NumPorts
!=0) { 1729 iomap
.flags
= MAP_ACTIVE
; 1730 switch(s
->io
[i
].Attributes
& IO_DATA_PATH_WIDTH
) { 1731 case IO_DATA_PATH_WIDTH_16
: 1732 iomap
.flags
|= MAP_16BIT
;break; 1733 case IO_DATA_PATH_WIDTH_AUTO
: 1734 iomap
.flags
|= MAP_AUTOSZ
;break; 1738 iomap
.start
= s
->io
[i
].BasePort
; 1739 iomap
.stop
= iomap
.start
+ s
->io
[i
].NumPorts
-1; 1740 set_io_map(s
, &iomap
); 1745 c
->state
|= CONFIG_LOCKED
; 1746 handle
->state
|= CLIENT_CONFIG_LOCKED
; 1748 }/* request_configuration */ 1750 /*====================================================================== 1752 Request_io() reserves ranges of port addresses for a socket. 1753 I have not implemented range sharing or alias addressing. 1755 ======================================================================*/ 1757 intpcmcia_request_io(client_handle_t handle
, io_req_t
*req
) 1762 if(CHECK_HANDLE(handle
)) 1763 return CS_BAD_HANDLE
; 1765 if(!(s
->state
& SOCKET_PRESENT
)) 1768 if(handle
->state
& CLIENT_CARDBUS
) { 1769 #ifdef CONFIG_CARDBUS 1770 int ret
=cb_config(s
); 1771 if(ret
== CS_SUCCESS
) 1772 handle
->state
|= CLIENT_IO_REQ
; 1775 return CS_UNSUPPORTED_FUNCTION
; 1780 return CS_UNSUPPORTED_MODE
; 1782 if(c
->state
& CONFIG_LOCKED
) 1783 return CS_CONFIGURATION_LOCKED
; 1784 if(c
->state
& CONFIG_IO_REQ
) 1786 if(req
->Attributes1
& (IO_SHARED
| IO_FORCE_ALIAS_ACCESS
)) 1787 return CS_BAD_ATTRIBUTE
; 1788 if((req
->NumPorts2
>0) && 1789 (req
->Attributes2
& (IO_SHARED
| IO_FORCE_ALIAS_ACCESS
))) 1790 return CS_BAD_ATTRIBUTE
; 1792 if(alloc_io_space(s
, req
->Attributes1
, &req
->BasePort1
, 1793 req
->NumPorts1
, req
->IOAddrLines
, 1797 if(req
->NumPorts2
) { 1798 if(alloc_io_space(s
, req
->Attributes2
, &req
->BasePort2
, 1799 req
->NumPorts2
, req
->IOAddrLines
, 1800 handle
->dev_info
)) { 1801 release_io_space(s
, req
->BasePort1
, req
->NumPorts1
); 1807 c
->state
|= CONFIG_IO_REQ
; 1808 handle
->state
|= CLIENT_IO_REQ
; 1812 /*====================================================================== 1814 Request_irq() reserves an irq for this client. 1816 Also, since Linux only reserves irq's when they are actually 1817 hooked, we don't guarantee that an irq will still be available 1818 when the configuration is locked. Now that I think about it, 1819 there might be a way to fix this using a dummy handler. 1821 ======================================================================*/ 1823 intpcmcia_request_irq(client_handle_t handle
, irq_req_t
*req
) 1827 inttry, ret
=0, irq
=0; 1830 if(CHECK_HANDLE(handle
)) 1831 return CS_BAD_HANDLE
; 1833 if(!(s
->state
& SOCKET_PRESENT
)) 1836 if(c
->state
& CONFIG_LOCKED
) 1837 return CS_CONFIGURATION_LOCKED
; 1838 if(c
->state
& CONFIG_IRQ_REQ
) 1841 /* Short cut: if there are no ISA interrupts, then it is PCI */ 1842 if(!s
->cap
.irq_mask
) 1843 irq
= s
->cap
.pci_irq
; 1845 else if(s
->irq
.AssignedIRQ
!=0) { 1846 /* If the interrupt is already assigned, it must match */ 1847 irq
= s
->irq
.AssignedIRQ
; 1848 if(req
->IRQInfo1
& IRQ_INFO2_VALID
) { 1849 mask
= req
->IRQInfo2
& s
->cap
.irq_mask
; 1850 ret
= ((mask
>> irq
) &1) ?0: CS_BAD_ARGS
; 1852 ret
= ((req
->IRQInfo1
&IRQ_MASK
) == irq
) ?0: CS_BAD_ARGS
; 1855 if(req
->IRQInfo1
& IRQ_INFO2_VALID
) { 1856 mask
= req
->IRQInfo2
& s
->cap
.irq_mask
; 1857 for(try=0;try<2;try++) { 1858 for(irq
=0; irq
<32; irq
++) 1859 if((mask
>> irq
) &1) { 1860 ret
=try_irq(req
->Attributes
, irq
,try); 1866 irq
= req
->IRQInfo1
& IRQ_MASK
; 1867 ret
=try_irq(req
->Attributes
, irq
,1); 1871 if(ret
!=0)return ret
; 1873 if(req
->Attributes
& IRQ_HANDLE_PRESENT
) { 1874 if(bus_request_irq(s
->cap
.bus
, irq
, req
->Handler
, 1875 ((req
->Attributes
& IRQ_TYPE_DYNAMIC_SHARING
) || 1876 (s
->functions
>1) || 1877 (irq
== s
->cap
.pci_irq
)) ? SA_SHIRQ
:0, 1878 handle
->dev_info
, req
->Instance
)) 1882 c
->irq
.Attributes
= req
->Attributes
; 1883 s
->irq
.AssignedIRQ
= req
->AssignedIRQ
= irq
; 1886 c
->state
|= CONFIG_IRQ_REQ
; 1887 handle
->state
|= CLIENT_IRQ_REQ
; 1889 }/* cs_request_irq */ 1891 /*====================================================================== 1893 Request_window() establishes a mapping between card memory space 1894 and system memory space. 1896 ======================================================================*/ 1898 intpcmcia_request_window(client_handle_t
*handle
, win_req_t
*req
, window_handle_t
*wh
) 1905 if(CHECK_HANDLE(*handle
)) 1906 return CS_BAD_HANDLE
; 1908 if(!(s
->state
& SOCKET_PRESENT
)) 1910 if(req
->Attributes
& (WIN_PAGED
| WIN_SHARED
)) 1911 return CS_BAD_ATTRIBUTE
; 1913 /* Window size defaults to smallest available */ 1915 req
->Size
= s
->cap
.map_size
; 1916 align
= (((s
->cap
.features
& SS_CAP_MEM_ALIGN
) || 1917 (req
->Attributes
& WIN_STRICT_ALIGN
)) ? 1918 req
->Size
: s
->cap
.map_size
); 1919 if(req
->Size
& (s
->cap
.map_size
-1)) 1921 if((req
->Base
&& (s
->cap
.features
& SS_CAP_STATIC_MAP
)) || 1922 (req
->Base
& (align
-1))) 1927 /* Allocate system memory window */ 1928 for(w
=0; w
< MAX_WIN
; w
++) 1929 if(!(s
->state
&SOCKET_WIN_REQ(w
)))break; 1931 return CS_OUT_OF_RESOURCE
; 1934 win
->magic
= WINDOW_MAGIC
; 1936 win
->handle
= *handle
; 1938 win
->base
= req
->Base
; 1939 win
->size
= req
->Size
; 1941 if(!(s
->cap
.features
& SS_CAP_STATIC_MAP
) && 1942 find_mem_region(&win
->base
, win
->size
, align
, 1943 (req
->Attributes
& WIN_MAP_BELOW_1MB
) || 1944 !(s
->cap
.features
& SS_CAP_PAGE_REGS
), 1945 (*handle
)->dev_info
)) 1947 (*handle
)->state
|=CLIENT_WIN_REQ(w
); 1949 /* Configure the socket controller */ 1952 win
->ctl
.speed
= req
->AccessSpeed
; 1953 if(req
->Attributes
& WIN_MEMORY_TYPE
) 1954 win
->ctl
.flags
|= MAP_ATTRIB
; 1955 if(req
->Attributes
& WIN_ENABLE
) 1956 win
->ctl
.flags
|= MAP_ACTIVE
; 1957 if(req
->Attributes
& WIN_DATA_WIDTH_16
) 1958 win
->ctl
.flags
|= MAP_16BIT
; 1959 if(req
->Attributes
& WIN_USE_WAIT
) 1960 win
->ctl
.flags
|= MAP_USE_WAIT
; 1961 win
->ctl
.sys_start
= win
->base
; 1962 win
->ctl
.sys_stop
= win
->base
+ win
->size
-1; 1963 win
->ctl
.card_start
=0; 1964 if(set_mem_map(s
, &win
->ctl
) !=0) 1966 s
->state
|=SOCKET_WIN_REQ(w
); 1968 /* Return window handle */ 1969 req
->Base
= win
->ctl
.sys_start
; 1973 }/* request_window */ 1975 /*====================================================================== 1977 I'm not sure which "reset" function this is supposed to use, 1978 but for now, it uses the low-level interface's reset, not the 1981 ======================================================================*/ 1983 intpcmcia_reset_card(client_handle_t handle
, client_req_t
*req
) 1988 if(CHECK_HANDLE(handle
)) 1989 return CS_BAD_HANDLE
; 1990 i
= handle
->Socket
; s
= socket_table
[i
]; 1991 if(!(s
->state
& SOCKET_PRESENT
)) 1993 if(s
->state
& SOCKET_RESET_PENDING
) 1995 s
->state
|= SOCKET_RESET_PENDING
; 1997 ret
=send_event(s
, CS_EVENT_RESET_REQUEST
, CS_EVENT_PRI_LOW
); 1999 s
->state
&= ~SOCKET_RESET_PENDING
; 2000 handle
->event_callback_args
.info
= (void*)(u_long
)ret
; 2001 EVENT(handle
, CS_EVENT_RESET_COMPLETE
, CS_EVENT_PRI_LOW
); 2003 DEBUG(1,"cs: resetting socket %d\n", i
); 2004 send_event(s
, CS_EVENT_RESET_PHYSICAL
, CS_EVENT_PRI_LOW
); 2005 s
->reset_handle
= handle
; 2011 /*====================================================================== 2013 These shut down or wake up a socket. They are sort of user 2014 initiated versions of the APM suspend and resume actions. 2016 ======================================================================*/ 2018 intpcmcia_suspend_card(client_handle_t handle
, client_req_t
*req
) 2023 if(CHECK_HANDLE(handle
)) 2024 return CS_BAD_HANDLE
; 2025 i
= handle
->Socket
; s
= socket_table
[i
]; 2026 if(!(s
->state
& SOCKET_PRESENT
)) 2028 if(s
->state
& SOCKET_SUSPEND
) 2031 DEBUG(1,"cs: suspending socket %d\n", i
); 2032 send_event(s
, CS_EVENT_PM_SUSPEND
, CS_EVENT_PRI_LOW
); 2034 s
->state
|= SOCKET_SUSPEND
; 2039 intpcmcia_resume_card(client_handle_t handle
, client_req_t
*req
) 2044 if(CHECK_HANDLE(handle
)) 2045 return CS_BAD_HANDLE
; 2046 i
= handle
->Socket
; s
= socket_table
[i
]; 2047 if(!(s
->state
& SOCKET_PRESENT
)) 2049 if(!(s
->state
& SOCKET_SUSPEND
)) 2052 DEBUG(1,"cs: waking up socket %d\n", i
); 2058 /*====================================================================== 2060 These handle user requests to eject or insert a card. 2062 ======================================================================*/ 2064 intpcmcia_eject_card(client_handle_t handle
, client_req_t
*req
) 2070 if(CHECK_HANDLE(handle
)) 2071 return CS_BAD_HANDLE
; 2072 i
= handle
->Socket
; s
= socket_table
[i
]; 2073 if(!(s
->state
& SOCKET_PRESENT
)) 2076 DEBUG(1,"cs: user eject request on socket %d\n", i
); 2078 ret
=send_event(s
, CS_EVENT_EJECTION_REQUEST
, CS_EVENT_PRI_LOW
); 2082 spin_lock_irqsave(&s
->lock
, flags
); 2084 spin_unlock_irqrestore(&s
->lock
, flags
); 2090 intpcmcia_insert_card(client_handle_t handle
, client_req_t
*req
) 2096 if(CHECK_HANDLE(handle
)) 2097 return CS_BAD_HANDLE
; 2098 i
= handle
->Socket
; s
= socket_table
[i
]; 2099 if(s
->state
& SOCKET_PRESENT
) 2102 DEBUG(1,"cs: user insert request on socket %d\n", i
); 2104 spin_lock_irqsave(&s
->lock
, flags
); 2105 if(!(s
->state
& SOCKET_SETUP_PENDING
)) { 2106 s
->state
|= SOCKET_SETUP_PENDING
; 2107 spin_unlock_irqrestore(&s
->lock
, flags
); 2108 get_socket_status(s
, &status
); 2109 if(status
& SS_DETECT
) 2112 s
->state
&= ~SOCKET_SETUP_PENDING
; 2116 spin_unlock_irqrestore(&s
->lock
, flags
); 2121 /*====================================================================== 2123 Maybe this should send a CS_EVENT_CARD_INSERTION event if we 2124 haven't sent one to this client yet? 2126 ======================================================================*/ 2128 intpcmcia_set_event_mask(client_handle_t handle
, eventmask_t
*mask
) 2131 if(CHECK_HANDLE(handle
)) 2132 return CS_BAD_HANDLE
; 2133 if(handle
->Attributes
& CONF_EVENT_MASK_VALID
) 2134 return CS_BAD_SOCKET
; 2135 handle
->EventMask
= mask
->EventMask
; 2136 events
= handle
->PendingEvents
& handle
->EventMask
; 2137 handle
->PendingEvents
-= events
; 2139 bit
= ((events
^ (events
-1)) +1) >>1; 2140 EVENT(handle
, bit
, CS_EVENT_PRI_LOW
); 2144 }/* set_event_mask */ 2146 /*====================================================================*/ 2148 intpcmcia_report_error(client_handle_t handle
, error_info_t
*err
) 2153 if(CHECK_HANDLE(handle
)) 2154 printk(KERN_NOTICE
); 2156 printk(KERN_NOTICE
"%s: ", handle
->dev_info
); 2158 for(i
=0; i
< SERVICE_COUNT
; i
++) 2159 if(service_table
[i
].key
== err
->func
)break; 2160 if(i
< SERVICE_COUNT
) 2161 serv
= service_table
[i
].msg
; 2163 serv
="Unknown service number"; 2165 for(i
=0; i
< ERROR_COUNT
; i
++) 2166 if(error_table
[i
].key
== err
->retcode
)break; 2168 printk("%s: %s\n", serv
, error_table
[i
].msg
); 2170 printk("%s: Unknown error code %#x\n", serv
, err
->retcode
); 2175 /*====================================================================*/ 2177 intCardServices(int func
,void*a1
,void*a2
,void*a3
) 2183 for(i
=0; i
< SERVICE_COUNT
; i
++) 2184 if(service_table
[i
].key
== func
)break; 2185 if(i
< SERVICE_COUNT
) 2186 printk(KERN_DEBUG
"cs: CardServices(%s, 0x%p, 0x%p)\n", 2187 service_table
[i
].msg
, a1
, a2
); 2189 printk(KERN_DEBUG
"cs: CardServices(Unknown func %d, " 2190 "0x%p, 0x%p)\n", func
, a1
, a2
); 2194 case AccessConfigurationRegister
: 2195 returnpcmcia_access_configuration_register(a1
, a2
);break; 2196 case AdjustResourceInfo
: 2197 returnpcmcia_adjust_resource_info(a1
, a2
);break; 2198 case CheckEraseQueue
: 2199 returnpcmcia_check_erase_queue(a1
);break; 2201 returnpcmcia_close_memory(a1
);break; 2203 returnpcmcia_copy_memory(a1
, a2
);break; 2204 case DeregisterClient
: 2205 returnpcmcia_deregister_client(a1
);break; 2206 case DeregisterEraseQueue
: 2207 returnpcmcia_deregister_erase_queue(a1
);break; 2208 case GetFirstClient
: 2209 returnpcmcia_get_first_client(a1
, a2
);break; 2210 case GetCardServicesInfo
: 2211 returnpcmcia_get_card_services_info(a1
);break; 2212 case GetConfigurationInfo
: 2213 returnpcmcia_get_configuration_info(a1
, a2
);break; 2215 returnpcmcia_get_next_client(a1
, a2
);break; 2216 case GetFirstRegion
: 2217 returnpcmcia_get_first_region(a1
, a2
);break; 2219 returnpcmcia_get_first_tuple(a1
, a2
);break; 2221 returnpcmcia_get_next_region(a1
, a2
);break; 2223 returnpcmcia_get_next_tuple(a1
, a2
);break; 2225 returnpcmcia_get_status(a1
, a2
);break; 2227 returnpcmcia_get_tuple_data(a1
, a2
);break; 2229 returnpcmcia_map_mem_page(a1
, a2
);break; 2230 case ModifyConfiguration
: 2231 returnpcmcia_modify_configuration(a1
, a2
);break; 2233 returnpcmcia_modify_window(a1
, a2
);break; 2235 /* return pcmcia_open_memory(a1, a2); */ 2238 int ret
=pcmcia_open_memory(a1
, a2
, &m
); 2239 *(memory_handle_t
*)a1
= m
; 2244 returnpcmcia_parse_tuple(a1
, a2
, a3
);break; 2246 returnpcmcia_read_memory(a1
, a2
, a3
);break; 2247 case RegisterClient
: 2248 returnpcmcia_register_client(a1
, a2
);break; 2249 case RegisterEraseQueue
: 2252 int ret
=pcmcia_register_erase_queue(a1
, a2
, &w
); 2253 *(eraseq_handle_t
*)a1
= w
; 2257 /* return pcmcia_register_erase_queue(a1, a2); break; */ 2259 returnpcmcia_register_mtd(a1
, a2
);break; 2260 case ReleaseConfiguration
: 2261 returnpcmcia_release_configuration(a1
);break; 2263 returnpcmcia_release_io(a1
, a2
);break; 2265 returnpcmcia_release_irq(a1
, a2
);break; 2267 returnpcmcia_release_window(a1
);break; 2268 case RequestConfiguration
: 2269 returnpcmcia_request_configuration(a1
, a2
);break; 2271 returnpcmcia_request_io(a1
, a2
);break; 2273 returnpcmcia_request_irq(a1
, a2
);break; 2277 int ret
=pcmcia_request_window(a1
, a2
, &w
); 2278 *(window_handle_t
*)a1
= w
; 2283 returnpcmcia_reset_card(a1
, a2
);break; 2285 returnpcmcia_set_event_mask(a1
, a2
);break; 2287 returnpcmcia_validate_cis(a1
, a2
);break; 2289 returnpcmcia_write_memory(a1
, a2
, a3
);break; 2291 returnpcmcia_bind_device(a1
);break; 2293 returnpcmcia_bind_mtd(a1
);break; 2295 returnpcmcia_report_error(a1
, a2
);break; 2297 returnpcmcia_suspend_card(a1
, a2
);break; 2299 returnpcmcia_resume_card(a1
, a2
);break; 2301 returnpcmcia_eject_card(a1
, a2
);break; 2303 returnpcmcia_insert_card(a1
, a2
);break; 2305 returnpcmcia_replace_cis(a1
, a2
);break; 2306 case GetFirstWindow
: 2307 returnpcmcia_get_first_window(a1
, a2
);break; 2309 returnpcmcia_get_next_window(a1
, a2
);break; 2311 returnpcmcia_get_mem_page(a1
, a2
);break; 2313 return CS_UNSUPPORTED_FUNCTION
;break; 2318 /*====================================================================== 2320 OS-specific module glue goes here 2322 ======================================================================*/ 2323 /* in alpha order */ 2324 EXPORT_SYMBOL(pcmcia_access_configuration_register
); 2325 EXPORT_SYMBOL(pcmcia_adjust_resource_info
); 2326 EXPORT_SYMBOL(pcmcia_bind_device
); 2327 EXPORT_SYMBOL(pcmcia_bind_mtd
); 2328 EXPORT_SYMBOL(pcmcia_check_erase_queue
); 2329 EXPORT_SYMBOL(pcmcia_close_memory
); 2330 EXPORT_SYMBOL(pcmcia_copy_memory
); 2331 EXPORT_SYMBOL(pcmcia_deregister_client
); 2332 EXPORT_SYMBOL(pcmcia_deregister_erase_queue
); 2333 EXPORT_SYMBOL(pcmcia_eject_card
); 2334 EXPORT_SYMBOL(pcmcia_get_first_client
); 2335 EXPORT_SYMBOL(pcmcia_get_card_services_info
); 2336 EXPORT_SYMBOL(pcmcia_get_configuration_info
); 2337 EXPORT_SYMBOL(pcmcia_get_mem_page
); 2338 EXPORT_SYMBOL(pcmcia_get_next_client
); 2339 EXPORT_SYMBOL(pcmcia_get_first_region
); 2340 EXPORT_SYMBOL(pcmcia_get_first_tuple
); 2341 EXPORT_SYMBOL(pcmcia_get_first_window
); 2342 EXPORT_SYMBOL(pcmcia_get_next_region
); 2343 EXPORT_SYMBOL(pcmcia_get_next_tuple
); 2344 EXPORT_SYMBOL(pcmcia_get_next_window
); 2345 EXPORT_SYMBOL(pcmcia_get_status
); 2346 EXPORT_SYMBOL(pcmcia_get_tuple_data
); 2347 EXPORT_SYMBOL(pcmcia_insert_card
); 2348 EXPORT_SYMBOL(pcmcia_map_mem_page
); 2349 EXPORT_SYMBOL(pcmcia_modify_configuration
); 2350 EXPORT_SYMBOL(pcmcia_modify_window
); 2351 EXPORT_SYMBOL(pcmcia_open_memory
); 2352 EXPORT_SYMBOL(pcmcia_parse_tuple
); 2353 EXPORT_SYMBOL(pcmcia_read_memory
); 2354 EXPORT_SYMBOL(pcmcia_register_client
); 2355 EXPORT_SYMBOL(pcmcia_register_erase_queue
); 2356 EXPORT_SYMBOL(pcmcia_register_mtd
); 2357 EXPORT_SYMBOL(pcmcia_release_configuration
); 2358 EXPORT_SYMBOL(pcmcia_release_io
); 2359 EXPORT_SYMBOL(pcmcia_release_irq
); 2360 EXPORT_SYMBOL(pcmcia_release_window
); 2361 EXPORT_SYMBOL(pcmcia_replace_cis
); 2362 EXPORT_SYMBOL(pcmcia_report_error
); 2363 EXPORT_SYMBOL(pcmcia_request_configuration
); 2364 EXPORT_SYMBOL(pcmcia_request_io
); 2365 EXPORT_SYMBOL(pcmcia_request_irq
); 2366 EXPORT_SYMBOL(pcmcia_request_window
); 2367 EXPORT_SYMBOL(pcmcia_reset_card
); 2368 EXPORT_SYMBOL(pcmcia_resume_card
); 2369 EXPORT_SYMBOL(pcmcia_set_event_mask
); 2370 EXPORT_SYMBOL(pcmcia_suspend_card
); 2371 EXPORT_SYMBOL(pcmcia_validate_cis
); 2372 EXPORT_SYMBOL(pcmcia_write_memory
); 2374 EXPORT_SYMBOL(dead_socket
); 2375 EXPORT_SYMBOL(register_ss_entry
); 2376 EXPORT_SYMBOL(unregister_ss_entry
); 2377 EXPORT_SYMBOL(CardServices
); 2378 EXPORT_SYMBOL(MTDHelperEntry
); 2379 #ifdef CONFIG_PROC_FS 2380 EXPORT_SYMBOL(proc_pccard
); 2383 EXPORT_SYMBOL(pcmcia_register_socket
); 2384 EXPORT_SYMBOL(pcmcia_unregister_socket
); 2385 EXPORT_SYMBOL(pcmcia_suspend_socket
); 2386 EXPORT_SYMBOL(pcmcia_resume_socket
); 2388 static int __init
init_pcmcia_cs(void) 2390 printk(KERN_INFO
"%s\n", release
); 2391 printk(KERN_INFO
" %s\n", options
); 2392 DEBUG(0,"%s\n", version
); 2394 pm_register(PM_SYS_DEV
, PM_SYS_PCMCIA
, handle_pm_event
); 2395 #ifdef CONFIG_PROC_FS 2396 proc_pccard
=proc_mkdir("pccard", proc_bus
); 2401 static void __exit
exit_pcmcia_cs(void) 2403 printk(KERN_INFO
"unloading PCMCIA Card Services\n"); 2404 #ifdef CONFIG_PROC_FS 2406 remove_proc_entry("pccard", proc_bus
); 2410 pm_unregister_all(handle_pm_event
); 2411 release_resource_db(); 2414 module_init(init_pcmcia_cs
); 2415 module_exit(exit_pcmcia_cs
); 2417 /*====================================================================*/