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",
39 * A shutdown-status-to-string lookup table, for exposing a human
40 * readable state via sysfs. Always keep in sync with enum mic_shutdown_status
42 static const char * const mic_shutdown_status_string[] = {
44 [MIC_CRASHED] = "crashed",
45 [MIC_HALTED] = "halted",
46 [MIC_POWER_OFF] = "poweroff",
47 [MIC_RESTART] = "restart",
50 void mic_set_shutdown_status(struct mic_device *mdev, u8 shutdown_status)
52 dev_dbg(mdev->sdev->parent, "Shutdown Status %s -> %s\n",
53 mic_shutdown_status_string[mdev->shutdown_status],
54 mic_shutdown_status_string[shutdown_status]);
55 mdev->shutdown_status = shutdown_status;
58 void mic_set_state(struct mic_device *mdev, u8 state)
60 dev_dbg(mdev->sdev->parent, "State %s -> %s\n",
61 mic_state_string[mdev->state],
62 mic_state_string[state]);
64 sysfs_notify_dirent(mdev->state_sysfs);
68 family_show(struct device *dev, struct device_attribute *attr, char *buf)
70 static const char x100[] = "x100";
71 static const char unknown[] = "Unknown";
72 const char *card = NULL;
73 struct mic_device *mdev = dev_get_drvdata(dev->parent);
78 switch (mdev->family) {
86 return scnprintf(buf, PAGE_SIZE, "%s\n", card);
88 static DEVICE_ATTR_RO(family);
91 stepping_show(struct device *dev, struct device_attribute *attr, char *buf)
93 struct mic_device *mdev = dev_get_drvdata(dev->parent);
99 switch (mdev->stepping) {
115 return scnprintf(buf, PAGE_SIZE, "%s\n", string);
117 static DEVICE_ATTR_RO(stepping);
120 state_show(struct device *dev, struct device_attribute *attr, char *buf)
122 struct mic_device *mdev = dev_get_drvdata(dev->parent);
124 if (!mdev || mdev->state >= MIC_LAST)
127 return scnprintf(buf, PAGE_SIZE, "%s\n",
128 mic_state_string[mdev->state]);
132 state_store(struct device *dev, struct device_attribute *attr,
133 const char *buf, size_t count)
136 struct mic_device *mdev = dev_get_drvdata(dev->parent);
139 if (sysfs_streq(buf, "boot")) {
140 rc = mic_start(mdev, buf);
142 dev_err(mdev->sdev->parent,
143 "mic_boot failed rc %d\n", rc);
149 if (sysfs_streq(buf, "reset")) {
150 schedule_work(&mdev->reset_trigger_work);
154 if (sysfs_streq(buf, "shutdown")) {
163 static DEVICE_ATTR_RW(state);
165 static ssize_t shutdown_status_show(struct device *dev,
166 struct device_attribute *attr, char *buf)
168 struct mic_device *mdev = dev_get_drvdata(dev->parent);
170 if (!mdev || mdev->shutdown_status >= MIC_STATUS_LAST)
173 return scnprintf(buf, PAGE_SIZE, "%s\n",
174 mic_shutdown_status_string[mdev->shutdown_status]);
176 static DEVICE_ATTR_RO(shutdown_status);
179 cmdline_show(struct device *dev, struct device_attribute *attr, char *buf)
181 struct mic_device *mdev = dev_get_drvdata(dev->parent);
187 cmdline = mdev->cmdline;
190 return scnprintf(buf, PAGE_SIZE, "%s\n", cmdline);
195 cmdline_store(struct device *dev, struct device_attribute *attr,
196 const char *buf, size_t count)
198 struct mic_device *mdev = dev_get_drvdata(dev->parent);
203 mutex_lock(&mdev->mic_mutex);
204 kfree(mdev->cmdline);
206 mdev->cmdline = kmalloc(count + 1, GFP_KERNEL);
207 if (!mdev->cmdline) {
212 strncpy(mdev->cmdline, buf, count);
214 if (mdev->cmdline[count - 1] == '\n')
215 mdev->cmdline[count - 1] = '\0';
217 mdev->cmdline[count] = '\0';
219 mutex_unlock(&mdev->mic_mutex);
222 static DEVICE_ATTR_RW(cmdline);
225 firmware_show(struct device *dev, struct device_attribute *attr, char *buf)
227 struct mic_device *mdev = dev_get_drvdata(dev->parent);
233 firmware = mdev->firmware;
236 return scnprintf(buf, PAGE_SIZE, "%s\n", firmware);
241 firmware_store(struct device *dev, struct device_attribute *attr,
242 const char *buf, size_t count)
244 struct mic_device *mdev = dev_get_drvdata(dev->parent);
249 mutex_lock(&mdev->mic_mutex);
250 kfree(mdev->firmware);
252 mdev->firmware = kmalloc(count + 1, GFP_KERNEL);
253 if (!mdev->firmware) {
257 strncpy(mdev->firmware, buf, count);
259 if (mdev->firmware[count - 1] == '\n')
260 mdev->firmware[count - 1] = '\0';
262 mdev->firmware[count] = '\0';
264 mutex_unlock(&mdev->mic_mutex);
267 static DEVICE_ATTR_RW(firmware);
270 ramdisk_show(struct device *dev, struct device_attribute *attr, char *buf)
272 struct mic_device *mdev = dev_get_drvdata(dev->parent);
278 ramdisk = mdev->ramdisk;
281 return scnprintf(buf, PAGE_SIZE, "%s\n", ramdisk);
286 ramdisk_store(struct device *dev, struct device_attribute *attr,
287 const char *buf, size_t count)
289 struct mic_device *mdev = dev_get_drvdata(dev->parent);
294 mutex_lock(&mdev->mic_mutex);
295 kfree(mdev->ramdisk);
297 mdev->ramdisk = kmalloc(count + 1, GFP_KERNEL);
298 if (!mdev->ramdisk) {
303 strncpy(mdev->ramdisk, buf, count);
305 if (mdev->ramdisk[count - 1] == '\n')
306 mdev->ramdisk[count - 1] = '\0';
308 mdev->ramdisk[count] = '\0';
310 mutex_unlock(&mdev->mic_mutex);
313 static DEVICE_ATTR_RW(ramdisk);
316 bootmode_show(struct device *dev, struct device_attribute *attr, char *buf)
318 struct mic_device *mdev = dev_get_drvdata(dev->parent);
324 bootmode = mdev->bootmode;
327 return scnprintf(buf, PAGE_SIZE, "%s\n", bootmode);
332 bootmode_store(struct device *dev, struct device_attribute *attr,
333 const char *buf, size_t count)
335 struct mic_device *mdev = dev_get_drvdata(dev->parent);
340 if (!sysfs_streq(buf, "linux") && !sysfs_streq(buf, "elf"))
343 mutex_lock(&mdev->mic_mutex);
344 kfree(mdev->bootmode);
346 mdev->bootmode = kmalloc(count + 1, GFP_KERNEL);
347 if (!mdev->bootmode) {
352 strncpy(mdev->bootmode, buf, count);
354 if (mdev->bootmode[count - 1] == '\n')
355 mdev->bootmode[count - 1] = '\0';
357 mdev->bootmode[count] = '\0';
359 mutex_unlock(&mdev->mic_mutex);
362 static DEVICE_ATTR_RW(bootmode);
365 log_buf_addr_show(struct device *dev, struct device_attribute *attr,
368 struct mic_device *mdev = dev_get_drvdata(dev->parent);
373 return scnprintf(buf, PAGE_SIZE, "%p\n", mdev->log_buf_addr);
377 log_buf_addr_store(struct device *dev, struct device_attribute *attr,
378 const char *buf, size_t count)
380 struct mic_device *mdev = dev_get_drvdata(dev->parent);
387 ret = kstrtoul(buf, 16, &addr);
391 mdev->log_buf_addr = (void *)addr;
396 static DEVICE_ATTR_RW(log_buf_addr);
399 log_buf_len_show(struct device *dev, struct device_attribute *attr,
402 struct mic_device *mdev = dev_get_drvdata(dev->parent);
407 return scnprintf(buf, PAGE_SIZE, "%p\n", mdev->log_buf_len);
411 log_buf_len_store(struct device *dev, struct device_attribute *attr,
412 const char *buf, size_t count)
414 struct mic_device *mdev = dev_get_drvdata(dev->parent);
421 ret = kstrtoul(buf, 16, &addr);
425 mdev->log_buf_len = (int *)addr;
430 static DEVICE_ATTR_RW(log_buf_len);
432 static struct attribute *mic_default_attrs[] = {
433 &dev_attr_family.attr,
434 &dev_attr_stepping.attr,
435 &dev_attr_state.attr,
436 &dev_attr_shutdown_status.attr,
437 &dev_attr_cmdline.attr,
438 &dev_attr_firmware.attr,
439 &dev_attr_ramdisk.attr,
440 &dev_attr_bootmode.attr,
441 &dev_attr_log_buf_addr.attr,
442 &dev_attr_log_buf_len.attr,
447 ATTRIBUTE_GROUPS(mic_default);
449 void mic_sysfs_init(struct mic_device *mdev)
451 mdev->attr_group = mic_default_groups;