aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug/pciehp_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/hotplug/pciehp_core.c')
-rw-r--r--drivers/pci/hotplug/pciehp_core.c112
1 files changed, 1 insertions, 111 deletions
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index fb254b2454de..2317557fdee6 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -73,7 +73,6 @@ static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *val
73static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); 73static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value);
74 74
75static struct hotplug_slot_ops pciehp_hotplug_slot_ops = { 75static struct hotplug_slot_ops pciehp_hotplug_slot_ops = {
76 .owner = THIS_MODULE,
77 .set_attention_status = set_attention_status, 76 .set_attention_status = set_attention_status,
78 .enable_slot = enable_slot, 77 .enable_slot = enable_slot,
79 .disable_slot = disable_slot, 78 .disable_slot = disable_slot,
@@ -85,99 +84,6 @@ static struct hotplug_slot_ops pciehp_hotplug_slot_ops = {
85 .get_cur_bus_speed = get_cur_bus_speed, 84 .get_cur_bus_speed = get_cur_bus_speed,
86}; 85};
87 86
88/*
89 * Check the status of the Electro Mechanical Interlock (EMI)
90 */
91static int get_lock_status(struct hotplug_slot *hotplug_slot, u8 *value)
92{
93 struct slot *slot = hotplug_slot->private;
94 return (slot->hpc_ops->get_emi_status(slot, value));
95}
96
97/*
98 * sysfs interface for the Electro Mechanical Interlock (EMI)
99 * 1 == locked, 0 == unlocked
100 */
101static ssize_t lock_read_file(struct hotplug_slot *slot, char *buf)
102{
103 int retval;
104 u8 value;
105
106 retval = get_lock_status(slot, &value);
107 if (retval)
108 goto lock_read_exit;
109 retval = sprintf (buf, "%d\n", value);
110
111lock_read_exit:
112 return retval;
113}
114
115/*
116 * Change the status of the Electro Mechanical Interlock (EMI)
117 * This is a toggle - in addition there must be at least 1 second
118 * in between toggles.
119 */
120static int set_lock_status(struct hotplug_slot *hotplug_slot, u8 status)
121{
122 struct slot *slot = hotplug_slot->private;
123 int retval;
124 u8 value;
125
126 mutex_lock(&slot->ctrl->crit_sect);
127
128 /* has it been >1 sec since our last toggle? */
129 if ((get_seconds() - slot->last_emi_toggle) < 1) {
130 mutex_unlock(&slot->ctrl->crit_sect);
131 return -EINVAL;
132 }
133
134 /* see what our current state is */
135 retval = get_lock_status(hotplug_slot, &value);
136 if (retval || (value == status))
137 goto set_lock_exit;
138
139 slot->hpc_ops->toggle_emi(slot);
140set_lock_exit:
141 mutex_unlock(&slot->ctrl->crit_sect);
142 return 0;
143}
144
145/*
146 * sysfs interface which allows the user to toggle the Electro Mechanical
147 * Interlock. Valid values are either 0 or 1. 0 == unlock, 1 == lock
148 */
149static ssize_t lock_write_file(struct hotplug_slot *hotplug_slot,
150 const char *buf, size_t count)
151{
152 struct slot *slot = hotplug_slot->private;
153 unsigned long llock;
154 u8 lock;
155 int retval = 0;
156
157 llock = simple_strtoul(buf, NULL, 10);
158 lock = (u8)(llock & 0xff);
159
160 switch (lock) {
161 case 0:
162 case 1:
163 retval = set_lock_status(hotplug_slot, lock);
164 break;
165 default:
166 ctrl_err(slot->ctrl, "%d is an invalid lock value\n",
167 lock);
168 retval = -EINVAL;
169 }
170 if (retval)
171 return retval;
172 return count;
173}
174
175static struct hotplug_slot_attribute hotplug_slot_attr_lock = {
176 .attr = {.name = "lock", .mode = S_IFREG | S_IRUGO | S_IWUSR},
177 .show = lock_read_file,
178 .store = lock_write_file
179};
180
181/** 87/**
182 * release_slot - free up the memory used by a slot 88 * release_slot - free up the memory used by a slot
183 * @hotplug_slot: slot to free 89 * @hotplug_slot: slot to free
@@ -236,17 +142,6 @@ static int init_slots(struct controller *ctrl)
236 get_attention_status(hotplug_slot, &info->attention_status); 142 get_attention_status(hotplug_slot, &info->attention_status);
237 get_latch_status(hotplug_slot, &info->latch_status); 143 get_latch_status(hotplug_slot, &info->latch_status);
238 get_adapter_status(hotplug_slot, &info->adapter_status); 144 get_adapter_status(hotplug_slot, &info->adapter_status);
239 /* create additional sysfs entries */
240 if (EMI(ctrl)) {
241 retval = sysfs_create_file(&hotplug_slot->pci_slot->kobj,
242 &hotplug_slot_attr_lock.attr);
243 if (retval) {
244 pci_hp_deregister(hotplug_slot);
245 ctrl_err(ctrl, "Cannot create additional sysfs "
246 "entries\n");
247 goto error_info;
248 }
249 }
250 } 145 }
251 146
252 return 0; 147 return 0;
@@ -261,13 +156,8 @@ error:
261static void cleanup_slots(struct controller *ctrl) 156static void cleanup_slots(struct controller *ctrl)
262{ 157{
263 struct slot *slot; 158 struct slot *slot;
264 159 list_for_each_entry(slot, &ctrl->slot_list, slot_list)
265 list_for_each_entry(slot, &ctrl->slot_list, slot_list) {
266 if (EMI(ctrl))
267 sysfs_remove_file(&slot->hotplug_slot->pci_slot->kobj,
268 &hotplug_slot_attr_lock.attr);
269 pci_hp_deregister(slot->hotplug_slot); 160 pci_hp_deregister(slot->hotplug_slot);
270 }
271} 161}
272 162
273/* 163/*