2 * Intel MIC Platform Software Stack (MPSS)
4 * Copyright(c) 2013 Intel Corporation.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
18 * Intel MIC Host driver.
21 #include <linux/pci.h>
23 #include <linux/mic_common.h>
24 #include "../common/mic_dev.h"
25 #include "mic_device.h"
28 * A state-to-string lookup table, for exposing a human readable state
29 * via sysfs. Always keep in sync with enum mic_states
31 static const char * const mic_state_string
[] = {
32 [MIC_OFFLINE
] = "offline",
33 [MIC_ONLINE
] = "online",
34 [MIC_SHUTTING_DOWN
] = "shutting_down",
35 [MIC_RESET_FAILED
] = "reset_failed",
36 [MIC_SUSPENDING
] = "suspending",
37 [MIC_SUSPENDED
] = "suspended",
41 * A shutdown-status-to-string lookup table, for exposing a human
42 * readable state via sysfs. Always keep in sync with enum mic_shutdown_status
44 static const char * const mic_shutdown_status_string
[] = {
46 [MIC_CRASHED
] = "crashed",
47 [MIC_HALTED
] = "halted",
48 [MIC_POWER_OFF
] = "poweroff",
49 [MIC_RESTART
] = "restart",
52 void mic_set_shutdown_status(struct mic_device
*mdev
, u8 shutdown_status
)
54 dev_dbg(mdev
->sdev
->parent
, "Shutdown Status %s -> %s\n",
55 mic_shutdown_status_string
[mdev
->shutdown_status
],
56 mic_shutdown_status_string
[shutdown_status
]);
57 mdev
->shutdown_status
= shutdown_status
;
60 void mic_set_state(struct mic_device
*mdev
, u8 state
)
62 dev_dbg(mdev
->sdev
->parent
, "State %s -> %s\n",
63 mic_state_string
[mdev
->state
],
64 mic_state_string
[state
]);
66 sysfs_notify_dirent(mdev
->state_sysfs
);
70 family_show(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
72 static const char x100
[] = "x100";
73 static const char unknown
[] = "Unknown";
74 const char *card
= NULL
;
75 struct mic_device
*mdev
= dev_get_drvdata(dev
->parent
);
80 switch (mdev
->family
) {
88 return scnprintf(buf
, PAGE_SIZE
, "%s\n", card
);
90 static DEVICE_ATTR_RO(family
);
93 stepping_show(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
95 struct mic_device
*mdev
= dev_get_drvdata(dev
->parent
);
101 switch (mdev
->stepping
) {
117 return scnprintf(buf
, PAGE_SIZE
, "%s\n", string
);
119 static DEVICE_ATTR_RO(stepping
);
122 state_show(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
124 struct mic_device
*mdev
= dev_get_drvdata(dev
->parent
);
126 if (!mdev
|| mdev
->state
>= MIC_LAST
)
129 return scnprintf(buf
, PAGE_SIZE
, "%s\n",
130 mic_state_string
[mdev
->state
]);
134 state_store(struct device
*dev
, struct device_attribute
*attr
,
135 const char *buf
, size_t count
)
138 struct mic_device
*mdev
= dev_get_drvdata(dev
->parent
);
141 if (sysfs_streq(buf
, "boot")) {
142 rc
= mic_start(mdev
, buf
);
144 dev_err(mdev
->sdev
->parent
,
145 "mic_boot failed rc %d\n", rc
);
151 if (sysfs_streq(buf
, "reset")) {
152 schedule_work(&mdev
->reset_trigger_work
);
156 if (sysfs_streq(buf
, "shutdown")) {
161 if (sysfs_streq(buf
, "suspend")) {
170 static DEVICE_ATTR_RW(state
);
172 static ssize_t
shutdown_status_show(struct device
*dev
,
173 struct device_attribute
*attr
, char *buf
)
175 struct mic_device
*mdev
= dev_get_drvdata(dev
->parent
);
177 if (!mdev
|| mdev
->shutdown_status
>= MIC_STATUS_LAST
)
180 return scnprintf(buf
, PAGE_SIZE
, "%s\n",
181 mic_shutdown_status_string
[mdev
->shutdown_status
]);
183 static DEVICE_ATTR_RO(shutdown_status
);
186 cmdline_show(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
188 struct mic_device
*mdev
= dev_get_drvdata(dev
->parent
);
194 cmdline
= mdev
->cmdline
;
197 return scnprintf(buf
, PAGE_SIZE
, "%s\n", cmdline
);
202 cmdline_store(struct device
*dev
, struct device_attribute
*attr
,
203 const char *buf
, size_t count
)
205 struct mic_device
*mdev
= dev_get_drvdata(dev
->parent
);
210 mutex_lock(&mdev
->mic_mutex
);
211 kfree(mdev
->cmdline
);
213 mdev
->cmdline
= kmalloc(count
+ 1, GFP_KERNEL
);
214 if (!mdev
->cmdline
) {
219 strncpy(mdev
->cmdline
, buf
, count
);
221 if (mdev
->cmdline
[count
- 1] == '\n')
222 mdev
->cmdline
[count
- 1] = '\0';
224 mdev
->cmdline
[count
] = '\0';
226 mutex_unlock(&mdev
->mic_mutex
);
229 static DEVICE_ATTR_RW(cmdline
);
232 firmware_show(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
234 struct mic_device
*mdev
= dev_get_drvdata(dev
->parent
);
240 firmware
= mdev
->firmware
;
243 return scnprintf(buf
, PAGE_SIZE
, "%s\n", firmware
);
248 firmware_store(struct device
*dev
, struct device_attribute
*attr
,
249 const char *buf
, size_t count
)
251 struct mic_device
*mdev
= dev_get_drvdata(dev
->parent
);
256 mutex_lock(&mdev
->mic_mutex
);
257 kfree(mdev
->firmware
);
259 mdev
->firmware
= kmalloc(count
+ 1, GFP_KERNEL
);
260 if (!mdev
->firmware
) {
264 strncpy(mdev
->firmware
, buf
, count
);
266 if (mdev
->firmware
[count
- 1] == '\n')
267 mdev
->firmware
[count
- 1] = '\0';
269 mdev
->firmware
[count
] = '\0';
271 mutex_unlock(&mdev
->mic_mutex
);
274 static DEVICE_ATTR_RW(firmware
);
277 ramdisk_show(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
279 struct mic_device
*mdev
= dev_get_drvdata(dev
->parent
);
285 ramdisk
= mdev
->ramdisk
;
288 return scnprintf(buf
, PAGE_SIZE
, "%s\n", ramdisk
);
293 ramdisk_store(struct device
*dev
, struct device_attribute
*attr
,
294 const char *buf
, size_t count
)
296 struct mic_device
*mdev
= dev_get_drvdata(dev
->parent
);
301 mutex_lock(&mdev
->mic_mutex
);
302 kfree(mdev
->ramdisk
);
304 mdev
->ramdisk
= kmalloc(count
+ 1, GFP_KERNEL
);
305 if (!mdev
->ramdisk
) {
310 strncpy(mdev
->ramdisk
, buf
, count
);
312 if (mdev
->ramdisk
[count
- 1] == '\n')
313 mdev
->ramdisk
[count
- 1] = '\0';
315 mdev
->ramdisk
[count
] = '\0';
317 mutex_unlock(&mdev
->mic_mutex
);
320 static DEVICE_ATTR_RW(ramdisk
);
323 bootmode_show(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
325 struct mic_device
*mdev
= dev_get_drvdata(dev
->parent
);
331 bootmode
= mdev
->bootmode
;
334 return scnprintf(buf
, PAGE_SIZE
, "%s\n", bootmode
);
339 bootmode_store(struct device
*dev
, struct device_attribute
*attr
,
340 const char *buf
, size_t count
)
342 struct mic_device
*mdev
= dev_get_drvdata(dev
->parent
);
347 if (!sysfs_streq(buf
, "linux") && !sysfs_streq(buf
, "elf"))
350 mutex_lock(&mdev
->mic_mutex
);
351 kfree(mdev
->bootmode
);
353 mdev
->bootmode
= kmalloc(count
+ 1, GFP_KERNEL
);
354 if (!mdev
->bootmode
) {
359 strncpy(mdev
->bootmode
, buf
, count
);
361 if (mdev
->bootmode
[count
- 1] == '\n')
362 mdev
->bootmode
[count
- 1] = '\0';
364 mdev
->bootmode
[count
] = '\0';
366 mutex_unlock(&mdev
->mic_mutex
);
369 static DEVICE_ATTR_RW(bootmode
);
372 log_buf_addr_show(struct device
*dev
, struct device_attribute
*attr
,
375 struct mic_device
*mdev
= dev_get_drvdata(dev
->parent
);
380 return scnprintf(buf
, PAGE_SIZE
, "%p\n", mdev
->log_buf_addr
);
384 log_buf_addr_store(struct device
*dev
, struct device_attribute
*attr
,
385 const char *buf
, size_t count
)
387 struct mic_device
*mdev
= dev_get_drvdata(dev
->parent
);
394 ret
= kstrtoul(buf
, 16, &addr
);
398 mdev
->log_buf_addr
= (void *)addr
;
403 static DEVICE_ATTR_RW(log_buf_addr
);
406 log_buf_len_show(struct device
*dev
, struct device_attribute
*attr
,
409 struct mic_device
*mdev
= dev_get_drvdata(dev
->parent
);
414 return scnprintf(buf
, PAGE_SIZE
, "%p\n", mdev
->log_buf_len
);
418 log_buf_len_store(struct device
*dev
, struct device_attribute
*attr
,
419 const char *buf
, size_t count
)
421 struct mic_device
*mdev
= dev_get_drvdata(dev
->parent
);
428 ret
= kstrtoul(buf
, 16, &addr
);
432 mdev
->log_buf_len
= (int *)addr
;
437 static DEVICE_ATTR_RW(log_buf_len
);
439 static struct attribute
*mic_default_attrs
[] = {
440 &dev_attr_family
.attr
,
441 &dev_attr_stepping
.attr
,
442 &dev_attr_state
.attr
,
443 &dev_attr_shutdown_status
.attr
,
444 &dev_attr_cmdline
.attr
,
445 &dev_attr_firmware
.attr
,
446 &dev_attr_ramdisk
.attr
,
447 &dev_attr_bootmode
.attr
,
448 &dev_attr_log_buf_addr
.attr
,
449 &dev_attr_log_buf_len
.attr
,
454 ATTRIBUTE_GROUPS(mic_default
);
456 void mic_sysfs_init(struct mic_device
*mdev
)
458 mdev
->attr_group
= mic_default_groups
;