-int try_irq(u_int Attributes, int irq, int specific)
-{
- irq_info_t *info = &irq_table[irq];
- int ret = 0;
-
- down(&rsrc_sem);
- if (info->Attributes & RES_ALLOCATED) {
- switch (Attributes & IRQ_TYPE) {
- case IRQ_TYPE_EXCLUSIVE:
- ret = CS_IN_USE;
- break;
- case IRQ_TYPE_TIME:
- if ((info->Attributes & RES_IRQ_TYPE)
- != RES_IRQ_TYPE_TIME) {
- ret = CS_IN_USE;
- break;
- }
- if (Attributes & IRQ_FIRST_SHARED) {
- ret = CS_BAD_ATTRIBUTE;
- break;
- }
- info->Attributes |= RES_IRQ_TYPE_TIME | RES_ALLOCATED;
- info->time_share++;
- break;
- case IRQ_TYPE_DYNAMIC_SHARING:
- if ((info->Attributes & RES_IRQ_TYPE)
- != RES_IRQ_TYPE_DYNAMIC) {
- ret = CS_IN_USE;
- break;
- }
- if (Attributes & IRQ_FIRST_SHARED) {
- ret = CS_BAD_ATTRIBUTE;
- break;
- }
- info->Attributes |= RES_IRQ_TYPE_DYNAMIC | RES_ALLOCATED;
- info->dyn_share++;
- break;
- }
- } else {
- if ((info->Attributes & RES_RESERVED) && !specific) {
- ret = CS_IN_USE;
- goto out;
- }
- if (check_irq(irq) != 0) {
- ret = CS_IN_USE;
- goto out;
- }
- switch (Attributes & IRQ_TYPE) {
- case IRQ_TYPE_EXCLUSIVE:
- info->Attributes |= RES_ALLOCATED;
- break;
- case IRQ_TYPE_TIME:
- if (!(Attributes & IRQ_FIRST_SHARED)) {
- ret = CS_BAD_ATTRIBUTE;
- break;
- }
- info->Attributes |= RES_IRQ_TYPE_TIME | RES_ALLOCATED;
- info->time_share = 1;
- break;
- case IRQ_TYPE_DYNAMIC_SHARING:
- if (!(Attributes & IRQ_FIRST_SHARED)) {
- ret = CS_BAD_ATTRIBUTE;
- break;
- }
- info->Attributes |= RES_IRQ_TYPE_DYNAMIC | RES_ALLOCATED;
- info->dyn_share = 1;
- break;
- }
- }
- out:
- up(&rsrc_sem);
- return ret;
-}
-
-#endif
-
-/*====================================================================*/
-
-#ifdef CONFIG_PCMCIA_PROBE
-
-void undo_irq(u_int Attributes, int irq)
-{
- irq_info_t *info;
-
- info = &irq_table[irq];
- down(&rsrc_sem);
- switch (Attributes & IRQ_TYPE) {
- case IRQ_TYPE_EXCLUSIVE:
- info->Attributes &= RES_RESERVED;
- break;
- case IRQ_TYPE_TIME:
- info->time_share--;
- if (info->time_share == 0)
- info->Attributes &= RES_RESERVED;
- break;
- case IRQ_TYPE_DYNAMIC_SHARING:
- info->dyn_share--;
- if (info->dyn_share == 0)
- info->Attributes &= RES_RESERVED;
- break;
- }
- up(&rsrc_sem);
-}
-
-#endif
-
-/*======================================================================
-
- The various adjust_* calls form the external interface to the
- resource database.
-
-======================================================================*/
-
-static int adjust_memory(adjust_t *adj)
-{
- u_long base, num;
- int ret;
-
- base = adj->resource.memory.Base;
- num = adj->resource.memory.Size;
- if ((num == 0) || (base+num-1 < base))
- return CS_BAD_SIZE;
-
- ret = CS_SUCCESS;
-
- down(&rsrc_sem);
- switch (adj->Action) {
- case ADD_MANAGED_RESOURCE:
- ret = add_interval(&mem_db, base, num);
- break;
- case REMOVE_MANAGED_RESOURCE:
- ret = sub_interval(&mem_db, base, num);
- if (ret == CS_SUCCESS) {
- struct pcmcia_socket *socket;
- down_read(&pcmcia_socket_list_rwsem);
- list_for_each_entry(socket, &pcmcia_socket_list, socket_list)
- release_cis_mem(socket);
- up_read(&pcmcia_socket_list_rwsem);
- }
- break;
- default:
- ret = CS_UNSUPPORTED_FUNCTION;
- }
- up(&rsrc_sem);
-
- return ret;
-}