Re: [PATCH] lib/relocator: always enforce the requested alignment in malloc_in_range()
On Fri, Apr 28, 2023 at 04:15:24PM +0200, Daniel Kiper wrote: > On Thu, Apr 27, 2023 at 05:06:54PM +0200, Roger Pau Monne via Grub-devel > wrote: > > On failure to allocate from grub_relocator_firmware_alloc_region() in > > malloc_in_range() the function would stop enforcing the alignment, and > > the following was returned: > > > > lib/relocator.c:431: trying to allocate in 0x20-0xffbf9fff aligned > > 0x20 size 0x406000 > > lib/relocator.c:1197: allocated: 0x74de2000+0x406000 > > lib/relocator.c:1407: allocated 0x74de2000/0x74de2000 > > > > Fix this by making sure that target always contains a suitably aligned > > address. After the change the return from the function is: > > > > lib/relocator.c:431: trying to allocate in 0x20-0xffb87fff aligned > > 0x20 size 0x478000 > > lib/relocator.c:1204: allocated: 0x74c0+0x478000 > > lib/relocator.c:1414: allocated 0x74c0/0x74c0 > > > > Fixes: 3a5768645c05 ('First version of allocation from firmware') > > Signed-off-by: Roger Pau Monné > > LGTM but I would like to hear Vladimir's opinion too. Thanks Daniel, just a gentle ping to see if we can unblock this. Regards, Roger. ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH 0/6] NVMeoFC support on Grub
This patch series adds support of NVMeoFC on grub. It consists of six patches. Patch 1/6 (0001-ieee1275-powerpc-implements-fibre-channel-discovery-.patch): grub-ofpathname doesn't work with fibre channel because there is no function currently implemented for it. This patch enables it by prividing a function that looks for the port name, building the entire path for OF devices. Patch 2/6(0002-ieee1275-powerpc-enables-device-mapper-discovery.patch): This patch enables the device mapper discovery on ofpath.c. Currently, when we are dealing with a device like /dev/dm-* the ofpath returns null since there is no function implemented to handle this case. This patch implements a function that will look into /sys/block/dm-* devices and search recursively inside slaves directory to find the root disk. Patch 3/6(0003-ieee1275-implement-FCP-methods-for-WWPN-and-LUNs.patch): This patch enables the fcp-targets and fcp-luns methods which are responsible to get WWPNs and LUNs for fibre channel devices. Those methods are specially necessary if the boot directory and grub installation are in different FCP disks, allowing the dev_iterate() to find the WWPNs and LUNs when called by searchfs.uuid tool. Patch 4/6(0004-change-partition-parser.patch): Usually grub will parse the PFW arguments by searching for the first occurence of the character ':'. However, we can have this char more than once on NQN. This patch changes the logic to find the last occurence of this char so we can get the proper values for NVMeoFC Patch 5/6(0005-ieee1275-add-support-for-NVMeoFC.patch): This patch implements the functions to scan and discovery of NVMeoFC. Patch 6/6(0006-ieee1275-ofpath-enable-NVMeoF-logical-device-transla.patch): This patch add code to enable the translation of logical devices to the of NVMeoFC paths. Avnish Chouhan (4): ieee1275: implement FCP methods for WWPN and LUNs ieee1275: change the logic of ieee1275_get_devargs() ieee1275: add support for NVMeoFC ieee1275: ofpath enable NVMeoF logical device translate Diego Domingos (2): ieee1275/powerpc: implements fibre channel discovery for ofpathname ieee1275/powerpc: enables device mapper discovery grub-core/disk/ieee1275/ofdisk.c grub-core/kern/ieee1275/openfw.c grub-core/osdep/linux/ofpath.c include/grub/util/ofpath.h 4 files changed -- 2.31.1 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH 1/6] ieee1275/powerpc: implements fibre channel discovery for ofpathname
From: Diego Domingos grub-ofpathname doesn't work with fibre channel because there is no function currently implemented for it. This patch enables it by prividing a function that looks for the port name, building the entire path for OF devices. Signed-off-by: Diego Domingos --- grub-core/osdep/linux/ofpath.c | 49 ++ 1 file changed, 49 insertions(+) diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c index a6153d35954..0f5d54e9f2d 100644 --- a/grub-core/osdep/linux/ofpath.c +++ b/grub-core/osdep/linux/ofpath.c @@ -350,6 +350,38 @@ of_path_of_ide(const char *sys_devname __attribute__((unused)), const char *devi return ret; } + +static void +of_fc_port_name(const char *path, const char *subpath, char *port_name) +{ + char *bname, *basepath, *p; + int fd; + + bname = xmalloc(sizeof(char)*150); + basepath = xmalloc(strlen(path)); + + /* Generate the path to get port name information from the drive */ + strncpy(basepath,path,subpath-path); + basepath[subpath-path-1] = '\0'; + p = get_basename(basepath); + snprintf(bname,sizeof(char)*150,"%s/fc_transport/%s/port_name",basepath,p); + + /* Read the information from the port name */ + fd = open (bname, O_RDONLY); + if (fd < 0) +grub_util_error (_("cannot open `%s': %s"), bname, strerror (errno)); + + if (read(fd,port_name,sizeof(char)*19) < 0) +grub_util_error (_("cannot read `%s': %s"), bname, strerror (errno)); + + sscanf(port_name,"0x%s",port_name); + + close(fd); + + free(bname); + free(basepath); +} + #ifdef __sparc__ static char * of_path_of_nvme(const char *sys_devname __attribute__((unused)), @@ -577,6 +609,16 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev digit_string = trailing_digits (device); if (strncmp (of_path, "/vdevice/", sizeof ("/vdevice/") - 1) == 0) { + if(strstr(of_path,"vfc-client")) +{ + char * port_name = xmalloc(sizeof(char)*17); + of_fc_port_name(sysfs_path, p, port_name); + + snprintf(disk,sizeof(disk),"/%s@%s", disk_name, port_name); + free(port_name); +} + else +{ unsigned long id = 0x8000 | (tgt << 8) | (bus << 5) | lun; if (*digit_string == '\0') { @@ -590,6 +632,13 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev snprintf(disk, sizeof (disk), "/%s@%04lx:%c", disk_name, id, 'a' + (part - 1)); } + } +} else if (strstr(of_path,"fibre-channel")||(strstr(of_path,"vfc-client"))){ +char * port_name = xmalloc(sizeof(char)*17); +of_fc_port_name(sysfs_path, p, port_name); + +snprintf(disk,sizeof(disk),"/%s@%s", disk_name, port_name); +free(port_name); } else { ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH 5/6] ieee1275: add support for NVMeoFC
This patch implements the functions to scan and discovery of NVMeoFC. Signed-off-by: Diego Domingos Signed-off-by: Avnish Chouhan --- grub-core/disk/ieee1275/ofdisk.c | 390 +-- 1 file changed, 296 insertions(+), 94 deletions(-) diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c index afdc272..cea10e1 100644 --- a/grub-core/disk/ieee1275/ofdisk.c +++ b/grub-core/disk/ieee1275/ofdisk.c @@ -24,6 +24,8 @@ #include #include #include +#define EXTEND_PATH_64 64 +#define EXTEND_PATH_512 512 static char *last_devpath; static grub_ieee1275_ihandle_t last_ihandle; @@ -207,116 +209,316 @@ dev_iterate_real (const char *name, const char *path) } static void -dev_iterate (const struct grub_ieee1275_devalias *alias) +dev_iterate_fcp_disks(const struct grub_ieee1275_devalias *alias) { - if (grub_strcmp (alias->type, "fcp") == 0) + /* + * If we are dealing with fcp devices, we need + * to find the WWPNs and LUNs to iterate them + */ + grub_ieee1275_ihandle_t ihandle; + grub_uint64_t *ptr_targets, *ptr_luns, k, l; + unsigned int i, j, pos; + char *buf, *bufptr; + struct set_fcp_targets_args + { +struct grub_ieee1275_common_hdr common; +grub_ieee1275_cell_t method; +grub_ieee1275_cell_t ihandle; +grub_ieee1275_cell_t catch_result; +grub_ieee1275_cell_t nentries; +grub_ieee1275_cell_t table; + } args_targets; + + struct set_fcp_luns_args + { +struct grub_ieee1275_common_hdr common; +grub_ieee1275_cell_t method; +grub_ieee1275_cell_t ihandle; +grub_ieee1275_cell_t wwpn_h; +grub_ieee1275_cell_t wwpn_l; +grub_ieee1275_cell_t catch_result; +grub_ieee1275_cell_t nentries; +grub_ieee1275_cell_t table; + } args_luns; + + struct args_ret + { +grub_uint64_t addr; +grub_uint64_t len; + }; + struct args_ret *targets_table; + struct args_ret *luns_table; + + if (grub_ieee1275_open (alias->path, &ihandle)) { - /* - * If we are dealing with fcp devices, we need - * to find the WWPNs and LUNs to iterate them - */ - grub_ieee1275_ihandle_t ihandle; - grub_uint64_t *ptr_targets, *ptr_luns, k, l; - unsigned int i, j, pos; - char *buf, *bufptr; - struct set_fcp_targets_args - { -struct grub_ieee1275_common_hdr common; -grub_ieee1275_cell_t method; -grub_ieee1275_cell_t ihandle; -grub_ieee1275_cell_t catch_result; -grub_ieee1275_cell_t nentries; -grub_ieee1275_cell_t table; - } args_targets; - - struct set_fcp_luns_args - { -struct grub_ieee1275_common_hdr common; -grub_ieee1275_cell_t method; -grub_ieee1275_cell_t ihandle; -grub_ieee1275_cell_t wwpn_h; -grub_ieee1275_cell_t wwpn_l; -grub_ieee1275_cell_t catch_result; -grub_ieee1275_cell_t nentries; -grub_ieee1275_cell_t table; - } args_luns; - - struct args_ret - { -grub_uint64_t addr; -grub_uint64_t len; - }; + grub_dprintf("disk", "failed to open the disk while iterating FCP disk path=%s\n", alias->path); + return; +} + + /* Setup the fcp-targets method to call via pfw*/ + INIT_IEEE1275_COMMON (&args_targets.common, "call-method", 2, 3); + args_targets.method = (grub_ieee1275_cell_t) "fcp-targets"; + args_targets.ihandle = ihandle; - if(grub_ieee1275_open (alias->path, &ihandle)) + /* Setup the fcp-luns method to call via pfw */ + INIT_IEEE1275_COMMON (&args_luns.common, "call-method", 4, 3); + args_luns.method = (grub_ieee1275_cell_t) "fcp-luns"; + args_luns.ihandle = ihandle; + if (IEEE1275_CALL_ENTRY_FN (&args_targets) == -1) +{ + grub_dprintf("disk", "failed to get the targets while iterating FCP disk path=%s\n", alias->path); + grub_ieee1275_close(ihandle); + return; +} + /* Allocate memory for building the path */ + buf = grub_malloc (grub_strlen (alias->path) + EXTEND_PATH_64); + if (!buf) +{ + grub_ieee1275_close(ihandle); + return; +} + bufptr = grub_stpcpy (buf, alias->path); + + /* + * Iterate over entries returned by pfw. Each entry contains a + * pointer to wwpn table and his length. + */ + targets_table = (struct args_ret *)(args_targets.table); + for (i=0; i< args_targets.nentries; i++) +{ + ptr_targets = (grub_uint64_t*) targets_table[i].addr; + /* Iterate over all wwpns in given table */ + for (k=0; kpath); - return; + args_luns.wwpn_l = (grub_ieee1275_cell_t) (*ptr_targets); + args_luns.wwpn_h = (grub_ieee1275_cell_t) (*ptr_targets >> 32); + pos = grub_snprintf (bufptr, 32, "/disk@%" PRIxGRUB_UINT64_T, + *ptr_targets++); + /* Get the luns for given wwpn target */ + if (IEEE1275_CALL_ENTRY_FN (&args_luns) == -1) +{ + grub_dprintf("disk", "failed to get the LUNS w
[PATCH 3/6] ieee1275: implement FCP methods for WWPN and LUNs
This patch enables the fcp-targets and fcp-luns methods which are responsible to get WWPNs and LUNs for fibre channel devices. Those methods are specially necessary if the boot directory and grub installation are in different FCP disks, allowing the dev_iterate() to find the WWPNs and LUNs when called by searchfs.uuid tool. Signed-off-by: Diego Domingos Signed-off-by: Avnish Chouhan --- grub-core/disk/ieee1275/ofdisk.c | 111 ++- 1 file changed, 110 insertions(+), 1 deletion(-) diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c index 5534684..5958e5e 100644 --- a/grub-core/disk/ieee1275/ofdisk.c +++ b/grub-core/disk/ieee1275/ofdisk.c @@ -209,7 +209,116 @@ dev_iterate_real (const char *name, const char *path) static void dev_iterate (const struct grub_ieee1275_devalias *alias) { - if (grub_strcmp (alias->type, "vscsi") == 0) + if (grub_strcmp (alias->type, "fcp") == 0) +{ + /* + * If we are dealing with fcp devices, we need + * to find the WWPNs and LUNs to iterate them + */ + grub_ieee1275_ihandle_t ihandle; + grub_uint64_t *ptr_targets, *ptr_luns, k, l; + unsigned int i, j, pos; + char *buf, *bufptr; + struct set_fcp_targets_args + { +struct grub_ieee1275_common_hdr common; +grub_ieee1275_cell_t method; +grub_ieee1275_cell_t ihandle; +grub_ieee1275_cell_t catch_result; +grub_ieee1275_cell_t nentries; +grub_ieee1275_cell_t table; + } args_targets; + + struct set_fcp_luns_args + { +struct grub_ieee1275_common_hdr common; +grub_ieee1275_cell_t method; +grub_ieee1275_cell_t ihandle; +grub_ieee1275_cell_t wwpn_h; +grub_ieee1275_cell_t wwpn_l; +grub_ieee1275_cell_t catch_result; +grub_ieee1275_cell_t nentries; +grub_ieee1275_cell_t table; + } args_luns; + + struct args_ret + { +grub_uint64_t addr; +grub_uint64_t len; + }; + + if(grub_ieee1275_open (alias->path, &ihandle)) +{ + grub_dprintf("disk", "failed to open the disk while iterating FCP disk path=%s\n", alias->path); + return; +} + + /* Setup the fcp-targets method to call via pfw*/ + INIT_IEEE1275_COMMON (&args_targets.common, "call-method", 2, 3); + args_targets.method = (grub_ieee1275_cell_t) "fcp-targets"; + args_targets.ihandle = ihandle; + + /* Setup the fcp-luns method to call via pfw */ + INIT_IEEE1275_COMMON (&args_luns.common, "call-method", 4, 3); + args_luns.method = (grub_ieee1275_cell_t) "fcp-luns"; + args_luns.ihandle = ihandle; + if (IEEE1275_CALL_ENTRY_FN (&args_targets) == -1) +{ + grub_dprintf("disk", "failed to get the targets while iterating FCP disk path=%s\n", alias->path); + grub_ieee1275_close(ihandle); + return; +} + buf = grub_malloc (grub_strlen (alias->path) + 32 + 32); + if (!buf) +{ + grub_ieee1275_close(ihandle); + return; +} + bufptr = grub_stpcpy (buf, alias->path); + + /* + * Iterate over entries returned by pfw. Each entry contains a + * pointer to wwpn table and his length. + */ + struct args_ret *targets_table = (struct args_ret *)(args_targets.table); + for (i=0; i< args_targets.nentries; i++) +{ + ptr_targets = (grub_uint64_t*)(grub_uint32_t) targets_table[i].addr; + /* Iterate over all wwpns in given table */ + for(k=0;k> 32); + pos = grub_snprintf (bufptr, 32, "/disk@%" PRIxGRUB_UINT64_T, + *ptr_targets++); + /* Get the luns for given wwpn target */ + if (IEEE1275_CALL_ENTRY_FN (&args_luns) == -1) +{ + grub_dprintf("disk", "failed to get the LUNS while iterating FCP disk path=%s\n", buf); + grub_ieee1275_close (ihandle); + grub_free (buf); + return; +} + struct args_ret *luns_table = (struct args_ret *)(args_luns.table); + + /* Iterate over all LUNs */ + for(j=0;jtype, "vscsi") == 0) { static grub_ieee1275_ihandle_t ihandle; struct set_color_args -- 2.31.1 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH 6/6] ieee1275: ofpath enable NVMeoF logical device translate
This patch add code to enable the translation of logical devices to the of NVMeoFC paths. Signed-off-by: Diego Domingos Signed-off-by: Avnish Chouhan --- grub-core/osdep/linux/ofpath.c | 371 +-- include/grub/util/ofpath.h | 28 2 file changed, 390 insertions(+), 9 deletions(-) diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c index cc849d9..a2b4eeb 100644 --- a/grub-core/osdep/linux/ofpath.c +++ b/grub-core/osdep/linux/ofpath.c @@ -137,7 +137,7 @@ trim_newline (char *path) *end-- = '\0'; } -#define MAX_DISK_CAT64 +#define MAX_DISK_CAT512 static char * find_obppath (const char *sysfs_path_orig) @@ -313,6 +313,92 @@ get_basename(char *p) return ret; } + +int +add_filename_to_pile(char *filename, struct ofpath_files_list_root* root) +{ + struct ofpath_files_list_node* file; + + file = malloc(sizeof(struct ofpath_files_list_node)); + if (!file) +return -1; + + file->filename = malloc(sizeof(char) * 1024); + if (!file->filename) +{ + grub_free(file); + return -1; +} + + grub_strcpy (file->filename, filename); + if (root->first == NULL) +{ + root->items = 1; + root->first = file; + file->next = NULL; +} + else +{ + root->items++; + file->next = root->first; + root->first = file; +} + + return 0; +} + +void +find_file(char* filename, char* directory, struct ofpath_files_list_root* root, int max_depth, int depth) +{ + struct dirent *ep; + struct stat statbuf; + DIR *dp; + int ret_val=0; + char* full_path; + + if (depth > max_depth) +{ + return; +} + + if ((dp = opendir(directory)) == NULL) +{ + return; +} + + full_path = malloc(1024 * sizeof(char)); + if (!full_path) +return; + + while ((ep = readdir(dp)) != NULL) +{ + snprintf(full_path,1024, "%s/%s", directory, ep->d_name); + lstat(full_path, &statbuf); + + if (S_ISLNK(statbuf.st_mode)) +{ + continue; +} + + if (!strcmp(ep->d_name, ".") || !strcmp(ep->d_name, "..")) +{ + continue; +} + + if (!strcmp(ep->d_name, filename)) +{ + ret_val = add_filename_to_pile(full_path, root); + if (ret_val == -1) +continue; +} + + find_file(filename, full_path, root, max_depth, depth+1); +} + + grub_free(full_path); + closedir(dp); +} + static char * of_path_of_vdisk(const char *sys_devname __attribute__((unused)), const char *device, @@ -383,7 +469,200 @@ of_fc_port_name(const char *path, const char *subpath, char *port_name) free(basepath); } -#ifdef __sparc__ +void +free_ofpath_files_list(struct ofpath_files_list_root* root) +{ + struct ofpath_files_list_node* node = root->first; + struct ofpath_files_list_node* next; + + while (node!=NULL) +{ + next = node->next; + grub_free(node->filename); + grub_free(node); + node = next; +} + + grub_free(root); + return; +} + +char* +of_find_fc_host(char* host_wwpn) +{ + FILE* fp; + char *buf; + char *ret_val; + char portname_filename[sizeof("port_name")] = "port_name"; + char devices_path[sizeof("/sys/devices")] = "/sys/devices"; + struct ofpath_files_list_root* portnames_file_list; + struct ofpath_files_list_node* node; + + ret_val = malloc(sizeof(char)*1024); + if (!ret_val) +return NULL; + + portnames_file_list = malloc(sizeof(struct ofpath_files_list_root)); + if (!portnames_file_list) +{ + grub_free(ret_val); + return NULL; +} + + portnames_file_list->items = 0; + portnames_file_list->first = NULL; + find_file(portname_filename, devices_path, portnames_file_list, 10, 0); + node = portnames_file_list->first; + + while (node != NULL) +{ + fp = fopen(node->filename, "r"); + buf = malloc(sizeof(char) * 512); + if (!buf) +break; + + fscanf(fp, "%s", buf); + fclose(fp); + + if ((strcmp(buf,host_wwpn) == 0) && grub_strstr(node->filename, "fc_host")) +{ + grub_free(buf); + grub_strcpy(ret_val, node->filename); + free_ofpath_files_list(portnames_file_list); + return ret_val; +} + + node = node->next; + grub_free(buf); +} + free_ofpath_files_list(portnames_file_list); + grub_free(ret_val); + return NULL; +} + +int +of_path_get_nvmeof_adapter_info(char* sysfs_path, + struct ofpath_nvmeof_info* nvmeof_info) +{ + FILE *fp; + char *buf, *buf2, *buf3; + + nvmeof_info->host_wwpn = malloc(sizeof(char) * 256); + nvmeof_info->target_wwpn = malloc(sizeof(char) * 256); + nvmeof_info->nqn = malloc(sizeof(char) * 256); + + if (nvmeof_info->host_wwpn == NULL || nvmeof_info->target_wwpn == NULL || nvmeof_info->nqn == NULL) +{ + grub_free(nvmeof_info->host_wwpn); + grub_free(nvmeof_info->target_wwpn); + gru
[PATCH 4/6] ieee1275: change the logic of ieee1275_get_devargs()
Usually grub will parse the PFW arguments by searching for the first occurence of the character ':'. However, we can have this char more than once on NQN. This patch changes the logic to find the last occurence of this char so we can get the proper values for NVMeoFC Signed-off-by: Diego Domingos Signed-off-by: Avnish Chouhan --- grub-core/kern/ieee1275/openfw.c | 19 +-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c index 0278054..b97104c 100644 --- a/grub-core/kern/ieee1275/openfw.c +++ b/grub-core/kern/ieee1275/openfw.c @@ -324,7 +324,7 @@ grub_claimmap (grub_addr_t addr, grub_size_t size) static char * grub_ieee1275_get_devargs (const char *path) { - char *colon = grub_strchr (path, ':'); + char *colon = grub_strrchr (path, ':'); if (! colon) return 0; @@ -339,6 +339,21 @@ grub_ieee1275_get_devname (const char *path) char *colon = grub_strchr (path, ':'); int pathlen = grub_strlen (path); struct grub_ieee1275_devalias curalias; + + /* Check some special cases */ + if(grub_strstr(path, "nvme-of")) +{ + char *namespace_split = grub_strstr(path,"/namespace@"); + if(namespace_split) +{ + colon = grub_strchr (namespace_split, ':'); +} + else +{ + colon = NULL; +} +} + if (colon) pathlen = (int)(colon - path); @@ -579,7 +594,7 @@ grub_ieee1275_get_boot_dev (void) return NULL; } - bootpath = (char *) grub_malloc ((grub_size_t) bootpath_size + 64); + bootpath = (char *) grub_malloc ((grub_size_t) bootpath_size + 64 + 256); if (! bootpath) { grub_print_error (); -- 2.31.1 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH 2/6] ieee1275/powerpc: enables device mapper discovery
From: Diego Domingos This patch enables the device mapper discovery on ofpath.c. Currently, when we are dealing with a device like /dev/dm-* the ofpath returns null since there is no function implemented to handle this case. This patch implements a function that will look into /sys/block/dm-* devices and search recursively inside slaves directory to find the root disk. Signed-off-by: Diego Domingos --- grub-core/osdep/linux/ofpath.c | 64 +- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c index 0f5d54e9f2d..cc849d9c94c 100644 --- a/grub-core/osdep/linux/ofpath.c +++ b/grub-core/osdep/linux/ofpath.c @@ -37,6 +37,7 @@ #include #include #include +#include #ifdef __sparc__ typedef enum @@ -755,13 +756,74 @@ strip_trailing_digits (const char *p) return new; } +static char * +get_slave_from_dm(const char * device){ + char *curr_device, *tmp; + char *directory; + char *ret = NULL; + + directory = grub_strdup (device); + tmp = get_basename(directory); + curr_device = grub_strdup (tmp); + *tmp = '\0'; + + /* Recursively check for slaves devices so we can find the root device */ + while ((curr_device[0] == 'd') && (curr_device[1] == 'm') && (curr_device[2] == '-')){ +DIR *dp; +struct dirent *ep; +char* device_path; + +device_path = grub_xasprintf ("/sys/block/%s/slaves", curr_device); +dp = opendir(device_path); +free(device_path); + +if (dp != NULL) + { +ep = readdir (dp); +while (ep != NULL) + { +/* avoid some system directories */ +if (!strcmp(ep->d_name,".")) + goto next_dir; +if (!strcmp(ep->d_name,"..")) + goto next_dir; + +free (curr_device); +free (ret); +curr_device = grub_strdup (ep->d_name); +ret = grub_xasprintf ("%s%s", directory, curr_device); +break; + +next_dir: +ep = readdir (dp); +continue; + } +closedir (dp); + } +else + grub_util_warn (_("cannot open directory `%s'"), device_path); + } + + free (directory); + free (curr_device); + + return ret; +} + char * grub_util_devname_to_ofpath (const char *sys_devname) { - char *name_buf, *device, *devnode, *devicenode, *ofpath; + char *name_buf, *device, *devnode, *devicenode, *ofpath, *realname; name_buf = xrealpath (sys_devname); + realname = get_slave_from_dm (name_buf); + if (realname) +{ + free (name_buf); + name_buf = realname; +} + device = get_basename (name_buf); devnode = strip_trailing_digits (name_buf); devicenode = strip_trailing_digits (device); ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH] ns8250: Fix incorrect usage of access_size
access_size is part of a union, so doesn't technically exist for a PIO port (ie, not MMIO), but we set it anyways. This doesn't cause a bug today because the other leg of the union doesn't have anything overlapping with it now, but it's bad, I will punish myself for writing it that way :-) In the meantime, fix this and actually name the struct inside the union for clarity of intent and to avoid such issue in the future. Signed-off-by: Benjamin Herrenschmidt --- grub-core/term/ns8250.c | 42 - include/grub/serial.h | 8 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/grub-core/term/ns8250.c b/grub-core/term/ns8250.c index fea7a45d2..23e8e0904 100644 --- a/grub-core/term/ns8250.c +++ b/grub-core/term/ns8250.c @@ -41,22 +41,22 @@ static grub_uint8_t ns8250_reg_read (struct grub_serial_port *port, grub_addr_t reg) { asm volatile("" : : : "memory"); - if (port->mmio == true) + if (port->use_mmio == true) { /* * Note: we assume MMIO UARTs are little endian. This is not true of all * embedded platforms but will do for now. */ - switch(port->access_size) + switch(port->mmio.access_size) { default: /* ACPI tables occasionally uses "0" (legacy) as equivalent to "1" (byte). */ case 1: - return *((volatile grub_uint8_t *) (port->mmio_base + reg)); + return *((volatile grub_uint8_t *) (port->mmio.base + reg)); case 2: - return grub_le_to_cpu16 (*((volatile grub_uint16_t *) (port->mmio_base + (reg << 1; + return grub_le_to_cpu16 (*((volatile grub_uint16_t *) (port->mmio.base + (reg << 1; case 3: - return grub_le_to_cpu32 (*((volatile grub_uint32_t *) (port->mmio_base + (reg << 2; + return grub_le_to_cpu32 (*((volatile grub_uint32_t *) (port->mmio.base + (reg << 2; case 4: /* * This will only work properly on 64-bit systems since 64-bit @@ -64,7 +64,7 @@ ns8250_reg_read (struct grub_serial_port *port, grub_addr_t reg) * case of a UART with a 64-bit register spacing on 32-bit * also probably doesn't exist. */ - return grub_le_to_cpu64 (*((volatile grub_uint64_t *) (port->mmio_base + (reg << 3; + return grub_le_to_cpu64 (*((volatile grub_uint64_t *) (port->mmio.base + (reg << 3; } } return grub_inb (port->port + reg); @@ -74,24 +74,24 @@ static void ns8250_reg_write (struct grub_serial_port *port, grub_uint8_t value, grub_addr_t reg) { asm volatile("" : : : "memory"); - if (port->mmio == true) + if (port->use_mmio == true) { - switch(port->access_size) + switch(port->mmio.access_size) { default: /* ACPI tables occasionally uses "0" (legacy) as equivalent to "1" (byte). */ case 1: - *((volatile grub_uint8_t *) (port->mmio_base + reg)) = value; + *((volatile grub_uint8_t *) (port->mmio.base + reg)) = value; break; case 2: - *((volatile grub_uint16_t *) (port->mmio_base + (reg << 1))) = grub_cpu_to_le16 (value); + *((volatile grub_uint16_t *) (port->mmio.base + (reg << 1))) = grub_cpu_to_le16 (value); break; case 3: - *((volatile grub_uint32_t *) (port->mmio_base + (reg << 2))) = grub_cpu_to_le32 (value); + *((volatile grub_uint32_t *) (port->mmio.base + (reg << 2))) = grub_cpu_to_le32 (value); break; case 4: /* See commment in ns8250_reg_read(). */ - *((volatile grub_uint64_t *) (port->mmio_base + (reg << 3))) = grub_cpu_to_le64 (value); + *((volatile grub_uint64_t *) (port->mmio.base + (reg << 3))) = grub_cpu_to_le64 (value); break; } } @@ -323,13 +323,12 @@ grub_ns8250_init (void) com_ports[i].name = com_names[i]; com_ports[i].driver = &grub_ns8250_driver; com_ports[i].port = serial_hw_io_addr[i]; - com_ports[i].mmio = false; + com_ports[i].use_mmio = false; err = grub_serial_config_defaults (&com_ports[i]); if (err) grub_print_error (); grub_serial_register (&com_ports[i]); - com_ports[i].access_size = 1; } } @@ -365,7 +364,7 @@ grub_serial_ns8250_add_port (grub_port_t port, struct grub_serial_config *config } FOR_SERIAL_PORTS (p) -if (p->mmio == false && p->port == port) +if (p->use_mmio == false && p->port == port) { if (config != NULL) grub_serial_port_configure (p, config); @@ -390,9 +389,8 @@ grub_serial_ns8250_add_port (grub_port_t port, struct grub_serial_config *config return NULL; } p->driver = &grub_ns8250_driver; - p->mmio = false; + p->use_mmio = false; p->port = port; - p->access_size = 1; if (config != NULL) grub_serial_port_configure (p, config);