aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia/pcmcia_resource.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pcmcia/pcmcia_resource.c')
-rw-r--r--drivers/pcmcia/pcmcia_resource.c45
1 files changed, 22 insertions, 23 deletions
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index 08377232d8eb..dbd5571064d1 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -88,7 +88,7 @@ static int alloc_io_space(struct pcmcia_socket *s, u_int attr, ioaddr_t *base,
88 } 88 }
89 if ((s->features & SS_CAP_STATIC_MAP) && s->io_offset) { 89 if ((s->features & SS_CAP_STATIC_MAP) && s->io_offset) {
90 *base = s->io_offset | (*base & 0x0fff); 90 *base = s->io_offset | (*base & 0x0fff);
91 s->io[0].Attributes = attr; 91 s->io[0].res->flags = (s->io[0].res->flags & ~IORESOURCE_BITS) | (attr & IORESOURCE_BITS);
92 return 0; 92 return 0;
93 } 93 }
94 /* Check for an already-allocated window that must conflict with 94 /* Check for an already-allocated window that must conflict with
@@ -96,38 +96,36 @@ static int alloc_io_space(struct pcmcia_socket *s, u_int attr, ioaddr_t *base,
96 * potential conflicts, just the most obvious ones. 96 * potential conflicts, just the most obvious ones.
97 */ 97 */
98 for (i = 0; i < MAX_IO_WIN; i++) 98 for (i = 0; i < MAX_IO_WIN; i++)
99 if ((s->io[i].NumPorts != 0) && 99 if ((s->io[i].res) &&
100 ((s->io[i].BasePort & (align-1)) == *base)) 100 ((s->io[i].res->start & (align-1)) == *base))
101 return 1; 101 return 1;
102 for (i = 0; i < MAX_IO_WIN; i++) { 102 for (i = 0; i < MAX_IO_WIN; i++) {
103 if (s->io[i].NumPorts == 0) { 103 if (!s->io[i].res) {
104 s->io[i].res = pcmcia_find_io_region(*base, num, align, s); 104 s->io[i].res = pcmcia_find_io_region(*base, num, align, s);
105 if (s->io[i].res) { 105 if (s->io[i].res) {
106 s->io[i].Attributes = attr; 106 *base = s->io[i].res->start;
107 s->io[i].BasePort = *base = s->io[i].res->start; 107 s->io[i].res->flags = (s->io[i].res->flags & ~IORESOURCE_BITS) | (attr & IORESOURCE_BITS);
108 s->io[i].NumPorts = s->io[i].InUse = num; 108 s->io[i].InUse = num;
109 break; 109 break;
110 } else 110 } else
111 return 1; 111 return 1;
112 } else if (s->io[i].Attributes != attr) 112 } else if ((s->io[i].res->flags & IORESOURCE_BITS) != (attr & IORESOURCE_BITS))
113 continue; 113 continue;
114 /* Try to extend top of window */ 114 /* Try to extend top of window */
115 try = s->io[i].BasePort + s->io[i].NumPorts; 115 try = s->io[i].res->end + 1;
116 if ((*base == 0) || (*base == try)) 116 if ((*base == 0) || (*base == try))
117 if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start, 117 if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start,
118 s->io[i].res->end + num, s) == 0) { 118 s->io[i].res->end + num, s) == 0) {
119 *base = try; 119 *base = try;
120 s->io[i].NumPorts += num;
121 s->io[i].InUse += num; 120 s->io[i].InUse += num;
122 break; 121 break;
123 } 122 }
124 /* Try to extend bottom of window */ 123 /* Try to extend bottom of window */
125 try = s->io[i].BasePort - num; 124 try = s->io[i].res->start - num;
126 if ((*base == 0) || (*base == try)) 125 if ((*base == 0) || (*base == try))
127 if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start - num, 126 if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start - num,
128 s->io[i].res->end, s) == 0) { 127 s->io[i].res->end, s) == 0) {
129 s->io[i].BasePort = *base = try; 128 *base = try;
130 s->io[i].NumPorts += num;
131 s->io[i].InUse += num; 129 s->io[i].InUse += num;
132 break; 130 break;
133 } 131 }
@@ -142,12 +140,13 @@ static void release_io_space(struct pcmcia_socket *s, ioaddr_t base,
142 int i; 140 int i;
143 141
144 for (i = 0; i < MAX_IO_WIN; i++) { 142 for (i = 0; i < MAX_IO_WIN; i++) {
145 if ((s->io[i].BasePort <= base) && 143 if (!s->io[i].res)
146 (s->io[i].BasePort+s->io[i].NumPorts >= base+num)) { 144 continue;
145 if ((s->io[i].res->start <= base) &&
146 (s->io[i].res->end >= base+num-1)) {
147 s->io[i].InUse -= num; 147 s->io[i].InUse -= num;
148 /* Free the window if no one else is using it */ 148 /* Free the window if no one else is using it */
149 if (s->io[i].InUse == 0) { 149 if (s->io[i].InUse == 0) {
150 s->io[i].NumPorts = 0;
151 release_resource(s->io[i].res); 150 release_resource(s->io[i].res);
152 kfree(s->io[i].res); 151 kfree(s->io[i].res);
153 s->io[i].res = NULL; 152 s->io[i].res = NULL;
@@ -224,8 +223,8 @@ int pccard_get_configuration_info(struct pcmcia_socket *s,
224 config->AssignedIRQ = s->irq.AssignedIRQ; 223 config->AssignedIRQ = s->irq.AssignedIRQ;
225 if (config->AssignedIRQ) 224 if (config->AssignedIRQ)
226 config->Attributes |= CONF_ENABLE_IRQ; 225 config->Attributes |= CONF_ENABLE_IRQ;
227 config->BasePort1 = s->io[0].BasePort; 226 config->BasePort1 = s->io[0].res->start;
228 config->NumPorts1 = s->io[0].NumPorts; 227 config->NumPorts1 = s->io[0].res->end - config->BasePort1 + 1;
229 } 228 }
230 return CS_SUCCESS; 229 return CS_SUCCESS;
231 } 230 }
@@ -468,7 +467,7 @@ int pcmcia_release_configuration(struct pcmcia_device *p_dev)
468 } 467 }
469 if (c->state & CONFIG_IO_REQ) 468 if (c->state & CONFIG_IO_REQ)
470 for (i = 0; i < MAX_IO_WIN; i++) { 469 for (i = 0; i < MAX_IO_WIN; i++) {
471 if (s->io[i].NumPorts == 0) 470 if (!s->io[i].res)
472 continue; 471 continue;
473 s->io[i].Config--; 472 s->io[i].Config--;
474 if (s->io[i].Config != 0) 473 if (s->io[i].Config != 0)
@@ -679,10 +678,10 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
679 if (c->state & CONFIG_IO_REQ) { 678 if (c->state & CONFIG_IO_REQ) {
680 iomap.speed = io_speed; 679 iomap.speed = io_speed;
681 for (i = 0; i < MAX_IO_WIN; i++) 680 for (i = 0; i < MAX_IO_WIN; i++)
682 if (s->io[i].NumPorts != 0) { 681 if (s->io[i].res) {
683 iomap.map = i; 682 iomap.map = i;
684 iomap.flags = MAP_ACTIVE; 683 iomap.flags = MAP_ACTIVE;
685 switch (s->io[i].Attributes & IO_DATA_PATH_WIDTH) { 684 switch (s->io[i].res->flags & IO_DATA_PATH_WIDTH) {
686 case IO_DATA_PATH_WIDTH_16: 685 case IO_DATA_PATH_WIDTH_16:
687 iomap.flags |= MAP_16BIT; break; 686 iomap.flags |= MAP_16BIT; break;
688 case IO_DATA_PATH_WIDTH_AUTO: 687 case IO_DATA_PATH_WIDTH_AUTO:
@@ -690,8 +689,8 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
690 default: 689 default:
691 break; 690 break;
692 } 691 }
693 iomap.start = s->io[i].BasePort; 692 iomap.start = s->io[i].res->start;
694 iomap.stop = iomap.start + s->io[i].NumPorts - 1; 693 iomap.stop = s->io[i].res->end;
695 s->ops->set_io_map(s, &iomap); 694 s->ops->set_io_map(s, &iomap);
696 s->io[i].Config++; 695 s->io[i].Config++;
697 } 696 }
lass="hl ppc">#define ISDN_FEATURE_L3_TRANS (0x10000 << ISDN_PROTO_L3_TRANS) #define ISDN_FEATURE_L3_TRANSDSP (0x10000 << ISDN_PROTO_L3_TRANSDSP) #define ISDN_FEATURE_L3_FCLASS2 (0x10000 << ISDN_PROTO_L3_FCLASS2) #define ISDN_FEATURE_L3_FCLASS1 (0x10000 << ISDN_PROTO_L3_FCLASS1) #define ISDN_FEATURE_L3_MASK (0x0FF0000) /* Max. 8 Protocols */ #define ISDN_FEATURE_L3_SHIFT (16) /* Signaling */ #define ISDN_FEATURE_P_UNKNOWN (0x1000000 << ISDN_PTYPE_UNKNOWN) #define ISDN_FEATURE_P_1TR6 (0x1000000 << ISDN_PTYPE_1TR6) #define ISDN_FEATURE_P_EURO (0x1000000 << ISDN_PTYPE_EURO) #define ISDN_FEATURE_P_NI1 (0x1000000 << ISDN_PTYPE_NI1) #define ISDN_FEATURE_P_MASK (0x0FF000000) /* Max. 8 Protocols */ #define ISDN_FEATURE_P_SHIFT (24) typedef struct setup_parm { unsigned char phone[32]; /* Remote Phone-Number */ unsigned char eazmsn[32]; /* Local EAZ or MSN */ unsigned char si1; /* Service Indicator 1 */ unsigned char si2; /* Service Indicator 2 */ unsigned char plan; /* Numbering plan */ unsigned char screen; /* Screening info */ } setup_parm; #ifdef CONFIG_ISDN_TTY_FAX /* T.30 Fax G3 */ #define FAXIDLEN 21 typedef struct T30_s { /* session parameters */ __u8 resolution; __u8 rate; __u8 width; __u8 length; __u8 compression; __u8 ecm; __u8 binary; __u8 scantime; __u8 id[FAXIDLEN]; /* additional parameters */ __u8 phase; __u8 direction; __u8 code; __u8 badlin; __u8 badmul; __u8 bor; __u8 fet; __u8 pollid[FAXIDLEN]; __u8 cq; __u8 cr; __u8 ctcrty; __u8 minsp; __u8 phcto; __u8 rel; __u8 nbc; /* remote station parameters */ __u8 r_resolution; __u8 r_rate; __u8 r_width; __u8 r_length; __u8 r_compression; __u8 r_ecm; __u8 r_binary; __u8 r_scantime; __u8 r_id[FAXIDLEN]; __u8 r_code; } __attribute__((packed)) T30_s; #define ISDN_TTY_FAX_CONN_IN 0 #define ISDN_TTY_FAX_CONN_OUT 1 #define ISDN_TTY_FAX_FCON 0 #define ISDN_TTY_FAX_DIS 1 #define ISDN_TTY_FAX_FTT 2 #define ISDN_TTY_FAX_MCF 3 #define ISDN_TTY_FAX_DCS 4 #define ISDN_TTY_FAX_TRAIN_OK 5 #define ISDN_TTY_FAX_EOP 6 #define ISDN_TTY_FAX_EOM 7 #define ISDN_TTY_FAX_MPS 8 #define ISDN_TTY_FAX_DTC 9 #define ISDN_TTY_FAX_RID 10 #define ISDN_TTY_FAX_HNG 11 #define ISDN_TTY_FAX_DT 12 #define ISDN_TTY_FAX_FCON_I 13 #define ISDN_TTY_FAX_DR 14 #define ISDN_TTY_FAX_ET 15 #define ISDN_TTY_FAX_CFR 16 #define ISDN_TTY_FAX_PTS 17 #define ISDN_TTY_FAX_SENT 18 #define ISDN_FAX_PHASE_IDLE 0 #define ISDN_FAX_PHASE_A 1 #define ISDN_FAX_PHASE_B 2 #define ISDN_FAX_PHASE_C 3 #define ISDN_FAX_PHASE_D 4 #define ISDN_FAX_PHASE_E 5 #endif /* TTY_FAX */ #define ISDN_FAX_CLASS1_FAE 0 #define ISDN_FAX_CLASS1_FTS 1 #define ISDN_FAX_CLASS1_FRS 2 #define ISDN_FAX_CLASS1_FTM 3 #define ISDN_FAX_CLASS1_FRM 4 #define ISDN_FAX_CLASS1_FTH 5 #define ISDN_FAX_CLASS1_FRH 6 #define ISDN_FAX_CLASS1_CTRL 7 #define ISDN_FAX_CLASS1_OK 0 #define ISDN_FAX_CLASS1_CONNECT 1 #define ISDN_FAX_CLASS1_NOCARR 2 #define ISDN_FAX_CLASS1_ERROR 3 #define ISDN_FAX_CLASS1_FCERROR 4 #define ISDN_FAX_CLASS1_QUERY 5 typedef struct { __u8 cmd; __u8 subcmd; __u8 para[50]; } aux_s; #define AT_COMMAND 0 #define AT_EQ_VALUE 1 #define AT_QUERY 2 #define AT_EQ_QUERY 3 /* CAPI structs */ /* this is compatible to the old union size */ #define MAX_CAPI_PARA_LEN 50 typedef struct { /* Header */ __u16 Length; __u16 ApplId; __u8 Command; __u8 Subcommand; __u16 Messagenumber; /* Parameter */ union { __u32 Controller; __u32 PLCI; __u32 NCCI; } adr; __u8 para[MAX_CAPI_PARA_LEN]; } capi_msg; /* * Structure for exchanging above infos * */ typedef struct { int driver; /* Lowlevel-Driver-ID */ int command; /* Command or Status (see above) */ ulong arg; /* Additional Data */ union { ulong errcode; /* Type of error with STAT_L1ERR */ int length; /* Amount of bytes sent with STAT_BSENT */ u_char num[50]; /* Additional Data */ setup_parm setup;/* For SETUP msg */ capi_msg cmsg; /* For CAPI like messages */ char display[85];/* display message data */ isdn_cmd_stat isdn_io; /* ISDN IO-parameter/result */ aux_s aux; /* for modem commands/indications */ #ifdef CONFIG_ISDN_TTY_FAX T30_s *fax; /* Pointer to ttys fax struct */ #endif ulong userdata; /* User Data */ } parm; } isdn_ctrl; #define dss1_io isdn_io #define ni1_io isdn_io /* * The interface-struct itself (initialized at load-time of lowlevel-driver) * * See Documentation/isdn/INTERFACE for a description, how the communication * between the ISDN subsystem and its drivers is done. * */ typedef struct { struct module *owner; /* Number of channels supported by this driver */ int channels; /* * Maximum Size of transmit/receive-buffer this driver supports. */ int maxbufsize; /* Feature-Flags for this driver. * See defines ISDN_FEATURE_... for Values */ unsigned long features; /* * Needed for calculating * dev->hard_header_len = linklayer header + hl_hdrlen; * Drivers, not supporting sk_buff's should set this to 0. */ unsigned short hl_hdrlen; /* * Receive-Callback using sk_buff's * Parameters: * int Driver-ID * int local channel-number (0 ...) * struct sk_buff *skb received Data */ void (*rcvcallb_skb)(int, int, struct sk_buff *); /* Status-Callback * Parameters: * isdn_ctrl* * driver = Driver ID. * command = One of above ISDN_STAT_... constants. * arg = depending on status-type. * num = depending on status-type. */ int (*statcallb)(isdn_ctrl*); /* Send command * Parameters: * isdn_ctrl* * driver = Driver ID. * command = One of above ISDN_CMD_... constants. * arg = depending on command. * num = depending on command. */ int (*command)(isdn_ctrl*); /* * Send data using sk_buff's * Parameters: * int driverId * int local channel-number (0...) * int Flag: Need ACK for this packet. * struct sk_buff *skb Data to send */ int (*writebuf_skb) (int, int, int, struct sk_buff *); /* Send raw D-Channel-Commands * Parameters: * u_char pointer data * int length of data * int driverId * int local channel-number (0 ...) */ int (*writecmd)(const u_char __user *, int, int, int); /* Read raw Status replies * u_char pointer data (volatile) * int length of buffer * int driverId * int local channel-number (0 ...) */ int (*readstat)(u_char __user *, int, int, int); char id[20]; } isdn_if; /* * Function which must be called by lowlevel-driver at loadtime with * the following fields of above struct set: * * channels Number of channels that will be supported. * hl_hdrlen Space to preserve in sk_buff's when sending. Drivers, not * supporting sk_buff's should set this to 0. * command Address of Command-Handler. * features Bitwise coded Features of this driver. (use ISDN_FEATURE_...) * writebuf_skb Address of Skbuff-Send-Handler. * writecmd " " D-Channel " which accepts raw D-Ch-Commands. * readstat " " D-Channel " which delivers raw Status-Data. * * The linklevel-driver fills the following fields: * * channels Driver-ID assigned to this driver. (Must be used on all * subsequent callbacks. * rcvcallb_skb Address of handler for received Skbuff's. * statcallb " " " for status-changes. * */ extern int register_isdn(isdn_if*); #include <asm/uaccess.h> #endif /* __KERNEL__ */ #endif /* __ISDNIF_H__ */