static int __init prism2cs_init(void) { #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68)) servinfo_t serv; #endif DBFENTER; WLAN_LOG_NOTICE("%s Loaded\n", version); WLAN_LOG_NOTICE("dev_info is: %s\n", dev_info); #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68)) pcmcia_get_card_services_info(&serv); if ( serv.Revision != CS_RELEASE_CODE ) { printk(KERN_NOTICE"%s: CardServices release does not match!\n", dev_info); return -1; } /* This call will result in a call to prism2sta_attach */ /* and eventually prism2sta_detach */ register_pccard_driver( &dev_info, &prism2sta_attach, &prism2sta_detach); #else pcmcia_register_driver(&prism2_cs_driver); #endif DBFEXIT; return 0; }
static int __init ivpnss_init(void) { servinfo_t serv; int rc; printk("iVPNSS: IXP4xx/iVPN socket service driver\n" \ "(C) Copyright 2004, Greg Ungerer <*****@*****.**>\n"); ivpnss_hwsetup(); if ((rc = ivpnss_memmap())) return rc; pcmcia_get_card_services_info(&serv); if (serv.Revision != CS_RELEASE_CODE) { printk("iVPNSS: Card Services version mis-match!\n"); return -ENODEV; } if (register_ss_entry(1, &ivpnss_operations)) { printk("iVPNSS: failed to register socket service?\n"); return -ENODEV; } if (register_chrdev(IVPNSS_MAJOR, IVPNSS_NAME, &ivpnss_fops)) printk("iVPNSS: failed to register debug char device?\n"); return 0; }
int __init init_pcmcia_ds(void) { client_reg_t client_reg; servinfo_t serv; bind_req_t bind; socket_info_t *s; int i, ret; DEBUG(0, "%s\n", version); /* * Ugly. But we want to wait for the socket threads to have started up. * We really should let the drivers themselves drive some of this.. */ current->state = TASK_INTERRUPTIBLE; schedule_timeout(HZ/10); pcmcia_get_card_services_info(&serv); if (serv.Revision != CS_RELEASE_CODE) { printk(KERN_NOTICE "ds: Card Services release does not match!\n"); return -1; } if (serv.Count == 0) { printk(KERN_NOTICE "ds: no socket drivers loaded!\n"); return -1; } sockets = serv.Count; socket_table = kmalloc(sockets*sizeof(socket_info_t), GFP_KERNEL); if (!socket_table) return -1; for (i = 0, s = socket_table; i < sockets; i++, s++) { s->state = 0; s->user = NULL; s->req_pending = 0; init_waitqueue_head(&s->queue); init_waitqueue_head(&s->request); s->handle = NULL; init_timer(&s->removal); s->removal.data = i; s->removal.function = &handle_removal; s->bind = NULL; } /* Set up hotline to Card Services */ client_reg.dev_info = bind.dev_info = &dev_info; client_reg.Attributes = INFO_MASTER_CLIENT; client_reg.EventMask = CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | CS_EVENT_EJECTION_REQUEST | CS_EVENT_INSERTION_REQUEST | CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; client_reg.event_handler = &ds_event; client_reg.Version = 0x0210; for (i = 0; i < sockets; i++) { bind.Socket = i; bind.Function = BIND_FN_ALL; ret = pcmcia_bind_device(&bind); if (ret != CS_SUCCESS) { cs_error(NULL, BindDevice, ret); break; } client_reg.event_callback_args.client_data = &socket_table[i]; ret = pcmcia_register_client(&socket_table[i].handle, &client_reg); if (ret != CS_SUCCESS) { cs_error(NULL, RegisterClient, ret); break; } } /* Set up character device for user mode clients */ i = register_chrdev(0, "pcmcia", &ds_fops); if (i == -EBUSY) printk(KERN_NOTICE "unable to find a free device # for " "Driver Services\n"); else major_dev = i; #ifdef CONFIG_PROC_FS if (proc_pccard) create_proc_read_entry("drivers",0,proc_pccard,proc_read_drivers,NULL); init_status = 0; #endif return 0; }
static int ds_ioctl(struct inode * inode, struct file * file, u_int cmd, u_long arg) { socket_t i = minor(inode->i_rdev); socket_info_t *s; u_int size; int ret, err; ds_ioctl_arg_t buf; DEBUG(2, "ds_ioctl(socket %d, %#x, %#lx)\n", i, cmd, arg); if ((i >= sockets) || (sockets == 0)) return -ENODEV; s = &socket_table[i]; size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT; if (size > sizeof(ds_ioctl_arg_t)) return -EINVAL; /* Permission check */ if (!(cmd & IOC_OUT) && !capable(CAP_SYS_ADMIN)) return -EPERM; if (cmd & IOC_IN) { err = verify_area(VERIFY_READ, (char *)arg, size); if (err) { DEBUG(3, "ds_ioctl(): verify_read = %d\n", err); return err; } } if (cmd & IOC_OUT) { err = verify_area(VERIFY_WRITE, (char *)arg, size); if (err) { DEBUG(3, "ds_ioctl(): verify_write = %d\n", err); return err; } } err = ret = 0; if (cmd & IOC_IN) copy_from_user((char *)&buf, (char *)arg, size); switch (cmd) { case DS_ADJUST_RESOURCE_INFO: ret = pcmcia_adjust_resource_info(s->handle, &buf.adjust); break; case DS_GET_CARD_SERVICES_INFO: ret = pcmcia_get_card_services_info(&buf.servinfo); break; case DS_GET_CONFIGURATION_INFO: ret = pcmcia_get_configuration_info(s->handle, &buf.config); break; case DS_GET_FIRST_TUPLE: ret = pcmcia_get_first_tuple(s->handle, &buf.tuple); break; case DS_GET_NEXT_TUPLE: ret = pcmcia_get_next_tuple(s->handle, &buf.tuple); break; case DS_GET_TUPLE_DATA: buf.tuple.TupleData = buf.tuple_parse.data; buf.tuple.TupleDataMax = sizeof(buf.tuple_parse.data); ret = pcmcia_get_tuple_data(s->handle, &buf.tuple); break; case DS_PARSE_TUPLE: buf.tuple.TupleData = buf.tuple_parse.data; ret = pcmcia_parse_tuple(s->handle, &buf.tuple, &buf.tuple_parse.parse); break; case DS_RESET_CARD: ret = pcmcia_reset_card(s->handle, NULL); break; case DS_GET_STATUS: ret = pcmcia_get_status(s->handle, &buf.status); break; case DS_VALIDATE_CIS: ret = pcmcia_validate_cis(s->handle, &buf.cisinfo); break; case DS_SUSPEND_CARD: ret = pcmcia_suspend_card(s->handle, NULL); break; case DS_RESUME_CARD: ret = pcmcia_resume_card(s->handle, NULL); break; case DS_EJECT_CARD: ret = pcmcia_eject_card(s->handle, NULL); break; case DS_INSERT_CARD: ret = pcmcia_insert_card(s->handle, NULL); break; case DS_ACCESS_CONFIGURATION_REGISTER: if ((buf.conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN)) return -EPERM; ret = pcmcia_access_configuration_register(s->handle, &buf.conf_reg); break; case DS_GET_FIRST_REGION: ret = pcmcia_get_first_region(s->handle, &buf.region); break; case DS_GET_NEXT_REGION: ret = pcmcia_get_next_region(s->handle, &buf.region); break; case DS_GET_FIRST_WINDOW: buf.win_info.handle = (window_handle_t)s->handle; ret = pcmcia_get_first_window(&buf.win_info.handle, &buf.win_info.window); break; case DS_GET_NEXT_WINDOW: ret = pcmcia_get_next_window(&buf.win_info.handle, &buf.win_info.window); break; case DS_GET_MEM_PAGE: ret = pcmcia_get_mem_page(buf.win_info.handle, &buf.win_info.map); break; case DS_REPLACE_CIS: ret = pcmcia_replace_cis(s->handle, &buf.cisdump); break; case DS_BIND_REQUEST: if (!capable(CAP_SYS_ADMIN)) return -EPERM; err = bind_request(i, &buf.bind_info); break; case DS_GET_DEVICE_INFO: err = get_device_info(i, &buf.bind_info, 1); break; case DS_GET_NEXT_DEVICE: err = get_device_info(i, &buf.bind_info, 0); break; case DS_UNBIND_REQUEST: err = unbind_request(i, &buf.bind_info); break; case DS_BIND_MTD: if (!suser()) return -EPERM; err = bind_mtd(i, &buf.mtd_info); break; default: err = -EINVAL; } if ((err == 0) && (ret != CS_SUCCESS)) { DEBUG(2, "ds_ioctl: ret = %d\n", ret); switch (ret) { case CS_BAD_SOCKET: case CS_NO_CARD: err = -ENODEV; break; case CS_BAD_ARGS: case CS_BAD_ATTRIBUTE: case CS_BAD_IRQ: case CS_BAD_TUPLE: err = -EINVAL; break; case CS_IN_USE: err = -EBUSY; break; case CS_OUT_OF_RESOURCE: err = -ENOSPC; break; case CS_NO_MORE_ITEMS: err = -ENODATA; break; case CS_UNSUPPORTED_FUNCTION: err = -ENOSYS; break; default: err = -EIO; break; } } if (cmd & IOC_OUT) copy_to_user((char *)arg, (char *)&buf, size); return err; } /* ds_ioctl */
static int __init init_hs(void) { servinfo_t serv; int i; unsigned short v; /* * Check API version */ pcmcia_get_card_services_info(&serv); if (serv.Revision != CS_RELEASE_CODE) { printk(KERN_NOTICE MODNAME ": Card Services release does not match!\n"); return -ENODEV; } /* hd64465_io_debug = 1; */ /* Wake both sockets out of STANDBY mode */ /* TODO: wait 15ms */ v = inw(HD64465_REG_SMSCR); v &= ~(HD64465_SMSCR_PC0ST|HD64465_SMSCR_PC1ST); outw(v, HD64465_REG_SMSCR); /* keep power controller out of shutdown mode */ v = inb(HD64465_REG_PCC0SCR); v |= HD64465_PCCSCR_SHDN; outb(v, HD64465_REG_PCC0SCR); /* use serial (TPS2206) power controller */ v = inb(HD64465_REG_PCC0CSCR); v |= HD64465_PCCCSCR_PSWSEL; outb(v, HD64465_REG_PCC0CSCR); hs_set_voltages(&hs_sockets[0], 0, 0); hs_set_voltages(&hs_sockets[1], 0, 0); /* * Setup hs_sockets[] structures and request system resources. * TODO: on memory allocation failure, power down the socket * before quitting. */ i = hs_init_socket(&hs_sockets[0], HD64465_IRQ_PCMCIA0, HD64465_PCC0_BASE, HD64465_REG_PCC0ISR); if (i < 0) return i; i = hs_init_socket(&hs_sockets[1], HD64465_IRQ_PCMCIA1, HD64465_PCC1_BASE, HD64465_REG_PCC1ISR); if (i < 0) return i; /* hd64465_io_debug = 0; */ if (register_ss_entry(HS_MAX_SOCKETS, &hs_operations) != 0) { for (i=0 ; i<HS_MAX_SOCKETS ; i++) hs_exit_socket(&hs_sockets[i]); return -ENODEV; } printk(KERN_INFO "HD64465 PCMCIA bridge:\n"); for (i=0 ; i<HS_MAX_SOCKETS ; i++) { hs_socket_t *sp = &hs_sockets[i]; printk(KERN_INFO " socket %d at 0x%08lx irq %d io window %ldK@0x%08lx\n", i, sp->mem_base, sp->irq, sp->io_vma->size>>10, (unsigned long)sp->io_vma->addr); } return 0; }