diff options
Diffstat (limited to 'drivers/pci/hotplug/shpchp_hpc.c')
-rw-r--r-- | drivers/pci/hotplug/shpchp_hpc.c | 518 |
1 files changed, 189 insertions, 329 deletions
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index b4226ff3a854..66123cf4deaa 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c | |||
@@ -82,31 +82,6 @@ | |||
82 | #define SLOT_100MHZ_PCIX_533 0x0f000000 | 82 | #define SLOT_100MHZ_PCIX_533 0x0f000000 |
83 | #define SLOT_133MHZ_PCIX_533 0xf0000000 | 83 | #define SLOT_133MHZ_PCIX_533 0xf0000000 |
84 | 84 | ||
85 | |||
86 | /* Secondary Bus Configuration Register */ | ||
87 | /* For PI = 1, Bits 0 to 2 have been encoded as follows to show current bus speed/mode */ | ||
88 | #define PCI_33MHZ 0x0 | ||
89 | #define PCI_66MHZ 0x1 | ||
90 | #define PCIX_66MHZ 0x2 | ||
91 | #define PCIX_100MHZ 0x3 | ||
92 | #define PCIX_133MHZ 0x4 | ||
93 | |||
94 | /* For PI = 2, Bits 0 to 3 have been encoded as follows to show current bus speed/mode */ | ||
95 | #define PCI_33MHZ 0x0 | ||
96 | #define PCI_66MHZ 0x1 | ||
97 | #define PCIX_66MHZ 0x2 | ||
98 | #define PCIX_100MHZ 0x3 | ||
99 | #define PCIX_133MHZ 0x4 | ||
100 | #define PCIX_66MHZ_ECC 0x5 | ||
101 | #define PCIX_100MHZ_ECC 0x6 | ||
102 | #define PCIX_133MHZ_ECC 0x7 | ||
103 | #define PCIX_66MHZ_266 0x9 | ||
104 | #define PCIX_100MHZ_266 0xa | ||
105 | #define PCIX_133MHZ_266 0xb | ||
106 | #define PCIX_66MHZ_533 0x11 | ||
107 | #define PCIX_100MHZ_533 0x12 | ||
108 | #define PCIX_133MHZ_533 0x13 | ||
109 | |||
110 | /* Slot Configuration */ | 85 | /* Slot Configuration */ |
111 | #define SLOT_NUM 0x0000001F | 86 | #define SLOT_NUM 0x0000001F |
112 | #define FIRST_DEV_NUM 0x00001F00 | 87 | #define FIRST_DEV_NUM 0x00001F00 |
@@ -231,6 +206,7 @@ static spinlock_t list_lock; | |||
231 | static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs); | 206 | static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs); |
232 | 207 | ||
233 | static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds); | 208 | static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds); |
209 | static int hpc_check_cmd_status(struct controller *ctrl); | ||
234 | 210 | ||
235 | /* This is the interrupt polling timeout function. */ | 211 | /* This is the interrupt polling timeout function. */ |
236 | static void int_poll_timeout(unsigned long lphp_ctlr) | 212 | static void int_poll_timeout(unsigned long lphp_ctlr) |
@@ -303,10 +279,13 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) | |||
303 | int i; | 279 | int i; |
304 | 280 | ||
305 | DBG_ENTER_ROUTINE | 281 | DBG_ENTER_ROUTINE |
306 | 282 | ||
283 | mutex_lock(&slot->ctrl->cmd_lock); | ||
284 | |||
307 | if (!php_ctlr) { | 285 | if (!php_ctlr) { |
308 | err("%s: Invalid HPC controller handle!\n", __FUNCTION__); | 286 | err("%s: Invalid HPC controller handle!\n", __FUNCTION__); |
309 | return -1; | 287 | retval = -EINVAL; |
288 | goto out; | ||
310 | } | 289 | } |
311 | 290 | ||
312 | for (i = 0; i < 10; i++) { | 291 | for (i = 0; i < 10; i++) { |
@@ -323,7 +302,8 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) | |||
323 | if (cmd_status & 0x1) { | 302 | if (cmd_status & 0x1) { |
324 | /* After 1 sec and and the controller is still busy */ | 303 | /* After 1 sec and and the controller is still busy */ |
325 | err("%s : Controller is still busy after 1 sec.\n", __FUNCTION__); | 304 | err("%s : Controller is still busy after 1 sec.\n", __FUNCTION__); |
326 | return -1; | 305 | retval = -EBUSY; |
306 | goto out; | ||
327 | } | 307 | } |
328 | 308 | ||
329 | ++t_slot; | 309 | ++t_slot; |
@@ -340,6 +320,17 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) | |||
340 | * Wait for command completion. | 320 | * Wait for command completion. |
341 | */ | 321 | */ |
342 | retval = shpc_wait_cmd(slot->ctrl); | 322 | retval = shpc_wait_cmd(slot->ctrl); |
323 | if (retval) | ||
324 | goto out; | ||
325 | |||
326 | cmd_status = hpc_check_cmd_status(slot->ctrl); | ||
327 | if (cmd_status) { | ||
328 | err("%s: Failed to issued command 0x%x (error code = %d)\n", | ||
329 | __FUNCTION__, cmd, cmd_status); | ||
330 | retval = -EIO; | ||
331 | } | ||
332 | out: | ||
333 | mutex_unlock(&slot->ctrl->cmd_lock); | ||
343 | 334 | ||
344 | DBG_LEAVE_ROUTINE | 335 | DBG_LEAVE_ROUTINE |
345 | return retval; | 336 | return retval; |
@@ -532,81 +523,41 @@ static int hpc_get_prog_int(struct slot *slot, u8 *prog_int) | |||
532 | 523 | ||
533 | static int hpc_get_adapter_speed(struct slot *slot, enum pci_bus_speed *value) | 524 | static int hpc_get_adapter_speed(struct slot *slot, enum pci_bus_speed *value) |
534 | { | 525 | { |
535 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; | ||
536 | u32 slot_reg; | ||
537 | u16 slot_status, sec_bus_status; | ||
538 | u8 m66_cap, pcix_cap, pi; | ||
539 | int retval = 0; | 526 | int retval = 0; |
527 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; | ||
528 | u32 slot_reg = readl(php_ctlr->creg + SLOT1 + 4 * slot->hp_slot); | ||
529 | u8 pcix_cap = (slot_reg >> 12) & 7; | ||
530 | u8 m66_cap = (slot_reg >> 9) & 1; | ||
540 | 531 | ||
541 | DBG_ENTER_ROUTINE | 532 | DBG_ENTER_ROUTINE |
542 | 533 | ||
543 | if (!slot->ctrl->hpc_ctlr_handle) { | 534 | dbg("%s: slot_reg = %x, pcix_cap = %x, m66_cap = %x\n", |
544 | err("%s: Invalid HPC controller handle!\n", __FUNCTION__); | 535 | __FUNCTION__, slot_reg, pcix_cap, m66_cap); |
545 | return -1; | ||
546 | } | ||
547 | |||
548 | if (slot->hp_slot >= php_ctlr->num_slots) { | ||
549 | err("%s: Invalid HPC slot number!\n", __FUNCTION__); | ||
550 | return -1; | ||
551 | } | ||
552 | |||
553 | pi = readb(php_ctlr->creg + PROG_INTERFACE); | ||
554 | slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot)); | ||
555 | dbg("%s: pi = %d, slot_reg = %x\n", __FUNCTION__, pi, slot_reg); | ||
556 | slot_status = (u16) slot_reg; | ||
557 | dbg("%s: slot_status = %x\n", __FUNCTION__, slot_status); | ||
558 | sec_bus_status = readw(php_ctlr->creg + SEC_BUS_CONFIG); | ||
559 | |||
560 | pcix_cap = (u8) ((slot_status & 0x3000) >> 12); | ||
561 | dbg("%s: pcix_cap = %x\n", __FUNCTION__, pcix_cap); | ||
562 | m66_cap = (u8) ((slot_status & 0x0200) >> 9); | ||
563 | dbg("%s: m66_cap = %x\n", __FUNCTION__, m66_cap); | ||
564 | |||
565 | 536 | ||
566 | if (pi == 2) { | 537 | switch (pcix_cap) { |
567 | switch (pcix_cap) { | 538 | case 0x0: |
568 | case 0: | 539 | *value = m66_cap ? PCI_SPEED_66MHz : PCI_SPEED_33MHz; |
569 | *value = m66_cap ? PCI_SPEED_66MHz : PCI_SPEED_33MHz; | 540 | break; |
570 | break; | 541 | case 0x1: |
571 | case 1: | 542 | *value = PCI_SPEED_66MHz_PCIX; |
572 | *value = PCI_SPEED_66MHz_PCIX; | 543 | break; |
573 | break; | 544 | case 0x3: |
574 | case 3: | 545 | *value = PCI_SPEED_133MHz_PCIX; |
575 | *value = PCI_SPEED_133MHz_PCIX; | 546 | break; |
576 | break; | 547 | case 0x4: |
577 | case 4: | 548 | *value = PCI_SPEED_133MHz_PCIX_266; |
578 | *value = PCI_SPEED_133MHz_PCIX_266; | 549 | break; |
579 | break; | 550 | case 0x5: |
580 | case 5: | 551 | *value = PCI_SPEED_133MHz_PCIX_533; |
581 | *value = PCI_SPEED_133MHz_PCIX_533; | 552 | break; |
582 | break; | 553 | case 0x2: |
583 | case 2: /* Reserved */ | 554 | default: |
584 | default: | 555 | *value = PCI_SPEED_UNKNOWN; |
585 | *value = PCI_SPEED_UNKNOWN; | 556 | retval = -ENODEV; |
586 | retval = -ENODEV; | 557 | break; |
587 | break; | ||
588 | } | ||
589 | } else { | ||
590 | switch (pcix_cap) { | ||
591 | case 0: | ||
592 | *value = m66_cap ? PCI_SPEED_66MHz : PCI_SPEED_33MHz; | ||
593 | break; | ||
594 | case 1: | ||
595 | *value = PCI_SPEED_66MHz_PCIX; | ||
596 | break; | ||
597 | case 3: | ||
598 | *value = PCI_SPEED_133MHz_PCIX; | ||
599 | break; | ||
600 | case 2: /* Reserved */ | ||
601 | default: | ||
602 | *value = PCI_SPEED_UNKNOWN; | ||
603 | retval = -ENODEV; | ||
604 | break; | ||
605 | } | ||
606 | } | 558 | } |
607 | 559 | ||
608 | dbg("Adapter speed = %d\n", *value); | 560 | dbg("Adapter speed = %d\n", *value); |
609 | |||
610 | DBG_LEAVE_ROUTINE | 561 | DBG_LEAVE_ROUTINE |
611 | return retval; | 562 | return retval; |
612 | } | 563 | } |
@@ -797,6 +748,7 @@ static void hpc_release_ctlr(struct controller *ctrl) | |||
797 | { | 748 | { |
798 | struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle; | 749 | struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle; |
799 | struct php_ctlr_state_s *p, *p_prev; | 750 | struct php_ctlr_state_s *p, *p_prev; |
751 | int i; | ||
800 | 752 | ||
801 | DBG_ENTER_ROUTINE | 753 | DBG_ENTER_ROUTINE |
802 | 754 | ||
@@ -805,6 +757,14 @@ static void hpc_release_ctlr(struct controller *ctrl) | |||
805 | return ; | 757 | return ; |
806 | } | 758 | } |
807 | 759 | ||
760 | /* | ||
761 | * Mask all slot event interrupts | ||
762 | */ | ||
763 | for (i = 0; i < ctrl->num_slots; i++) | ||
764 | writel(0xffff3fff, php_ctlr->creg + SLOT1 + (4 * i)); | ||
765 | |||
766 | cleanup_slots(ctrl); | ||
767 | |||
808 | if (shpchp_poll_mode) { | 768 | if (shpchp_poll_mode) { |
809 | del_timer(&php_ctlr->int_poll_timer); | 769 | del_timer(&php_ctlr->int_poll_timer); |
810 | } else { | 770 | } else { |
@@ -814,6 +774,7 @@ static void hpc_release_ctlr(struct controller *ctrl) | |||
814 | pci_disable_msi(php_ctlr->pci_dev); | 774 | pci_disable_msi(php_ctlr->pci_dev); |
815 | } | 775 | } |
816 | } | 776 | } |
777 | |||
817 | if (php_ctlr->pci_dev) { | 778 | if (php_ctlr->pci_dev) { |
818 | iounmap(php_ctlr->creg); | 779 | iounmap(php_ctlr->creg); |
819 | release_mem_region(ctrl->mmio_base, ctrl->mmio_size); | 780 | release_mem_region(ctrl->mmio_base, ctrl->mmio_size); |
@@ -939,98 +900,66 @@ static int hpc_slot_disable(struct slot * slot) | |||
939 | 900 | ||
940 | static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) | 901 | static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) |
941 | { | 902 | { |
942 | u8 slot_cmd; | 903 | int retval; |
943 | u8 pi; | ||
944 | int retval = 0; | ||
945 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; | 904 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; |
905 | u8 pi, cmd; | ||
946 | 906 | ||
947 | DBG_ENTER_ROUTINE | 907 | DBG_ENTER_ROUTINE |
948 | |||
949 | if (!slot->ctrl->hpc_ctlr_handle) { | ||
950 | err("%s: Invalid HPC controller handle!\n", __FUNCTION__); | ||
951 | return -1; | ||
952 | } | ||
953 | 908 | ||
954 | pi = readb(php_ctlr->creg + PROG_INTERFACE); | 909 | pi = readb(php_ctlr->creg + PROG_INTERFACE); |
955 | 910 | if ((pi == 1) && (value > PCI_SPEED_133MHz_PCIX)) | |
956 | if (pi == 1) { | 911 | return -EINVAL; |
957 | switch (value) { | ||
958 | case 0: | ||
959 | slot_cmd = SETA_PCI_33MHZ; | ||
960 | break; | ||
961 | case 1: | ||
962 | slot_cmd = SETA_PCI_66MHZ; | ||
963 | break; | ||
964 | case 2: | ||
965 | slot_cmd = SETA_PCIX_66MHZ; | ||
966 | break; | ||
967 | case 3: | ||
968 | slot_cmd = SETA_PCIX_100MHZ; | ||
969 | break; | ||
970 | case 4: | ||
971 | slot_cmd = SETA_PCIX_133MHZ; | ||
972 | break; | ||
973 | default: | ||
974 | slot_cmd = PCI_SPEED_UNKNOWN; | ||
975 | retval = -ENODEV; | ||
976 | return retval; | ||
977 | } | ||
978 | } else { | ||
979 | switch (value) { | ||
980 | case 0: | ||
981 | slot_cmd = SETB_PCI_33MHZ; | ||
982 | break; | ||
983 | case 1: | ||
984 | slot_cmd = SETB_PCI_66MHZ; | ||
985 | break; | ||
986 | case 2: | ||
987 | slot_cmd = SETB_PCIX_66MHZ_PM; | ||
988 | break; | ||
989 | case 3: | ||
990 | slot_cmd = SETB_PCIX_100MHZ_PM; | ||
991 | break; | ||
992 | case 4: | ||
993 | slot_cmd = SETB_PCIX_133MHZ_PM; | ||
994 | break; | ||
995 | case 5: | ||
996 | slot_cmd = SETB_PCIX_66MHZ_EM; | ||
997 | break; | ||
998 | case 6: | ||
999 | slot_cmd = SETB_PCIX_100MHZ_EM; | ||
1000 | break; | ||
1001 | case 7: | ||
1002 | slot_cmd = SETB_PCIX_133MHZ_EM; | ||
1003 | break; | ||
1004 | case 8: | ||
1005 | slot_cmd = SETB_PCIX_66MHZ_266; | ||
1006 | break; | ||
1007 | case 0x9: | ||
1008 | slot_cmd = SETB_PCIX_100MHZ_266; | ||
1009 | break; | ||
1010 | case 0xa: | ||
1011 | slot_cmd = SETB_PCIX_133MHZ_266; | ||
1012 | break; | ||
1013 | case 0xb: | ||
1014 | slot_cmd = SETB_PCIX_66MHZ_533; | ||
1015 | break; | ||
1016 | case 0xc: | ||
1017 | slot_cmd = SETB_PCIX_100MHZ_533; | ||
1018 | break; | ||
1019 | case 0xd: | ||
1020 | slot_cmd = SETB_PCIX_133MHZ_533; | ||
1021 | break; | ||
1022 | default: | ||
1023 | slot_cmd = PCI_SPEED_UNKNOWN; | ||
1024 | retval = -ENODEV; | ||
1025 | return retval; | ||
1026 | } | ||
1027 | 912 | ||
913 | switch (value) { | ||
914 | case PCI_SPEED_33MHz: | ||
915 | cmd = SETA_PCI_33MHZ; | ||
916 | break; | ||
917 | case PCI_SPEED_66MHz: | ||
918 | cmd = SETA_PCI_66MHZ; | ||
919 | break; | ||
920 | case PCI_SPEED_66MHz_PCIX: | ||
921 | cmd = SETA_PCIX_66MHZ; | ||
922 | break; | ||
923 | case PCI_SPEED_100MHz_PCIX: | ||
924 | cmd = SETA_PCIX_100MHZ; | ||
925 | break; | ||
926 | case PCI_SPEED_133MHz_PCIX: | ||
927 | cmd = SETA_PCIX_133MHZ; | ||
928 | break; | ||
929 | case PCI_SPEED_66MHz_PCIX_ECC: | ||
930 | cmd = SETB_PCIX_66MHZ_EM; | ||
931 | break; | ||
932 | case PCI_SPEED_100MHz_PCIX_ECC: | ||
933 | cmd = SETB_PCIX_100MHZ_EM; | ||
934 | break; | ||
935 | case PCI_SPEED_133MHz_PCIX_ECC: | ||
936 | cmd = SETB_PCIX_133MHZ_EM; | ||
937 | break; | ||
938 | case PCI_SPEED_66MHz_PCIX_266: | ||
939 | cmd = SETB_PCIX_66MHZ_266; | ||
940 | break; | ||
941 | case PCI_SPEED_100MHz_PCIX_266: | ||
942 | cmd = SETB_PCIX_100MHZ_266; | ||
943 | break; | ||
944 | case PCI_SPEED_133MHz_PCIX_266: | ||
945 | cmd = SETB_PCIX_133MHZ_266; | ||
946 | break; | ||
947 | case PCI_SPEED_66MHz_PCIX_533: | ||
948 | cmd = SETB_PCIX_66MHZ_533; | ||
949 | break; | ||
950 | case PCI_SPEED_100MHz_PCIX_533: | ||
951 | cmd = SETB_PCIX_100MHZ_533; | ||
952 | break; | ||
953 | case PCI_SPEED_133MHz_PCIX_533: | ||
954 | cmd = SETB_PCIX_133MHZ_533; | ||
955 | break; | ||
956 | default: | ||
957 | return -EINVAL; | ||
1028 | } | 958 | } |
1029 | retval = shpc_write_cmd(slot, 0, slot_cmd); | 959 | |
1030 | if (retval) { | 960 | retval = shpc_write_cmd(slot, 0, cmd); |
961 | if (retval) | ||
1031 | err("%s: Write command failed!\n", __FUNCTION__); | 962 | err("%s: Write command failed!\n", __FUNCTION__); |
1032 | return -1; | ||
1033 | } | ||
1034 | 963 | ||
1035 | DBG_LEAVE_ROUTINE | 964 | DBG_LEAVE_ROUTINE |
1036 | return retval; | 965 | return retval; |
@@ -1093,14 +1022,8 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs) | |||
1093 | wake_up_interruptible(&ctrl->queue); | 1022 | wake_up_interruptible(&ctrl->queue); |
1094 | } | 1023 | } |
1095 | 1024 | ||
1096 | if ((intr_loc = (intr_loc >> 1)) == 0) { | 1025 | if ((intr_loc = (intr_loc >> 1)) == 0) |
1097 | /* Unmask Global Interrupt Mask */ | 1026 | goto out; |
1098 | temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE); | ||
1099 | temp_dword &= 0xfffffffe; | ||
1100 | writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE); | ||
1101 | |||
1102 | return IRQ_NONE; | ||
1103 | } | ||
1104 | 1027 | ||
1105 | for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) { | 1028 | for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) { |
1106 | /* To find out which slot has interrupt pending */ | 1029 | /* To find out which slot has interrupt pending */ |
@@ -1130,6 +1053,7 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs) | |||
1130 | dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2); | 1053 | dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2); |
1131 | } | 1054 | } |
1132 | } | 1055 | } |
1056 | out: | ||
1133 | if (!shpchp_poll_mode) { | 1057 | if (!shpchp_poll_mode) { |
1134 | /* Unmask Global Interrupt Mask */ | 1058 | /* Unmask Global Interrupt Mask */ |
1135 | temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE); | 1059 | temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE); |
@@ -1142,64 +1066,43 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs) | |||
1142 | 1066 | ||
1143 | static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) | 1067 | static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) |
1144 | { | 1068 | { |
1069 | int retval = 0; | ||
1145 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; | 1070 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; |
1146 | enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; | 1071 | enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; |
1147 | int retval = 0; | 1072 | u8 pi = readb(php_ctlr->creg + PROG_INTERFACE); |
1148 | u8 pi; | 1073 | u32 slot_avail1 = readl(php_ctlr->creg + SLOT_AVAIL1); |
1149 | u32 slot_avail1, slot_avail2; | 1074 | u32 slot_avail2 = readl(php_ctlr->creg + SLOT_AVAIL2); |
1150 | 1075 | ||
1151 | DBG_ENTER_ROUTINE | 1076 | DBG_ENTER_ROUTINE |
1152 | 1077 | ||
1153 | if (!slot->ctrl->hpc_ctlr_handle) { | ||
1154 | err("%s: Invalid HPC controller handle!\n", __FUNCTION__); | ||
1155 | return -1; | ||
1156 | } | ||
1157 | |||
1158 | if (slot->hp_slot >= php_ctlr->num_slots) { | ||
1159 | err("%s: Invalid HPC slot number!\n", __FUNCTION__); | ||
1160 | return -1; | ||
1161 | } | ||
1162 | |||
1163 | pi = readb(php_ctlr->creg + PROG_INTERFACE); | ||
1164 | slot_avail1 = readl(php_ctlr->creg + SLOT_AVAIL1); | ||
1165 | slot_avail2 = readl(php_ctlr->creg + SLOT_AVAIL2); | ||
1166 | |||
1167 | if (pi == 2) { | 1078 | if (pi == 2) { |
1168 | if (slot_avail2 & SLOT_133MHZ_PCIX_533) | 1079 | if (slot_avail2 & SLOT_133MHZ_PCIX_533) |
1169 | bus_speed = PCIX_133MHZ_533; | 1080 | bus_speed = PCI_SPEED_133MHz_PCIX_533; |
1170 | else if (slot_avail2 & SLOT_100MHZ_PCIX_533) | 1081 | else if (slot_avail2 & SLOT_100MHZ_PCIX_533) |
1171 | bus_speed = PCIX_100MHZ_533; | 1082 | bus_speed = PCI_SPEED_100MHz_PCIX_533; |
1172 | else if (slot_avail2 & SLOT_66MHZ_PCIX_533) | 1083 | else if (slot_avail2 & SLOT_66MHZ_PCIX_533) |
1173 | bus_speed = PCIX_66MHZ_533; | 1084 | bus_speed = PCI_SPEED_66MHz_PCIX_533; |
1174 | else if (slot_avail2 & SLOT_133MHZ_PCIX_266) | 1085 | else if (slot_avail2 & SLOT_133MHZ_PCIX_266) |
1175 | bus_speed = PCIX_133MHZ_266; | 1086 | bus_speed = PCI_SPEED_133MHz_PCIX_266; |
1176 | else if (slot_avail2 & SLOT_100MHZ_PCIX_266) | 1087 | else if (slot_avail2 & SLOT_100MHZ_PCIX_266) |
1177 | bus_speed = PCIX_100MHZ_266; | 1088 | bus_speed = PCI_SPEED_100MHz_PCIX_266; |
1178 | else if (slot_avail2 & SLOT_66MHZ_PCIX_266) | 1089 | else if (slot_avail2 & SLOT_66MHZ_PCIX_266) |
1179 | bus_speed = PCIX_66MHZ_266; | 1090 | bus_speed = PCI_SPEED_66MHz_PCIX_266; |
1180 | else if (slot_avail1 & SLOT_133MHZ_PCIX) | 1091 | } |
1181 | bus_speed = PCIX_133MHZ; | 1092 | |
1182 | else if (slot_avail1 & SLOT_100MHZ_PCIX) | 1093 | if (bus_speed == PCI_SPEED_UNKNOWN) { |
1183 | bus_speed = PCIX_100MHZ; | ||
1184 | else if (slot_avail1 & SLOT_66MHZ_PCIX) | ||
1185 | bus_speed = PCIX_66MHZ; | ||
1186 | else if (slot_avail2 & SLOT_66MHZ) | ||
1187 | bus_speed = PCI_66MHZ; | ||
1188 | else if (slot_avail1 & SLOT_33MHZ) | ||
1189 | bus_speed = PCI_33MHZ; | ||
1190 | else bus_speed = PCI_SPEED_UNKNOWN; | ||
1191 | } else { | ||
1192 | if (slot_avail1 & SLOT_133MHZ_PCIX) | 1094 | if (slot_avail1 & SLOT_133MHZ_PCIX) |
1193 | bus_speed = PCIX_133MHZ; | 1095 | bus_speed = PCI_SPEED_133MHz_PCIX; |
1194 | else if (slot_avail1 & SLOT_100MHZ_PCIX) | 1096 | else if (slot_avail1 & SLOT_100MHZ_PCIX) |
1195 | bus_speed = PCIX_100MHZ; | 1097 | bus_speed = PCI_SPEED_100MHz_PCIX; |
1196 | else if (slot_avail1 & SLOT_66MHZ_PCIX) | 1098 | else if (slot_avail1 & SLOT_66MHZ_PCIX) |
1197 | bus_speed = PCIX_66MHZ; | 1099 | bus_speed = PCI_SPEED_66MHz_PCIX; |
1198 | else if (slot_avail2 & SLOT_66MHZ) | 1100 | else if (slot_avail2 & SLOT_66MHZ) |
1199 | bus_speed = PCI_66MHZ; | 1101 | bus_speed = PCI_SPEED_66MHz; |
1200 | else if (slot_avail1 & SLOT_33MHZ) | 1102 | else if (slot_avail1 & SLOT_33MHZ) |
1201 | bus_speed = PCI_33MHZ; | 1103 | bus_speed = PCI_SPEED_33MHz; |
1202 | else bus_speed = PCI_SPEED_UNKNOWN; | 1104 | else |
1105 | retval = -ENODEV; | ||
1203 | } | 1106 | } |
1204 | 1107 | ||
1205 | *value = bus_speed; | 1108 | *value = bus_speed; |
@@ -1210,111 +1113,69 @@ static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) | |||
1210 | 1113 | ||
1211 | static int hpc_get_cur_bus_speed (struct slot *slot, enum pci_bus_speed *value) | 1114 | static int hpc_get_cur_bus_speed (struct slot *slot, enum pci_bus_speed *value) |
1212 | { | 1115 | { |
1116 | int retval = 0; | ||
1213 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; | 1117 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; |
1214 | enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; | 1118 | enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; |
1215 | u16 sec_bus_status; | 1119 | u16 sec_bus_reg = readw(php_ctlr->creg + SEC_BUS_CONFIG); |
1216 | int retval = 0; | 1120 | u8 pi = readb(php_ctlr->creg + PROG_INTERFACE); |
1217 | u8 pi; | 1121 | u8 speed_mode = (pi == 2) ? (sec_bus_reg & 0xF) : (sec_bus_reg & 0x7); |
1218 | 1122 | ||
1219 | DBG_ENTER_ROUTINE | 1123 | DBG_ENTER_ROUTINE |
1220 | 1124 | ||
1221 | if (!slot->ctrl->hpc_ctlr_handle) { | 1125 | if ((pi == 1) && (speed_mode > 4)) { |
1222 | err("%s: Invalid HPC controller handle!\n", __FUNCTION__); | 1126 | *value = PCI_SPEED_UNKNOWN; |
1223 | return -1; | 1127 | return -ENODEV; |
1224 | } | ||
1225 | |||
1226 | if (slot->hp_slot >= php_ctlr->num_slots) { | ||
1227 | err("%s: Invalid HPC slot number!\n", __FUNCTION__); | ||
1228 | return -1; | ||
1229 | } | 1128 | } |
1230 | 1129 | ||
1231 | pi = readb(php_ctlr->creg + PROG_INTERFACE); | 1130 | switch (speed_mode) { |
1232 | sec_bus_status = readw(php_ctlr->creg + SEC_BUS_CONFIG); | 1131 | case 0x0: |
1233 | 1132 | *value = PCI_SPEED_33MHz; | |
1234 | if (pi == 2) { | 1133 | break; |
1235 | switch (sec_bus_status & 0x000f) { | 1134 | case 0x1: |
1236 | case 0: | 1135 | *value = PCI_SPEED_66MHz; |
1237 | bus_speed = PCI_SPEED_33MHz; | 1136 | break; |
1238 | break; | 1137 | case 0x2: |
1239 | case 1: | 1138 | *value = PCI_SPEED_66MHz_PCIX; |
1240 | bus_speed = PCI_SPEED_66MHz; | 1139 | break; |
1241 | break; | 1140 | case 0x3: |
1242 | case 2: | 1141 | *value = PCI_SPEED_100MHz_PCIX; |
1243 | bus_speed = PCI_SPEED_66MHz_PCIX; | 1142 | break; |
1244 | break; | 1143 | case 0x4: |
1245 | case 3: | 1144 | *value = PCI_SPEED_133MHz_PCIX; |
1246 | bus_speed = PCI_SPEED_100MHz_PCIX; | 1145 | break; |
1247 | break; | 1146 | case 0x5: |
1248 | case 4: | 1147 | *value = PCI_SPEED_66MHz_PCIX_ECC; |
1249 | bus_speed = PCI_SPEED_133MHz_PCIX; | 1148 | break; |
1250 | break; | 1149 | case 0x6: |
1251 | case 5: | 1150 | *value = PCI_SPEED_100MHz_PCIX_ECC; |
1252 | bus_speed = PCI_SPEED_66MHz_PCIX_ECC; | 1151 | break; |
1253 | break; | 1152 | case 0x7: |
1254 | case 6: | 1153 | *value = PCI_SPEED_133MHz_PCIX_ECC; |
1255 | bus_speed = PCI_SPEED_100MHz_PCIX_ECC; | 1154 | break; |
1256 | break; | 1155 | case 0x8: |
1257 | case 7: | 1156 | *value = PCI_SPEED_66MHz_PCIX_266; |
1258 | bus_speed = PCI_SPEED_133MHz_PCIX_ECC; | 1157 | break; |
1259 | break; | 1158 | case 0x9: |
1260 | case 8: | 1159 | *value = PCI_SPEED_100MHz_PCIX_266; |
1261 | bus_speed = PCI_SPEED_66MHz_PCIX_266; | 1160 | break; |
1262 | break; | 1161 | case 0xa: |
1263 | case 9: | 1162 | *value = PCI_SPEED_133MHz_PCIX_266; |
1264 | bus_speed = PCI_SPEED_100MHz_PCIX_266; | 1163 | break; |
1265 | break; | 1164 | case 0xb: |
1266 | case 0xa: | 1165 | *value = PCI_SPEED_66MHz_PCIX_533; |
1267 | bus_speed = PCI_SPEED_133MHz_PCIX_266; | 1166 | break; |
1268 | break; | 1167 | case 0xc: |
1269 | case 0xb: | 1168 | *value = PCI_SPEED_100MHz_PCIX_533; |
1270 | bus_speed = PCI_SPEED_66MHz_PCIX_533; | 1169 | break; |
1271 | break; | 1170 | case 0xd: |
1272 | case 0xc: | 1171 | *value = PCI_SPEED_133MHz_PCIX_533; |
1273 | bus_speed = PCI_SPEED_100MHz_PCIX_533; | 1172 | break; |
1274 | break; | 1173 | default: |
1275 | case 0xd: | 1174 | *value = PCI_SPEED_UNKNOWN; |
1276 | bus_speed = PCI_SPEED_133MHz_PCIX_533; | 1175 | retval = -ENODEV; |
1277 | break; | 1176 | break; |
1278 | case 0xe: | ||
1279 | case 0xf: | ||
1280 | default: | ||
1281 | bus_speed = PCI_SPEED_UNKNOWN; | ||
1282 | break; | ||
1283 | } | ||
1284 | } else { | ||
1285 | /* In the case where pi is undefined, default it to 1 */ | ||
1286 | switch (sec_bus_status & 0x0007) { | ||
1287 | case 0: | ||
1288 | bus_speed = PCI_SPEED_33MHz; | ||
1289 | break; | ||
1290 | case 1: | ||
1291 | bus_speed = PCI_SPEED_66MHz; | ||
1292 | break; | ||
1293 | case 2: | ||
1294 | bus_speed = PCI_SPEED_66MHz_PCIX; | ||
1295 | break; | ||
1296 | case 3: | ||
1297 | bus_speed = PCI_SPEED_100MHz_PCIX; | ||
1298 | break; | ||
1299 | case 4: | ||
1300 | bus_speed = PCI_SPEED_133MHz_PCIX; | ||
1301 | break; | ||
1302 | case 5: | ||
1303 | bus_speed = PCI_SPEED_UNKNOWN; /* Reserved */ | ||
1304 | break; | ||
1305 | case 6: | ||
1306 | bus_speed = PCI_SPEED_UNKNOWN; /* Reserved */ | ||
1307 | break; | ||
1308 | case 7: | ||
1309 | bus_speed = PCI_SPEED_UNKNOWN; /* Reserved */ | ||
1310 | break; | ||
1311 | default: | ||
1312 | bus_speed = PCI_SPEED_UNKNOWN; | ||
1313 | break; | ||
1314 | } | ||
1315 | } | 1177 | } |
1316 | 1178 | ||
1317 | *value = bus_speed; | ||
1318 | dbg("Current bus speed = %d\n", bus_speed); | 1179 | dbg("Current bus speed = %d\n", bus_speed); |
1319 | DBG_LEAVE_ROUTINE | 1180 | DBG_LEAVE_ROUTINE |
1320 | return retval; | 1181 | return retval; |
@@ -1343,7 +1204,6 @@ static struct hpc_ops shpchp_hpc_ops = { | |||
1343 | .green_led_blink = hpc_set_green_led_blink, | 1204 | .green_led_blink = hpc_set_green_led_blink, |
1344 | 1205 | ||
1345 | .release_ctlr = hpc_release_ctlr, | 1206 | .release_ctlr = hpc_release_ctlr, |
1346 | .check_cmd_status = hpc_check_cmd_status, | ||
1347 | }; | 1207 | }; |
1348 | 1208 | ||
1349 | inline static int shpc_indirect_creg_read(struct controller *ctrl, int index, | 1209 | inline static int shpc_indirect_creg_read(struct controller *ctrl, int index, |
@@ -1375,15 +1235,13 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
1375 | ctrl->pci_dev = pdev; /* pci_dev of the P2P bridge */ | 1235 | ctrl->pci_dev = pdev; /* pci_dev of the P2P bridge */ |
1376 | 1236 | ||
1377 | spin_lock_init(&list_lock); | 1237 | spin_lock_init(&list_lock); |
1378 | php_ctlr = (struct php_ctlr_state_s *) kmalloc(sizeof(struct php_ctlr_state_s), GFP_KERNEL); | 1238 | php_ctlr = kzalloc(sizeof(*php_ctlr), GFP_KERNEL); |
1379 | 1239 | ||
1380 | if (!php_ctlr) { /* allocate controller state data */ | 1240 | if (!php_ctlr) { /* allocate controller state data */ |
1381 | err("%s: HPC controller memory allocation error!\n", __FUNCTION__); | 1241 | err("%s: HPC controller memory allocation error!\n", __FUNCTION__); |
1382 | goto abort; | 1242 | goto abort; |
1383 | } | 1243 | } |
1384 | 1244 | ||
1385 | memset(php_ctlr, 0, sizeof(struct php_ctlr_state_s)); | ||
1386 | |||
1387 | php_ctlr->pci_dev = pdev; /* save pci_dev in context */ | 1245 | php_ctlr->pci_dev = pdev; /* save pci_dev in context */ |
1388 | 1246 | ||
1389 | if ((pdev->vendor == PCI_VENDOR_ID_AMD) || (pdev->device == | 1247 | if ((pdev->vendor == PCI_VENDOR_ID_AMD) || (pdev->device == |
@@ -1454,7 +1312,9 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
1454 | } | 1312 | } |
1455 | dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg); | 1313 | dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg); |
1456 | 1314 | ||
1457 | init_MUTEX(&ctrl->crit_sect); | 1315 | mutex_init(&ctrl->crit_sect); |
1316 | mutex_init(&ctrl->cmd_lock); | ||
1317 | |||
1458 | /* Setup wait queue */ | 1318 | /* Setup wait queue */ |
1459 | init_waitqueue_head(&ctrl->queue); | 1319 | init_waitqueue_head(&ctrl->queue); |
1460 | 1320 | ||