aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2006-06-11 23:04:37 -0400
committerJeff Garzik <jeff@garzik.org>2006-06-11 23:04:37 -0400
commitfec69a97489f961026e24536dbb7b86ac663948c (patch)
tree869713470d81ebc261598489a2711960336c7c37 /drivers/message
parent1049cb478783c74ca8c99ef70e7d2bf920b9335b (diff)
parent2f9719b61e1fcf7422a016ac4f2420a0cc6ba320 (diff)
Merge branch 'upstream-fixes' into upstream
Conflicts: drivers/scsi/sata_sil24.c
Diffstat (limited to 'drivers/message')
-rw-r--r--drivers/message/fusion/mptbase.c27
-rw-r--r--drivers/message/fusion/mptspi.c2
-rw-r--r--drivers/message/i2o/exec-osm.c72
-rw-r--r--drivers/message/i2o/iop.c4
4 files changed, 61 insertions, 44 deletions
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 9080853fe283..a30084076ac8 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -1605,6 +1605,21 @@ mpt_resume(struct pci_dev *pdev)
1605} 1605}
1606#endif 1606#endif
1607 1607
1608static int
1609mpt_signal_reset(int index, MPT_ADAPTER *ioc, int reset_phase)
1610{
1611 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
1612 ioc->bus_type != SPI) ||
1613 (MptDriverClass[index] == MPTFC_DRIVER &&
1614 ioc->bus_type != FC) ||
1615 (MptDriverClass[index] == MPTSAS_DRIVER &&
1616 ioc->bus_type != SAS))
1617 /* make sure we only call the relevant reset handler
1618 * for the bus */
1619 return 0;
1620 return (MptResetHandlers[index])(ioc, reset_phase);
1621}
1622
1608/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1623/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1609/* 1624/*
1610 * mpt_do_ioc_recovery - Initialize or recover MPT adapter. 1625 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
@@ -1885,14 +1900,14 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1885 if ((ret == 0) && MptResetHandlers[ii]) { 1900 if ((ret == 0) && MptResetHandlers[ii]) {
1886 dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n", 1901 dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n",
1887 ioc->name, ii)); 1902 ioc->name, ii));
1888 rc += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_POST_RESET); 1903 rc += mpt_signal_reset(ii, ioc, MPT_IOC_POST_RESET);
1889 handlers++; 1904 handlers++;
1890 } 1905 }
1891 1906
1892 if (alt_ioc_ready && MptResetHandlers[ii]) { 1907 if (alt_ioc_ready && MptResetHandlers[ii]) {
1893 drsprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n", 1908 drsprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
1894 ioc->name, ioc->alt_ioc->name, ii)); 1909 ioc->name, ioc->alt_ioc->name, ii));
1895 rc += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET); 1910 rc += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_POST_RESET);
1896 handlers++; 1911 handlers++;
1897 } 1912 }
1898 } 1913 }
@@ -3267,11 +3282,11 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3267 if (MptResetHandlers[ii]) { 3282 if (MptResetHandlers[ii]) {
3268 dprintk((MYIOC_s_INFO_FMT "Calling IOC pre_reset handler #%d\n", 3283 dprintk((MYIOC_s_INFO_FMT "Calling IOC pre_reset handler #%d\n",
3269 ioc->name, ii)); 3284 ioc->name, ii));
3270 r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_PRE_RESET); 3285 r += mpt_signal_reset(ii, ioc, MPT_IOC_PRE_RESET);
3271 if (ioc->alt_ioc) { 3286 if (ioc->alt_ioc) {
3272 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s pre_reset handler #%d\n", 3287 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s pre_reset handler #%d\n",
3273 ioc->name, ioc->alt_ioc->name, ii)); 3288 ioc->name, ioc->alt_ioc->name, ii));
3274 r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_PRE_RESET); 3289 r += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_PRE_RESET);
3275 } 3290 }
3276 } 3291 }
3277 } 3292 }
@@ -5706,11 +5721,11 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
5706 if (MptResetHandlers[ii]) { 5721 if (MptResetHandlers[ii]) {
5707 dtmprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n", 5722 dtmprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n",
5708 ioc->name, ii)); 5723 ioc->name, ii));
5709 r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_SETUP_RESET); 5724 r += mpt_signal_reset(ii, ioc, MPT_IOC_SETUP_RESET);
5710 if (ioc->alt_ioc) { 5725 if (ioc->alt_ioc) {
5711 dtmprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n", 5726 dtmprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n",
5712 ioc->name, ioc->alt_ioc->name, ii)); 5727 ioc->name, ioc->alt_ioc->name, ii));
5713 r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_SETUP_RESET); 5728 r += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
5714 } 5729 }
5715 } 5730 }
5716 } 5731 }
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
index f2a4d382ea19..3201de053943 100644
--- a/drivers/message/fusion/mptspi.c
+++ b/drivers/message/fusion/mptspi.c
@@ -831,6 +831,7 @@ mptspi_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
831 return rc; 831 return rc;
832} 832}
833 833
834#ifdef CONFIG_PM
834/* 835/*
835 * spi module resume handler 836 * spi module resume handler
836 */ 837 */
@@ -846,6 +847,7 @@ mptspi_resume(struct pci_dev *pdev)
846 847
847 return rc; 848 return rc;
848} 849}
850#endif
849 851
850/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 852/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
851/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 853/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c
index 5ea133c59afb..7bd4d85d0b42 100644
--- a/drivers/message/i2o/exec-osm.c
+++ b/drivers/message/i2o/exec-osm.c
@@ -55,6 +55,7 @@ struct i2o_exec_wait {
55 u32 m; /* message id */ 55 u32 m; /* message id */
56 struct i2o_message *msg; /* pointer to the reply message */ 56 struct i2o_message *msg; /* pointer to the reply message */
57 struct list_head list; /* node in global wait list */ 57 struct list_head list; /* node in global wait list */
58 spinlock_t lock; /* lock before modifying */
58}; 59};
59 60
60/* Work struct needed to handle LCT NOTIFY replies */ 61/* Work struct needed to handle LCT NOTIFY replies */
@@ -87,6 +88,7 @@ static struct i2o_exec_wait *i2o_exec_wait_alloc(void)
87 return NULL; 88 return NULL;
88 89
89 INIT_LIST_HEAD(&wait->list); 90 INIT_LIST_HEAD(&wait->list);
91 spin_lock_init(&wait->lock);
90 92
91 return wait; 93 return wait;
92}; 94};
@@ -125,6 +127,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, struct i2o_message *msg,
125 DECLARE_WAIT_QUEUE_HEAD(wq); 127 DECLARE_WAIT_QUEUE_HEAD(wq);
126 struct i2o_exec_wait *wait; 128 struct i2o_exec_wait *wait;
127 static u32 tcntxt = 0x80000000; 129 static u32 tcntxt = 0x80000000;
130 long flags;
128 int rc = 0; 131 int rc = 0;
129 132
130 wait = i2o_exec_wait_alloc(); 133 wait = i2o_exec_wait_alloc();
@@ -146,33 +149,28 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, struct i2o_message *msg,
146 wait->tcntxt = tcntxt++; 149 wait->tcntxt = tcntxt++;
147 msg->u.s.tcntxt = cpu_to_le32(wait->tcntxt); 150 msg->u.s.tcntxt = cpu_to_le32(wait->tcntxt);
148 151
152 wait->wq = &wq;
153 /*
154 * we add elements to the head, because if a entry in the list will
155 * never be removed, we have to iterate over it every time
156 */
157 list_add(&wait->list, &i2o_exec_wait_list);
158
149 /* 159 /*
150 * Post the message to the controller. At some point later it will 160 * Post the message to the controller. At some point later it will
151 * return. If we time out before it returns then complete will be zero. 161 * return. If we time out before it returns then complete will be zero.
152 */ 162 */
153 i2o_msg_post(c, msg); 163 i2o_msg_post(c, msg);
154 164
155 if (!wait->complete) { 165 wait_event_interruptible_timeout(wq, wait->complete, timeout * HZ);
156 wait->wq = &wq;
157 /*
158 * we add elements add the head, because if a entry in the list
159 * will never be removed, we have to iterate over it every time
160 */
161 list_add(&wait->list, &i2o_exec_wait_list);
162
163 wait_event_interruptible_timeout(wq, wait->complete,
164 timeout * HZ);
165 166
166 wait->wq = NULL; 167 spin_lock_irqsave(&wait->lock, flags);
167 }
168 168
169 barrier(); 169 wait->wq = NULL;
170 170
171 if (wait->complete) { 171 if (wait->complete)
172 rc = le32_to_cpu(wait->msg->body[0]) >> 24; 172 rc = le32_to_cpu(wait->msg->body[0]) >> 24;
173 i2o_flush_reply(c, wait->m); 173 else {
174 i2o_exec_wait_free(wait);
175 } else {
176 /* 174 /*
177 * We cannot remove it now. This is important. When it does 175 * We cannot remove it now. This is important. When it does
178 * terminate (which it must do if the controller has not 176 * terminate (which it must do if the controller has not
@@ -186,6 +184,13 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, struct i2o_message *msg,
186 rc = -ETIMEDOUT; 184 rc = -ETIMEDOUT;
187 } 185 }
188 186
187 spin_unlock_irqrestore(&wait->lock, flags);
188
189 if (rc != -ETIMEDOUT) {
190 i2o_flush_reply(c, wait->m);
191 i2o_exec_wait_free(wait);
192 }
193
189 return rc; 194 return rc;
190}; 195};
191 196
@@ -213,7 +218,6 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m,
213{ 218{
214 struct i2o_exec_wait *wait, *tmp; 219 struct i2o_exec_wait *wait, *tmp;
215 unsigned long flags; 220 unsigned long flags;
216 static spinlock_t lock = SPIN_LOCK_UNLOCKED;
217 int rc = 1; 221 int rc = 1;
218 222
219 /* 223 /*
@@ -223,23 +227,24 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m,
223 * already expired. Not much we can do about that except log it for 227 * already expired. Not much we can do about that except log it for
224 * debug purposes, increase timeout, and recompile. 228 * debug purposes, increase timeout, and recompile.
225 */ 229 */
226 spin_lock_irqsave(&lock, flags);
227 list_for_each_entry_safe(wait, tmp, &i2o_exec_wait_list, list) { 230 list_for_each_entry_safe(wait, tmp, &i2o_exec_wait_list, list) {
228 if (wait->tcntxt == context) { 231 if (wait->tcntxt == context) {
229 list_del(&wait->list); 232 spin_lock_irqsave(&wait->lock, flags);
230 233
231 spin_unlock_irqrestore(&lock, flags); 234 list_del(&wait->list);
232 235
233 wait->m = m; 236 wait->m = m;
234 wait->msg = msg; 237 wait->msg = msg;
235 wait->complete = 1; 238 wait->complete = 1;
236 239
237 barrier(); 240 if (wait->wq)
238
239 if (wait->wq) {
240 wake_up_interruptible(wait->wq);
241 rc = 0; 241 rc = 0;
242 } else { 242 else
243 rc = -1;
244
245 spin_unlock_irqrestore(&wait->lock, flags);
246
247 if (rc) {
243 struct device *dev; 248 struct device *dev;
244 249
245 dev = &c->pdev->dev; 250 dev = &c->pdev->dev;
@@ -248,15 +253,13 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m,
248 c->name); 253 c->name);
249 i2o_dma_free(dev, &wait->dma); 254 i2o_dma_free(dev, &wait->dma);
250 i2o_exec_wait_free(wait); 255 i2o_exec_wait_free(wait);
251 rc = -1; 256 } else
252 } 257 wake_up_interruptible(wait->wq);
253 258
254 return rc; 259 return rc;
255 } 260 }
256 } 261 }
257 262
258 spin_unlock_irqrestore(&lock, flags);
259
260 osm_warn("%s: Bogus reply in POST WAIT (tr-context: %08x)!\n", c->name, 263 osm_warn("%s: Bogus reply in POST WAIT (tr-context: %08x)!\n", c->name,
261 context); 264 context);
262 265
@@ -322,14 +325,9 @@ static DEVICE_ATTR(product_id, S_IRUGO, i2o_exec_show_product_id, NULL);
322static int i2o_exec_probe(struct device *dev) 325static int i2o_exec_probe(struct device *dev)
323{ 326{
324 struct i2o_device *i2o_dev = to_i2o_device(dev); 327 struct i2o_device *i2o_dev = to_i2o_device(dev);
325 struct i2o_controller *c = i2o_dev->iop;
326 328
327 i2o_event_register(i2o_dev, &i2o_exec_driver, 0, 0xffffffff); 329 i2o_event_register(i2o_dev, &i2o_exec_driver, 0, 0xffffffff);
328 330
329 c->exec = i2o_dev;
330
331 i2o_exec_lct_notify(c, c->lct->change_ind + 1);
332
333 device_create_file(dev, &dev_attr_vendor_id); 331 device_create_file(dev, &dev_attr_vendor_id);
334 device_create_file(dev, &dev_attr_product_id); 332 device_create_file(dev, &dev_attr_product_id);
335 333
@@ -523,6 +521,8 @@ static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind)
523 struct device *dev; 521 struct device *dev;
524 struct i2o_message *msg; 522 struct i2o_message *msg;
525 523
524 down(&c->lct_lock);
525
526 dev = &c->pdev->dev; 526 dev = &c->pdev->dev;
527 527
528 if (i2o_dma_realloc 528 if (i2o_dma_realloc
@@ -545,6 +545,8 @@ static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind)
545 545
546 i2o_msg_post(c, msg); 546 i2o_msg_post(c, msg);
547 547
548 up(&c->lct_lock);
549
548 return 0; 550 return 0;
549}; 551};
550 552
diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c
index 492167446936..febbdd4e0605 100644
--- a/drivers/message/i2o/iop.c
+++ b/drivers/message/i2o/iop.c
@@ -804,8 +804,6 @@ void i2o_iop_remove(struct i2o_controller *c)
804 804
805 /* Ask the IOP to switch to RESET state */ 805 /* Ask the IOP to switch to RESET state */
806 i2o_iop_reset(c); 806 i2o_iop_reset(c);
807
808 put_device(&c->device);
809} 807}
810 808
811/** 809/**
@@ -1059,7 +1057,7 @@ struct i2o_controller *i2o_iop_alloc(void)
1059 1057
1060 snprintf(poolname, sizeof(poolname), "i2o_%s_msg_inpool", c->name); 1058 snprintf(poolname, sizeof(poolname), "i2o_%s_msg_inpool", c->name);
1061 if (i2o_pool_alloc 1059 if (i2o_pool_alloc
1062 (&c->in_msg, poolname, I2O_INBOUND_MSG_FRAME_SIZE * 4, 1060 (&c->in_msg, poolname, I2O_INBOUND_MSG_FRAME_SIZE * 4 + sizeof(u32),
1063 I2O_MSG_INPOOL_MIN)) { 1061 I2O_MSG_INPOOL_MIN)) {
1064 kfree(c); 1062 kfree(c);
1065 return ERR_PTR(-ENOMEM); 1063 return ERR_PTR(-ENOMEM);