diff options
Diffstat (limited to 'drivers/scsi/aacraid/commsup.c')
-rw-r--r-- | drivers/scsi/aacraid/commsup.c | 394 |
1 files changed, 239 insertions, 155 deletions
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index abce48ccc85b..81b36923e0ef 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c | |||
@@ -56,7 +56,7 @@ | |||
56 | * Allocate and map the shared PCI space for the FIB blocks used to | 56 | * Allocate and map the shared PCI space for the FIB blocks used to |
57 | * talk to the Adaptec firmware. | 57 | * talk to the Adaptec firmware. |
58 | */ | 58 | */ |
59 | 59 | ||
60 | static int fib_map_alloc(struct aac_dev *dev) | 60 | static int fib_map_alloc(struct aac_dev *dev) |
61 | { | 61 | { |
62 | dprintk((KERN_INFO | 62 | dprintk((KERN_INFO |
@@ -109,14 +109,16 @@ int aac_fib_setup(struct aac_dev * dev) | |||
109 | } | 109 | } |
110 | if (i<0) | 110 | if (i<0) |
111 | return -ENOMEM; | 111 | return -ENOMEM; |
112 | 112 | ||
113 | hw_fib = dev->hw_fib_va; | 113 | hw_fib = dev->hw_fib_va; |
114 | hw_fib_pa = dev->hw_fib_pa; | 114 | hw_fib_pa = dev->hw_fib_pa; |
115 | memset(hw_fib, 0, dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB)); | 115 | memset(hw_fib, 0, dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB)); |
116 | /* | 116 | /* |
117 | * Initialise the fibs | 117 | * Initialise the fibs |
118 | */ | 118 | */ |
119 | for (i = 0, fibptr = &dev->fibs[i]; i < (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); i++, fibptr++) | 119 | for (i = 0, fibptr = &dev->fibs[i]; |
120 | i < (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); | ||
121 | i++, fibptr++) | ||
120 | { | 122 | { |
121 | fibptr->dev = dev; | 123 | fibptr->dev = dev; |
122 | fibptr->hw_fib_va = hw_fib; | 124 | fibptr->hw_fib_va = hw_fib; |
@@ -148,13 +150,13 @@ int aac_fib_setup(struct aac_dev * dev) | |||
148 | * Allocate a fib from the adapter fib pool. If the pool is empty we | 150 | * Allocate a fib from the adapter fib pool. If the pool is empty we |
149 | * return NULL. | 151 | * return NULL. |
150 | */ | 152 | */ |
151 | 153 | ||
152 | struct fib *aac_fib_alloc(struct aac_dev *dev) | 154 | struct fib *aac_fib_alloc(struct aac_dev *dev) |
153 | { | 155 | { |
154 | struct fib * fibptr; | 156 | struct fib * fibptr; |
155 | unsigned long flags; | 157 | unsigned long flags; |
156 | spin_lock_irqsave(&dev->fib_lock, flags); | 158 | spin_lock_irqsave(&dev->fib_lock, flags); |
157 | fibptr = dev->free_fib; | 159 | fibptr = dev->free_fib; |
158 | if(!fibptr){ | 160 | if(!fibptr){ |
159 | spin_unlock_irqrestore(&dev->fib_lock, flags); | 161 | spin_unlock_irqrestore(&dev->fib_lock, flags); |
160 | return fibptr; | 162 | return fibptr; |
@@ -171,6 +173,7 @@ struct fib *aac_fib_alloc(struct aac_dev *dev) | |||
171 | * each I/O | 173 | * each I/O |
172 | */ | 174 | */ |
173 | fibptr->hw_fib_va->header.XferState = 0; | 175 | fibptr->hw_fib_va->header.XferState = 0; |
176 | fibptr->flags = 0; | ||
174 | fibptr->callback = NULL; | 177 | fibptr->callback = NULL; |
175 | fibptr->callback_data = NULL; | 178 | fibptr->callback_data = NULL; |
176 | 179 | ||
@@ -183,7 +186,7 @@ struct fib *aac_fib_alloc(struct aac_dev *dev) | |||
183 | * | 186 | * |
184 | * Frees up a fib and places it on the appropriate queue | 187 | * Frees up a fib and places it on the appropriate queue |
185 | */ | 188 | */ |
186 | 189 | ||
187 | void aac_fib_free(struct fib *fibptr) | 190 | void aac_fib_free(struct fib *fibptr) |
188 | { | 191 | { |
189 | unsigned long flags; | 192 | unsigned long flags; |
@@ -204,10 +207,10 @@ void aac_fib_free(struct fib *fibptr) | |||
204 | /** | 207 | /** |
205 | * aac_fib_init - initialise a fib | 208 | * aac_fib_init - initialise a fib |
206 | * @fibptr: The fib to initialize | 209 | * @fibptr: The fib to initialize |
207 | * | 210 | * |
208 | * Set up the generic fib fields ready for use | 211 | * Set up the generic fib fields ready for use |
209 | */ | 212 | */ |
210 | 213 | ||
211 | void aac_fib_init(struct fib *fibptr) | 214 | void aac_fib_init(struct fib *fibptr) |
212 | { | 215 | { |
213 | struct hw_fib *hw_fib = fibptr->hw_fib_va; | 216 | struct hw_fib *hw_fib = fibptr->hw_fib_va; |
@@ -227,12 +230,12 @@ void aac_fib_init(struct fib *fibptr) | |||
227 | * Will deallocate and return to the free pool the FIB pointed to by the | 230 | * Will deallocate and return to the free pool the FIB pointed to by the |
228 | * caller. | 231 | * caller. |
229 | */ | 232 | */ |
230 | 233 | ||
231 | static void fib_dealloc(struct fib * fibptr) | 234 | static void fib_dealloc(struct fib * fibptr) |
232 | { | 235 | { |
233 | struct hw_fib *hw_fib = fibptr->hw_fib_va; | 236 | struct hw_fib *hw_fib = fibptr->hw_fib_va; |
234 | BUG_ON(hw_fib->header.StructType != FIB_MAGIC); | 237 | BUG_ON(hw_fib->header.StructType != FIB_MAGIC); |
235 | hw_fib->header.XferState = 0; | 238 | hw_fib->header.XferState = 0; |
236 | } | 239 | } |
237 | 240 | ||
238 | /* | 241 | /* |
@@ -241,7 +244,7 @@ static void fib_dealloc(struct fib * fibptr) | |||
241 | * these routines and are the only routines which have a knowledge of the | 244 | * these routines and are the only routines which have a knowledge of the |
242 | * how these queues are implemented. | 245 | * how these queues are implemented. |
243 | */ | 246 | */ |
244 | 247 | ||
245 | /** | 248 | /** |
246 | * aac_get_entry - get a queue entry | 249 | * aac_get_entry - get a queue entry |
247 | * @dev: Adapter | 250 | * @dev: Adapter |
@@ -254,7 +257,7 @@ static void fib_dealloc(struct fib * fibptr) | |||
254 | * is full(no free entries) than no entry is returned and the function returns 0 otherwise 1 is | 257 | * is full(no free entries) than no entry is returned and the function returns 0 otherwise 1 is |
255 | * returned. | 258 | * returned. |
256 | */ | 259 | */ |
257 | 260 | ||
258 | static int aac_get_entry (struct aac_dev * dev, u32 qid, struct aac_entry **entry, u32 * index, unsigned long *nonotify) | 261 | static int aac_get_entry (struct aac_dev * dev, u32 qid, struct aac_entry **entry, u32 * index, unsigned long *nonotify) |
259 | { | 262 | { |
260 | struct aac_queue * q; | 263 | struct aac_queue * q; |
@@ -279,26 +282,27 @@ static int aac_get_entry (struct aac_dev * dev, u32 qid, struct aac_entry **entr | |||
279 | idx = ADAP_NORM_RESP_ENTRIES; | 282 | idx = ADAP_NORM_RESP_ENTRIES; |
280 | } | 283 | } |
281 | if (idx != le32_to_cpu(*(q->headers.consumer))) | 284 | if (idx != le32_to_cpu(*(q->headers.consumer))) |
282 | *nonotify = 1; | 285 | *nonotify = 1; |
283 | } | 286 | } |
284 | 287 | ||
285 | if (qid == AdapNormCmdQueue) { | 288 | if (qid == AdapNormCmdQueue) { |
286 | if (*index >= ADAP_NORM_CMD_ENTRIES) | 289 | if (*index >= ADAP_NORM_CMD_ENTRIES) |
287 | *index = 0; /* Wrap to front of the Producer Queue. */ | 290 | *index = 0; /* Wrap to front of the Producer Queue. */ |
288 | } else { | 291 | } else { |
289 | if (*index >= ADAP_NORM_RESP_ENTRIES) | 292 | if (*index >= ADAP_NORM_RESP_ENTRIES) |
290 | *index = 0; /* Wrap to front of the Producer Queue. */ | 293 | *index = 0; /* Wrap to front of the Producer Queue. */ |
291 | } | 294 | } |
292 | 295 | ||
293 | if ((*index + 1) == le32_to_cpu(*(q->headers.consumer))) { /* Queue is full */ | 296 | /* Queue is full */ |
297 | if ((*index + 1) == le32_to_cpu(*(q->headers.consumer))) { | ||
294 | printk(KERN_WARNING "Queue %d full, %u outstanding.\n", | 298 | printk(KERN_WARNING "Queue %d full, %u outstanding.\n", |
295 | qid, q->numpending); | 299 | qid, q->numpending); |
296 | return 0; | 300 | return 0; |
297 | } else { | 301 | } else { |
298 | *entry = q->base + *index; | 302 | *entry = q->base + *index; |
299 | return 1; | 303 | return 1; |
300 | } | 304 | } |
301 | } | 305 | } |
302 | 306 | ||
303 | /** | 307 | /** |
304 | * aac_queue_get - get the next free QE | 308 | * aac_queue_get - get the next free QE |
@@ -320,31 +324,29 @@ int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw | |||
320 | { | 324 | { |
321 | struct aac_entry * entry = NULL; | 325 | struct aac_entry * entry = NULL; |
322 | int map = 0; | 326 | int map = 0; |
323 | 327 | ||
324 | if (qid == AdapNormCmdQueue) { | 328 | if (qid == AdapNormCmdQueue) { |
325 | /* if no entries wait for some if caller wants to */ | 329 | /* if no entries wait for some if caller wants to */ |
326 | while (!aac_get_entry(dev, qid, &entry, index, nonotify)) | 330 | while (!aac_get_entry(dev, qid, &entry, index, nonotify)) { |
327 | { | ||
328 | printk(KERN_ERR "GetEntries failed\n"); | 331 | printk(KERN_ERR "GetEntries failed\n"); |
329 | } | 332 | } |
330 | /* | 333 | /* |
331 | * Setup queue entry with a command, status and fib mapped | 334 | * Setup queue entry with a command, status and fib mapped |
332 | */ | 335 | */ |
333 | entry->size = cpu_to_le32(le16_to_cpu(hw_fib->header.Size)); | 336 | entry->size = cpu_to_le32(le16_to_cpu(hw_fib->header.Size)); |
334 | map = 1; | 337 | map = 1; |
335 | } else { | 338 | } else { |
336 | while(!aac_get_entry(dev, qid, &entry, index, nonotify)) | 339 | while (!aac_get_entry(dev, qid, &entry, index, nonotify)) { |
337 | { | ||
338 | /* if no entries wait for some if caller wants to */ | 340 | /* if no entries wait for some if caller wants to */ |
339 | } | 341 | } |
340 | /* | 342 | /* |
341 | * Setup queue entry with command, status and fib mapped | 343 | * Setup queue entry with command, status and fib mapped |
342 | */ | 344 | */ |
343 | entry->size = cpu_to_le32(le16_to_cpu(hw_fib->header.Size)); | 345 | entry->size = cpu_to_le32(le16_to_cpu(hw_fib->header.Size)); |
344 | entry->addr = hw_fib->header.SenderFibAddress; | 346 | entry->addr = hw_fib->header.SenderFibAddress; |
345 | /* Restore adapters pointer to the FIB */ | 347 | /* Restore adapters pointer to the FIB */ |
346 | hw_fib->header.ReceiverFibAddress = hw_fib->header.SenderFibAddress; /* Let the adapter now where to find its data */ | 348 | hw_fib->header.ReceiverFibAddress = hw_fib->header.SenderFibAddress; /* Let the adapter now where to find its data */ |
347 | map = 0; | 349 | map = 0; |
348 | } | 350 | } |
349 | /* | 351 | /* |
350 | * If MapFib is true than we need to map the Fib and put pointers | 352 | * If MapFib is true than we need to map the Fib and put pointers |
@@ -356,8 +358,8 @@ int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw | |||
356 | } | 358 | } |
357 | 359 | ||
358 | /* | 360 | /* |
359 | * Define the highest level of host to adapter communication routines. | 361 | * Define the highest level of host to adapter communication routines. |
360 | * These routines will support host to adapter FS commuication. These | 362 | * These routines will support host to adapter FS commuication. These |
361 | * routines have no knowledge of the commuication method used. This level | 363 | * routines have no knowledge of the commuication method used. This level |
362 | * sends and receives FIBs. This level has no knowledge of how these FIBs | 364 | * sends and receives FIBs. This level has no knowledge of how these FIBs |
363 | * get passed back and forth. | 365 | * get passed back and forth. |
@@ -379,7 +381,7 @@ int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw | |||
379 | * an event to wait on must be supplied. This event will be set when a | 381 | * an event to wait on must be supplied. This event will be set when a |
380 | * response FIB is received from the adapter. | 382 | * response FIB is received from the adapter. |
381 | */ | 383 | */ |
382 | 384 | ||
383 | int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | 385 | int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, |
384 | int priority, int wait, int reply, fib_callback callback, | 386 | int priority, int wait, int reply, fib_callback callback, |
385 | void *callback_data) | 387 | void *callback_data) |
@@ -392,16 +394,17 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
392 | if (!(hw_fib->header.XferState & cpu_to_le32(HostOwned))) | 394 | if (!(hw_fib->header.XferState & cpu_to_le32(HostOwned))) |
393 | return -EBUSY; | 395 | return -EBUSY; |
394 | /* | 396 | /* |
395 | * There are 5 cases with the wait and reponse requested flags. | 397 | * There are 5 cases with the wait and reponse requested flags. |
396 | * The only invalid cases are if the caller requests to wait and | 398 | * The only invalid cases are if the caller requests to wait and |
397 | * does not request a response and if the caller does not want a | 399 | * does not request a response and if the caller does not want a |
398 | * response and the Fib is not allocated from pool. If a response | 400 | * response and the Fib is not allocated from pool. If a response |
399 | * is not requesed the Fib will just be deallocaed by the DPC | 401 | * is not requesed the Fib will just be deallocaed by the DPC |
400 | * routine when the response comes back from the adapter. No | 402 | * routine when the response comes back from the adapter. No |
401 | * further processing will be done besides deleting the Fib. We | 403 | * further processing will be done besides deleting the Fib. We |
402 | * will have a debug mode where the adapter can notify the host | 404 | * will have a debug mode where the adapter can notify the host |
403 | * it had a problem and the host can log that fact. | 405 | * it had a problem and the host can log that fact. |
404 | */ | 406 | */ |
407 | fibptr->flags = 0; | ||
405 | if (wait && !reply) { | 408 | if (wait && !reply) { |
406 | return -EINVAL; | 409 | return -EINVAL; |
407 | } else if (!wait && reply) { | 410 | } else if (!wait && reply) { |
@@ -413,7 +416,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
413 | } else if (wait && reply) { | 416 | } else if (wait && reply) { |
414 | hw_fib->header.XferState |= cpu_to_le32(ResponseExpected); | 417 | hw_fib->header.XferState |= cpu_to_le32(ResponseExpected); |
415 | FIB_COUNTER_INCREMENT(aac_config.NormalSent); | 418 | FIB_COUNTER_INCREMENT(aac_config.NormalSent); |
416 | } | 419 | } |
417 | /* | 420 | /* |
418 | * Map the fib into 32bits by using the fib number | 421 | * Map the fib into 32bits by using the fib number |
419 | */ | 422 | */ |
@@ -436,7 +439,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
436 | hw_fib->header.Size = cpu_to_le16(sizeof(struct aac_fibhdr) + size); | 439 | hw_fib->header.Size = cpu_to_le16(sizeof(struct aac_fibhdr) + size); |
437 | if (le16_to_cpu(hw_fib->header.Size) > le16_to_cpu(hw_fib->header.SenderSize)) { | 440 | if (le16_to_cpu(hw_fib->header.Size) > le16_to_cpu(hw_fib->header.SenderSize)) { |
438 | return -EMSGSIZE; | 441 | return -EMSGSIZE; |
439 | } | 442 | } |
440 | /* | 443 | /* |
441 | * Get a queue entry connect the FIB to it and send an notify | 444 | * Get a queue entry connect the FIB to it and send an notify |
442 | * the adapter a command is ready. | 445 | * the adapter a command is ready. |
@@ -450,10 +453,10 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
450 | if (!wait) { | 453 | if (!wait) { |
451 | fibptr->callback = callback; | 454 | fibptr->callback = callback; |
452 | fibptr->callback_data = callback_data; | 455 | fibptr->callback_data = callback_data; |
456 | fibptr->flags = FIB_CONTEXT_FLAG; | ||
453 | } | 457 | } |
454 | 458 | ||
455 | fibptr->done = 0; | 459 | fibptr->done = 0; |
456 | fibptr->flags = 0; | ||
457 | 460 | ||
458 | FIB_COUNTER_INCREMENT(aac_config.FibsSent); | 461 | FIB_COUNTER_INCREMENT(aac_config.FibsSent); |
459 | 462 | ||
@@ -473,9 +476,9 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
473 | aac_adapter_deliver(fibptr); | 476 | aac_adapter_deliver(fibptr); |
474 | 477 | ||
475 | /* | 478 | /* |
476 | * If the caller wanted us to wait for response wait now. | 479 | * If the caller wanted us to wait for response wait now. |
477 | */ | 480 | */ |
478 | 481 | ||
479 | if (wait) { | 482 | if (wait) { |
480 | spin_unlock_irqrestore(&fibptr->event_lock, flags); | 483 | spin_unlock_irqrestore(&fibptr->event_lock, flags); |
481 | /* Only set for first known interruptable command */ | 484 | /* Only set for first known interruptable command */ |
@@ -522,7 +525,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
522 | } | 525 | } |
523 | spin_unlock_irqrestore(&fibptr->event_lock, flags); | 526 | spin_unlock_irqrestore(&fibptr->event_lock, flags); |
524 | BUG_ON(fibptr->done == 0); | 527 | BUG_ON(fibptr->done == 0); |
525 | 528 | ||
526 | if(unlikely(fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) | 529 | if(unlikely(fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) |
527 | return -ETIMEDOUT; | 530 | return -ETIMEDOUT; |
528 | return 0; | 531 | return 0; |
@@ -537,15 +540,15 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
537 | return 0; | 540 | return 0; |
538 | } | 541 | } |
539 | 542 | ||
540 | /** | 543 | /** |
541 | * aac_consumer_get - get the top of the queue | 544 | * aac_consumer_get - get the top of the queue |
542 | * @dev: Adapter | 545 | * @dev: Adapter |
543 | * @q: Queue | 546 | * @q: Queue |
544 | * @entry: Return entry | 547 | * @entry: Return entry |
545 | * | 548 | * |
546 | * Will return a pointer to the entry on the top of the queue requested that | 549 | * Will return a pointer to the entry on the top of the queue requested that |
547 | * we are a consumer of, and return the address of the queue entry. It does | 550 | * we are a consumer of, and return the address of the queue entry. It does |
548 | * not change the state of the queue. | 551 | * not change the state of the queue. |
549 | */ | 552 | */ |
550 | 553 | ||
551 | int aac_consumer_get(struct aac_dev * dev, struct aac_queue * q, struct aac_entry **entry) | 554 | int aac_consumer_get(struct aac_dev * dev, struct aac_queue * q, struct aac_entry **entry) |
@@ -560,10 +563,10 @@ int aac_consumer_get(struct aac_dev * dev, struct aac_queue * q, struct aac_entr | |||
560 | * the end of the queue, else we just use the entry | 563 | * the end of the queue, else we just use the entry |
561 | * pointed to by the header index | 564 | * pointed to by the header index |
562 | */ | 565 | */ |
563 | if (le32_to_cpu(*q->headers.consumer) >= q->entries) | 566 | if (le32_to_cpu(*q->headers.consumer) >= q->entries) |
564 | index = 0; | 567 | index = 0; |
565 | else | 568 | else |
566 | index = le32_to_cpu(*q->headers.consumer); | 569 | index = le32_to_cpu(*q->headers.consumer); |
567 | *entry = q->base + index; | 570 | *entry = q->base + index; |
568 | status = 1; | 571 | status = 1; |
569 | } | 572 | } |
@@ -587,12 +590,12 @@ void aac_consumer_free(struct aac_dev * dev, struct aac_queue *q, u32 qid) | |||
587 | 590 | ||
588 | if ((le32_to_cpu(*q->headers.producer)+1) == le32_to_cpu(*q->headers.consumer)) | 591 | if ((le32_to_cpu(*q->headers.producer)+1) == le32_to_cpu(*q->headers.consumer)) |
589 | wasfull = 1; | 592 | wasfull = 1; |
590 | 593 | ||
591 | if (le32_to_cpu(*q->headers.consumer) >= q->entries) | 594 | if (le32_to_cpu(*q->headers.consumer) >= q->entries) |
592 | *q->headers.consumer = cpu_to_le32(1); | 595 | *q->headers.consumer = cpu_to_le32(1); |
593 | else | 596 | else |
594 | *q->headers.consumer = cpu_to_le32(le32_to_cpu(*q->headers.consumer)+1); | 597 | *q->headers.consumer = cpu_to_le32(le32_to_cpu(*q->headers.consumer)+1); |
595 | 598 | ||
596 | if (wasfull) { | 599 | if (wasfull) { |
597 | switch (qid) { | 600 | switch (qid) { |
598 | 601 | ||
@@ -608,7 +611,7 @@ void aac_consumer_free(struct aac_dev * dev, struct aac_queue *q, u32 qid) | |||
608 | } | 611 | } |
609 | aac_adapter_notify(dev, notify); | 612 | aac_adapter_notify(dev, notify); |
610 | } | 613 | } |
611 | } | 614 | } |
612 | 615 | ||
613 | /** | 616 | /** |
614 | * aac_fib_adapter_complete - complete adapter issued fib | 617 | * aac_fib_adapter_complete - complete adapter issued fib |
@@ -630,32 +633,32 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size) | |||
630 | if (hw_fib->header.XferState == 0) { | 633 | if (hw_fib->header.XferState == 0) { |
631 | if (dev->comm_interface == AAC_COMM_MESSAGE) | 634 | if (dev->comm_interface == AAC_COMM_MESSAGE) |
632 | kfree (hw_fib); | 635 | kfree (hw_fib); |
633 | return 0; | 636 | return 0; |
634 | } | 637 | } |
635 | /* | 638 | /* |
636 | * If we plan to do anything check the structure type first. | 639 | * If we plan to do anything check the structure type first. |
637 | */ | 640 | */ |
638 | if ( hw_fib->header.StructType != FIB_MAGIC ) { | 641 | if (hw_fib->header.StructType != FIB_MAGIC) { |
639 | if (dev->comm_interface == AAC_COMM_MESSAGE) | 642 | if (dev->comm_interface == AAC_COMM_MESSAGE) |
640 | kfree (hw_fib); | 643 | kfree (hw_fib); |
641 | return -EINVAL; | 644 | return -EINVAL; |
642 | } | 645 | } |
643 | /* | 646 | /* |
644 | * This block handles the case where the adapter had sent us a | 647 | * This block handles the case where the adapter had sent us a |
645 | * command and we have finished processing the command. We | 648 | * command and we have finished processing the command. We |
646 | * call completeFib when we are done processing the command | 649 | * call completeFib when we are done processing the command |
647 | * and want to send a response back to the adapter. This will | 650 | * and want to send a response back to the adapter. This will |
648 | * send the completed cdb to the adapter. | 651 | * send the completed cdb to the adapter. |
649 | */ | 652 | */ |
650 | if (hw_fib->header.XferState & cpu_to_le32(SentFromAdapter)) { | 653 | if (hw_fib->header.XferState & cpu_to_le32(SentFromAdapter)) { |
651 | if (dev->comm_interface == AAC_COMM_MESSAGE) { | 654 | if (dev->comm_interface == AAC_COMM_MESSAGE) { |
652 | kfree (hw_fib); | 655 | kfree (hw_fib); |
653 | } else { | 656 | } else { |
654 | u32 index; | 657 | u32 index; |
655 | hw_fib->header.XferState |= cpu_to_le32(HostProcessed); | 658 | hw_fib->header.XferState |= cpu_to_le32(HostProcessed); |
656 | if (size) { | 659 | if (size) { |
657 | size += sizeof(struct aac_fibhdr); | 660 | size += sizeof(struct aac_fibhdr); |
658 | if (size > le16_to_cpu(hw_fib->header.SenderSize)) | 661 | if (size > le16_to_cpu(hw_fib->header.SenderSize)) |
659 | return -EMSGSIZE; | 662 | return -EMSGSIZE; |
660 | hw_fib->header.Size = cpu_to_le16(size); | 663 | hw_fib->header.Size = cpu_to_le16(size); |
661 | } | 664 | } |
@@ -667,12 +670,11 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size) | |||
667 | if (!(nointr & (int)aac_config.irq_mod)) | 670 | if (!(nointr & (int)aac_config.irq_mod)) |
668 | aac_adapter_notify(dev, AdapNormRespQueue); | 671 | aac_adapter_notify(dev, AdapNormRespQueue); |
669 | } | 672 | } |
673 | } else { | ||
674 | printk(KERN_WARNING "aac_fib_adapter_complete: " | ||
675 | "Unknown xferstate detected.\n"); | ||
676 | BUG(); | ||
670 | } | 677 | } |
671 | else | ||
672 | { | ||
673 | printk(KERN_WARNING "aac_fib_adapter_complete: Unknown xferstate detected.\n"); | ||
674 | BUG(); | ||
675 | } | ||
676 | return 0; | 678 | return 0; |
677 | } | 679 | } |
678 | 680 | ||
@@ -682,7 +684,7 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size) | |||
682 | * | 684 | * |
683 | * Will do all necessary work to complete a FIB. | 685 | * Will do all necessary work to complete a FIB. |
684 | */ | 686 | */ |
685 | 687 | ||
686 | int aac_fib_complete(struct fib *fibptr) | 688 | int aac_fib_complete(struct fib *fibptr) |
687 | { | 689 | { |
688 | struct hw_fib * hw_fib = fibptr->hw_fib_va; | 690 | struct hw_fib * hw_fib = fibptr->hw_fib_va; |
@@ -692,15 +694,15 @@ int aac_fib_complete(struct fib *fibptr) | |||
692 | */ | 694 | */ |
693 | 695 | ||
694 | if (hw_fib->header.XferState == 0) | 696 | if (hw_fib->header.XferState == 0) |
695 | return 0; | 697 | return 0; |
696 | /* | 698 | /* |
697 | * If we plan to do anything check the structure type first. | 699 | * If we plan to do anything check the structure type first. |
698 | */ | 700 | */ |
699 | 701 | ||
700 | if (hw_fib->header.StructType != FIB_MAGIC) | 702 | if (hw_fib->header.StructType != FIB_MAGIC) |
701 | return -EINVAL; | 703 | return -EINVAL; |
702 | /* | 704 | /* |
703 | * This block completes a cdb which orginated on the host and we | 705 | * This block completes a cdb which orginated on the host and we |
704 | * just need to deallocate the cdb or reinit it. At this point the | 706 | * just need to deallocate the cdb or reinit it. At this point the |
705 | * command is complete that we had sent to the adapter and this | 707 | * command is complete that we had sent to the adapter and this |
706 | * cdb could be reused. | 708 | * cdb could be reused. |
@@ -721,7 +723,7 @@ int aac_fib_complete(struct fib *fibptr) | |||
721 | fib_dealloc(fibptr); | 723 | fib_dealloc(fibptr); |
722 | } else { | 724 | } else { |
723 | BUG(); | 725 | BUG(); |
724 | } | 726 | } |
725 | return 0; | 727 | return 0; |
726 | } | 728 | } |
727 | 729 | ||
@@ -741,7 +743,7 @@ void aac_printf(struct aac_dev *dev, u32 val) | |||
741 | { | 743 | { |
742 | int length = val & 0xffff; | 744 | int length = val & 0xffff; |
743 | int level = (val >> 16) & 0xffff; | 745 | int level = (val >> 16) & 0xffff; |
744 | 746 | ||
745 | /* | 747 | /* |
746 | * The size of the printfbuf is set in port.c | 748 | * The size of the printfbuf is set in port.c |
747 | * There is no variable or define for it | 749 | * There is no variable or define for it |
@@ -755,7 +757,7 @@ void aac_printf(struct aac_dev *dev, u32 val) | |||
755 | else | 757 | else |
756 | printk(KERN_INFO "%s:%s", dev->name, cp); | 758 | printk(KERN_INFO "%s:%s", dev->name, cp); |
757 | } | 759 | } |
758 | memset(cp, 0, 256); | 760 | memset(cp, 0, 256); |
759 | } | 761 | } |
760 | 762 | ||
761 | 763 | ||
@@ -773,20 +775,20 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) | |||
773 | { | 775 | { |
774 | struct hw_fib * hw_fib = fibptr->hw_fib_va; | 776 | struct hw_fib * hw_fib = fibptr->hw_fib_va; |
775 | struct aac_aifcmd * aifcmd = (struct aac_aifcmd *)hw_fib->data; | 777 | struct aac_aifcmd * aifcmd = (struct aac_aifcmd *)hw_fib->data; |
776 | u32 container; | 778 | u32 channel, id, lun, container; |
777 | struct scsi_device *device; | 779 | struct scsi_device *device; |
778 | enum { | 780 | enum { |
779 | NOTHING, | 781 | NOTHING, |
780 | DELETE, | 782 | DELETE, |
781 | ADD, | 783 | ADD, |
782 | CHANGE | 784 | CHANGE |
783 | } device_config_needed; | 785 | } device_config_needed = NOTHING; |
784 | 786 | ||
785 | /* Sniff for container changes */ | 787 | /* Sniff for container changes */ |
786 | 788 | ||
787 | if (!dev || !dev->fsa_dev) | 789 | if (!dev || !dev->fsa_dev) |
788 | return; | 790 | return; |
789 | container = (u32)-1; | 791 | container = channel = id = lun = (u32)-1; |
790 | 792 | ||
791 | /* | 793 | /* |
792 | * We have set this up to try and minimize the number of | 794 | * We have set this up to try and minimize the number of |
@@ -796,13 +798,13 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) | |||
796 | */ | 798 | */ |
797 | switch (le32_to_cpu(aifcmd->command)) { | 799 | switch (le32_to_cpu(aifcmd->command)) { |
798 | case AifCmdDriverNotify: | 800 | case AifCmdDriverNotify: |
799 | switch (le32_to_cpu(((u32 *)aifcmd->data)[0])) { | 801 | switch (le32_to_cpu(((__le32 *)aifcmd->data)[0])) { |
800 | /* | 802 | /* |
801 | * Morph or Expand complete | 803 | * Morph or Expand complete |
802 | */ | 804 | */ |
803 | case AifDenMorphComplete: | 805 | case AifDenMorphComplete: |
804 | case AifDenVolumeExtendComplete: | 806 | case AifDenVolumeExtendComplete: |
805 | container = le32_to_cpu(((u32 *)aifcmd->data)[1]); | 807 | container = le32_to_cpu(((__le32 *)aifcmd->data)[1]); |
806 | if (container >= dev->maximum_num_containers) | 808 | if (container >= dev->maximum_num_containers) |
807 | break; | 809 | break; |
808 | 810 | ||
@@ -814,9 +816,9 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) | |||
814 | */ | 816 | */ |
815 | 817 | ||
816 | if ((dev != NULL) && (dev->scsi_host_ptr != NULL)) { | 818 | if ((dev != NULL) && (dev->scsi_host_ptr != NULL)) { |
817 | device = scsi_device_lookup(dev->scsi_host_ptr, | 819 | device = scsi_device_lookup(dev->scsi_host_ptr, |
818 | CONTAINER_TO_CHANNEL(container), | 820 | CONTAINER_TO_CHANNEL(container), |
819 | CONTAINER_TO_ID(container), | 821 | CONTAINER_TO_ID(container), |
820 | CONTAINER_TO_LUN(container)); | 822 | CONTAINER_TO_LUN(container)); |
821 | if (device) { | 823 | if (device) { |
822 | dev->fsa_dev[container].config_needed = CHANGE; | 824 | dev->fsa_dev[container].config_needed = CHANGE; |
@@ -835,25 +837,29 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) | |||
835 | if (container >= dev->maximum_num_containers) | 837 | if (container >= dev->maximum_num_containers) |
836 | break; | 838 | break; |
837 | if ((dev->fsa_dev[container].config_waiting_on == | 839 | if ((dev->fsa_dev[container].config_waiting_on == |
838 | le32_to_cpu(*(u32 *)aifcmd->data)) && | 840 | le32_to_cpu(*(__le32 *)aifcmd->data)) && |
839 | time_before(jiffies, dev->fsa_dev[container].config_waiting_stamp + AIF_SNIFF_TIMEOUT)) | 841 | time_before(jiffies, dev->fsa_dev[container].config_waiting_stamp + AIF_SNIFF_TIMEOUT)) |
840 | dev->fsa_dev[container].config_waiting_on = 0; | 842 | dev->fsa_dev[container].config_waiting_on = 0; |
841 | } else for (container = 0; | 843 | } else for (container = 0; |
842 | container < dev->maximum_num_containers; ++container) { | 844 | container < dev->maximum_num_containers; ++container) { |
843 | if ((dev->fsa_dev[container].config_waiting_on == | 845 | if ((dev->fsa_dev[container].config_waiting_on == |
844 | le32_to_cpu(*(u32 *)aifcmd->data)) && | 846 | le32_to_cpu(*(__le32 *)aifcmd->data)) && |
845 | time_before(jiffies, dev->fsa_dev[container].config_waiting_stamp + AIF_SNIFF_TIMEOUT)) | 847 | time_before(jiffies, dev->fsa_dev[container].config_waiting_stamp + AIF_SNIFF_TIMEOUT)) |
846 | dev->fsa_dev[container].config_waiting_on = 0; | 848 | dev->fsa_dev[container].config_waiting_on = 0; |
847 | } | 849 | } |
848 | break; | 850 | break; |
849 | 851 | ||
850 | case AifCmdEventNotify: | 852 | case AifCmdEventNotify: |
851 | switch (le32_to_cpu(((u32 *)aifcmd->data)[0])) { | 853 | switch (le32_to_cpu(((__le32 *)aifcmd->data)[0])) { |
854 | case AifEnBatteryEvent: | ||
855 | dev->cache_protected = | ||
856 | (((__le32 *)aifcmd->data)[1] == cpu_to_le32(3)); | ||
857 | break; | ||
852 | /* | 858 | /* |
853 | * Add an Array. | 859 | * Add an Array. |
854 | */ | 860 | */ |
855 | case AifEnAddContainer: | 861 | case AifEnAddContainer: |
856 | container = le32_to_cpu(((u32 *)aifcmd->data)[1]); | 862 | container = le32_to_cpu(((__le32 *)aifcmd->data)[1]); |
857 | if (container >= dev->maximum_num_containers) | 863 | if (container >= dev->maximum_num_containers) |
858 | break; | 864 | break; |
859 | dev->fsa_dev[container].config_needed = ADD; | 865 | dev->fsa_dev[container].config_needed = ADD; |
@@ -866,7 +872,7 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) | |||
866 | * Delete an Array. | 872 | * Delete an Array. |
867 | */ | 873 | */ |
868 | case AifEnDeleteContainer: | 874 | case AifEnDeleteContainer: |
869 | container = le32_to_cpu(((u32 *)aifcmd->data)[1]); | 875 | container = le32_to_cpu(((__le32 *)aifcmd->data)[1]); |
870 | if (container >= dev->maximum_num_containers) | 876 | if (container >= dev->maximum_num_containers) |
871 | break; | 877 | break; |
872 | dev->fsa_dev[container].config_needed = DELETE; | 878 | dev->fsa_dev[container].config_needed = DELETE; |
@@ -880,7 +886,7 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) | |||
880 | * waiting on something else, setup to wait on a Config Change. | 886 | * waiting on something else, setup to wait on a Config Change. |
881 | */ | 887 | */ |
882 | case AifEnContainerChange: | 888 | case AifEnContainerChange: |
883 | container = le32_to_cpu(((u32 *)aifcmd->data)[1]); | 889 | container = le32_to_cpu(((__le32 *)aifcmd->data)[1]); |
884 | if (container >= dev->maximum_num_containers) | 890 | if (container >= dev->maximum_num_containers) |
885 | break; | 891 | break; |
886 | if (dev->fsa_dev[container].config_waiting_on && | 892 | if (dev->fsa_dev[container].config_waiting_on && |
@@ -895,6 +901,60 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) | |||
895 | case AifEnConfigChange: | 901 | case AifEnConfigChange: |
896 | break; | 902 | break; |
897 | 903 | ||
904 | case AifEnAddJBOD: | ||
905 | case AifEnDeleteJBOD: | ||
906 | container = le32_to_cpu(((__le32 *)aifcmd->data)[1]); | ||
907 | if ((container >> 28)) | ||
908 | break; | ||
909 | channel = (container >> 24) & 0xF; | ||
910 | if (channel >= dev->maximum_num_channels) | ||
911 | break; | ||
912 | id = container & 0xFFFF; | ||
913 | if (id >= dev->maximum_num_physicals) | ||
914 | break; | ||
915 | lun = (container >> 16) & 0xFF; | ||
916 | channel = aac_phys_to_logical(channel); | ||
917 | device_config_needed = | ||
918 | (((__le32 *)aifcmd->data)[0] == | ||
919 | cpu_to_le32(AifEnAddJBOD)) ? ADD : DELETE; | ||
920 | break; | ||
921 | |||
922 | case AifEnEnclosureManagement: | ||
923 | /* | ||
924 | * If in JBOD mode, automatic exposure of new | ||
925 | * physical target to be suppressed until configured. | ||
926 | */ | ||
927 | if (dev->jbod) | ||
928 | break; | ||
929 | switch (le32_to_cpu(((__le32 *)aifcmd->data)[3])) { | ||
930 | case EM_DRIVE_INSERTION: | ||
931 | case EM_DRIVE_REMOVAL: | ||
932 | container = le32_to_cpu( | ||
933 | ((__le32 *)aifcmd->data)[2]); | ||
934 | if ((container >> 28)) | ||
935 | break; | ||
936 | channel = (container >> 24) & 0xF; | ||
937 | if (channel >= dev->maximum_num_channels) | ||
938 | break; | ||
939 | id = container & 0xFFFF; | ||
940 | lun = (container >> 16) & 0xFF; | ||
941 | if (id >= dev->maximum_num_physicals) { | ||
942 | /* legacy dev_t ? */ | ||
943 | if ((0x2000 <= id) || lun || channel || | ||
944 | ((channel = (id >> 7) & 0x3F) >= | ||
945 | dev->maximum_num_channels)) | ||
946 | break; | ||
947 | lun = (id >> 4) & 7; | ||
948 | id &= 0xF; | ||
949 | } | ||
950 | channel = aac_phys_to_logical(channel); | ||
951 | device_config_needed = | ||
952 | (((__le32 *)aifcmd->data)[3] | ||
953 | == cpu_to_le32(EM_DRIVE_INSERTION)) ? | ||
954 | ADD : DELETE; | ||
955 | break; | ||
956 | } | ||
957 | break; | ||
898 | } | 958 | } |
899 | 959 | ||
900 | /* | 960 | /* |
@@ -905,13 +965,13 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) | |||
905 | if (container >= dev->maximum_num_containers) | 965 | if (container >= dev->maximum_num_containers) |
906 | break; | 966 | break; |
907 | if ((dev->fsa_dev[container].config_waiting_on == | 967 | if ((dev->fsa_dev[container].config_waiting_on == |
908 | le32_to_cpu(*(u32 *)aifcmd->data)) && | 968 | le32_to_cpu(*(__le32 *)aifcmd->data)) && |
909 | time_before(jiffies, dev->fsa_dev[container].config_waiting_stamp + AIF_SNIFF_TIMEOUT)) | 969 | time_before(jiffies, dev->fsa_dev[container].config_waiting_stamp + AIF_SNIFF_TIMEOUT)) |
910 | dev->fsa_dev[container].config_waiting_on = 0; | 970 | dev->fsa_dev[container].config_waiting_on = 0; |
911 | } else for (container = 0; | 971 | } else for (container = 0; |
912 | container < dev->maximum_num_containers; ++container) { | 972 | container < dev->maximum_num_containers; ++container) { |
913 | if ((dev->fsa_dev[container].config_waiting_on == | 973 | if ((dev->fsa_dev[container].config_waiting_on == |
914 | le32_to_cpu(*(u32 *)aifcmd->data)) && | 974 | le32_to_cpu(*(__le32 *)aifcmd->data)) && |
915 | time_before(jiffies, dev->fsa_dev[container].config_waiting_stamp + AIF_SNIFF_TIMEOUT)) | 975 | time_before(jiffies, dev->fsa_dev[container].config_waiting_stamp + AIF_SNIFF_TIMEOUT)) |
916 | dev->fsa_dev[container].config_waiting_on = 0; | 976 | dev->fsa_dev[container].config_waiting_on = 0; |
917 | } | 977 | } |
@@ -926,9 +986,9 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) | |||
926 | * wait for a container change. | 986 | * wait for a container change. |
927 | */ | 987 | */ |
928 | 988 | ||
929 | if ((((u32 *)aifcmd->data)[1] == cpu_to_le32(AifJobCtrZero)) | 989 | if (((__le32 *)aifcmd->data)[1] == cpu_to_le32(AifJobCtrZero) && |
930 | && ((((u32 *)aifcmd->data)[6] == ((u32 *)aifcmd->data)[5]) | 990 | (((__le32 *)aifcmd->data)[6] == ((__le32 *)aifcmd->data)[5] || |
931 | || (((u32 *)aifcmd->data)[4] == cpu_to_le32(AifJobStsSuccess)))) { | 991 | ((__le32 *)aifcmd->data)[4] == cpu_to_le32(AifJobStsSuccess))) { |
932 | for (container = 0; | 992 | for (container = 0; |
933 | container < dev->maximum_num_containers; | 993 | container < dev->maximum_num_containers; |
934 | ++container) { | 994 | ++container) { |
@@ -943,9 +1003,9 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) | |||
943 | jiffies; | 1003 | jiffies; |
944 | } | 1004 | } |
945 | } | 1005 | } |
946 | if ((((u32 *)aifcmd->data)[1] == cpu_to_le32(AifJobCtrZero)) | 1006 | if (((__le32 *)aifcmd->data)[1] == cpu_to_le32(AifJobCtrZero) && |
947 | && (((u32 *)aifcmd->data)[6] == 0) | 1007 | ((__le32 *)aifcmd->data)[6] == 0 && |
948 | && (((u32 *)aifcmd->data)[4] == cpu_to_le32(AifJobStsRunning))) { | 1008 | ((__le32 *)aifcmd->data)[4] == cpu_to_le32(AifJobStsRunning)) { |
949 | for (container = 0; | 1009 | for (container = 0; |
950 | container < dev->maximum_num_containers; | 1010 | container < dev->maximum_num_containers; |
951 | ++container) { | 1011 | ++container) { |
@@ -963,7 +1023,7 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) | |||
963 | break; | 1023 | break; |
964 | } | 1024 | } |
965 | 1025 | ||
966 | device_config_needed = NOTHING; | 1026 | if (device_config_needed == NOTHING) |
967 | for (container = 0; container < dev->maximum_num_containers; | 1027 | for (container = 0; container < dev->maximum_num_containers; |
968 | ++container) { | 1028 | ++container) { |
969 | if ((dev->fsa_dev[container].config_waiting_on == 0) && | 1029 | if ((dev->fsa_dev[container].config_waiting_on == 0) && |
@@ -972,6 +1032,9 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) | |||
972 | device_config_needed = | 1032 | device_config_needed = |
973 | dev->fsa_dev[container].config_needed; | 1033 | dev->fsa_dev[container].config_needed; |
974 | dev->fsa_dev[container].config_needed = NOTHING; | 1034 | dev->fsa_dev[container].config_needed = NOTHING; |
1035 | channel = CONTAINER_TO_CHANNEL(container); | ||
1036 | id = CONTAINER_TO_ID(container); | ||
1037 | lun = CONTAINER_TO_LUN(container); | ||
975 | break; | 1038 | break; |
976 | } | 1039 | } |
977 | } | 1040 | } |
@@ -995,34 +1058,56 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) | |||
995 | /* | 1058 | /* |
996 | * force reload of disk info via aac_probe_container | 1059 | * force reload of disk info via aac_probe_container |
997 | */ | 1060 | */ |
998 | if ((device_config_needed == CHANGE) | 1061 | if ((channel == CONTAINER_CHANNEL) && |
999 | && (dev->fsa_dev[container].valid == 1)) | 1062 | (device_config_needed != NOTHING)) { |
1000 | dev->fsa_dev[container].valid = 2; | 1063 | if (dev->fsa_dev[container].valid == 1) |
1001 | if ((device_config_needed == CHANGE) || | 1064 | dev->fsa_dev[container].valid = 2; |
1002 | (device_config_needed == ADD)) | ||
1003 | aac_probe_container(dev, container); | 1065 | aac_probe_container(dev, container); |
1004 | device = scsi_device_lookup(dev->scsi_host_ptr, | 1066 | } |
1005 | CONTAINER_TO_CHANNEL(container), | 1067 | device = scsi_device_lookup(dev->scsi_host_ptr, channel, id, lun); |
1006 | CONTAINER_TO_ID(container), | ||
1007 | CONTAINER_TO_LUN(container)); | ||
1008 | if (device) { | 1068 | if (device) { |
1009 | switch (device_config_needed) { | 1069 | switch (device_config_needed) { |
1010 | case DELETE: | 1070 | case DELETE: |
1071 | if (scsi_device_online(device)) { | ||
1072 | scsi_device_set_state(device, SDEV_OFFLINE); | ||
1073 | sdev_printk(KERN_INFO, device, | ||
1074 | "Device offlined - %s\n", | ||
1075 | (channel == CONTAINER_CHANNEL) ? | ||
1076 | "array deleted" : | ||
1077 | "enclosure services event"); | ||
1078 | } | ||
1079 | break; | ||
1080 | case ADD: | ||
1081 | if (!scsi_device_online(device)) { | ||
1082 | sdev_printk(KERN_INFO, device, | ||
1083 | "Device online - %s\n", | ||
1084 | (channel == CONTAINER_CHANNEL) ? | ||
1085 | "array created" : | ||
1086 | "enclosure services event"); | ||
1087 | scsi_device_set_state(device, SDEV_RUNNING); | ||
1088 | } | ||
1089 | /* FALLTHRU */ | ||
1011 | case CHANGE: | 1090 | case CHANGE: |
1091 | if ((channel == CONTAINER_CHANNEL) | ||
1092 | && (!dev->fsa_dev[container].valid)) { | ||
1093 | if (!scsi_device_online(device)) | ||
1094 | break; | ||
1095 | scsi_device_set_state(device, SDEV_OFFLINE); | ||
1096 | sdev_printk(KERN_INFO, device, | ||
1097 | "Device offlined - %s\n", | ||
1098 | "array failed"); | ||
1099 | break; | ||
1100 | } | ||
1012 | scsi_rescan_device(&device->sdev_gendev); | 1101 | scsi_rescan_device(&device->sdev_gendev); |
1013 | 1102 | ||
1014 | default: | 1103 | default: |
1015 | break; | 1104 | break; |
1016 | } | 1105 | } |
1017 | scsi_device_put(device); | 1106 | scsi_device_put(device); |
1107 | device_config_needed = NOTHING; | ||
1018 | } | 1108 | } |
1019 | if (device_config_needed == ADD) { | 1109 | if (device_config_needed == ADD) |
1020 | scsi_add_device(dev->scsi_host_ptr, | 1110 | scsi_add_device(dev->scsi_host_ptr, channel, id, lun); |
1021 | CONTAINER_TO_CHANNEL(container), | ||
1022 | CONTAINER_TO_ID(container), | ||
1023 | CONTAINER_TO_LUN(container)); | ||
1024 | } | ||
1025 | |||
1026 | } | 1111 | } |
1027 | 1112 | ||
1028 | static int _aac_reset_adapter(struct aac_dev *aac, int forced) | 1113 | static int _aac_reset_adapter(struct aac_dev *aac, int forced) |
@@ -1099,7 +1184,8 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced) | |||
1099 | free_irq(aac->pdev->irq, aac); | 1184 | free_irq(aac->pdev->irq, aac); |
1100 | kfree(aac->fsa_dev); | 1185 | kfree(aac->fsa_dev); |
1101 | aac->fsa_dev = NULL; | 1186 | aac->fsa_dev = NULL; |
1102 | if (aac_get_driver_ident(index)->quirks & AAC_QUIRK_31BIT) { | 1187 | quirks = aac_get_driver_ident(index)->quirks; |
1188 | if (quirks & AAC_QUIRK_31BIT) { | ||
1103 | if (((retval = pci_set_dma_mask(aac->pdev, DMA_31BIT_MASK))) || | 1189 | if (((retval = pci_set_dma_mask(aac->pdev, DMA_31BIT_MASK))) || |
1104 | ((retval = pci_set_consistent_dma_mask(aac->pdev, DMA_31BIT_MASK)))) | 1190 | ((retval = pci_set_consistent_dma_mask(aac->pdev, DMA_31BIT_MASK)))) |
1105 | goto out; | 1191 | goto out; |
@@ -1110,7 +1196,7 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced) | |||
1110 | } | 1196 | } |
1111 | if ((retval = (*(aac_get_driver_ident(index)->init))(aac))) | 1197 | if ((retval = (*(aac_get_driver_ident(index)->init))(aac))) |
1112 | goto out; | 1198 | goto out; |
1113 | if (aac_get_driver_ident(index)->quirks & AAC_QUIRK_31BIT) | 1199 | if (quirks & AAC_QUIRK_31BIT) |
1114 | if ((retval = pci_set_dma_mask(aac->pdev, DMA_32BIT_MASK))) | 1200 | if ((retval = pci_set_dma_mask(aac->pdev, DMA_32BIT_MASK))) |
1115 | goto out; | 1201 | goto out; |
1116 | if (jafo) { | 1202 | if (jafo) { |
@@ -1121,15 +1207,14 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced) | |||
1121 | } | 1207 | } |
1122 | } | 1208 | } |
1123 | (void)aac_get_adapter_info(aac); | 1209 | (void)aac_get_adapter_info(aac); |
1124 | quirks = aac_get_driver_ident(index)->quirks; | ||
1125 | if ((quirks & AAC_QUIRK_34SG) && (host->sg_tablesize > 34)) { | 1210 | if ((quirks & AAC_QUIRK_34SG) && (host->sg_tablesize > 34)) { |
1126 | host->sg_tablesize = 34; | 1211 | host->sg_tablesize = 34; |
1127 | host->max_sectors = (host->sg_tablesize * 8) + 112; | 1212 | host->max_sectors = (host->sg_tablesize * 8) + 112; |
1128 | } | 1213 | } |
1129 | if ((quirks & AAC_QUIRK_17SG) && (host->sg_tablesize > 17)) { | 1214 | if ((quirks & AAC_QUIRK_17SG) && (host->sg_tablesize > 17)) { |
1130 | host->sg_tablesize = 17; | 1215 | host->sg_tablesize = 17; |
1131 | host->max_sectors = (host->sg_tablesize * 8) + 112; | 1216 | host->max_sectors = (host->sg_tablesize * 8) + 112; |
1132 | } | 1217 | } |
1133 | aac_get_config_status(aac, 1); | 1218 | aac_get_config_status(aac, 1); |
1134 | aac_get_containers(aac); | 1219 | aac_get_containers(aac); |
1135 | /* | 1220 | /* |
@@ -1217,12 +1302,13 @@ int aac_reset_adapter(struct aac_dev * aac, int forced) | |||
1217 | } | 1302 | } |
1218 | 1303 | ||
1219 | /* Quiesce build, flush cache, write through mode */ | 1304 | /* Quiesce build, flush cache, write through mode */ |
1220 | aac_send_shutdown(aac); | 1305 | if (forced < 2) |
1306 | aac_send_shutdown(aac); | ||
1221 | spin_lock_irqsave(host->host_lock, flagv); | 1307 | spin_lock_irqsave(host->host_lock, flagv); |
1222 | retval = _aac_reset_adapter(aac, forced); | 1308 | retval = _aac_reset_adapter(aac, forced ? forced : ((aac_check_reset != 0) && (aac_check_reset != 1))); |
1223 | spin_unlock_irqrestore(host->host_lock, flagv); | 1309 | spin_unlock_irqrestore(host->host_lock, flagv); |
1224 | 1310 | ||
1225 | if (retval == -ENODEV) { | 1311 | if ((forced < 2) && (retval == -ENODEV)) { |
1226 | /* Unwind aac_send_shutdown() IOP_RESET unsupported/disabled */ | 1312 | /* Unwind aac_send_shutdown() IOP_RESET unsupported/disabled */ |
1227 | struct fib * fibctx = aac_fib_alloc(aac); | 1313 | struct fib * fibctx = aac_fib_alloc(aac); |
1228 | if (fibctx) { | 1314 | if (fibctx) { |
@@ -1338,11 +1424,11 @@ int aac_check_health(struct aac_dev * aac) | |||
1338 | fib->data = hw_fib->data; | 1424 | fib->data = hw_fib->data; |
1339 | aif = (struct aac_aifcmd *)hw_fib->data; | 1425 | aif = (struct aac_aifcmd *)hw_fib->data; |
1340 | aif->command = cpu_to_le32(AifCmdEventNotify); | 1426 | aif->command = cpu_to_le32(AifCmdEventNotify); |
1341 | aif->seqnum = cpu_to_le32(0xFFFFFFFF); | 1427 | aif->seqnum = cpu_to_le32(0xFFFFFFFF); |
1342 | aif->data[0] = AifEnExpEvent; | 1428 | ((__le32 *)aif->data)[0] = cpu_to_le32(AifEnExpEvent); |
1343 | aif->data[1] = AifExeFirmwarePanic; | 1429 | ((__le32 *)aif->data)[1] = cpu_to_le32(AifExeFirmwarePanic); |
1344 | aif->data[2] = AifHighPriority; | 1430 | ((__le32 *)aif->data)[2] = cpu_to_le32(AifHighPriority); |
1345 | aif->data[3] = BlinkLED; | 1431 | ((__le32 *)aif->data)[3] = cpu_to_le32(BlinkLED); |
1346 | 1432 | ||
1347 | /* | 1433 | /* |
1348 | * Put the FIB onto the | 1434 | * Put the FIB onto the |
@@ -1372,14 +1458,14 @@ int aac_check_health(struct aac_dev * aac) | |||
1372 | 1458 | ||
1373 | printk(KERN_ERR "%s: Host adapter BLINK LED 0x%x\n", aac->name, BlinkLED); | 1459 | printk(KERN_ERR "%s: Host adapter BLINK LED 0x%x\n", aac->name, BlinkLED); |
1374 | 1460 | ||
1375 | if (!aac_check_reset || | 1461 | if (!aac_check_reset || ((aac_check_reset != 1) && |
1376 | (aac->supplement_adapter_info.SupportedOptions2 & | 1462 | (aac->supplement_adapter_info.SupportedOptions2 & |
1377 | le32_to_cpu(AAC_OPTION_IGNORE_RESET))) | 1463 | AAC_OPTION_IGNORE_RESET))) |
1378 | goto out; | 1464 | goto out; |
1379 | host = aac->scsi_host_ptr; | 1465 | host = aac->scsi_host_ptr; |
1380 | if (aac->thread->pid != current->pid) | 1466 | if (aac->thread->pid != current->pid) |
1381 | spin_lock_irqsave(host->host_lock, flagv); | 1467 | spin_lock_irqsave(host->host_lock, flagv); |
1382 | BlinkLED = _aac_reset_adapter(aac, 0); | 1468 | BlinkLED = _aac_reset_adapter(aac, aac_check_reset != 1); |
1383 | if (aac->thread->pid != current->pid) | 1469 | if (aac->thread->pid != current->pid) |
1384 | spin_unlock_irqrestore(host->host_lock, flagv); | 1470 | spin_unlock_irqrestore(host->host_lock, flagv); |
1385 | return BlinkLED; | 1471 | return BlinkLED; |
@@ -1399,7 +1485,7 @@ out: | |||
1399 | * until the queue is empty. When the queue is empty it will wait for | 1485 | * until the queue is empty. When the queue is empty it will wait for |
1400 | * more FIBs. | 1486 | * more FIBs. |
1401 | */ | 1487 | */ |
1402 | 1488 | ||
1403 | int aac_command_thread(void *data) | 1489 | int aac_command_thread(void *data) |
1404 | { | 1490 | { |
1405 | struct aac_dev *dev = data; | 1491 | struct aac_dev *dev = data; |
@@ -1425,30 +1511,29 @@ int aac_command_thread(void *data) | |||
1425 | add_wait_queue(&dev->queues->queue[HostNormCmdQueue].cmdready, &wait); | 1511 | add_wait_queue(&dev->queues->queue[HostNormCmdQueue].cmdready, &wait); |
1426 | set_current_state(TASK_INTERRUPTIBLE); | 1512 | set_current_state(TASK_INTERRUPTIBLE); |
1427 | dprintk ((KERN_INFO "aac_command_thread start\n")); | 1513 | dprintk ((KERN_INFO "aac_command_thread start\n")); |
1428 | while(1) | 1514 | while (1) { |
1429 | { | ||
1430 | spin_lock_irqsave(dev->queues->queue[HostNormCmdQueue].lock, flags); | 1515 | spin_lock_irqsave(dev->queues->queue[HostNormCmdQueue].lock, flags); |
1431 | while(!list_empty(&(dev->queues->queue[HostNormCmdQueue].cmdq))) { | 1516 | while(!list_empty(&(dev->queues->queue[HostNormCmdQueue].cmdq))) { |
1432 | struct list_head *entry; | 1517 | struct list_head *entry; |
1433 | struct aac_aifcmd * aifcmd; | 1518 | struct aac_aifcmd * aifcmd; |
1434 | 1519 | ||
1435 | set_current_state(TASK_RUNNING); | 1520 | set_current_state(TASK_RUNNING); |
1436 | 1521 | ||
1437 | entry = dev->queues->queue[HostNormCmdQueue].cmdq.next; | 1522 | entry = dev->queues->queue[HostNormCmdQueue].cmdq.next; |
1438 | list_del(entry); | 1523 | list_del(entry); |
1439 | 1524 | ||
1440 | spin_unlock_irqrestore(dev->queues->queue[HostNormCmdQueue].lock, flags); | 1525 | spin_unlock_irqrestore(dev->queues->queue[HostNormCmdQueue].lock, flags); |
1441 | fib = list_entry(entry, struct fib, fiblink); | 1526 | fib = list_entry(entry, struct fib, fiblink); |
1442 | /* | 1527 | /* |
1443 | * We will process the FIB here or pass it to a | 1528 | * We will process the FIB here or pass it to a |
1444 | * worker thread that is TBD. We Really can't | 1529 | * worker thread that is TBD. We Really can't |
1445 | * do anything at this point since we don't have | 1530 | * do anything at this point since we don't have |
1446 | * anything defined for this thread to do. | 1531 | * anything defined for this thread to do. |
1447 | */ | 1532 | */ |
1448 | hw_fib = fib->hw_fib_va; | 1533 | hw_fib = fib->hw_fib_va; |
1449 | memset(fib, 0, sizeof(struct fib)); | 1534 | memset(fib, 0, sizeof(struct fib)); |
1450 | fib->type = FSAFS_NTC_FIB_CONTEXT; | 1535 | fib->type = FSAFS_NTC_FIB_CONTEXT; |
1451 | fib->size = sizeof( struct fib ); | 1536 | fib->size = sizeof(struct fib); |
1452 | fib->hw_fib_va = hw_fib; | 1537 | fib->hw_fib_va = hw_fib; |
1453 | fib->data = hw_fib->data; | 1538 | fib->data = hw_fib->data; |
1454 | fib->dev = dev; | 1539 | fib->dev = dev; |
@@ -1462,20 +1547,19 @@ int aac_command_thread(void *data) | |||
1462 | *(__le32 *)hw_fib->data = cpu_to_le32(ST_OK); | 1547 | *(__le32 *)hw_fib->data = cpu_to_le32(ST_OK); |
1463 | aac_fib_adapter_complete(fib, (u16)sizeof(u32)); | 1548 | aac_fib_adapter_complete(fib, (u16)sizeof(u32)); |
1464 | } else { | 1549 | } else { |
1465 | struct list_head *entry; | ||
1466 | /* The u32 here is important and intended. We are using | 1550 | /* The u32 here is important and intended. We are using |
1467 | 32bit wrapping time to fit the adapter field */ | 1551 | 32bit wrapping time to fit the adapter field */ |
1468 | 1552 | ||
1469 | u32 time_now, time_last; | 1553 | u32 time_now, time_last; |
1470 | unsigned long flagv; | 1554 | unsigned long flagv; |
1471 | unsigned num; | 1555 | unsigned num; |
1472 | struct hw_fib ** hw_fib_pool, ** hw_fib_p; | 1556 | struct hw_fib ** hw_fib_pool, ** hw_fib_p; |
1473 | struct fib ** fib_pool, ** fib_p; | 1557 | struct fib ** fib_pool, ** fib_p; |
1474 | 1558 | ||
1475 | /* Sniff events */ | 1559 | /* Sniff events */ |
1476 | if ((aifcmd->command == | 1560 | if ((aifcmd->command == |
1477 | cpu_to_le32(AifCmdEventNotify)) || | 1561 | cpu_to_le32(AifCmdEventNotify)) || |
1478 | (aifcmd->command == | 1562 | (aifcmd->command == |
1479 | cpu_to_le32(AifCmdJobProgress))) { | 1563 | cpu_to_le32(AifCmdJobProgress))) { |
1480 | aac_handle_aif(dev, fib); | 1564 | aac_handle_aif(dev, fib); |
1481 | } | 1565 | } |
@@ -1527,7 +1611,7 @@ int aac_command_thread(void *data) | |||
1527 | spin_lock_irqsave(&dev->fib_lock, flagv); | 1611 | spin_lock_irqsave(&dev->fib_lock, flagv); |
1528 | entry = dev->fib_list.next; | 1612 | entry = dev->fib_list.next; |
1529 | /* | 1613 | /* |
1530 | * For each Context that is on the | 1614 | * For each Context that is on the |
1531 | * fibctxList, make a copy of the | 1615 | * fibctxList, make a copy of the |
1532 | * fib, and then set the event to wake up the | 1616 | * fib, and then set the event to wake up the |
1533 | * thread that is waiting for it. | 1617 | * thread that is waiting for it. |
@@ -1552,7 +1636,7 @@ int aac_command_thread(void *data) | |||
1552 | */ | 1636 | */ |
1553 | time_last = fibctx->jiffies; | 1637 | time_last = fibctx->jiffies; |
1554 | /* | 1638 | /* |
1555 | * Has it been > 2 minutes | 1639 | * Has it been > 2 minutes |
1556 | * since the last read off | 1640 | * since the last read off |
1557 | * the queue? | 1641 | * the queue? |
1558 | */ | 1642 | */ |
@@ -1583,7 +1667,7 @@ int aac_command_thread(void *data) | |||
1583 | */ | 1667 | */ |
1584 | list_add_tail(&newfib->fiblink, &fibctx->fib_list); | 1668 | list_add_tail(&newfib->fiblink, &fibctx->fib_list); |
1585 | fibctx->count++; | 1669 | fibctx->count++; |
1586 | /* | 1670 | /* |
1587 | * Set the event to wake up the | 1671 | * Set the event to wake up the |
1588 | * thread that is waiting. | 1672 | * thread that is waiting. |
1589 | */ | 1673 | */ |
@@ -1655,11 +1739,11 @@ int aac_command_thread(void *data) | |||
1655 | struct fib *fibptr; | 1739 | struct fib *fibptr; |
1656 | 1740 | ||
1657 | if ((fibptr = aac_fib_alloc(dev))) { | 1741 | if ((fibptr = aac_fib_alloc(dev))) { |
1658 | u32 * info; | 1742 | __le32 *info; |
1659 | 1743 | ||
1660 | aac_fib_init(fibptr); | 1744 | aac_fib_init(fibptr); |
1661 | 1745 | ||
1662 | info = (u32 *) fib_data(fibptr); | 1746 | info = (__le32 *) fib_data(fibptr); |
1663 | if (now.tv_usec > 500000) | 1747 | if (now.tv_usec > 500000) |
1664 | ++now.tv_sec; | 1748 | ++now.tv_sec; |
1665 | 1749 | ||