diff options
Diffstat (limited to 'drivers/ieee1394/sbp2.c')
| -rw-r--r-- | drivers/ieee1394/sbp2.c | 481 |
1 files changed, 249 insertions, 232 deletions
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index b08755e2e68f..6986ac188281 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c | |||
| @@ -38,31 +38,36 @@ | |||
| 38 | * but the code needs additional debugging. | 38 | * but the code needs additional debugging. |
| 39 | */ | 39 | */ |
| 40 | 40 | ||
| 41 | #include <linux/blkdev.h> | ||
| 42 | #include <linux/compiler.h> | ||
| 43 | #include <linux/delay.h> | ||
| 44 | #include <linux/device.h> | ||
| 45 | #include <linux/dma-mapping.h> | ||
| 46 | #include <linux/gfp.h> | ||
| 47 | #include <linux/init.h> | ||
| 41 | #include <linux/kernel.h> | 48 | #include <linux/kernel.h> |
| 42 | #include <linux/list.h> | 49 | #include <linux/list.h> |
| 43 | #include <linux/string.h> | ||
| 44 | #include <linux/stringify.h> | ||
| 45 | #include <linux/slab.h> | ||
| 46 | #include <linux/interrupt.h> | ||
| 47 | #include <linux/fs.h> | ||
| 48 | #include <linux/poll.h> | ||
| 49 | #include <linux/module.h> | 50 | #include <linux/module.h> |
| 50 | #include <linux/moduleparam.h> | 51 | #include <linux/moduleparam.h> |
| 51 | #include <linux/types.h> | ||
| 52 | #include <linux/delay.h> | ||
| 53 | #include <linux/sched.h> | ||
| 54 | #include <linux/blkdev.h> | ||
| 55 | #include <linux/smp_lock.h> | ||
| 56 | #include <linux/init.h> | ||
| 57 | #include <linux/pci.h> | 52 | #include <linux/pci.h> |
| 53 | #include <linux/slab.h> | ||
| 54 | #include <linux/spinlock.h> | ||
| 55 | #include <linux/stat.h> | ||
| 56 | #include <linux/string.h> | ||
| 57 | #include <linux/stringify.h> | ||
| 58 | #include <linux/types.h> | ||
| 59 | #include <linux/wait.h> | ||
| 58 | 60 | ||
| 59 | #include <asm/current.h> | ||
| 60 | #include <asm/uaccess.h> | ||
| 61 | #include <asm/io.h> | ||
| 62 | #include <asm/byteorder.h> | 61 | #include <asm/byteorder.h> |
| 63 | #include <asm/atomic.h> | 62 | #include <asm/errno.h> |
| 64 | #include <asm/system.h> | 63 | #include <asm/param.h> |
| 65 | #include <asm/scatterlist.h> | 64 | #include <asm/scatterlist.h> |
| 65 | #include <asm/system.h> | ||
| 66 | #include <asm/types.h> | ||
| 67 | |||
| 68 | #ifdef CONFIG_IEEE1394_SBP2_PHYS_DMA | ||
| 69 | #include <asm/io.h> /* for bus_to_virt */ | ||
| 70 | #endif | ||
| 66 | 71 | ||
| 67 | #include <scsi/scsi.h> | 72 | #include <scsi/scsi.h> |
| 68 | #include <scsi/scsi_cmnd.h> | 73 | #include <scsi/scsi_cmnd.h> |
| @@ -71,13 +76,14 @@ | |||
| 71 | #include <scsi/scsi_host.h> | 76 | #include <scsi/scsi_host.h> |
| 72 | 77 | ||
| 73 | #include "csr1212.h" | 78 | #include "csr1212.h" |
| 79 | #include "highlevel.h" | ||
| 80 | #include "hosts.h" | ||
| 74 | #include "ieee1394.h" | 81 | #include "ieee1394.h" |
| 75 | #include "ieee1394_types.h" | ||
| 76 | #include "ieee1394_core.h" | 82 | #include "ieee1394_core.h" |
| 77 | #include "nodemgr.h" | 83 | #include "ieee1394_hotplug.h" |
| 78 | #include "hosts.h" | ||
| 79 | #include "highlevel.h" | ||
| 80 | #include "ieee1394_transactions.h" | 84 | #include "ieee1394_transactions.h" |
| 85 | #include "ieee1394_types.h" | ||
| 86 | #include "nodemgr.h" | ||
| 81 | #include "sbp2.h" | 87 | #include "sbp2.h" |
| 82 | 88 | ||
| 83 | /* | 89 | /* |
| @@ -173,11 +179,6 @@ MODULE_PARM_DESC(workarounds, "Work around device bugs (default = 0" | |||
| 173 | ", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE) | 179 | ", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE) |
| 174 | ", or a combination)"); | 180 | ", or a combination)"); |
| 175 | 181 | ||
| 176 | /* legacy parameter */ | ||
| 177 | static int force_inquiry_hack; | ||
| 178 | module_param(force_inquiry_hack, int, 0644); | ||
| 179 | MODULE_PARM_DESC(force_inquiry_hack, "Deprecated, use 'workarounds'"); | ||
| 180 | |||
| 181 | /* | 182 | /* |
| 182 | * Export information about protocols/devices supported by this driver. | 183 | * Export information about protocols/devices supported by this driver. |
| 183 | */ | 184 | */ |
| @@ -208,9 +209,9 @@ static u32 global_outstanding_command_orbs = 0; | |||
| 208 | #define outstanding_orb_incr global_outstanding_command_orbs++ | 209 | #define outstanding_orb_incr global_outstanding_command_orbs++ |
| 209 | #define outstanding_orb_decr global_outstanding_command_orbs-- | 210 | #define outstanding_orb_decr global_outstanding_command_orbs-- |
| 210 | #else | 211 | #else |
| 211 | #define SBP2_ORB_DEBUG(fmt, args...) | 212 | #define SBP2_ORB_DEBUG(fmt, args...) do {} while (0) |
| 212 | #define outstanding_orb_incr | 213 | #define outstanding_orb_incr do {} while (0) |
| 213 | #define outstanding_orb_decr | 214 | #define outstanding_orb_decr do {} while (0) |
| 214 | #endif | 215 | #endif |
| 215 | 216 | ||
| 216 | #ifdef CONFIG_IEEE1394_SBP2_DEBUG_DMA | 217 | #ifdef CONFIG_IEEE1394_SBP2_DEBUG_DMA |
| @@ -222,8 +223,8 @@ static u32 global_outstanding_command_orbs = 0; | |||
| 222 | --global_outstanding_dmas, ## args) | 223 | --global_outstanding_dmas, ## args) |
| 223 | static u32 global_outstanding_dmas = 0; | 224 | static u32 global_outstanding_dmas = 0; |
| 224 | #else | 225 | #else |
| 225 | #define SBP2_DMA_ALLOC(fmt, args...) | 226 | #define SBP2_DMA_ALLOC(fmt, args...) do {} while (0) |
| 226 | #define SBP2_DMA_FREE(fmt, args...) | 227 | #define SBP2_DMA_FREE(fmt, args...) do {} while (0) |
| 227 | #endif | 228 | #endif |
| 228 | 229 | ||
| 229 | #if CONFIG_IEEE1394_SBP2_DEBUG >= 2 | 230 | #if CONFIG_IEEE1394_SBP2_DEBUG >= 2 |
| @@ -237,7 +238,7 @@ static u32 global_outstanding_dmas = 0; | |||
| 237 | #define SBP2_NOTICE(fmt, args...) HPSB_NOTICE("sbp2: "fmt, ## args) | 238 | #define SBP2_NOTICE(fmt, args...) HPSB_NOTICE("sbp2: "fmt, ## args) |
| 238 | #define SBP2_WARN(fmt, args...) HPSB_WARN("sbp2: "fmt, ## args) | 239 | #define SBP2_WARN(fmt, args...) HPSB_WARN("sbp2: "fmt, ## args) |
| 239 | #else | 240 | #else |
| 240 | #define SBP2_DEBUG(fmt, args...) | 241 | #define SBP2_DEBUG(fmt, args...) do {} while (0) |
| 241 | #define SBP2_INFO(fmt, args...) HPSB_INFO("sbp2: "fmt, ## args) | 242 | #define SBP2_INFO(fmt, args...) HPSB_INFO("sbp2: "fmt, ## args) |
| 242 | #define SBP2_NOTICE(fmt, args...) HPSB_NOTICE("sbp2: "fmt, ## args) | 243 | #define SBP2_NOTICE(fmt, args...) HPSB_NOTICE("sbp2: "fmt, ## args) |
| 243 | #define SBP2_WARN(fmt, args...) HPSB_WARN("sbp2: "fmt, ## args) | 244 | #define SBP2_WARN(fmt, args...) HPSB_WARN("sbp2: "fmt, ## args) |
| @@ -356,7 +357,7 @@ static const struct { | |||
| 356 | /* | 357 | /* |
| 357 | * Converts a buffer from be32 to cpu byte ordering. Length is in bytes. | 358 | * Converts a buffer from be32 to cpu byte ordering. Length is in bytes. |
| 358 | */ | 359 | */ |
| 359 | static __inline__ void sbp2util_be32_to_cpu_buffer(void *buffer, int length) | 360 | static inline void sbp2util_be32_to_cpu_buffer(void *buffer, int length) |
| 360 | { | 361 | { |
| 361 | u32 *temp = buffer; | 362 | u32 *temp = buffer; |
| 362 | 363 | ||
| @@ -369,7 +370,7 @@ static __inline__ void sbp2util_be32_to_cpu_buffer(void *buffer, int length) | |||
| 369 | /* | 370 | /* |
| 370 | * Converts a buffer from cpu to be32 byte ordering. Length is in bytes. | 371 | * Converts a buffer from cpu to be32 byte ordering. Length is in bytes. |
| 371 | */ | 372 | */ |
| 372 | static __inline__ void sbp2util_cpu_to_be32_buffer(void *buffer, int length) | 373 | static inline void sbp2util_cpu_to_be32_buffer(void *buffer, int length) |
| 373 | { | 374 | { |
| 374 | u32 *temp = buffer; | 375 | u32 *temp = buffer; |
| 375 | 376 | ||
| @@ -380,8 +381,8 @@ static __inline__ void sbp2util_cpu_to_be32_buffer(void *buffer, int length) | |||
| 380 | } | 381 | } |
| 381 | #else /* BIG_ENDIAN */ | 382 | #else /* BIG_ENDIAN */ |
| 382 | /* Why waste the cpu cycles? */ | 383 | /* Why waste the cpu cycles? */ |
| 383 | #define sbp2util_be32_to_cpu_buffer(x,y) | 384 | #define sbp2util_be32_to_cpu_buffer(x,y) do {} while (0) |
| 384 | #define sbp2util_cpu_to_be32_buffer(x,y) | 385 | #define sbp2util_cpu_to_be32_buffer(x,y) do {} while (0) |
| 385 | #endif | 386 | #endif |
| 386 | 387 | ||
| 387 | #ifdef CONFIG_IEEE1394_SBP2_PACKET_DUMP | 388 | #ifdef CONFIG_IEEE1394_SBP2_PACKET_DUMP |
| @@ -417,24 +418,26 @@ static void sbp2util_packet_dump(void *buffer, int length, char *dump_name, | |||
| 417 | return; | 418 | return; |
| 418 | } | 419 | } |
| 419 | #else | 420 | #else |
| 420 | #define sbp2util_packet_dump(w,x,y,z) | 421 | #define sbp2util_packet_dump(w,x,y,z) do {} while (0) |
| 421 | #endif | 422 | #endif |
| 422 | 423 | ||
| 424 | static DECLARE_WAIT_QUEUE_HEAD(access_wq); | ||
| 425 | |||
| 423 | /* | 426 | /* |
| 424 | * Goofy routine that basically does a down_timeout function. | 427 | * Waits for completion of an SBP-2 access request. |
| 428 | * Returns nonzero if timed out or prematurely interrupted. | ||
| 425 | */ | 429 | */ |
| 426 | static int sbp2util_down_timeout(atomic_t *done, int timeout) | 430 | static int sbp2util_access_timeout(struct scsi_id_instance_data *scsi_id, |
| 431 | int timeout) | ||
| 427 | { | 432 | { |
| 428 | int i; | 433 | long leftover = wait_event_interruptible_timeout( |
| 434 | access_wq, scsi_id->access_complete, timeout); | ||
| 429 | 435 | ||
| 430 | for (i = timeout; (i > 0 && atomic_read(done) == 0); i-= HZ/10) { | 436 | scsi_id->access_complete = 0; |
| 431 | if (msleep_interruptible(100)) /* 100ms */ | 437 | return leftover <= 0; |
| 432 | return 1; | ||
| 433 | } | ||
| 434 | return (i > 0) ? 0 : 1; | ||
| 435 | } | 438 | } |
| 436 | 439 | ||
| 437 | /* Free's an allocated packet */ | 440 | /* Frees an allocated packet */ |
| 438 | static void sbp2_free_packet(struct hpsb_packet *packet) | 441 | static void sbp2_free_packet(struct hpsb_packet *packet) |
| 439 | { | 442 | { |
| 440 | hpsb_free_tlabel(packet); | 443 | hpsb_free_tlabel(packet); |
| @@ -468,6 +471,44 @@ static int sbp2util_node_write_no_wait(struct node_entry *ne, u64 addr, | |||
| 468 | return 0; | 471 | return 0; |
| 469 | } | 472 | } |
| 470 | 473 | ||
| 474 | static void sbp2util_notify_fetch_agent(struct scsi_id_instance_data *scsi_id, | ||
| 475 | u64 offset, quadlet_t *data, size_t len) | ||
| 476 | { | ||
| 477 | /* | ||
| 478 | * There is a small window after a bus reset within which the node | ||
| 479 | * entry's generation is current but the reconnect wasn't completed. | ||
| 480 | */ | ||
| 481 | if (unlikely(atomic_read(&scsi_id->state) == SBP2LU_STATE_IN_RESET)) | ||
| 482 | return; | ||
| 483 | |||
| 484 | if (hpsb_node_write(scsi_id->ne, | ||
| 485 | scsi_id->sbp2_command_block_agent_addr + offset, | ||
| 486 | data, len)) | ||
| 487 | SBP2_ERR("sbp2util_notify_fetch_agent failed."); | ||
| 488 | /* | ||
| 489 | * Now accept new SCSI commands, unless a bus reset happended during | ||
| 490 | * hpsb_node_write. | ||
| 491 | */ | ||
| 492 | if (likely(atomic_read(&scsi_id->state) != SBP2LU_STATE_IN_RESET)) | ||
| 493 | scsi_unblock_requests(scsi_id->scsi_host); | ||
| 494 | } | ||
| 495 | |||
| 496 | static void sbp2util_write_orb_pointer(void *p) | ||
| 497 | { | ||
| 498 | quadlet_t data[2]; | ||
| 499 | |||
| 500 | data[0] = ORB_SET_NODE_ID( | ||
| 501 | ((struct scsi_id_instance_data *)p)->hi->host->node_id); | ||
| 502 | data[1] = ((struct scsi_id_instance_data *)p)->last_orb_dma; | ||
| 503 | sbp2util_cpu_to_be32_buffer(data, 8); | ||
| 504 | sbp2util_notify_fetch_agent(p, SBP2_ORB_POINTER_OFFSET, data, 8); | ||
| 505 | } | ||
| 506 | |||
| 507 | static void sbp2util_write_doorbell(void *p) | ||
| 508 | { | ||
| 509 | sbp2util_notify_fetch_agent(p, SBP2_DOORBELL_OFFSET, NULL, 4); | ||
| 510 | } | ||
| 511 | |||
| 471 | /* | 512 | /* |
| 472 | * This function is called to create a pool of command orbs used for | 513 | * This function is called to create a pool of command orbs used for |
| 473 | * command processing. It is called when a new sbp2 device is detected. | 514 | * command processing. It is called when a new sbp2 device is detected. |
| @@ -492,7 +533,7 @@ static int sbp2util_create_command_orb_pool(struct scsi_id_instance_data *scsi_i | |||
| 492 | command->command_orb_dma = | 533 | command->command_orb_dma = |
| 493 | pci_map_single(hi->host->pdev, &command->command_orb, | 534 | pci_map_single(hi->host->pdev, &command->command_orb, |
| 494 | sizeof(struct sbp2_command_orb), | 535 | sizeof(struct sbp2_command_orb), |
| 495 | PCI_DMA_BIDIRECTIONAL); | 536 | PCI_DMA_TODEVICE); |
| 496 | SBP2_DMA_ALLOC("single command orb DMA"); | 537 | SBP2_DMA_ALLOC("single command orb DMA"); |
| 497 | command->sge_dma = | 538 | command->sge_dma = |
| 498 | pci_map_single(hi->host->pdev, | 539 | pci_map_single(hi->host->pdev, |
| @@ -525,7 +566,7 @@ static void sbp2util_remove_command_orb_pool(struct scsi_id_instance_data *scsi_ | |||
| 525 | /* Release our generic DMA's */ | 566 | /* Release our generic DMA's */ |
| 526 | pci_unmap_single(host->pdev, command->command_orb_dma, | 567 | pci_unmap_single(host->pdev, command->command_orb_dma, |
| 527 | sizeof(struct sbp2_command_orb), | 568 | sizeof(struct sbp2_command_orb), |
| 528 | PCI_DMA_BIDIRECTIONAL); | 569 | PCI_DMA_TODEVICE); |
| 529 | SBP2_DMA_FREE("single command orb DMA"); | 570 | SBP2_DMA_FREE("single command orb DMA"); |
| 530 | pci_unmap_single(host->pdev, command->sge_dma, | 571 | pci_unmap_single(host->pdev, command->sge_dma, |
| 531 | sizeof(command->scatter_gather_element), | 572 | sizeof(command->scatter_gather_element), |
| @@ -715,6 +756,7 @@ static int sbp2_remove(struct device *dev) | |||
| 715 | sbp2scsi_complete_all_commands(scsi_id, DID_NO_CONNECT); | 756 | sbp2scsi_complete_all_commands(scsi_id, DID_NO_CONNECT); |
| 716 | /* scsi_remove_device() will trigger shutdown functions of SCSI | 757 | /* scsi_remove_device() will trigger shutdown functions of SCSI |
| 717 | * highlevel drivers which would deadlock if blocked. */ | 758 | * highlevel drivers which would deadlock if blocked. */ |
| 759 | atomic_set(&scsi_id->state, SBP2LU_STATE_IN_SHUTDOWN); | ||
| 718 | scsi_unblock_requests(scsi_id->scsi_host); | 760 | scsi_unblock_requests(scsi_id->scsi_host); |
| 719 | } | 761 | } |
| 720 | sdev = scsi_id->sdev; | 762 | sdev = scsi_id->sdev; |
| @@ -766,10 +808,12 @@ static int sbp2_update(struct unit_directory *ud) | |||
| 766 | */ | 808 | */ |
| 767 | sbp2scsi_complete_all_commands(scsi_id, DID_BUS_BUSY); | 809 | sbp2scsi_complete_all_commands(scsi_id, DID_BUS_BUSY); |
| 768 | 810 | ||
| 769 | /* Make sure we unblock requests (since this is likely after a bus | 811 | /* Accept new commands unless there was another bus reset in the |
| 770 | * reset). */ | 812 | * meantime. */ |
| 771 | scsi_unblock_requests(scsi_id->scsi_host); | 813 | if (hpsb_node_entry_valid(scsi_id->ne)) { |
| 772 | 814 | atomic_set(&scsi_id->state, SBP2LU_STATE_RUNNING); | |
| 815 | scsi_unblock_requests(scsi_id->scsi_host); | ||
| 816 | } | ||
| 773 | return 0; | 817 | return 0; |
| 774 | } | 818 | } |
| 775 | 819 | ||
| @@ -794,11 +838,12 @@ static struct scsi_id_instance_data *sbp2_alloc_device(struct unit_directory *ud | |||
| 794 | scsi_id->speed_code = IEEE1394_SPEED_100; | 838 | scsi_id->speed_code = IEEE1394_SPEED_100; |
| 795 | scsi_id->max_payload_size = sbp2_speedto_max_payload[IEEE1394_SPEED_100]; | 839 | scsi_id->max_payload_size = sbp2_speedto_max_payload[IEEE1394_SPEED_100]; |
| 796 | scsi_id->status_fifo_addr = CSR1212_INVALID_ADDR_SPACE; | 840 | scsi_id->status_fifo_addr = CSR1212_INVALID_ADDR_SPACE; |
| 797 | atomic_set(&scsi_id->sbp2_login_complete, 0); | ||
| 798 | INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_inuse); | 841 | INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_inuse); |
| 799 | INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_completed); | 842 | INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_completed); |
| 800 | INIT_LIST_HEAD(&scsi_id->scsi_list); | 843 | INIT_LIST_HEAD(&scsi_id->scsi_list); |
| 801 | spin_lock_init(&scsi_id->sbp2_command_orb_lock); | 844 | spin_lock_init(&scsi_id->sbp2_command_orb_lock); |
| 845 | atomic_set(&scsi_id->state, SBP2LU_STATE_RUNNING); | ||
| 846 | INIT_WORK(&scsi_id->protocol_work, NULL, NULL); | ||
| 802 | 847 | ||
| 803 | ud->device.driver_data = scsi_id; | 848 | ud->device.driver_data = scsi_id; |
| 804 | 849 | ||
| @@ -881,11 +926,14 @@ static void sbp2_host_reset(struct hpsb_host *host) | |||
| 881 | struct scsi_id_instance_data *scsi_id; | 926 | struct scsi_id_instance_data *scsi_id; |
| 882 | 927 | ||
| 883 | hi = hpsb_get_hostinfo(&sbp2_highlevel, host); | 928 | hi = hpsb_get_hostinfo(&sbp2_highlevel, host); |
| 884 | 929 | if (!hi) | |
| 885 | if (hi) { | 930 | return; |
| 886 | list_for_each_entry(scsi_id, &hi->scsi_ids, scsi_list) | 931 | list_for_each_entry(scsi_id, &hi->scsi_ids, scsi_list) |
| 932 | if (likely(atomic_read(&scsi_id->state) != | ||
| 933 | SBP2LU_STATE_IN_SHUTDOWN)) { | ||
| 934 | atomic_set(&scsi_id->state, SBP2LU_STATE_IN_RESET); | ||
| 887 | scsi_block_requests(scsi_id->scsi_host); | 935 | scsi_block_requests(scsi_id->scsi_host); |
| 888 | } | 936 | } |
| 889 | } | 937 | } |
| 890 | 938 | ||
| 891 | /* | 939 | /* |
| @@ -970,8 +1018,7 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id) | |||
| 970 | * connected to the sbp2 device being removed. That host would | 1018 | * connected to the sbp2 device being removed. That host would |
| 971 | * have a certain amount of time to relogin before the sbp2 device | 1019 | * have a certain amount of time to relogin before the sbp2 device |
| 972 | * allows someone else to login instead. One second makes sense. */ | 1020 | * allows someone else to login instead. One second makes sense. */ |
| 973 | msleep_interruptible(1000); | 1021 | if (msleep_interruptible(1000)) { |
| 974 | if (signal_pending(current)) { | ||
| 975 | sbp2_remove_device(scsi_id); | 1022 | sbp2_remove_device(scsi_id); |
| 976 | return -EINTR; | 1023 | return -EINTR; |
| 977 | } | 1024 | } |
| @@ -1036,7 +1083,7 @@ static void sbp2_remove_device(struct scsi_id_instance_data *scsi_id) | |||
| 1036 | scsi_remove_host(scsi_id->scsi_host); | 1083 | scsi_remove_host(scsi_id->scsi_host); |
| 1037 | scsi_host_put(scsi_id->scsi_host); | 1084 | scsi_host_put(scsi_id->scsi_host); |
| 1038 | } | 1085 | } |
| 1039 | 1086 | flush_scheduled_work(); | |
| 1040 | sbp2util_remove_command_orb_pool(scsi_id); | 1087 | sbp2util_remove_command_orb_pool(scsi_id); |
| 1041 | 1088 | ||
| 1042 | list_del(&scsi_id->scsi_list); | 1089 | list_del(&scsi_id->scsi_list); |
| @@ -1182,17 +1229,14 @@ static int sbp2_query_logins(struct scsi_id_instance_data *scsi_id) | |||
| 1182 | "sbp2 query logins orb", scsi_id->query_logins_orb_dma); | 1229 | "sbp2 query logins orb", scsi_id->query_logins_orb_dma); |
| 1183 | 1230 | ||
| 1184 | memset(scsi_id->query_logins_response, 0, sizeof(struct sbp2_query_logins_response)); | 1231 | memset(scsi_id->query_logins_response, 0, sizeof(struct sbp2_query_logins_response)); |
| 1185 | memset(&scsi_id->status_block, 0, sizeof(struct sbp2_status_block)); | ||
| 1186 | 1232 | ||
| 1187 | data[0] = ORB_SET_NODE_ID(hi->host->node_id); | 1233 | data[0] = ORB_SET_NODE_ID(hi->host->node_id); |
| 1188 | data[1] = scsi_id->query_logins_orb_dma; | 1234 | data[1] = scsi_id->query_logins_orb_dma; |
| 1189 | sbp2util_cpu_to_be32_buffer(data, 8); | 1235 | sbp2util_cpu_to_be32_buffer(data, 8); |
| 1190 | 1236 | ||
| 1191 | atomic_set(&scsi_id->sbp2_login_complete, 0); | ||
| 1192 | |||
| 1193 | hpsb_node_write(scsi_id->ne, scsi_id->sbp2_management_agent_addr, data, 8); | 1237 | hpsb_node_write(scsi_id->ne, scsi_id->sbp2_management_agent_addr, data, 8); |
| 1194 | 1238 | ||
| 1195 | if (sbp2util_down_timeout(&scsi_id->sbp2_login_complete, 2*HZ)) { | 1239 | if (sbp2util_access_timeout(scsi_id, 2*HZ)) { |
| 1196 | SBP2_INFO("Error querying logins to SBP-2 device - timed out"); | 1240 | SBP2_INFO("Error querying logins to SBP-2 device - timed out"); |
| 1197 | return -EIO; | 1241 | return -EIO; |
| 1198 | } | 1242 | } |
| @@ -1202,11 +1246,8 @@ static int sbp2_query_logins(struct scsi_id_instance_data *scsi_id) | |||
| 1202 | return -EIO; | 1246 | return -EIO; |
| 1203 | } | 1247 | } |
| 1204 | 1248 | ||
| 1205 | if (STATUS_GET_RESP(scsi_id->status_block.ORB_offset_hi_misc) || | 1249 | if (STATUS_TEST_RDS(scsi_id->status_block.ORB_offset_hi_misc)) { |
| 1206 | STATUS_GET_DEAD_BIT(scsi_id->status_block.ORB_offset_hi_misc) || | 1250 | SBP2_INFO("Error querying logins to SBP-2 device - failed"); |
| 1207 | STATUS_GET_SBP_STATUS(scsi_id->status_block.ORB_offset_hi_misc)) { | ||
| 1208 | |||
| 1209 | SBP2_INFO("Error querying logins to SBP-2 device - timed out"); | ||
| 1210 | return -EIO; | 1251 | return -EIO; |
| 1211 | } | 1252 | } |
| 1212 | 1253 | ||
| @@ -1278,21 +1319,18 @@ static int sbp2_login_device(struct scsi_id_instance_data *scsi_id) | |||
| 1278 | "sbp2 login orb", scsi_id->login_orb_dma); | 1319 | "sbp2 login orb", scsi_id->login_orb_dma); |
| 1279 | 1320 | ||
| 1280 | memset(scsi_id->login_response, 0, sizeof(struct sbp2_login_response)); | 1321 | memset(scsi_id->login_response, 0, sizeof(struct sbp2_login_response)); |
| 1281 | memset(&scsi_id->status_block, 0, sizeof(struct sbp2_status_block)); | ||
| 1282 | 1322 | ||
| 1283 | data[0] = ORB_SET_NODE_ID(hi->host->node_id); | 1323 | data[0] = ORB_SET_NODE_ID(hi->host->node_id); |
| 1284 | data[1] = scsi_id->login_orb_dma; | 1324 | data[1] = scsi_id->login_orb_dma; |
| 1285 | sbp2util_cpu_to_be32_buffer(data, 8); | 1325 | sbp2util_cpu_to_be32_buffer(data, 8); |
| 1286 | 1326 | ||
| 1287 | atomic_set(&scsi_id->sbp2_login_complete, 0); | ||
| 1288 | |||
| 1289 | hpsb_node_write(scsi_id->ne, scsi_id->sbp2_management_agent_addr, data, 8); | 1327 | hpsb_node_write(scsi_id->ne, scsi_id->sbp2_management_agent_addr, data, 8); |
| 1290 | 1328 | ||
| 1291 | /* | 1329 | /* |
| 1292 | * Wait for login status (up to 20 seconds)... | 1330 | * Wait for login status (up to 20 seconds)... |
| 1293 | */ | 1331 | */ |
| 1294 | if (sbp2util_down_timeout(&scsi_id->sbp2_login_complete, 20*HZ)) { | 1332 | if (sbp2util_access_timeout(scsi_id, 20*HZ)) { |
| 1295 | SBP2_ERR("Error logging into SBP-2 device - login timed-out"); | 1333 | SBP2_ERR("Error logging into SBP-2 device - timed out"); |
| 1296 | return -EIO; | 1334 | return -EIO; |
| 1297 | } | 1335 | } |
| 1298 | 1336 | ||
| @@ -1300,18 +1338,12 @@ static int sbp2_login_device(struct scsi_id_instance_data *scsi_id) | |||
| 1300 | * Sanity. Make sure status returned matches login orb. | 1338 | * Sanity. Make sure status returned matches login orb. |
| 1301 | */ | 1339 | */ |
| 1302 | if (scsi_id->status_block.ORB_offset_lo != scsi_id->login_orb_dma) { | 1340 | if (scsi_id->status_block.ORB_offset_lo != scsi_id->login_orb_dma) { |
| 1303 | SBP2_ERR("Error logging into SBP-2 device - login timed-out"); | 1341 | SBP2_ERR("Error logging into SBP-2 device - timed out"); |
| 1304 | return -EIO; | 1342 | return -EIO; |
| 1305 | } | 1343 | } |
| 1306 | 1344 | ||
| 1307 | /* | 1345 | if (STATUS_TEST_RDS(scsi_id->status_block.ORB_offset_hi_misc)) { |
| 1308 | * Check status | 1346 | SBP2_ERR("Error logging into SBP-2 device - failed"); |
| 1309 | */ | ||
| 1310 | if (STATUS_GET_RESP(scsi_id->status_block.ORB_offset_hi_misc) || | ||
| 1311 | STATUS_GET_DEAD_BIT(scsi_id->status_block.ORB_offset_hi_misc) || | ||
| 1312 | STATUS_GET_SBP_STATUS(scsi_id->status_block.ORB_offset_hi_misc)) { | ||
| 1313 | |||
| 1314 | SBP2_ERR("Error logging into SBP-2 device - login failed"); | ||
| 1315 | return -EIO; | 1347 | return -EIO; |
| 1316 | } | 1348 | } |
| 1317 | 1349 | ||
| @@ -1335,9 +1367,7 @@ static int sbp2_login_device(struct scsi_id_instance_data *scsi_id) | |||
| 1335 | scsi_id->sbp2_command_block_agent_addr &= 0x0000ffffffffffffULL; | 1367 | scsi_id->sbp2_command_block_agent_addr &= 0x0000ffffffffffffULL; |
| 1336 | 1368 | ||
| 1337 | SBP2_INFO("Logged into SBP-2 device"); | 1369 | SBP2_INFO("Logged into SBP-2 device"); |
| 1338 | |||
| 1339 | return 0; | 1370 | return 0; |
| 1340 | |||
| 1341 | } | 1371 | } |
| 1342 | 1372 | ||
| 1343 | /* | 1373 | /* |
| @@ -1387,21 +1417,17 @@ static int sbp2_logout_device(struct scsi_id_instance_data *scsi_id) | |||
| 1387 | data[1] = scsi_id->logout_orb_dma; | 1417 | data[1] = scsi_id->logout_orb_dma; |
| 1388 | sbp2util_cpu_to_be32_buffer(data, 8); | 1418 | sbp2util_cpu_to_be32_buffer(data, 8); |
| 1389 | 1419 | ||
| 1390 | atomic_set(&scsi_id->sbp2_login_complete, 0); | ||
| 1391 | |||
| 1392 | error = hpsb_node_write(scsi_id->ne, | 1420 | error = hpsb_node_write(scsi_id->ne, |
| 1393 | scsi_id->sbp2_management_agent_addr, data, 8); | 1421 | scsi_id->sbp2_management_agent_addr, data, 8); |
| 1394 | if (error) | 1422 | if (error) |
| 1395 | return error; | 1423 | return error; |
| 1396 | 1424 | ||
| 1397 | /* Wait for device to logout...1 second. */ | 1425 | /* Wait for device to logout...1 second. */ |
| 1398 | if (sbp2util_down_timeout(&scsi_id->sbp2_login_complete, HZ)) | 1426 | if (sbp2util_access_timeout(scsi_id, HZ)) |
| 1399 | return -EIO; | 1427 | return -EIO; |
| 1400 | 1428 | ||
| 1401 | SBP2_INFO("Logged out of SBP-2 device"); | 1429 | SBP2_INFO("Logged out of SBP-2 device"); |
| 1402 | |||
| 1403 | return 0; | 1430 | return 0; |
| 1404 | |||
| 1405 | } | 1431 | } |
| 1406 | 1432 | ||
| 1407 | /* | 1433 | /* |
| @@ -1445,20 +1471,10 @@ static int sbp2_reconnect_device(struct scsi_id_instance_data *scsi_id) | |||
| 1445 | sbp2util_packet_dump(scsi_id->reconnect_orb, sizeof(struct sbp2_reconnect_orb), | 1471 | sbp2util_packet_dump(scsi_id->reconnect_orb, sizeof(struct sbp2_reconnect_orb), |
| 1446 | "sbp2 reconnect orb", scsi_id->reconnect_orb_dma); | 1472 | "sbp2 reconnect orb", scsi_id->reconnect_orb_dma); |
| 1447 | 1473 | ||
| 1448 | /* | ||
| 1449 | * Initialize status fifo | ||
| 1450 | */ | ||
| 1451 | memset(&scsi_id->status_block, 0, sizeof(struct sbp2_status_block)); | ||
| 1452 | |||
| 1453 | /* | ||
| 1454 | * Ok, let's write to the target's management agent register | ||
| 1455 | */ | ||
| 1456 | data[0] = ORB_SET_NODE_ID(hi->host->node_id); | 1474 | data[0] = ORB_SET_NODE_ID(hi->host->node_id); |
| 1457 | data[1] = scsi_id->reconnect_orb_dma; | 1475 | data[1] = scsi_id->reconnect_orb_dma; |
| 1458 | sbp2util_cpu_to_be32_buffer(data, 8); | 1476 | sbp2util_cpu_to_be32_buffer(data, 8); |
| 1459 | 1477 | ||
| 1460 | atomic_set(&scsi_id->sbp2_login_complete, 0); | ||
| 1461 | |||
| 1462 | error = hpsb_node_write(scsi_id->ne, | 1478 | error = hpsb_node_write(scsi_id->ne, |
| 1463 | scsi_id->sbp2_management_agent_addr, data, 8); | 1479 | scsi_id->sbp2_management_agent_addr, data, 8); |
| 1464 | if (error) | 1480 | if (error) |
| @@ -1467,8 +1483,8 @@ static int sbp2_reconnect_device(struct scsi_id_instance_data *scsi_id) | |||
| 1467 | /* | 1483 | /* |
| 1468 | * Wait for reconnect status (up to 1 second)... | 1484 | * Wait for reconnect status (up to 1 second)... |
| 1469 | */ | 1485 | */ |
| 1470 | if (sbp2util_down_timeout(&scsi_id->sbp2_login_complete, HZ)) { | 1486 | if (sbp2util_access_timeout(scsi_id, HZ)) { |
| 1471 | SBP2_ERR("Error reconnecting to SBP-2 device - reconnect timed-out"); | 1487 | SBP2_ERR("Error reconnecting to SBP-2 device - timed out"); |
| 1472 | return -EIO; | 1488 | return -EIO; |
| 1473 | } | 1489 | } |
| 1474 | 1490 | ||
| @@ -1476,25 +1492,17 @@ static int sbp2_reconnect_device(struct scsi_id_instance_data *scsi_id) | |||
| 1476 | * Sanity. Make sure status returned matches reconnect orb. | 1492 | * Sanity. Make sure status returned matches reconnect orb. |
| 1477 | */ | 1493 | */ |
| 1478 | if (scsi_id->status_block.ORB_offset_lo != scsi_id->reconnect_orb_dma) { | 1494 | if (scsi_id->status_block.ORB_offset_lo != scsi_id->reconnect_orb_dma) { |
| 1479 | SBP2_ERR("Error reconnecting to SBP-2 device - reconnect timed-out"); | 1495 | SBP2_ERR("Error reconnecting to SBP-2 device - timed out"); |
| 1480 | return -EIO; | 1496 | return -EIO; |
| 1481 | } | 1497 | } |
| 1482 | 1498 | ||
| 1483 | /* | 1499 | if (STATUS_TEST_RDS(scsi_id->status_block.ORB_offset_hi_misc)) { |
| 1484 | * Check status | 1500 | SBP2_ERR("Error reconnecting to SBP-2 device - failed"); |
| 1485 | */ | ||
| 1486 | if (STATUS_GET_RESP(scsi_id->status_block.ORB_offset_hi_misc) || | ||
| 1487 | STATUS_GET_DEAD_BIT(scsi_id->status_block.ORB_offset_hi_misc) || | ||
| 1488 | STATUS_GET_SBP_STATUS(scsi_id->status_block.ORB_offset_hi_misc)) { | ||
| 1489 | |||
| 1490 | SBP2_ERR("Error reconnecting to SBP-2 device - reconnect failed"); | ||
| 1491 | return -EIO; | 1501 | return -EIO; |
| 1492 | } | 1502 | } |
| 1493 | 1503 | ||
| 1494 | HPSB_DEBUG("Reconnected to SBP-2 device"); | 1504 | HPSB_DEBUG("Reconnected to SBP-2 device"); |
| 1495 | |||
| 1496 | return 0; | 1505 | return 0; |
| 1497 | |||
| 1498 | } | 1506 | } |
| 1499 | 1507 | ||
| 1500 | /* | 1508 | /* |
| @@ -1592,11 +1600,6 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id, | |||
| 1592 | } | 1600 | } |
| 1593 | 1601 | ||
| 1594 | workarounds = sbp2_default_workarounds; | 1602 | workarounds = sbp2_default_workarounds; |
| 1595 | if (force_inquiry_hack) { | ||
| 1596 | SBP2_WARN("force_inquiry_hack is deprecated. " | ||
| 1597 | "Use parameter 'workarounds' instead."); | ||
| 1598 | workarounds |= SBP2_WORKAROUND_INQUIRY_36; | ||
| 1599 | } | ||
| 1600 | 1603 | ||
| 1601 | if (!(workarounds & SBP2_WORKAROUND_OVERRIDE)) | 1604 | if (!(workarounds & SBP2_WORKAROUND_OVERRIDE)) |
| 1602 | for (i = 0; i < ARRAY_SIZE(sbp2_workarounds_table); i++) { | 1605 | for (i = 0; i < ARRAY_SIZE(sbp2_workarounds_table); i++) { |
| @@ -1705,9 +1708,14 @@ static int sbp2_agent_reset(struct scsi_id_instance_data *scsi_id, int wait) | |||
| 1705 | quadlet_t data; | 1708 | quadlet_t data; |
| 1706 | u64 addr; | 1709 | u64 addr; |
| 1707 | int retval; | 1710 | int retval; |
| 1711 | unsigned long flags; | ||
| 1708 | 1712 | ||
| 1709 | SBP2_DEBUG_ENTER(); | 1713 | SBP2_DEBUG_ENTER(); |
| 1710 | 1714 | ||
| 1715 | cancel_delayed_work(&scsi_id->protocol_work); | ||
| 1716 | if (wait) | ||
| 1717 | flush_scheduled_work(); | ||
| 1718 | |||
| 1711 | data = ntohl(SBP2_AGENT_RESET_DATA); | 1719 | data = ntohl(SBP2_AGENT_RESET_DATA); |
| 1712 | addr = scsi_id->sbp2_command_block_agent_addr + SBP2_AGENT_RESET_OFFSET; | 1720 | addr = scsi_id->sbp2_command_block_agent_addr + SBP2_AGENT_RESET_OFFSET; |
| 1713 | 1721 | ||
| @@ -1724,7 +1732,9 @@ static int sbp2_agent_reset(struct scsi_id_instance_data *scsi_id, int wait) | |||
| 1724 | /* | 1732 | /* |
| 1725 | * Need to make sure orb pointer is written on next command | 1733 | * Need to make sure orb pointer is written on next command |
| 1726 | */ | 1734 | */ |
| 1735 | spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags); | ||
| 1727 | scsi_id->last_orb = NULL; | 1736 | scsi_id->last_orb = NULL; |
| 1737 | spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); | ||
| 1728 | 1738 | ||
| 1729 | return 0; | 1739 | return 0; |
| 1730 | } | 1740 | } |
| @@ -1961,13 +1971,17 @@ static void sbp2_create_command_orb(struct scsi_id_instance_data *scsi_id, | |||
| 1961 | /* | 1971 | /* |
| 1962 | * This function is called in order to begin a regular SBP-2 command. | 1972 | * This function is called in order to begin a regular SBP-2 command. |
| 1963 | */ | 1973 | */ |
| 1964 | static int sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id, | 1974 | static void sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id, |
| 1965 | struct sbp2_command_info *command) | 1975 | struct sbp2_command_info *command) |
| 1966 | { | 1976 | { |
| 1967 | struct sbp2scsi_host_info *hi = scsi_id->hi; | 1977 | struct sbp2scsi_host_info *hi = scsi_id->hi; |
| 1968 | struct sbp2_command_orb *command_orb = &command->command_orb; | 1978 | struct sbp2_command_orb *command_orb = &command->command_orb; |
| 1969 | struct node_entry *ne = scsi_id->ne; | 1979 | struct sbp2_command_orb *last_orb; |
| 1970 | u64 addr; | 1980 | dma_addr_t last_orb_dma; |
| 1981 | u64 addr = scsi_id->sbp2_command_block_agent_addr; | ||
| 1982 | quadlet_t data[2]; | ||
| 1983 | size_t length; | ||
| 1984 | unsigned long flags; | ||
| 1971 | 1985 | ||
| 1972 | outstanding_orb_incr; | 1986 | outstanding_orb_incr; |
| 1973 | SBP2_ORB_DEBUG("sending command orb %p, total orbs = %x", | 1987 | SBP2_ORB_DEBUG("sending command orb %p, total orbs = %x", |
| @@ -1975,73 +1989,70 @@ static int sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id, | |||
| 1975 | 1989 | ||
| 1976 | pci_dma_sync_single_for_device(hi->host->pdev, command->command_orb_dma, | 1990 | pci_dma_sync_single_for_device(hi->host->pdev, command->command_orb_dma, |
| 1977 | sizeof(struct sbp2_command_orb), | 1991 | sizeof(struct sbp2_command_orb), |
| 1978 | PCI_DMA_BIDIRECTIONAL); | 1992 | PCI_DMA_TODEVICE); |
| 1979 | pci_dma_sync_single_for_device(hi->host->pdev, command->sge_dma, | 1993 | pci_dma_sync_single_for_device(hi->host->pdev, command->sge_dma, |
| 1980 | sizeof(command->scatter_gather_element), | 1994 | sizeof(command->scatter_gather_element), |
| 1981 | PCI_DMA_BIDIRECTIONAL); | 1995 | PCI_DMA_BIDIRECTIONAL); |
| 1982 | /* | 1996 | /* |
| 1983 | * Check to see if there are any previous orbs to use | 1997 | * Check to see if there are any previous orbs to use |
| 1984 | */ | 1998 | */ |
| 1985 | if (scsi_id->last_orb == NULL) { | 1999 | spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags); |
| 1986 | quadlet_t data[2]; | 2000 | last_orb = scsi_id->last_orb; |
| 1987 | 2001 | last_orb_dma = scsi_id->last_orb_dma; | |
| 2002 | if (!last_orb) { | ||
| 1988 | /* | 2003 | /* |
| 1989 | * Ok, let's write to the target's management agent register | 2004 | * last_orb == NULL means: We know that the target's fetch agent |
| 2005 | * is not active right now. | ||
| 1990 | */ | 2006 | */ |
| 1991 | addr = scsi_id->sbp2_command_block_agent_addr + SBP2_ORB_POINTER_OFFSET; | 2007 | addr += SBP2_ORB_POINTER_OFFSET; |
| 1992 | data[0] = ORB_SET_NODE_ID(hi->host->node_id); | 2008 | data[0] = ORB_SET_NODE_ID(hi->host->node_id); |
| 1993 | data[1] = command->command_orb_dma; | 2009 | data[1] = command->command_orb_dma; |
| 1994 | sbp2util_cpu_to_be32_buffer(data, 8); | 2010 | sbp2util_cpu_to_be32_buffer(data, 8); |
| 1995 | 2011 | length = 8; | |
| 1996 | SBP2_ORB_DEBUG("write command agent, command orb %p", command_orb); | ||
| 1997 | |||
| 1998 | if (sbp2util_node_write_no_wait(ne, addr, data, 8) < 0) { | ||
| 1999 | SBP2_ERR("sbp2util_node_write_no_wait failed.\n"); | ||
| 2000 | return -EIO; | ||
| 2001 | } | ||
| 2002 | |||
| 2003 | SBP2_ORB_DEBUG("write command agent complete"); | ||
| 2004 | |||
| 2005 | scsi_id->last_orb = command_orb; | ||
| 2006 | scsi_id->last_orb_dma = command->command_orb_dma; | ||
| 2007 | |||
| 2008 | } else { | 2012 | } else { |
| 2009 | quadlet_t data; | ||
| 2010 | |||
| 2011 | /* | 2013 | /* |
| 2012 | * We have an orb already sent (maybe or maybe not | 2014 | * last_orb != NULL means: We know that the target's fetch agent |
| 2013 | * processed) that we can append this orb to. So do so, | 2015 | * is (very probably) not dead or in reset state right now. |
| 2014 | * and ring the doorbell. Have to be very careful | 2016 | * We have an ORB already sent that we can append a new one to. |
| 2015 | * modifying these next orb pointers, as they are accessed | 2017 | * The target's fetch agent may or may not have read this |
| 2016 | * both by the sbp2 device and us. | 2018 | * previous ORB yet. |
| 2017 | */ | 2019 | */ |
| 2018 | scsi_id->last_orb->next_ORB_lo = | 2020 | pci_dma_sync_single_for_cpu(hi->host->pdev, last_orb_dma, |
| 2019 | cpu_to_be32(command->command_orb_dma); | 2021 | sizeof(struct sbp2_command_orb), |
| 2022 | PCI_DMA_TODEVICE); | ||
| 2023 | last_orb->next_ORB_lo = cpu_to_be32(command->command_orb_dma); | ||
| 2024 | wmb(); | ||
| 2020 | /* Tells hardware that this pointer is valid */ | 2025 | /* Tells hardware that this pointer is valid */ |
| 2021 | scsi_id->last_orb->next_ORB_hi = 0x0; | 2026 | last_orb->next_ORB_hi = 0; |
| 2022 | pci_dma_sync_single_for_device(hi->host->pdev, | 2027 | pci_dma_sync_single_for_device(hi->host->pdev, last_orb_dma, |
| 2023 | scsi_id->last_orb_dma, | ||
| 2024 | sizeof(struct sbp2_command_orb), | 2028 | sizeof(struct sbp2_command_orb), |
| 2025 | PCI_DMA_BIDIRECTIONAL); | 2029 | PCI_DMA_TODEVICE); |
| 2030 | addr += SBP2_DOORBELL_OFFSET; | ||
| 2031 | data[0] = 0; | ||
| 2032 | length = 4; | ||
| 2033 | } | ||
| 2034 | scsi_id->last_orb = command_orb; | ||
| 2035 | scsi_id->last_orb_dma = command->command_orb_dma; | ||
| 2036 | spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); | ||
| 2026 | 2037 | ||
| 2038 | SBP2_ORB_DEBUG("write to %s register, command orb %p", | ||
| 2039 | last_orb ? "DOORBELL" : "ORB_POINTER", command_orb); | ||
| 2040 | if (sbp2util_node_write_no_wait(scsi_id->ne, addr, data, length)) { | ||
| 2027 | /* | 2041 | /* |
| 2028 | * Ring the doorbell | 2042 | * sbp2util_node_write_no_wait failed. We certainly ran out |
| 2043 | * of transaction labels, perhaps just because there were no | ||
| 2044 | * context switches which gave khpsbpkt a chance to collect | ||
| 2045 | * free tlabels. Try again in non-atomic context. If necessary, | ||
| 2046 | * the workqueue job will sleep to guaranteedly get a tlabel. | ||
| 2047 | * We do not accept new commands until the job is over. | ||
| 2029 | */ | 2048 | */ |
| 2030 | data = cpu_to_be32(command->command_orb_dma); | 2049 | scsi_block_requests(scsi_id->scsi_host); |
| 2031 | addr = scsi_id->sbp2_command_block_agent_addr + SBP2_DOORBELL_OFFSET; | 2050 | PREPARE_WORK(&scsi_id->protocol_work, |
| 2032 | 2051 | last_orb ? sbp2util_write_doorbell: | |
| 2033 | SBP2_ORB_DEBUG("ring doorbell, command orb %p", command_orb); | 2052 | sbp2util_write_orb_pointer, |
| 2034 | 2053 | scsi_id); | |
| 2035 | if (sbp2util_node_write_no_wait(ne, addr, &data, 4) < 0) { | 2054 | schedule_work(&scsi_id->protocol_work); |
| 2036 | SBP2_ERR("sbp2util_node_write_no_wait failed"); | ||
| 2037 | return -EIO; | ||
| 2038 | } | ||
| 2039 | |||
| 2040 | scsi_id->last_orb = command_orb; | ||
| 2041 | scsi_id->last_orb_dma = command->command_orb_dma; | ||
| 2042 | |||
| 2043 | } | 2055 | } |
| 2044 | return 0; | ||
| 2045 | } | 2056 | } |
| 2046 | 2057 | ||
| 2047 | /* | 2058 | /* |
| @@ -2078,11 +2089,6 @@ static int sbp2_send_command(struct scsi_id_instance_data *scsi_id, | |||
| 2078 | "sbp2 command orb", command->command_orb_dma); | 2089 | "sbp2 command orb", command->command_orb_dma); |
| 2079 | 2090 | ||
| 2080 | /* | 2091 | /* |
| 2081 | * Initialize status fifo | ||
| 2082 | */ | ||
| 2083 | memset(&scsi_id->status_block, 0, sizeof(struct sbp2_status_block)); | ||
| 2084 | |||
| 2085 | /* | ||
| 2086 | * Link up the orb, and ring the doorbell if needed | 2092 | * Link up the orb, and ring the doorbell if needed |
| 2087 | */ | 2093 | */ |
| 2088 | sbp2_link_orb_command(scsi_id, command); | 2094 | sbp2_link_orb_command(scsi_id, command); |
| @@ -2123,12 +2129,14 @@ static unsigned int sbp2_status_to_sense_data(unchar *sbp2_status, unchar *sense | |||
| 2123 | /* | 2129 | /* |
| 2124 | * This function deals with status writes from the SBP-2 device | 2130 | * This function deals with status writes from the SBP-2 device |
| 2125 | */ | 2131 | */ |
| 2126 | static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int destid, | 2132 | static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, |
| 2127 | quadlet_t *data, u64 addr, size_t length, u16 fl) | 2133 | int destid, quadlet_t *data, u64 addr, |
| 2134 | size_t length, u16 fl) | ||
| 2128 | { | 2135 | { |
| 2129 | struct sbp2scsi_host_info *hi; | 2136 | struct sbp2scsi_host_info *hi; |
| 2130 | struct scsi_id_instance_data *scsi_id = NULL, *scsi_id_tmp; | 2137 | struct scsi_id_instance_data *scsi_id = NULL, *scsi_id_tmp; |
| 2131 | struct scsi_cmnd *SCpnt = NULL; | 2138 | struct scsi_cmnd *SCpnt = NULL; |
| 2139 | struct sbp2_status_block *sb; | ||
| 2132 | u32 scsi_status = SBP2_SCSI_STATUS_GOOD; | 2140 | u32 scsi_status = SBP2_SCSI_STATUS_GOOD; |
| 2133 | struct sbp2_command_info *command; | 2141 | struct sbp2_command_info *command; |
| 2134 | unsigned long flags; | 2142 | unsigned long flags; |
| @@ -2137,18 +2145,19 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest | |||
| 2137 | 2145 | ||
| 2138 | sbp2util_packet_dump(data, length, "sbp2 status write by device", (u32)addr); | 2146 | sbp2util_packet_dump(data, length, "sbp2 status write by device", (u32)addr); |
| 2139 | 2147 | ||
| 2140 | if (!host) { | 2148 | if (unlikely(length < 8 || length > sizeof(struct sbp2_status_block))) { |
| 2149 | SBP2_ERR("Wrong size of status block"); | ||
| 2150 | return RCODE_ADDRESS_ERROR; | ||
| 2151 | } | ||
| 2152 | if (unlikely(!host)) { | ||
| 2141 | SBP2_ERR("host is NULL - this is bad!"); | 2153 | SBP2_ERR("host is NULL - this is bad!"); |
| 2142 | return RCODE_ADDRESS_ERROR; | 2154 | return RCODE_ADDRESS_ERROR; |
| 2143 | } | 2155 | } |
| 2144 | |||
| 2145 | hi = hpsb_get_hostinfo(&sbp2_highlevel, host); | 2156 | hi = hpsb_get_hostinfo(&sbp2_highlevel, host); |
| 2146 | 2157 | if (unlikely(!hi)) { | |
| 2147 | if (!hi) { | ||
| 2148 | SBP2_ERR("host info is NULL - this is bad!"); | 2158 | SBP2_ERR("host info is NULL - this is bad!"); |
| 2149 | return RCODE_ADDRESS_ERROR; | 2159 | return RCODE_ADDRESS_ERROR; |
| 2150 | } | 2160 | } |
| 2151 | |||
| 2152 | /* | 2161 | /* |
| 2153 | * Find our scsi_id structure by looking at the status fifo address | 2162 | * Find our scsi_id structure by looking at the status fifo address |
| 2154 | * written to by the sbp2 device. | 2163 | * written to by the sbp2 device. |
| @@ -2160,32 +2169,35 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest | |||
| 2160 | break; | 2169 | break; |
| 2161 | } | 2170 | } |
| 2162 | } | 2171 | } |
| 2163 | 2172 | if (unlikely(!scsi_id)) { | |
| 2164 | if (!scsi_id) { | ||
| 2165 | SBP2_ERR("scsi_id is NULL - device is gone?"); | 2173 | SBP2_ERR("scsi_id is NULL - device is gone?"); |
| 2166 | return RCODE_ADDRESS_ERROR; | 2174 | return RCODE_ADDRESS_ERROR; |
| 2167 | } | 2175 | } |
| 2168 | 2176 | ||
| 2169 | /* | 2177 | /* |
| 2170 | * Put response into scsi_id status fifo... | 2178 | * Put response into scsi_id status fifo buffer. The first two bytes |
| 2179 | * come in big endian bit order. Often the target writes only a | ||
| 2180 | * truncated status block, minimally the first two quadlets. The rest | ||
| 2181 | * is implied to be zeros. | ||
| 2171 | */ | 2182 | */ |
| 2172 | memcpy(&scsi_id->status_block, data, length); | 2183 | sb = &scsi_id->status_block; |
| 2184 | memset(sb->command_set_dependent, 0, sizeof(sb->command_set_dependent)); | ||
| 2185 | memcpy(sb, data, length); | ||
| 2186 | sbp2util_be32_to_cpu_buffer(sb, 8); | ||
| 2173 | 2187 | ||
| 2174 | /* | 2188 | /* |
| 2175 | * Byte swap first two quadlets (8 bytes) of status for processing | 2189 | * Ignore unsolicited status. Handle command ORB status. |
| 2176 | */ | 2190 | */ |
| 2177 | sbp2util_be32_to_cpu_buffer(&scsi_id->status_block, 8); | 2191 | if (unlikely(STATUS_GET_SRC(sb->ORB_offset_hi_misc) == 2)) |
| 2178 | 2192 | command = NULL; | |
| 2179 | /* | 2193 | else |
| 2180 | * Handle command ORB status here if necessary. First, need to match status with command. | 2194 | command = sbp2util_find_command_for_orb(scsi_id, |
| 2181 | */ | 2195 | sb->ORB_offset_lo); |
| 2182 | command = sbp2util_find_command_for_orb(scsi_id, scsi_id->status_block.ORB_offset_lo); | ||
| 2183 | if (command) { | 2196 | if (command) { |
| 2184 | |||
| 2185 | SBP2_DEBUG("Found status for command ORB"); | 2197 | SBP2_DEBUG("Found status for command ORB"); |
| 2186 | pci_dma_sync_single_for_cpu(hi->host->pdev, command->command_orb_dma, | 2198 | pci_dma_sync_single_for_cpu(hi->host->pdev, command->command_orb_dma, |
| 2187 | sizeof(struct sbp2_command_orb), | 2199 | sizeof(struct sbp2_command_orb), |
| 2188 | PCI_DMA_BIDIRECTIONAL); | 2200 | PCI_DMA_TODEVICE); |
| 2189 | pci_dma_sync_single_for_cpu(hi->host->pdev, command->sge_dma, | 2201 | pci_dma_sync_single_for_cpu(hi->host->pdev, command->sge_dma, |
| 2190 | sizeof(command->scatter_gather_element), | 2202 | sizeof(command->scatter_gather_element), |
| 2191 | PCI_DMA_BIDIRECTIONAL); | 2203 | PCI_DMA_BIDIRECTIONAL); |
| @@ -2194,7 +2206,12 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest | |||
| 2194 | outstanding_orb_decr; | 2206 | outstanding_orb_decr; |
| 2195 | 2207 | ||
| 2196 | /* | 2208 | /* |
| 2197 | * Matched status with command, now grab scsi command pointers and check status | 2209 | * Matched status with command, now grab scsi command pointers |
| 2210 | * and check status. | ||
| 2211 | */ | ||
| 2212 | /* | ||
| 2213 | * FIXME: If the src field in the status is 1, the ORB DMA must | ||
| 2214 | * not be reused until status for a subsequent ORB is received. | ||
| 2198 | */ | 2215 | */ |
| 2199 | SCpnt = command->Current_SCpnt; | 2216 | SCpnt = command->Current_SCpnt; |
| 2200 | spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags); | 2217 | spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags); |
| @@ -2202,61 +2219,64 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest | |||
| 2202 | spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); | 2219 | spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); |
| 2203 | 2220 | ||
| 2204 | if (SCpnt) { | 2221 | if (SCpnt) { |
| 2205 | 2222 | u32 h = sb->ORB_offset_hi_misc; | |
| 2223 | u32 r = STATUS_GET_RESP(h); | ||
| 2224 | |||
| 2225 | if (r != RESP_STATUS_REQUEST_COMPLETE) { | ||
| 2226 | SBP2_WARN("resp 0x%x, sbp_status 0x%x", | ||
| 2227 | r, STATUS_GET_SBP_STATUS(h)); | ||
| 2228 | scsi_status = | ||
| 2229 | r == RESP_STATUS_TRANSPORT_FAILURE ? | ||
| 2230 | SBP2_SCSI_STATUS_BUSY : | ||
| 2231 | SBP2_SCSI_STATUS_COMMAND_TERMINATED; | ||
| 2232 | } | ||
| 2206 | /* | 2233 | /* |
| 2207 | * See if the target stored any scsi status information | 2234 | * See if the target stored any scsi status information. |
| 2208 | */ | 2235 | */ |
| 2209 | if (STATUS_GET_LENGTH(scsi_id->status_block.ORB_offset_hi_misc) > 1) { | 2236 | if (STATUS_GET_LEN(h) > 1) { |
| 2210 | /* | ||
| 2211 | * Translate SBP-2 status to SCSI sense data | ||
| 2212 | */ | ||
| 2213 | SBP2_DEBUG("CHECK CONDITION"); | 2237 | SBP2_DEBUG("CHECK CONDITION"); |
| 2214 | scsi_status = sbp2_status_to_sense_data((unchar *)&scsi_id->status_block, SCpnt->sense_buffer); | 2238 | scsi_status = sbp2_status_to_sense_data( |
| 2239 | (unchar *)sb, SCpnt->sense_buffer); | ||
| 2215 | } | 2240 | } |
| 2216 | |||
| 2217 | /* | 2241 | /* |
| 2218 | * Check to see if the dead bit is set. If so, we'll have to initiate | 2242 | * Check to see if the dead bit is set. If so, we'll |
| 2219 | * a fetch agent reset. | 2243 | * have to initiate a fetch agent reset. |
| 2220 | */ | 2244 | */ |
| 2221 | if (STATUS_GET_DEAD_BIT(scsi_id->status_block.ORB_offset_hi_misc)) { | 2245 | if (STATUS_TEST_DEAD(h)) { |
| 2222 | 2246 | SBP2_DEBUG("Dead bit set - " | |
| 2223 | /* | 2247 | "initiating fetch agent reset"); |
| 2224 | * Initiate a fetch agent reset. | ||
| 2225 | */ | ||
| 2226 | SBP2_DEBUG("Dead bit set - initiating fetch agent reset"); | ||
| 2227 | sbp2_agent_reset(scsi_id, 0); | 2248 | sbp2_agent_reset(scsi_id, 0); |
| 2228 | } | 2249 | } |
| 2229 | |||
| 2230 | SBP2_ORB_DEBUG("completing command orb %p", &command->command_orb); | 2250 | SBP2_ORB_DEBUG("completing command orb %p", &command->command_orb); |
| 2231 | } | 2251 | } |
| 2232 | 2252 | ||
| 2233 | /* | 2253 | /* |
| 2234 | * Check here to see if there are no commands in-use. If there are none, we can | 2254 | * Check here to see if there are no commands in-use. If there |
| 2235 | * null out last orb so that next time around we write directly to the orb pointer... | 2255 | * are none, we know that the fetch agent left the active state |
| 2236 | * Quick start saves one 1394 bus transaction. | 2256 | * _and_ that we did not reactivate it yet. Therefore clear |
| 2257 | * last_orb so that next time we write directly to the | ||
| 2258 | * ORB_POINTER register. That way the fetch agent does not need | ||
| 2259 | * to refetch the next_ORB. | ||
| 2237 | */ | 2260 | */ |
| 2238 | spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags); | 2261 | spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags); |
| 2239 | if (list_empty(&scsi_id->sbp2_command_orb_inuse)) { | 2262 | if (list_empty(&scsi_id->sbp2_command_orb_inuse)) |
| 2240 | scsi_id->last_orb = NULL; | 2263 | scsi_id->last_orb = NULL; |
| 2241 | } | ||
| 2242 | spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); | 2264 | spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); |
| 2243 | 2265 | ||
| 2244 | } else { | 2266 | } else { |
| 2245 | |||
| 2246 | /* | 2267 | /* |
| 2247 | * It's probably a login/logout/reconnect status. | 2268 | * It's probably a login/logout/reconnect status. |
| 2248 | */ | 2269 | */ |
| 2249 | if ((scsi_id->login_orb_dma == scsi_id->status_block.ORB_offset_lo) || | 2270 | if ((sb->ORB_offset_lo == scsi_id->reconnect_orb_dma) || |
| 2250 | (scsi_id->query_logins_orb_dma == scsi_id->status_block.ORB_offset_lo) || | 2271 | (sb->ORB_offset_lo == scsi_id->login_orb_dma) || |
| 2251 | (scsi_id->reconnect_orb_dma == scsi_id->status_block.ORB_offset_lo) || | 2272 | (sb->ORB_offset_lo == scsi_id->query_logins_orb_dma) || |
| 2252 | (scsi_id->logout_orb_dma == scsi_id->status_block.ORB_offset_lo)) { | 2273 | (sb->ORB_offset_lo == scsi_id->logout_orb_dma)) { |
| 2253 | atomic_set(&scsi_id->sbp2_login_complete, 1); | 2274 | scsi_id->access_complete = 1; |
| 2275 | wake_up_interruptible(&access_wq); | ||
| 2254 | } | 2276 | } |
| 2255 | } | 2277 | } |
| 2256 | 2278 | ||
| 2257 | if (SCpnt) { | 2279 | if (SCpnt) { |
| 2258 | |||
| 2259 | /* Complete the SCSI command. */ | ||
| 2260 | SBP2_DEBUG("Completing SCSI command"); | 2280 | SBP2_DEBUG("Completing SCSI command"); |
| 2261 | sbp2scsi_complete_command(scsi_id, scsi_status, SCpnt, | 2281 | sbp2scsi_complete_command(scsi_id, scsi_status, SCpnt, |
| 2262 | command->Current_done); | 2282 | command->Current_done); |
| @@ -2372,7 +2392,7 @@ static void sbp2scsi_complete_all_commands(struct scsi_id_instance_data *scsi_id | |||
| 2372 | command = list_entry(lh, struct sbp2_command_info, list); | 2392 | command = list_entry(lh, struct sbp2_command_info, list); |
| 2373 | pci_dma_sync_single_for_cpu(hi->host->pdev, command->command_orb_dma, | 2393 | pci_dma_sync_single_for_cpu(hi->host->pdev, command->command_orb_dma, |
| 2374 | sizeof(struct sbp2_command_orb), | 2394 | sizeof(struct sbp2_command_orb), |
| 2375 | PCI_DMA_BIDIRECTIONAL); | 2395 | PCI_DMA_TODEVICE); |
| 2376 | pci_dma_sync_single_for_cpu(hi->host->pdev, command->sge_dma, | 2396 | pci_dma_sync_single_for_cpu(hi->host->pdev, command->sge_dma, |
| 2377 | sizeof(command->scatter_gather_element), | 2397 | sizeof(command->scatter_gather_element), |
| 2378 | PCI_DMA_BIDIRECTIONAL); | 2398 | PCI_DMA_BIDIRECTIONAL); |
| @@ -2495,6 +2515,7 @@ static int sbp2scsi_slave_alloc(struct scsi_device *sdev) | |||
| 2495 | (struct scsi_id_instance_data *)sdev->host->hostdata[0]; | 2515 | (struct scsi_id_instance_data *)sdev->host->hostdata[0]; |
| 2496 | 2516 | ||
| 2497 | scsi_id->sdev = sdev; | 2517 | scsi_id->sdev = sdev; |
| 2518 | sdev->allow_restart = 1; | ||
| 2498 | 2519 | ||
| 2499 | if (scsi_id->workarounds & SBP2_WORKAROUND_INQUIRY_36) | 2520 | if (scsi_id->workarounds & SBP2_WORKAROUND_INQUIRY_36) |
| 2500 | sdev->inquiry_len = 36; | 2521 | sdev->inquiry_len = 36; |
| @@ -2508,16 +2529,12 @@ static int sbp2scsi_slave_configure(struct scsi_device *sdev) | |||
| 2508 | 2529 | ||
| 2509 | blk_queue_dma_alignment(sdev->request_queue, (512 - 1)); | 2530 | blk_queue_dma_alignment(sdev->request_queue, (512 - 1)); |
| 2510 | sdev->use_10_for_rw = 1; | 2531 | sdev->use_10_for_rw = 1; |
| 2511 | sdev->use_10_for_ms = 1; | ||
| 2512 | 2532 | ||
| 2513 | if (sdev->type == TYPE_DISK && | 2533 | if (sdev->type == TYPE_DISK && |
| 2514 | scsi_id->workarounds & SBP2_WORKAROUND_MODE_SENSE_8) | 2534 | scsi_id->workarounds & SBP2_WORKAROUND_MODE_SENSE_8) |
| 2515 | sdev->skip_ms_page_8 = 1; | 2535 | sdev->skip_ms_page_8 = 1; |
| 2516 | if (scsi_id->workarounds & SBP2_WORKAROUND_FIX_CAPACITY) | 2536 | if (scsi_id->workarounds & SBP2_WORKAROUND_FIX_CAPACITY) |
| 2517 | sdev->fix_capacity = 1; | 2537 | sdev->fix_capacity = 1; |
| 2518 | if (scsi_id->ne->guid_vendor_id == 0x0010b9 && /* Maxtor's OUI */ | ||
| 2519 | (sdev->type == TYPE_DISK || sdev->type == TYPE_RBC)) | ||
| 2520 | sdev->allow_restart = 1; | ||
| 2521 | return 0; | 2538 | return 0; |
| 2522 | } | 2539 | } |
| 2523 | 2540 | ||
| @@ -2555,7 +2572,7 @@ static int sbp2scsi_abort(struct scsi_cmnd *SCpnt) | |||
| 2555 | pci_dma_sync_single_for_cpu(hi->host->pdev, | 2572 | pci_dma_sync_single_for_cpu(hi->host->pdev, |
| 2556 | command->command_orb_dma, | 2573 | command->command_orb_dma, |
| 2557 | sizeof(struct sbp2_command_orb), | 2574 | sizeof(struct sbp2_command_orb), |
| 2558 | PCI_DMA_BIDIRECTIONAL); | 2575 | PCI_DMA_TODEVICE); |
| 2559 | pci_dma_sync_single_for_cpu(hi->host->pdev, | 2576 | pci_dma_sync_single_for_cpu(hi->host->pdev, |
| 2560 | command->sge_dma, | 2577 | command->sge_dma, |
| 2561 | sizeof(command->scatter_gather_element), | 2578 | sizeof(command->scatter_gather_element), |
| @@ -2571,7 +2588,7 @@ static int sbp2scsi_abort(struct scsi_cmnd *SCpnt) | |||
| 2571 | /* | 2588 | /* |
| 2572 | * Initiate a fetch agent reset. | 2589 | * Initiate a fetch agent reset. |
| 2573 | */ | 2590 | */ |
| 2574 | sbp2_agent_reset(scsi_id, 0); | 2591 | sbp2_agent_reset(scsi_id, 1); |
| 2575 | sbp2scsi_complete_all_commands(scsi_id, DID_BUS_BUSY); | 2592 | sbp2scsi_complete_all_commands(scsi_id, DID_BUS_BUSY); |
| 2576 | } | 2593 | } |
| 2577 | 2594 | ||
| @@ -2590,7 +2607,7 @@ static int sbp2scsi_reset(struct scsi_cmnd *SCpnt) | |||
| 2590 | 2607 | ||
| 2591 | if (sbp2util_node_is_available(scsi_id)) { | 2608 | if (sbp2util_node_is_available(scsi_id)) { |
| 2592 | SBP2_ERR("Generating sbp2 fetch agent reset"); | 2609 | SBP2_ERR("Generating sbp2 fetch agent reset"); |
| 2593 | sbp2_agent_reset(scsi_id, 0); | 2610 | sbp2_agent_reset(scsi_id, 1); |
| 2594 | } | 2611 | } |
| 2595 | 2612 | ||
| 2596 | return SUCCESS; | 2613 | return SUCCESS; |
