mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	pcmcia: move cistpl.c into pcmcia module
As PCMCIA is the only real user of CIS access functions, include cistpl.c in the PCMCIA module, not in the PCMCIA & CardBus core module. Tested-by: Wolfram Sang <w.sang@pengutronix.de> Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
This commit is contained in:
		
							parent
							
								
									4e8804ff6d
								
							
						
					
					
						commit
						6e7b51a733
					
				
					 6 changed files with 194 additions and 198 deletions
				
			
		| 
						 | 
					@ -2,11 +2,11 @@
 | 
				
			||||||
# Makefile for the kernel pcmcia subsystem (c/o David Hinds)
 | 
					# Makefile for the kernel pcmcia subsystem (c/o David Hinds)
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pcmcia_core-y					+= cs.o cistpl.o rsrc_mgr.o socket_sysfs.o
 | 
					pcmcia_core-y					+= cs.o rsrc_mgr.o socket_sysfs.o
 | 
				
			||||||
pcmcia_core-$(CONFIG_CARDBUS)			+= cardbus.o
 | 
					pcmcia_core-$(CONFIG_CARDBUS)			+= cardbus.o
 | 
				
			||||||
obj-$(CONFIG_PCCARD)				+= pcmcia_core.o
 | 
					obj-$(CONFIG_PCCARD)				+= pcmcia_core.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pcmcia-y					+= ds.o pcmcia_resource.o
 | 
					pcmcia-y					+= ds.o pcmcia_resource.o cistpl.o
 | 
				
			||||||
pcmcia-$(CONFIG_PCMCIA_IOCTL)			+= pcmcia_ioctl.o
 | 
					pcmcia-$(CONFIG_PCMCIA_IOCTL)			+= pcmcia_ioctl.o
 | 
				
			||||||
obj-$(CONFIG_PCMCIA)				+= pcmcia.o
 | 
					obj-$(CONFIG_PCMCIA)				+= pcmcia.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -76,7 +76,6 @@ void release_cis_mem(struct pcmcia_socket *s)
 | 
				
			||||||
	s->cis_virt = NULL;
 | 
						s->cis_virt = NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(release_cis_mem);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Map the card memory at "card_offset" into virtual space.
 | 
					 * Map the card memory at "card_offset" into virtual space.
 | 
				
			||||||
| 
						 | 
					@ -195,7 +194,6 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
 | 
				
			||||||
	  *(u_char *)(ptr+2), *(u_char *)(ptr+3));
 | 
						  *(u_char *)(ptr+2), *(u_char *)(ptr+3));
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(pcmcia_read_cis_mem);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
 | 
					void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
 | 
				
			||||||
| 
						 | 
					@ -254,7 +252,6 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(pcmcia_write_cis_mem);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*======================================================================
 | 
					/*======================================================================
 | 
				
			||||||
| 
						 | 
					@ -335,7 +332,6 @@ void destroy_cis_cache(struct pcmcia_socket *s)
 | 
				
			||||||
		kfree(cis);
 | 
							kfree(cis);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(destroy_cis_cache);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*======================================================================
 | 
					/*======================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -374,7 +370,6 @@ int verify_cis_cache(struct pcmcia_socket *s)
 | 
				
			||||||
	kfree(buf);
 | 
						kfree(buf);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(verify_cis_cache);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*======================================================================
 | 
					/*======================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -400,7 +395,6 @@ int pcmcia_replace_cis(struct pcmcia_socket *s,
 | 
				
			||||||
	memcpy(s->fake_cis, data, len);
 | 
						memcpy(s->fake_cis, data, len);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(pcmcia_replace_cis);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*======================================================================
 | 
					/*======================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -446,7 +440,6 @@ int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function, tuple
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return pccard_get_next_tuple(s, function, tuple);
 | 
					    return pccard_get_next_tuple(s, function, tuple);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(pccard_get_first_tuple);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int follow_link(struct pcmcia_socket *s, tuple_t *tuple)
 | 
					static int follow_link(struct pcmcia_socket *s, tuple_t *tuple)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -582,7 +575,6 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_
 | 
				
			||||||
    tuple->CISOffset = ofs + 2;
 | 
					    tuple->CISOffset = ofs + 2;
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(pccard_get_next_tuple);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*====================================================================*/
 | 
					/*====================================================================*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -606,7 +598,6 @@ int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple)
 | 
				
			||||||
		   _MIN(len, tuple->TupleDataMax), tuple->TupleData);
 | 
							   _MIN(len, tuple->TupleDataMax), tuple->TupleData);
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(pccard_get_tuple_data);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*======================================================================
 | 
					/*======================================================================
 | 
				
			||||||
| 
						 | 
					@ -1379,7 +1370,6 @@ int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t
 | 
				
			||||||
    kfree(buf);
 | 
					    kfree(buf);
 | 
				
			||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(pccard_read_tuple);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -1439,7 +1429,6 @@ int pccard_loop_tuple(struct pcmcia_socket *s, unsigned int function,
 | 
				
			||||||
	kfree(buf);
 | 
						kfree(buf);
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(pccard_loop_tuple);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -1533,4 +1522,149 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info)
 | 
				
			||||||
	kfree(p);
 | 
						kfree(p);
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(pccard_validate_cis);
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define to_socket(_dev) container_of(_dev, struct pcmcia_socket, dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static ssize_t pccard_extract_cis(struct pcmcia_socket *s, char *buf,
 | 
				
			||||||
 | 
									  loff_t off, size_t count)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						tuple_t tuple;
 | 
				
			||||||
 | 
						int status, i;
 | 
				
			||||||
 | 
						loff_t pointer = 0;
 | 
				
			||||||
 | 
						ssize_t ret = 0;
 | 
				
			||||||
 | 
						u_char *tuplebuffer;
 | 
				
			||||||
 | 
						u_char *tempbuffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tuplebuffer = kmalloc(sizeof(u_char) * 256, GFP_KERNEL);
 | 
				
			||||||
 | 
						if (!tuplebuffer)
 | 
				
			||||||
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tempbuffer = kmalloc(sizeof(u_char) * 258, GFP_KERNEL);
 | 
				
			||||||
 | 
						if (!tempbuffer) {
 | 
				
			||||||
 | 
							ret = -ENOMEM;
 | 
				
			||||||
 | 
							goto free_tuple;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memset(&tuple, 0, sizeof(tuple_t));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tuple.Attributes = TUPLE_RETURN_LINK | TUPLE_RETURN_COMMON;
 | 
				
			||||||
 | 
						tuple.DesiredTuple = RETURN_FIRST_TUPLE;
 | 
				
			||||||
 | 
						tuple.TupleOffset = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						status = pccard_get_first_tuple(s, BIND_FN_ALL, &tuple);
 | 
				
			||||||
 | 
						while (!status) {
 | 
				
			||||||
 | 
							tuple.TupleData = tuplebuffer;
 | 
				
			||||||
 | 
							tuple.TupleDataMax = 255;
 | 
				
			||||||
 | 
							memset(tuplebuffer, 0, sizeof(u_char) * 255);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							status = pccard_get_tuple_data(s, &tuple);
 | 
				
			||||||
 | 
							if (status)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (off < (pointer + 2 + tuple.TupleDataLen)) {
 | 
				
			||||||
 | 
								tempbuffer[0] = tuple.TupleCode & 0xff;
 | 
				
			||||||
 | 
								tempbuffer[1] = tuple.TupleLink & 0xff;
 | 
				
			||||||
 | 
								for (i = 0; i < tuple.TupleDataLen; i++)
 | 
				
			||||||
 | 
									tempbuffer[i + 2] = tuplebuffer[i] & 0xff;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								for (i = 0; i < (2 + tuple.TupleDataLen); i++) {
 | 
				
			||||||
 | 
									if (((i + pointer) >= off) &&
 | 
				
			||||||
 | 
									    (i + pointer) < (off + count)) {
 | 
				
			||||||
 | 
										buf[ret] = tempbuffer[i];
 | 
				
			||||||
 | 
										ret++;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							pointer += 2 + tuple.TupleDataLen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (pointer >= (off + count))
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (tuple.TupleCode == CISTPL_END)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							status = pccard_get_next_tuple(s, BIND_FN_ALL, &tuple);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						kfree(tempbuffer);
 | 
				
			||||||
 | 
					 free_tuple:
 | 
				
			||||||
 | 
						kfree(tuplebuffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static ssize_t pccard_show_cis(struct kobject *kobj,
 | 
				
			||||||
 | 
								       struct bin_attribute *bin_attr,
 | 
				
			||||||
 | 
								       char *buf, loff_t off, size_t count)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned int size = 0x200;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (off >= size)
 | 
				
			||||||
 | 
							count = 0;
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							struct pcmcia_socket *s;
 | 
				
			||||||
 | 
							unsigned int chains;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (off + count > size)
 | 
				
			||||||
 | 
								count = size - off;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							s = to_socket(container_of(kobj, struct device, kobj));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (!(s->state & SOCKET_PRESENT))
 | 
				
			||||||
 | 
								return -ENODEV;
 | 
				
			||||||
 | 
							if (pccard_validate_cis(s, &chains))
 | 
				
			||||||
 | 
								return -EIO;
 | 
				
			||||||
 | 
							if (!chains)
 | 
				
			||||||
 | 
								return -ENODATA;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							count = pccard_extract_cis(s, buf, off, count);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return count;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static ssize_t pccard_store_cis(struct kobject *kobj,
 | 
				
			||||||
 | 
									struct bin_attribute *bin_attr,
 | 
				
			||||||
 | 
									char *buf, loff_t off, size_t count)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct pcmcia_socket *s;
 | 
				
			||||||
 | 
						int error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						s = to_socket(container_of(kobj, struct device, kobj));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (off)
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (count >= CISTPL_MAX_CIS_SIZE)
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!(s->state & SOCKET_PRESENT))
 | 
				
			||||||
 | 
							return -ENODEV;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						error = pcmcia_replace_cis(s, buf, count);
 | 
				
			||||||
 | 
						if (error)
 | 
				
			||||||
 | 
							return -EIO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_lock(&s->skt_mutex);
 | 
				
			||||||
 | 
						if ((s->callback) && (s->state & SOCKET_PRESENT) &&
 | 
				
			||||||
 | 
						    !(s->state & SOCKET_CARDBUS)) {
 | 
				
			||||||
 | 
							if (try_module_get(s->callback->owner)) {
 | 
				
			||||||
 | 
								s->callback->requery(s, 1);
 | 
				
			||||||
 | 
								module_put(s->callback->owner);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						mutex_unlock(&s->skt_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return count;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct bin_attribute pccard_cis_attr = {
 | 
				
			||||||
 | 
						.attr = { .name = "cis", .mode = S_IRUGO | S_IWUSR },
 | 
				
			||||||
 | 
						.size = 0x200,
 | 
				
			||||||
 | 
						.read = pccard_show_cis,
 | 
				
			||||||
 | 
						.write = pccard_store_cis,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -92,9 +92,6 @@ struct pccard_resource_ops {
 | 
				
			||||||
 * Stuff internal to module "pcmcia_core":
 | 
					 * Stuff internal to module "pcmcia_core":
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* cistpl.c */
 | 
					 | 
				
			||||||
int verify_cis_cache(struct pcmcia_socket *s);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* socket_sysfs.c */
 | 
					/* socket_sysfs.c */
 | 
				
			||||||
extern int pccard_sysfs_add_socket(struct device *dev);
 | 
					extern int pccard_sysfs_add_socket(struct device *dev);
 | 
				
			||||||
extern void pccard_sysfs_remove_socket(struct device *dev);
 | 
					extern void pccard_sysfs_remove_socket(struct device *dev);
 | 
				
			||||||
| 
						 | 
					@ -102,8 +99,6 @@ extern void pccard_sysfs_remove_socket(struct device *dev);
 | 
				
			||||||
/* cardbus.c */
 | 
					/* cardbus.c */
 | 
				
			||||||
int cb_alloc(struct pcmcia_socket *s);
 | 
					int cb_alloc(struct pcmcia_socket *s);
 | 
				
			||||||
void cb_free(struct pcmcia_socket *s);
 | 
					void cb_free(struct pcmcia_socket *s);
 | 
				
			||||||
int read_cb_mem(struct pcmcia_socket *s, int space, u_int addr, u_int len,
 | 
					 | 
				
			||||||
		void *ptr);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -116,6 +111,7 @@ struct pcmcia_callback{
 | 
				
			||||||
	int		(*event) (struct pcmcia_socket *s,
 | 
						int		(*event) (struct pcmcia_socket *s,
 | 
				
			||||||
				  event_t event, int priority);
 | 
									  event_t event, int priority);
 | 
				
			||||||
	void		(*requery) (struct pcmcia_socket *s, int new_cis);
 | 
						void		(*requery) (struct pcmcia_socket *s, int new_cis);
 | 
				
			||||||
 | 
						int		(*validate) (struct pcmcia_socket *s, unsigned int *i);
 | 
				
			||||||
	int		(*suspend) (struct pcmcia_socket *s);
 | 
						int		(*suspend) (struct pcmcia_socket *s);
 | 
				
			||||||
	int		(*resume) (struct pcmcia_socket *s);
 | 
						int		(*resume) (struct pcmcia_socket *s);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -137,35 +133,6 @@ int pcmcia_insert_card(struct pcmcia_socket *skt);
 | 
				
			||||||
struct pcmcia_socket *pcmcia_get_socket(struct pcmcia_socket *skt);
 | 
					struct pcmcia_socket *pcmcia_get_socket(struct pcmcia_socket *skt);
 | 
				
			||||||
void pcmcia_put_socket(struct pcmcia_socket *skt);
 | 
					void pcmcia_put_socket(struct pcmcia_socket *skt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* cistpl.c */
 | 
					 | 
				
			||||||
int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr,
 | 
					 | 
				
			||||||
			u_int addr, u_int len, void *ptr);
 | 
					 | 
				
			||||||
void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr,
 | 
					 | 
				
			||||||
			  u_int addr, u_int len, void *ptr);
 | 
					 | 
				
			||||||
void release_cis_mem(struct pcmcia_socket *s);
 | 
					 | 
				
			||||||
void destroy_cis_cache(struct pcmcia_socket *s);
 | 
					 | 
				
			||||||
int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function,
 | 
					 | 
				
			||||||
		      cisdata_t code, void *parse);
 | 
					 | 
				
			||||||
int pcmcia_replace_cis(struct pcmcia_socket *s,
 | 
					 | 
				
			||||||
		       const u8 *data, const size_t len);
 | 
					 | 
				
			||||||
int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *count);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* loop over CIS entries */
 | 
					 | 
				
			||||||
int pccard_loop_tuple(struct pcmcia_socket *s, unsigned int function,
 | 
					 | 
				
			||||||
		      cisdata_t code, cisparse_t *parse, void *priv_data,
 | 
					 | 
				
			||||||
		      int (*loop_tuple) (tuple_t *tuple,
 | 
					 | 
				
			||||||
					 cisparse_t *parse,
 | 
					 | 
				
			||||||
					 void *priv_data));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function,
 | 
					 | 
				
			||||||
			tuple_t *tuple);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function,
 | 
					 | 
				
			||||||
			tuple_t *tuple);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* rsrc_mgr.c */
 | 
					/* rsrc_mgr.c */
 | 
				
			||||||
int pcmcia_validate_mem(struct pcmcia_socket *s);
 | 
					int pcmcia_validate_mem(struct pcmcia_socket *s);
 | 
				
			||||||
struct resource *pcmcia_find_mem_region(u_long base,
 | 
					struct resource *pcmcia_find_mem_region(u_long base,
 | 
				
			||||||
| 
						 | 
					@ -183,6 +150,37 @@ extern struct bus_type pcmcia_bus_type;
 | 
				
			||||||
/* pcmcia_resource.c */
 | 
					/* pcmcia_resource.c */
 | 
				
			||||||
extern int pcmcia_release_configuration(struct pcmcia_device *p_dev);
 | 
					extern int pcmcia_release_configuration(struct pcmcia_device *p_dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* cistpl.c */
 | 
				
			||||||
 | 
					extern struct bin_attribute pccard_cis_attr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr,
 | 
				
			||||||
 | 
								u_int addr, u_int len, void *ptr);
 | 
				
			||||||
 | 
					void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr,
 | 
				
			||||||
 | 
								  u_int addr, u_int len, void *ptr);
 | 
				
			||||||
 | 
					void release_cis_mem(struct pcmcia_socket *s);
 | 
				
			||||||
 | 
					void destroy_cis_cache(struct pcmcia_socket *s);
 | 
				
			||||||
 | 
					int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function,
 | 
				
			||||||
 | 
							      cisdata_t code, void *parse);
 | 
				
			||||||
 | 
					int pcmcia_replace_cis(struct pcmcia_socket *s,
 | 
				
			||||||
 | 
							       const u8 *data, const size_t len);
 | 
				
			||||||
 | 
					int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *count);
 | 
				
			||||||
 | 
					int verify_cis_cache(struct pcmcia_socket *s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int pccard_loop_tuple(struct pcmcia_socket *s, unsigned int function,
 | 
				
			||||||
 | 
							      cisdata_t code, cisparse_t *parse, void *priv_data,
 | 
				
			||||||
 | 
							      int (*loop_tuple) (tuple_t *tuple,
 | 
				
			||||||
 | 
										 cisparse_t *parse,
 | 
				
			||||||
 | 
										 void *priv_data));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function,
 | 
				
			||||||
 | 
								tuple_t *tuple);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function,
 | 
				
			||||||
 | 
								tuple_t *tuple);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_PCMCIA_IOCTL
 | 
					#ifdef CONFIG_PCMCIA_IOCTL
 | 
				
			||||||
/* ds.c */
 | 
					/* ds.c */
 | 
				
			||||||
extern spinlock_t pcmcia_dev_list_lock;
 | 
					extern spinlock_t pcmcia_dev_list_lock;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1313,6 +1313,7 @@ static struct pcmcia_callback pcmcia_bus_callback = {
 | 
				
			||||||
	.owner = THIS_MODULE,
 | 
						.owner = THIS_MODULE,
 | 
				
			||||||
	.event = ds_event,
 | 
						.event = ds_event,
 | 
				
			||||||
	.requery = pcmcia_bus_rescan,
 | 
						.requery = pcmcia_bus_rescan,
 | 
				
			||||||
 | 
						.validate = pccard_validate_cis,
 | 
				
			||||||
	.suspend = pcmcia_bus_suspend,
 | 
						.suspend = pcmcia_bus_suspend,
 | 
				
			||||||
	.resume = pcmcia_bus_resume,
 | 
						.resume = pcmcia_bus_resume,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -1336,6 +1337,13 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev,
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	msleep(250);
 | 
						msleep(250);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = sysfs_create_bin_file(&dev->kobj, &pccard_cis_attr);
 | 
				
			||||||
 | 
						if (ret) {
 | 
				
			||||||
 | 
							dev_printk(KERN_ERR, dev, "PCMCIA registration failed\n");
 | 
				
			||||||
 | 
							pcmcia_put_socket(socket);
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_PCMCIA_IOCTL
 | 
					#ifdef CONFIG_PCMCIA_IOCTL
 | 
				
			||||||
	init_waitqueue_head(&socket->queue);
 | 
						init_waitqueue_head(&socket->queue);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -1371,6 +1379,8 @@ static void pcmcia_bus_remove_socket(struct device *dev,
 | 
				
			||||||
	release_cis_mem(socket);
 | 
						release_cis_mem(socket);
 | 
				
			||||||
	mutex_unlock(&socket->skt_mutex);
 | 
						mutex_unlock(&socket->skt_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sysfs_remove_bin_file(&dev->kobj, &pccard_cis_attr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pcmcia_put_socket(socket);
 | 
						pcmcia_put_socket(socket);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return;
 | 
						return;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -277,7 +277,9 @@ static int readable(struct pcmcia_socket *s, struct resource *res,
 | 
				
			||||||
	s->cis_mem.res = res;
 | 
						s->cis_mem.res = res;
 | 
				
			||||||
	s->cis_virt = ioremap(res->start, s->map_size);
 | 
						s->cis_virt = ioremap(res->start, s->map_size);
 | 
				
			||||||
	if (s->cis_virt) {
 | 
						if (s->cis_virt) {
 | 
				
			||||||
		ret = pccard_validate_cis(s, count);
 | 
							/* as we're only called from pcmcia.c, we're safe */
 | 
				
			||||||
 | 
							if (s->callback->validate)
 | 
				
			||||||
 | 
								ret = s->callback->validate(s, count);
 | 
				
			||||||
		/* invalidate mapping */
 | 
							/* invalidate mapping */
 | 
				
			||||||
		iounmap(s->cis_virt);
 | 
							iounmap(s->cis_virt);
 | 
				
			||||||
		s->cis_virt = NULL;
 | 
							s->cis_virt = NULL;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -213,138 +213,6 @@ static ssize_t pccard_store_resource(struct device *dev,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
static DEVICE_ATTR(available_resources_setup_done, 0600, pccard_show_resource, pccard_store_resource);
 | 
					static DEVICE_ATTR(available_resources_setup_done, 0600, pccard_show_resource, pccard_store_resource);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
static ssize_t pccard_extract_cis(struct pcmcia_socket *s, char *buf, loff_t off, size_t count)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	tuple_t tuple;
 | 
					 | 
				
			||||||
	int status, i;
 | 
					 | 
				
			||||||
	loff_t pointer = 0;
 | 
					 | 
				
			||||||
	ssize_t ret = 0;
 | 
					 | 
				
			||||||
	u_char *tuplebuffer;
 | 
					 | 
				
			||||||
	u_char *tempbuffer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	tuplebuffer = kmalloc(sizeof(u_char) * 256, GFP_KERNEL);
 | 
					 | 
				
			||||||
	if (!tuplebuffer)
 | 
					 | 
				
			||||||
		return -ENOMEM;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	tempbuffer = kmalloc(sizeof(u_char) * 258, GFP_KERNEL);
 | 
					 | 
				
			||||||
	if (!tempbuffer) {
 | 
					 | 
				
			||||||
		ret = -ENOMEM;
 | 
					 | 
				
			||||||
		goto free_tuple;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	memset(&tuple, 0, sizeof(tuple_t));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	tuple.Attributes = TUPLE_RETURN_LINK | TUPLE_RETURN_COMMON;
 | 
					 | 
				
			||||||
	tuple.DesiredTuple = RETURN_FIRST_TUPLE;
 | 
					 | 
				
			||||||
	tuple.TupleOffset = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	status = pccard_get_first_tuple(s, BIND_FN_ALL, &tuple);
 | 
					 | 
				
			||||||
	while (!status) {
 | 
					 | 
				
			||||||
		tuple.TupleData = tuplebuffer;
 | 
					 | 
				
			||||||
		tuple.TupleDataMax = 255;
 | 
					 | 
				
			||||||
		memset(tuplebuffer, 0, sizeof(u_char) * 255);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		status = pccard_get_tuple_data(s, &tuple);
 | 
					 | 
				
			||||||
		if (status)
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (off < (pointer + 2 + tuple.TupleDataLen)) {
 | 
					 | 
				
			||||||
			tempbuffer[0] = tuple.TupleCode & 0xff;
 | 
					 | 
				
			||||||
			tempbuffer[1] = tuple.TupleLink & 0xff;
 | 
					 | 
				
			||||||
			for (i = 0; i < tuple.TupleDataLen; i++)
 | 
					 | 
				
			||||||
				tempbuffer[i + 2] = tuplebuffer[i] & 0xff;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			for (i = 0; i < (2 + tuple.TupleDataLen); i++) {
 | 
					 | 
				
			||||||
				if (((i + pointer) >= off) &&
 | 
					 | 
				
			||||||
				    (i + pointer) < (off + count)) {
 | 
					 | 
				
			||||||
					buf[ret] = tempbuffer[i];
 | 
					 | 
				
			||||||
					ret++;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		pointer += 2 + tuple.TupleDataLen;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (pointer >= (off + count))
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (tuple.TupleCode == CISTPL_END)
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		status = pccard_get_next_tuple(s, BIND_FN_ALL, &tuple);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	kfree(tempbuffer);
 | 
					 | 
				
			||||||
 free_tuple:
 | 
					 | 
				
			||||||
	kfree(tuplebuffer);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return ret;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static ssize_t pccard_show_cis(struct kobject *kobj,
 | 
					 | 
				
			||||||
			       struct bin_attribute *bin_attr,
 | 
					 | 
				
			||||||
			       char *buf, loff_t off, size_t count)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	unsigned int size = 0x200;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (off >= size)
 | 
					 | 
				
			||||||
		count = 0;
 | 
					 | 
				
			||||||
	else {
 | 
					 | 
				
			||||||
		struct pcmcia_socket *s;
 | 
					 | 
				
			||||||
		unsigned int chains;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (off + count > size)
 | 
					 | 
				
			||||||
			count = size - off;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		s = to_socket(container_of(kobj, struct device, kobj));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (!(s->state & SOCKET_PRESENT))
 | 
					 | 
				
			||||||
			return -ENODEV;
 | 
					 | 
				
			||||||
		if (pccard_validate_cis(s, &chains))
 | 
					 | 
				
			||||||
			return -EIO;
 | 
					 | 
				
			||||||
		if (!chains)
 | 
					 | 
				
			||||||
			return -ENODATA;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		count = pccard_extract_cis(s, buf, off, count);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return count;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static ssize_t pccard_store_cis(struct kobject *kobj,
 | 
					 | 
				
			||||||
				struct bin_attribute *bin_attr,
 | 
					 | 
				
			||||||
				char *buf, loff_t off, size_t count)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct pcmcia_socket *s = to_socket(container_of(kobj, struct device, kobj));
 | 
					 | 
				
			||||||
	int error;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (off)
 | 
					 | 
				
			||||||
		return -EINVAL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (count >= CISTPL_MAX_CIS_SIZE)
 | 
					 | 
				
			||||||
		return -EINVAL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!(s->state & SOCKET_PRESENT))
 | 
					 | 
				
			||||||
		return -ENODEV;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	error = pcmcia_replace_cis(s, buf, count);
 | 
					 | 
				
			||||||
	if (error)
 | 
					 | 
				
			||||||
		return -EIO;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	mutex_lock(&s->skt_mutex);
 | 
					 | 
				
			||||||
	if ((s->callback) && (s->state & SOCKET_PRESENT) &&
 | 
					 | 
				
			||||||
	    !(s->state & SOCKET_CARDBUS)) {
 | 
					 | 
				
			||||||
		if (try_module_get(s->callback->owner)) {
 | 
					 | 
				
			||||||
			s->callback->requery(s, 1);
 | 
					 | 
				
			||||||
			module_put(s->callback->owner);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	mutex_unlock(&s->skt_mutex);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return count;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static struct attribute *pccard_socket_attributes[] = {
 | 
					static struct attribute *pccard_socket_attributes[] = {
 | 
				
			||||||
	&dev_attr_card_type.attr,
 | 
						&dev_attr_card_type.attr,
 | 
				
			||||||
	&dev_attr_card_voltage.attr,
 | 
						&dev_attr_card_voltage.attr,
 | 
				
			||||||
| 
						 | 
					@ -362,28 +230,12 @@ static const struct attribute_group socket_attrs = {
 | 
				
			||||||
	.attrs = pccard_socket_attributes,
 | 
						.attrs = pccard_socket_attributes,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct bin_attribute pccard_cis_attr = {
 | 
					 | 
				
			||||||
	.attr = { .name = "cis", .mode = S_IRUGO | S_IWUSR },
 | 
					 | 
				
			||||||
	.size = 0x200,
 | 
					 | 
				
			||||||
	.read = pccard_show_cis,
 | 
					 | 
				
			||||||
	.write = pccard_store_cis,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int pccard_sysfs_add_socket(struct device *dev)
 | 
					int pccard_sysfs_add_socket(struct device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int ret = 0;
 | 
						return sysfs_create_group(&dev->kobj, &socket_attrs);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	ret = sysfs_create_group(&dev->kobj, &socket_attrs);
 | 
					 | 
				
			||||||
	if (!ret) {
 | 
					 | 
				
			||||||
		ret = sysfs_create_bin_file(&dev->kobj, &pccard_cis_attr);
 | 
					 | 
				
			||||||
		if (ret)
 | 
					 | 
				
			||||||
			sysfs_remove_group(&dev->kobj, &socket_attrs);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return ret;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void pccard_sysfs_remove_socket(struct device *dev)
 | 
					void pccard_sysfs_remove_socket(struct device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	sysfs_remove_bin_file(&dev->kobj, &pccard_cis_attr);
 | 
					 | 
				
			||||||
	sysfs_remove_group(&dev->kobj, &socket_attrs);
 | 
						sysfs_remove_group(&dev->kobj, &socket_attrs);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue