diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/hotplug/cpqphp.h | 9 | ||||
| -rw-r--r-- | drivers/hotplug/cpqphp_core.c | 66 | ||||
| -rw-r--r-- | drivers/hotplug/cpqphp_ctrl.c | 4 | ||||
| -rw-r--r-- | drivers/hotplug/ibmphp_core.c | 32 | ||||
| -rw-r--r-- | drivers/hotplug/pci_hotplug.h | 28 | ||||
| -rw-r--r-- | drivers/hotplug/pci_hotplug_core.c | 290 | ||||
| -rw-r--r-- | drivers/pci/proc.c | 3 |
7 files changed, 351 insertions, 81 deletions
diff --git a/drivers/hotplug/cpqphp.h b/drivers/hotplug/cpqphp.h index 18f99fad6989..0be973674055 100644 --- a/drivers/hotplug/cpqphp.h +++ b/drivers/hotplug/cpqphp.h @@ -305,8 +305,8 @@ struct controller { u8 first_slot; u8 add_support; u8 push_flag; - u8 speed; /* 0 = 33MHz, 1 = 66MHz */ - u8 speed_capability; /* 0 = 33MHz, 1 = 66MHz */ + enum pci_bus_speed speed; + enum pci_bus_speed speed_capability; u8 push_button; /* 0 = no pushbutton, 1 = pushbutton present */ u8 slot_switch_type; /* 0 = no switch, 1 = switch present */ u8 defeature_PHP; /* 0 = PHP not supported, 1 = PHP supported */ @@ -321,9 +321,6 @@ struct controller { wait_queue_head_t queue; /* sleep & wake process */ }; -#define CTRL_SPEED_33MHz 0 -#define CTRL_SPEED_66MHz 1 - struct irq_mapping { u8 barber_pole; u8 valid_INT; @@ -635,7 +632,7 @@ static inline u8 get_controller_speed (struct controller *ctrl) u16 misc; misc = readw(ctrl->hpc_reg + MISC); - return (misc & 0x0800) ? 1 : 0; + return (misc & 0x0800) ? PCI_SPEED_66MHz : PCI_SPEED_33MHz; } diff --git a/drivers/hotplug/cpqphp_core.c b/drivers/hotplug/cpqphp_core.c index aec0ecc145bc..4241575713e8 100644 --- a/drivers/hotplug/cpqphp_core.c +++ b/drivers/hotplug/cpqphp_core.c @@ -79,6 +79,8 @@ static int get_power_status (struct hotplug_slot *slot, u8 *value); static int get_attention_status (struct hotplug_slot *slot, u8 *value); static int get_latch_status (struct hotplug_slot *slot, u8 *value); static int get_adapter_status (struct hotplug_slot *slot, u8 *value); +static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); +static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = { .owner = THIS_MODULE, @@ -90,6 +92,8 @@ static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = { .get_attention_status = get_attention_status, .get_latch_status = get_latch_status, .get_adapter_status = get_adapter_status, + .get_max_bus_speed = get_max_bus_speed, + .get_cur_bus_speed = get_cur_bus_speed, }; @@ -378,7 +382,7 @@ static int ctrl_slot_setup (struct controller * ctrl, void *smbios_start, void * new_slot->capabilities |= PCISLOT_64_BIT_SUPPORTED; if (is_slot66mhz(new_slot)) new_slot->capabilities |= PCISLOT_66_MHZ_SUPPORTED; - if (ctrl->speed == 1) + if (ctrl->speed == PCI_SPEED_66MHz) new_slot->capabilities |= PCISLOT_66_MHZ_OPERATION; ctrl_slot = slot_device - (readb(ctrl->hpc_reg + SLOT_MASK) >> 4); @@ -782,6 +786,44 @@ static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value) return 0; } +static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) +{ + struct slot *slot = get_slot (hotplug_slot, __FUNCTION__); + struct controller *ctrl; + + if (slot == NULL) + return -ENODEV; + + dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); + + ctrl = slot->ctrl; + if (ctrl == NULL) + return -ENODEV; + + *value = ctrl->speed_capability; + + return 0; +} + +static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) +{ + struct slot *slot = get_slot (hotplug_slot, __FUNCTION__); + struct controller *ctrl; + + if (slot == NULL) + return -ENODEV; + + dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); + + ctrl = slot->ctrl; + if (ctrl == NULL) + return -ENODEV; + + *value = ctrl->speed; + + return 0; +} + static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { u8 num_of_slots = 0; @@ -853,28 +895,28 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) case PCI_SUB_HPC_ID: /* Original 6500/7000 implementation */ ctrl->slot_switch_type = 1; // Switch is present - ctrl->speed_capability = CTRL_SPEED_33MHz; + ctrl->speed_capability = PCI_SPEED_33MHz; ctrl->push_button = 0; // No pushbutton ctrl->pci_config_space = 1; // Index/data access to working registers 0 = not supported, 1 = supported - ctrl->defeature_PHP = 1; // PHP is supported + ctrl->defeature_PHP = 1; // PHP is supported ctrl->pcix_support = 0; // PCI-X not supported - ctrl->pcix_speed_capability = 0; // N/A since PCI-X not supported + ctrl->pcix_speed_capability = 0; // N/A since PCI-X not supported break; case PCI_SUB_HPC_ID2: /* First Pushbutton implementation */ ctrl->push_flag = 1; ctrl->slot_switch_type = 1; // Switch is present - ctrl->speed_capability = CTRL_SPEED_33MHz; + ctrl->speed_capability = PCI_SPEED_33MHz; ctrl->push_button = 1; // Pushbutton is present ctrl->pci_config_space = 1; // Index/data access to working registers 0 = not supported, 1 = supported - ctrl->defeature_PHP = 1; // PHP is supported + ctrl->defeature_PHP = 1; // PHP is supported ctrl->pcix_support = 0; // PCI-X not supported - ctrl->pcix_speed_capability = 0; // N/A since PCI-X not supported + ctrl->pcix_speed_capability = 0; // N/A since PCI-X not supported break; case PCI_SUB_HPC_ID_INTC: /* Third party (6500/7000) */ ctrl->slot_switch_type = 1; // Switch is present - ctrl->speed_capability = CTRL_SPEED_33MHz; + ctrl->speed_capability = PCI_SPEED_33MHz; ctrl->push_button = 0; // No pushbutton ctrl->pci_config_space = 1; // Index/data access to working registers 0 = not supported, 1 = supported ctrl->defeature_PHP = 1; // PHP is supported @@ -885,7 +927,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* First 66 Mhz implementation */ ctrl->push_flag = 1; ctrl->slot_switch_type = 1; // Switch is present - ctrl->speed_capability = CTRL_SPEED_66MHz; + ctrl->speed_capability = PCI_SPEED_66MHz; ctrl->push_button = 1; // Pushbutton is present ctrl->pci_config_space = 1; // Index/data access to working registers 0 = not supported, 1 = supported ctrl->defeature_PHP = 1; // PHP is supported @@ -903,9 +945,9 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) case PCI_VENDOR_ID_INTEL: /* Check for speed capability (0=33, 1=66) */ if (subsystem_deviceid & 0x0001) { - ctrl->speed_capability = CTRL_SPEED_66MHz; + ctrl->speed_capability = PCI_SPEED_66MHz; } else { - ctrl->speed_capability = CTRL_SPEED_33MHz; + ctrl->speed_capability = PCI_SPEED_33MHz; } /* Check for push button */ @@ -982,7 +1024,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) info("Initializing the PCI hot plug controller residing on PCI bus %d\n", pdev->bus->number); dbg ("Hotplug controller capabilities:\n"); - dbg (" speed_capability %s\n", ctrl->speed_capability == CTRL_SPEED_33MHz ? "33MHz" : "66Mhz"); + dbg (" speed_capability %s\n", ctrl->speed_capability == PCI_SPEED_33MHz ? "33MHz" : "66Mhz"); dbg (" slot_switch_type %s\n", ctrl->slot_switch_type == 0 ? "no switch" : "switch present"); dbg (" defeature_PHP %s\n", ctrl->defeature_PHP == 0 ? "PHP not supported" : "PHP supported"); dbg (" alternate_base_address %s\n", ctrl->alternate_base_address == 0 ? "not supported" : "supported"); diff --git a/drivers/hotplug/cpqphp_ctrl.c b/drivers/hotplug/cpqphp_ctrl.c index e30b88ac17f6..d90f7eaee445 100644 --- a/drivers/hotplug/cpqphp_ctrl.c +++ b/drivers/hotplug/cpqphp_ctrl.c @@ -1187,7 +1187,7 @@ static u32 board_replaced(struct pci_func * func, struct controller * ctrl) //********************************* rc = CARD_FUNCTIONING; } else { - if (ctrl->speed == 1) { + if (ctrl->speed == PCI_SPEED_66MHz) { // Wait for exclusive access to hardware down(&ctrl->crit_sect); @@ -1385,7 +1385,7 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl) dbg("%s: func->device, slot_offset, hp_slot = %d, %d ,%d\n", __FUNCTION__, func->device, ctrl->slot_device_offset, hp_slot); - if (ctrl->speed == 1) { + if (ctrl->speed == PCI_SPEED_66MHz) { // Wait for exclusive access to hardware down(&ctrl->crit_sect); diff --git a/drivers/hotplug/ibmphp_core.c b/drivers/hotplug/ibmphp_core.c index 5113d30f93f1..04354bc93a57 100644 --- a/drivers/hotplug/ibmphp_core.c +++ b/drivers/hotplug/ibmphp_core.c @@ -384,14 +384,15 @@ static int get_adapter_present (struct hotplug_slot *hotplug_slot, u8 * value) debug ("get_adapter_present - Exit rc[%d] hpcrc[%x] value[%x]\n", rc, hpcrc, *value); return rc; } -/* -static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, u8 * value) + +static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) { int rc = -ENODEV; struct slot *pslot; u8 mode = 0; - debug ("get_max_bus_speed - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong)hotplug_slot, (ulong) value); + debug ("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __FUNCTION__, + hotplug_slot, value); ibmphp_lock_operations (); @@ -413,25 +414,26 @@ static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, u8 * value) *value = pslot->supported_speed + 0x01; break; default: -*/ /* Note (will need to change): there would be soon 256, 512 also */ -/* rc = -ENODEV; + /* Note (will need to change): there would be soon 256, 512 also */ + rc = -ENODEV; } } } else rc = -ENODEV; ibmphp_unlock_operations (); - debug ("get_max_bus_speed - Exit rc[%d] value[%x]\n", rc, *value); + debug ("%s - Exit rc[%d] value[%x]\n", __FUNCTION__, rc, *value); return rc; } -static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, u8 * value) +static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) { int rc = -ENODEV; struct slot *pslot; u8 mode = 0; - debug ("get_cur_bus_speed - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong)hotplug_slot, (ulong) value); + debug ("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __FUNCTION__, + hotplug_slot, value); ibmphp_lock_operations (); @@ -458,8 +460,8 @@ static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, u8 * value) *value += 0x01; break; default: -*/ /* Note of change: there would also be 256, 512 soon */ -/* rc = -ENODEV; + /* Note of change: there would also be 256, 512 soon */ + rc = -ENODEV; } } } @@ -467,10 +469,10 @@ static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, u8 * value) rc = -ENODEV; ibmphp_unlock_operations (); - debug ("get_cur_bus_speed - Exit rc[%d] value[%x]\n", rc, *value); + debug ("%s - Exit rc[%d] value[%x]\n", __FUNCTION__, rc, *value); return rc; } - +/* static int get_max_adapter_speed_1 (struct hotplug_slot *hotplug_slot, u8 * value, u8 flag) { int rc = -ENODEV; @@ -1584,9 +1586,9 @@ struct hotplug_slot_ops ibmphp_hotplug_slot_ops = { .get_attention_status = get_attention_status, .get_latch_status = get_latch_status, .get_adapter_status = get_adapter_present, -/* .get_max_bus_speed_status = get_max_bus_speed, - .get_max_adapter_speed_status = get_max_adapter_speed, - .get_cur_bus_speed_status = get_cur_bus_speed, + .get_max_bus_speed = get_max_bus_speed, + .get_cur_bus_speed = get_cur_bus_speed, +/* .get_max_adapter_speed = get_max_adapter_speed, .get_bus_name_status = get_bus_name, */ }; diff --git a/drivers/hotplug/pci_hotplug.h b/drivers/hotplug/pci_hotplug.h index ae13d0c7ee5b..c7cd9e968193 100644 --- a/drivers/hotplug/pci_hotplug.h +++ b/drivers/hotplug/pci_hotplug.h @@ -29,6 +29,22 @@ #define _PCI_HOTPLUG_H +/* These values come from the PCI Hotplug Spec */ +enum pci_bus_speed { + PCI_SPEED_33MHz = 0x00, + PCI_SPEED_66MHz = 0x01, + PCI_SPEED_66MHz_PCIX = 0x02, + PCI_SPEED_100MHz_PCIX = 0x03, + PCI_SPEED_133MHz_PCIX = 0x04, + PCI_SPEED_66MHz_PCIX_266 = 0x09, + PCI_SPEED_100MHz_PCIX_266 = 0x0a, + PCI_SPEED_133MHz_PCIX_266 = 0x0b, + PCI_SPEED_66MHz_PCIX_533 = 0x11, + PCI_SPEED_100MHz_PCIX_533 = 0X12, + PCI_SPEED_133MHz_PCIX_533 = 0x13, + PCI_SPEED_UNKNOWN = 0xff, +}; + struct hotplug_slot; struct hotplug_slot_core; @@ -50,7 +66,13 @@ struct hotplug_slot_core; * @get_latch_status: Called to get the current latch status of a slot. * If this field is NULL, the value passed in the struct hotplug_slot_info * will be used when this value is requested by a user. - * @get_adapter_present: Called to get see if an adapter is present in the slot or not. + * @get_adapter_status: Called to get see if an adapter is present in the slot or not. + * If this field is NULL, the value passed in the struct hotplug_slot_info + * will be used when this value is requested by a user. + * @get_max_bus_speed: Called to get the max bus speed for a slot. + * If this field is NULL, the value passed in the struct hotplug_slot_info + * will be used when this value is requested by a user. + * @get_cur_bus_speed: Called to get the current bus speed for a slot. * If this field is NULL, the value passed in the struct hotplug_slot_info * will be used when this value is requested by a user. * @@ -69,6 +91,8 @@ struct hotplug_slot_ops { int (*get_attention_status) (struct hotplug_slot *slot, u8 *value); int (*get_latch_status) (struct hotplug_slot *slot, u8 *value); int (*get_adapter_status) (struct hotplug_slot *slot, u8 *value); + int (*get_max_bus_speed) (struct hotplug_slot *slot, enum pci_bus_speed *value); + int (*get_cur_bus_speed) (struct hotplug_slot *slot, enum pci_bus_speed *value); }; /** @@ -85,6 +109,8 @@ struct hotplug_slot_info { u8 attention_status; u8 latch_status; u8 adapter_status; + enum pci_bus_speed max_bus_speed; + enum pci_bus_speed cur_bus_speed; }; /** diff --git a/drivers/hotplug/pci_hotplug_core.c b/drivers/hotplug/pci_hotplug_core.c index 15bc11a842c8..89e2247acd80 100644 --- a/drivers/hotplug/pci_hotplug_core.c +++ b/drivers/hotplug/pci_hotplug_core.c @@ -38,6 +38,8 @@ #include <linux/init.h> #include <linux/namei.h> #include <linux/pci.h> +#include <linux/dnotify.h> +#include <linux/proc_fs.h> #include <asm/uaccess.h> #include "pci_hotplug.h" @@ -74,6 +76,8 @@ struct hotplug_slot_core { struct dentry *latch_dentry; struct dentry *adapter_dentry; struct dentry *test_dentry; + struct dentry *max_bus_speed_dentry; + struct dentry *cur_bus_speed_dentry; }; static struct super_operations pcihpfs_ops; @@ -86,6 +90,35 @@ static spinlock_t list_lock; LIST_HEAD(pci_hotplug_slot_list); +/* these strings match up with the values in pci_bus_speed */ +static char *pci_bus_speed_strings[] = { + "33 MHz PCI", /* 0x00 */ + "66 MHz PCI", /* 0x01 */ + "66 MHz PCIX", /* 0x02 */ + "100 MHz PCIX", /* 0x03 */ + "133 MHz PCIX", /* 0x04 */ + NULL, /* 0x05 */ + NULL, /* 0x06 */ + NULL, /* 0x07 */ + NULL, /* 0x08 */ + "66 MHz PCIX 266", /* 0x09 */ + "100 MHz PCIX 266", /* 0x0a */ + "133 MHz PCIX 266", /* 0x0b */ + NULL, /* 0x0c */ + NULL, /* 0x0d */ + NULL, /* 0x0e */ + NULL, /* 0x0f */ + NULL, /* 0x10 */ + "66 MHz PCIX 533", /* 0x11 */ + "100 MHz PCIX 533", /* 0x12 */ + "133 MHz PCIX 533", /* 0x13 */ +}; + +#ifdef CONFIG_PROC_FS +extern struct proc_dir_entry *proc_bus_pci_dir; +static struct proc_dir_entry *slotdir = NULL; +static const char *slotdir_name = "slots"; +#endif static struct inode *pcihpfs_get_inode (struct super_block *sb, int mode, int dev) { @@ -274,6 +307,24 @@ static struct file_operations presence_file_operations = { .llseek = default_file_lseek, }; +/* file ops for the "max bus speed" files */ +static ssize_t max_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset); +static struct file_operations max_bus_speed_file_operations = { + read: max_bus_speed_read_file, + write: default_write_file, + open: default_open, + llseek: default_file_lseek, +}; + +/* file ops for the "current bus speed" files */ +static ssize_t cur_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset); +static struct file_operations cur_bus_speed_file_operations = { + read: cur_bus_speed_read_file, + write: default_write_file, + open: default_open, + llseek: default_file_lseek, +}; + /* file ops for the "test" files */ static ssize_t test_write_file (struct file *file, const char *buf, size_t count, loff_t *ppos); static struct file_operations test_file_operations = { @@ -501,26 +552,28 @@ static void fs_remove_file (struct dentry *dentry) up(&parent->d_inode->i_sem); } -#define GET_STATUS(name) \ -static int get_##name##_status (struct hotplug_slot *slot, u8 *value) \ +#define GET_STATUS(name,type) \ +static int get_##name (struct hotplug_slot *slot, type *value) \ { \ struct hotplug_slot_ops *ops = slot->ops; \ int retval = 0; \ if (ops->owner) \ __MOD_INC_USE_COUNT(ops->owner); \ - if (ops->get_##name##_status) \ - retval = ops->get_##name##_status (slot, value); \ + if (ops->get_##name) \ + retval = ops->get_##name (slot, value); \ else \ - *value = slot->info->name##_status; \ + *value = slot->info->name; \ if (ops->owner) \ __MOD_DEC_USE_COUNT(ops->owner); \ return retval; \ } -GET_STATUS(power) -GET_STATUS(attention) -GET_STATUS(latch) -GET_STATUS(adapter) +GET_STATUS(power_status, u8) +GET_STATUS(attention_status, u8) +GET_STATUS(latch_status, u8) +GET_STATUS(adapter_status, u8) +GET_STATUS(max_bus_speed, enum pci_bus_speed) +GET_STATUS(cur_bus_speed, enum pci_bus_speed) static ssize_t power_read_file (struct file *file, char *buf, size_t count, loff_t *offset) { @@ -575,7 +628,7 @@ static ssize_t power_write_file (struct file *file, const char *ubuff, size_t co if (*offset < 0) return -EINVAL; - if (count <= 0) + if (count == 0 || count > 16384) return 0; if (*offset != 0) return 0; @@ -686,7 +739,7 @@ static ssize_t attention_write_file (struct file *file, const char *ubuff, size_ if (*offset < 0) return -EINVAL; - if (count <= 0) + if (count == 0 || count > 16384) return 0; if (*offset != 0) return 0; @@ -769,7 +822,6 @@ exit: return retval; } - static ssize_t presence_read_file (struct file *file, char *buf, size_t count, loff_t *offset) { struct hotplug_slot *slot = file->private_data; @@ -813,6 +865,108 @@ exit: return retval; } +static char *unknown_speed = "Unknown bus speed"; + +static ssize_t max_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset) +{ + struct hotplug_slot *slot = file->private_data; + unsigned char *page; + char *speed_string; + int retval; + int len = 0; + enum pci_bus_speed value; + + dbg ("count = %d, offset = %lld\n", count, *offset); + + if (*offset < 0) + return -EINVAL; + if (count <= 0) + return 0; + if (*offset != 0) + return 0; + + if (slot == NULL) { + dbg("slot == NULL???\n"); + return -ENODEV; + } + + page = (unsigned char *)__get_free_page(GFP_KERNEL); + if (!page) + return -ENOMEM; + + retval = get_max_bus_speed (slot, &value); + if (retval) + goto exit; + + if (value == PCI_SPEED_UNKNOWN) + speed_string = unknown_speed; + else + speed_string = pci_bus_speed_strings[value]; + + len = sprintf (page, "%s\n", speed_string); + + if (copy_to_user (buf, page, len)) { + retval = -EFAULT; + goto exit; + } + *offset += len; + retval = len; + +exit: + free_page((unsigned long)page); + return retval; +} + +static ssize_t cur_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset) +{ + struct hotplug_slot *slot = file->private_data; + unsigned char *page; + char *speed_string; + int retval; + int len = 0; + enum pci_bus_speed value; + + dbg ("count = %d, offset = %lld\n", count, *offset); + + if (*offset < 0) + return -EINVAL; + if (count <= 0) + return 0; + if (*offset != 0) + return 0; + + if (slot == NULL) { + dbg("slot == NULL???\n"); + return -ENODEV; + } + + page = (unsigned char *)__get_free_page(GFP_KERNEL); + if (!page) + return -ENOMEM; + + retval = get_cur_bus_speed (slot, &value); + if (retval) + goto exit; + + if (value == PCI_SPEED_UNKNOWN) + speed_string = unknown_speed; + else + speed_string = pci_bus_speed_strings[value]; + + len = sprintf (page, "%s\n", speed_string); + + if (copy_to_user (buf, page, len)) { + retval = -EFAULT; + goto exit; + } + *offset += len; + retval = len; + +exit: + free_page((unsigned long)page); + return retval; +} + static ssize_t test_write_file (struct file *file, const char *ubuff, size_t count, loff_t *offset) { struct hotplug_slot *slot = file->private_data; @@ -823,7 +977,7 @@ static ssize_t test_write_file (struct file *file, const char *ubuff, size_t cou if (*offset < 0) return -EINVAL; - if (count <= 0) + if (count == 0 || count > 16384) return 0; if (*offset != 0) return 0; @@ -876,30 +1030,57 @@ static int fs_add_slot (struct hotplug_slot *slot) S_IFDIR | S_IXUGO | S_IRUGO, NULL, NULL, NULL); if (core->dir_dentry != NULL) { - core->power_dentry = fs_create_file ("power", - S_IFREG | S_IRUGO | S_IWUSR, - core->dir_dentry, slot, - &power_file_operations); - - core->attention_dentry = fs_create_file ("attention", - S_IFREG | S_IRUGO | S_IWUSR, - core->dir_dentry, slot, - &attention_file_operations); - - core->latch_dentry = fs_create_file ("latch", - S_IFREG | S_IRUGO, - core->dir_dentry, slot, - &latch_file_operations); - - core->adapter_dentry = fs_create_file ("adapter", - S_IFREG | S_IRUGO, - core->dir_dentry, slot, - &presence_file_operations); - - core->test_dentry = fs_create_file ("test", - S_IFREG | S_IRUGO | S_IWUSR, - core->dir_dentry, slot, - &test_file_operations); + if ((slot->ops->enable_slot) || + (slot->ops->disable_slot) || + (slot->ops->get_power_status)) + core->power_dentry = + fs_create_file ("power", + S_IFREG | S_IRUGO | S_IWUSR, + core->dir_dentry, slot, + &power_file_operations); + + if ((slot->ops->set_attention_status) || + (slot->ops->get_attention_status)) + core->attention_dentry = + fs_create_file ("attention", + S_IFREG | S_IRUGO | S_IWUSR, + core->dir_dentry, slot, + &attention_file_operations); + + if (slot->ops->get_latch_status) + core->latch_dentry = + fs_create_file ("latch", + S_IFREG | S_IRUGO, + core->dir_dentry, slot, + &latch_file_operations); + + if (slot->ops->get_adapter_status) + core->adapter_dentry = + fs_create_file ("adapter", + S_IFREG | S_IRUGO, + core->dir_dentry, slot, + &presence_file_operations); + + if (slot->ops->get_max_bus_speed) + core->max_bus_speed_dentry = + fs_create_file ("max_bus_speed", + S_IFREG | S_IRUGO, + core->dir_dentry, slot, + &max_bus_speed_file_operations); + + if (slot->ops->get_cur_bus_speed) + core->cur_bus_speed_dentry = + fs_create_file ("cur_bus_speed", + S_IFREG | S_IRUGO, + core->dir_dentry, slot, + &cur_bus_speed_file_operations); + + if (slot->ops->hardware_test) + core->test_dentry = + fs_create_file ("test", + S_IFREG | S_IRUGO | S_IWUSR, + core->dir_dentry, slot, + &test_file_operations); } return 0; } @@ -917,6 +1098,10 @@ static void fs_remove_slot (struct hotplug_slot *slot) fs_remove_file (core->latch_dentry); if (core->adapter_dentry) fs_remove_file (core->adapter_dentry); + if (core->max_bus_speed_dentry) + fs_remove_file (core->max_bus_speed_dentry); + if (core->cur_bus_speed_dentry) + fs_remove_file (core->cur_bus_speed_dentry); if (core->test_dentry) fs_remove_file (core->test_dentry); fs_remove_file (core->dir_dentry); @@ -969,6 +1154,7 @@ int pci_hp_register (struct hotplug_slot *slot) return -EINVAL; } + memset (core, 0, sizeof (struct hotplug_slot_core)); slot->core_priv = core; list_add (&slot->slot_list, &pci_hotplug_slot_list); @@ -1012,10 +1198,13 @@ int pci_hp_deregister (struct hotplug_slot *slot) return 0; } -static inline void update_inode_time (struct inode *inode) +static inline void update_dentry_inode_time (struct dentry *dentry) { - if (inode) - inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; + struct inode *inode = dentry->d_inode; + if (inode) { + inode->i_mtime = CURRENT_TIME; + dnotify_parent(dentry, DN_MODIFY); + } } /** @@ -1050,16 +1239,19 @@ int pci_hp_change_slot_info (const char *name, struct hotplug_slot_info *info) core = temp->core_priv; if ((core->power_dentry) && (temp->info->power_status != info->power_status)) - update_inode_time (core->power_dentry->d_inode); + update_dentry_inode_time (core->power_dentry); if ((core->attention_dentry) && (temp->info->attention_status != info->attention_status)) - update_inode_time (core->attention_dentry->d_inode); + update_dentry_inode_time (core->attention_dentry); if ((core->latch_dentry) && (temp->info->latch_status != info->latch_status)) - update_inode_time (core->latch_dentry->d_inode); + update_dentry_inode_time (core->latch_dentry); if ((core->adapter_dentry) && (temp->info->adapter_status != info->adapter_status)) - update_inode_time (core->adapter_dentry->d_inode); + update_dentry_inode_time (core->adapter_dentry); + if ((core->cur_bus_speed_dentry) && + (temp->info->cur_bus_speed != info->cur_bus_speed)) + update_dentry_inode_time (core->cur_bus_speed_dentry); memcpy (temp->info, info, sizeof (struct hotplug_slot_info)); spin_unlock (&list_lock); @@ -1080,6 +1272,11 @@ static int __init pci_hotplug_init (void) goto exit; } +#ifdef CONFIG_PROC_FS + /* create mount point for pcihpfs */ + slotdir = proc_mkdir(slotdir_name, proc_bus_pci_dir); +#endif + info (DRIVER_DESC " version: " DRIVER_VERSION "\n"); exit: @@ -1089,6 +1286,11 @@ exit: static void __exit pci_hotplug_exit (void) { unregister_filesystem(&pcihpfs_type); + +#ifdef CONFIG_PROC_FS + if (slotdir) + remove_proc_entry(slotdir_name, proc_bus_pci_dir); +#endif } module_init(pci_hotplug_init); diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index 582fac9f16f7..cc72b3a8251d 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c @@ -371,7 +371,7 @@ static struct seq_operations proc_bus_pci_devices_op = { show: show_device }; -static struct proc_dir_entry *proc_bus_pci_dir; +struct proc_dir_entry *proc_bus_pci_dir; /* driverfs files */ static ssize_t pci_show_irq(struct device * dev, char * buf, size_t count, loff_t off) @@ -621,5 +621,6 @@ EXPORT_SYMBOL(pci_proc_attach_device); EXPORT_SYMBOL(pci_proc_detach_device); EXPORT_SYMBOL(pci_proc_attach_bus); EXPORT_SYMBOL(pci_proc_detach_bus); +EXPORT_SYMBOL(proc_bus_pci_dir); #endif |
