diff options
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 | ||