diff options
| author | Jeff Garzik <jgarzik@pretzel.yyz.us> | 2005-06-26 23:42:30 -0400 |
|---|---|---|
| committer | Jeff Garzik <jgarzik@pobox.com> | 2005-06-26 23:42:30 -0400 |
| commit | f45727d52d1581e9ff4df9d1a12a60789ad2d1eb (patch) | |
| tree | 773ae25f98542e6d382c688f7e85e8137d065614 /drivers/misc/ibmasm/module.c | |
| parent | 4c925f452cfd16c690209e96821ee094e09a2404 (diff) | |
| parent | 5696c1944a33b4434a9a1ebb6383b906afd43a10 (diff) | |
Merge /spare/repo/netdev-2.6/ branch 'ieee80211'
Diffstat (limited to 'drivers/misc/ibmasm/module.c')
| -rw-r--r-- | drivers/misc/ibmasm/module.c | 69 |
1 files changed, 40 insertions, 29 deletions
diff --git a/drivers/misc/ibmasm/module.c b/drivers/misc/ibmasm/module.c index 777432ae764a..1fdf03fd2da7 100644 --- a/drivers/misc/ibmasm/module.c +++ b/drivers/misc/ibmasm/module.c | |||
| @@ -56,17 +56,26 @@ | |||
| 56 | #include "lowlevel.h" | 56 | #include "lowlevel.h" |
| 57 | #include "remote.h" | 57 | #include "remote.h" |
| 58 | 58 | ||
| 59 | int ibmasm_debug = 0; | ||
| 60 | module_param(ibmasm_debug, int , S_IRUGO | S_IWUSR); | ||
| 61 | MODULE_PARM_DESC(ibmasm_debug, " Set debug mode on or off"); | ||
| 62 | |||
| 59 | 63 | ||
| 60 | static int __devinit ibmasm_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | 64 | static int __devinit ibmasm_init_one(struct pci_dev *pdev, const struct pci_device_id *id) |
| 61 | { | 65 | { |
| 62 | int err, result = -ENOMEM; | 66 | int result; |
| 63 | struct service_processor *sp; | 67 | struct service_processor *sp; |
| 64 | 68 | ||
| 65 | if ((err = pci_enable_device(pdev))) { | 69 | if ((result = pci_enable_device(pdev))) { |
| 66 | printk(KERN_ERR "%s: can't enable PCI device at %s\n", | 70 | dev_err(&pdev->dev, "Failed to enable PCI device\n"); |
| 67 | DRIVER_NAME, pci_name(pdev)); | 71 | return result; |
| 68 | return err; | ||
| 69 | } | 72 | } |
| 73 | if ((result = pci_request_regions(pdev, DRIVER_NAME))) { | ||
| 74 | dev_err(&pdev->dev, "Failed to allocate PCI resources\n"); | ||
| 75 | goto error_resources; | ||
| 76 | } | ||
| 77 | /* vnc client won't work without bus-mastering */ | ||
| 78 | pci_set_master(pdev); | ||
| 70 | 79 | ||
| 71 | sp = kmalloc(sizeof(struct service_processor), GFP_KERNEL); | 80 | sp = kmalloc(sizeof(struct service_processor), GFP_KERNEL); |
| 72 | if (sp == NULL) { | 81 | if (sp == NULL) { |
| @@ -76,6 +85,9 @@ static int __devinit ibmasm_init_one(struct pci_dev *pdev, const struct pci_devi | |||
| 76 | } | 85 | } |
| 77 | memset(sp, 0, sizeof(struct service_processor)); | 86 | memset(sp, 0, sizeof(struct service_processor)); |
| 78 | 87 | ||
| 88 | sp->lock = SPIN_LOCK_UNLOCKED; | ||
| 89 | INIT_LIST_HEAD(&sp->command_queue); | ||
| 90 | |||
| 79 | pci_set_drvdata(pdev, (void *)sp); | 91 | pci_set_drvdata(pdev, (void *)sp); |
| 80 | sp->dev = &pdev->dev; | 92 | sp->dev = &pdev->dev; |
| 81 | sp->number = pdev->bus->number; | 93 | sp->number = pdev->bus->number; |
| @@ -101,15 +113,6 @@ static int __devinit ibmasm_init_one(struct pci_dev *pdev, const struct pci_devi | |||
| 101 | goto error_ioremap; | 113 | goto error_ioremap; |
| 102 | } | 114 | } |
| 103 | 115 | ||
| 104 | result = ibmasm_init_remote_queue(sp); | ||
| 105 | if (result) { | ||
| 106 | dev_err(sp->dev, "Failed to initialize remote queue\n"); | ||
| 107 | goto error_remote_queue; | ||
| 108 | } | ||
| 109 | |||
| 110 | spin_lock_init(&sp->lock); | ||
| 111 | INIT_LIST_HEAD(&sp->command_queue); | ||
| 112 | |||
| 113 | result = request_irq(sp->irq, ibmasm_interrupt_handler, SA_SHIRQ, sp->devname, (void*)sp); | 116 | result = request_irq(sp->irq, ibmasm_interrupt_handler, SA_SHIRQ, sp->devname, (void*)sp); |
| 114 | if (result) { | 117 | if (result) { |
| 115 | dev_err(sp->dev, "Failed to register interrupt handler\n"); | 118 | dev_err(sp->dev, "Failed to register interrupt handler\n"); |
| @@ -117,7 +120,12 @@ static int __devinit ibmasm_init_one(struct pci_dev *pdev, const struct pci_devi | |||
| 117 | } | 120 | } |
| 118 | 121 | ||
| 119 | enable_sp_interrupts(sp->base_address); | 122 | enable_sp_interrupts(sp->base_address); |
| 120 | disable_mouse_interrupts(sp); | 123 | |
| 124 | result = ibmasm_init_remote_input_dev(sp); | ||
| 125 | if (result) { | ||
| 126 | dev_err(sp->dev, "Failed to initialize remote queue\n"); | ||
| 127 | goto error_send_message; | ||
| 128 | } | ||
| 121 | 129 | ||
| 122 | result = ibmasm_send_driver_vpd(sp); | 130 | result = ibmasm_send_driver_vpd(sp); |
| 123 | if (result) { | 131 | if (result) { |
| @@ -133,30 +141,25 @@ static int __devinit ibmasm_init_one(struct pci_dev *pdev, const struct pci_devi | |||
| 133 | 141 | ||
| 134 | ibmasm_register_uart(sp); | 142 | ibmasm_register_uart(sp); |
| 135 | 143 | ||
| 136 | dev_printk(KERN_DEBUG, &pdev->dev, "WARNING: This software may not be supported or function\n"); | ||
| 137 | dev_printk(KERN_DEBUG, &pdev->dev, "correctly on your IBM server. Please consult the IBM\n"); | ||
| 138 | dev_printk(KERN_DEBUG, &pdev->dev, "ServerProven website\n"); | ||
| 139 | dev_printk(KERN_DEBUG, &pdev->dev, "http://www.pc.ibm.com/ww/eserver/xseries/serverproven\n"); | ||
| 140 | dev_printk(KERN_DEBUG, &pdev->dev, "for information on the specific driver level and support\n"); | ||
| 141 | dev_printk(KERN_DEBUG, &pdev->dev, "statement for your IBM server.\n"); | ||
| 142 | |||
| 143 | return 0; | 144 | return 0; |
| 144 | 145 | ||
| 145 | error_send_message: | 146 | error_send_message: |
| 146 | disable_sp_interrupts(sp->base_address); | 147 | disable_sp_interrupts(sp->base_address); |
| 148 | ibmasm_free_remote_input_dev(sp); | ||
| 147 | free_irq(sp->irq, (void *)sp); | 149 | free_irq(sp->irq, (void *)sp); |
| 148 | error_request_irq: | 150 | error_request_irq: |
| 149 | ibmasm_free_remote_queue(sp); | ||
| 150 | error_remote_queue: | ||
| 151 | iounmap(sp->base_address); | 151 | iounmap(sp->base_address); |
| 152 | error_ioremap: | 152 | error_ioremap: |
| 153 | ibmasm_heartbeat_exit(sp); | 153 | ibmasm_heartbeat_exit(sp); |
| 154 | error_heartbeat: | 154 | error_heartbeat: |
| 155 | ibmasm_event_buffer_exit(sp); | 155 | ibmasm_event_buffer_exit(sp); |
| 156 | error_eventbuffer: | 156 | error_eventbuffer: |
| 157 | pci_set_drvdata(pdev, NULL); | ||
| 157 | kfree(sp); | 158 | kfree(sp); |
| 158 | error_kmalloc: | 159 | error_kmalloc: |
| 159 | pci_disable_device(pdev); | 160 | pci_release_regions(pdev); |
| 161 | error_resources: | ||
| 162 | pci_disable_device(pdev); | ||
| 160 | 163 | ||
| 161 | return result; | 164 | return result; |
| 162 | } | 165 | } |
| @@ -165,16 +168,24 @@ static void __devexit ibmasm_remove_one(struct pci_dev *pdev) | |||
| 165 | { | 168 | { |
| 166 | struct service_processor *sp = (struct service_processor *)pci_get_drvdata(pdev); | 169 | struct service_processor *sp = (struct service_processor *)pci_get_drvdata(pdev); |
| 167 | 170 | ||
| 171 | dbg("Unregistering UART\n"); | ||
| 168 | ibmasm_unregister_uart(sp); | 172 | ibmasm_unregister_uart(sp); |
| 169 | ibmasm_send_os_state(sp, SYSTEM_STATE_OS_DOWN); | 173 | dbg("Sending OS down message\n"); |
| 174 | if (ibmasm_send_os_state(sp, SYSTEM_STATE_OS_DOWN)) | ||
| 175 | err("failed to get repsonse to 'Send OS State' command\n"); | ||
| 176 | dbg("Disabling heartbeats\n"); | ||
| 177 | ibmasm_heartbeat_exit(sp); | ||
| 178 | dbg("Disabling interrupts\n"); | ||
| 170 | disable_sp_interrupts(sp->base_address); | 179 | disable_sp_interrupts(sp->base_address); |
| 171 | disable_mouse_interrupts(sp); | 180 | dbg("Freeing SP irq\n"); |
| 172 | free_irq(sp->irq, (void *)sp); | 181 | free_irq(sp->irq, (void *)sp); |
| 173 | ibmasm_heartbeat_exit(sp); | 182 | dbg("Cleaning up\n"); |
| 174 | ibmasm_free_remote_queue(sp); | 183 | ibmasm_free_remote_input_dev(sp); |
| 175 | iounmap(sp->base_address); | 184 | iounmap(sp->base_address); |
| 176 | ibmasm_event_buffer_exit(sp); | 185 | ibmasm_event_buffer_exit(sp); |
| 186 | pci_set_drvdata(pdev, NULL); | ||
| 177 | kfree(sp); | 187 | kfree(sp); |
| 188 | pci_release_regions(pdev); | ||
| 178 | pci_disable_device(pdev); | 189 | pci_disable_device(pdev); |
| 179 | } | 190 | } |
| 180 | 191 | ||
