Changeset View
Changeset View
Standalone View
Standalone View
stand/efi/libefi/efipart.c
Show First 20 Lines • Show All 113 Lines • ▼ Show 20 Lines | if (dev->dv_type == DEVT_DISK) | ||||
return (&hdinfo); | return (&hdinfo); | ||||
if (dev->dv_type == DEVT_CD) | if (dev->dv_type == DEVT_CD) | ||||
return (&cdinfo); | return (&cdinfo); | ||||
if (dev->dv_type == DEVT_FD) | if (dev->dv_type == DEVT_FD) | ||||
return (&fdinfo); | return (&fdinfo); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
/* XXX this gets called way way too often, investigate */ | |||||
pdinfo_t * | pdinfo_t * | ||||
efiblk_get_pdinfo(struct devdesc *dev) | efiblk_get_pdinfo(struct devdesc *dev) | ||||
{ | { | ||||
pdinfo_list_t *pdi; | pdinfo_list_t *pdi; | ||||
pdinfo_t *pd = NULL; | pdinfo_t *pd = NULL; | ||||
pdi = efiblk_get_pdinfo_list(dev->d_dev); | pdi = efiblk_get_pdinfo_list(dev->d_dev); | ||||
if (pdi == NULL) | if (pdi == NULL) | ||||
return (pd); | return (pd); | ||||
STAILQ_FOREACH(pd, pdi, pd_link) { | STAILQ_FOREACH(pd, pdi, pd_link) { | ||||
if (pd->pd_unit == dev->d_unit) | if (pd->pd_unit == dev->d_unit) | ||||
return (pd); | return (pd); | ||||
} | } | ||||
return (pd); | return (pd); | ||||
} | } | ||||
static bool | |||||
same_handle(pdinfo_t *pd, EFI_HANDLE h) | |||||
{ | |||||
return (pd->pd_handle == h || pd->pd_alias == h); | |||||
} | |||||
pdinfo_t * | |||||
efiblk_get_pdinfo_by_handle(EFI_HANDLE h) | |||||
{ | |||||
pdinfo_t *dp, *pp; | |||||
/* | |||||
* Check hard disks, then cd, then floppy | |||||
*/ | |||||
STAILQ_FOREACH(dp, &hdinfo, pd_link) { | |||||
if (same_handle(dp, h)) | |||||
return (dp); | |||||
STAILQ_FOREACH(pp, &dp->pd_part, pd_link) { | |||||
if (same_handle(pp, h)) | |||||
return (pp); | |||||
} | |||||
} | |||||
STAILQ_FOREACH(dp, &cdinfo, pd_link) { | |||||
if (same_handle(dp, h)) | |||||
return (dp); | |||||
} | |||||
STAILQ_FOREACH(dp, &fdinfo, pd_link) { | |||||
if (same_handle(dp, h)) | |||||
return (dp); | |||||
} | |||||
return (NULL); | |||||
} | |||||
static int | static int | ||||
efiblk_pdinfo_count(pdinfo_list_t *pdi) | efiblk_pdinfo_count(pdinfo_list_t *pdi) | ||||
{ | { | ||||
pdinfo_t *pd; | pdinfo_t *pd; | ||||
int i = 0; | int i = 0; | ||||
STAILQ_FOREACH(pd, pdi, pd_link) { | STAILQ_FOREACH(pd, pdi, pd_link) { | ||||
i++; | i++; | ||||
▲ Show 20 Lines • Show All 142 Lines • ▼ Show 20 Lines | if (fd == NULL) { | ||||
printf("Failed to register floppy %d, out of memory\n", uid); | printf("Failed to register floppy %d, out of memory\n", uid); | ||||
return (ENOMEM); | return (ENOMEM); | ||||
} | } | ||||
STAILQ_INIT(&fd->pd_part); | STAILQ_INIT(&fd->pd_part); | ||||
fd->pd_unit = uid; | fd->pd_unit = uid; | ||||
fd->pd_handle = handle; | fd->pd_handle = handle; | ||||
fd->pd_devpath = devpath; | fd->pd_devpath = devpath; | ||||
fd->pd_parent = NULL; | |||||
fd->pd_devsw = &efipart_fddev; | |||||
STAILQ_INSERT_TAIL(&fdinfo, fd, pd_link); | STAILQ_INSERT_TAIL(&fdinfo, fd, pd_link); | ||||
return (0); | return (0); | ||||
} | } | ||||
static void | static void | ||||
efipart_updatefd(void) | efipart_updatefd(void) | ||||
{ | { | ||||
EFI_DEVICE_PATH *devpath, *node; | EFI_DEVICE_PATH *devpath, *node; | ||||
▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | if (cd == NULL) { | ||||
return (ENOMEM); | return (ENOMEM); | ||||
} | } | ||||
STAILQ_INIT(&cd->pd_part); | STAILQ_INIT(&cd->pd_part); | ||||
cd->pd_handle = handle; | cd->pd_handle = handle; | ||||
cd->pd_unit = unit; | cd->pd_unit = unit; | ||||
cd->pd_alias = alias; | cd->pd_alias = alias; | ||||
cd->pd_devpath = devpath; | cd->pd_devpath = devpath; | ||||
cd->pd_parent = NULL; | |||||
cd->pd_devsw = &efipart_cddev; | |||||
STAILQ_INSERT_TAIL(&cdinfo, cd, pd_link); | STAILQ_INSERT_TAIL(&cdinfo, cd, pd_link); | ||||
return (0); | return (0); | ||||
} | } | ||||
static void | static void | ||||
efipart_updatecd(void) | efipart_updatecd(void) | ||||
{ | { | ||||
int i, nin; | int i, nin; | ||||
▲ Show 20 Lines • Show All 109 Lines • ▼ Show 20 Lines | STAILQ_FOREACH(hd, &hdinfo, pd_link) { | ||||
if (efi_devpath_match(hd->pd_devpath, disk_devpath) == true) { | if (efi_devpath_match(hd->pd_devpath, disk_devpath) == true) { | ||||
if (part_devpath == NULL) | if (part_devpath == NULL) | ||||
return (0); | return (0); | ||||
/* Add the partition. */ | /* Add the partition. */ | ||||
pd->pd_handle = part_handle; | pd->pd_handle = part_handle; | ||||
pd->pd_unit = node->PartitionNumber; | pd->pd_unit = node->PartitionNumber; | ||||
pd->pd_devpath = part_devpath; | pd->pd_devpath = part_devpath; | ||||
pd->pd_parent = hd; | |||||
pd->pd_devsw = &efipart_hddev; | |||||
STAILQ_INSERT_TAIL(&hd->pd_part, pd, pd_link); | STAILQ_INSERT_TAIL(&hd->pd_part, pd, pd_link); | ||||
return (0); | return (0); | ||||
} | } | ||||
} | } | ||||
last = STAILQ_LAST(&hdinfo, pdinfo, pd_link); | last = STAILQ_LAST(&hdinfo, pdinfo, pd_link); | ||||
if (last != NULL) | if (last != NULL) | ||||
unit = last->pd_unit + 1; | unit = last->pd_unit + 1; | ||||
else | else | ||||
unit = 0; | unit = 0; | ||||
/* Add the disk. */ | /* Add the disk. */ | ||||
hd = pd; | hd = pd; | ||||
hd->pd_handle = disk_handle; | hd->pd_handle = disk_handle; | ||||
hd->pd_unit = unit; | hd->pd_unit = unit; | ||||
hd->pd_devpath = disk_devpath; | hd->pd_devpath = disk_devpath; | ||||
hd->pd_parent = NULL; | |||||
hd->pd_devsw = &efipart_hddev; | |||||
STAILQ_INSERT_TAIL(&hdinfo, hd, pd_link); | STAILQ_INSERT_TAIL(&hdinfo, hd, pd_link); | ||||
if (part_devpath == NULL) | if (part_devpath == NULL) | ||||
return (0); | return (0); | ||||
pd = calloc(1, sizeof(pdinfo_t)); | pd = calloc(1, sizeof(pdinfo_t)); | ||||
if (pd == NULL) { | if (pd == NULL) { | ||||
printf("Failed to add partition, out of memory\n"); | printf("Failed to add partition, out of memory\n"); | ||||
return (ENOMEM); | return (ENOMEM); | ||||
} | } | ||||
STAILQ_INIT(&pd->pd_part); | STAILQ_INIT(&pd->pd_part); | ||||
/* Add the partition. */ | /* Add the partition. */ | ||||
pd->pd_handle = part_handle; | pd->pd_handle = part_handle; | ||||
pd->pd_unit = node->PartitionNumber; | pd->pd_unit = node->PartitionNumber; | ||||
pd->pd_devpath = part_devpath; | pd->pd_devpath = part_devpath; | ||||
pd->pd_parent = hd; | |||||
pd->pd_devsw = &efipart_hddev; | |||||
STAILQ_INSERT_TAIL(&hd->pd_part, pd, pd_link); | STAILQ_INSERT_TAIL(&hd->pd_part, pd, pd_link); | ||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
* The MEDIA_FILEPATH_DP has device name. | * The MEDIA_FILEPATH_DP has device name. | ||||
* From U-Boot sources it looks like names are in the form | * From U-Boot sources it looks like names are in the form | ||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | efipart_hdinfo_add_filepath(EFI_HANDLE disk_handle) | ||||
* Assume we are receiving handles in order, first disk handle, | * Assume we are receiving handles in order, first disk handle, | ||||
* then partitions for this disk. If this assumption proves | * then partitions for this disk. If this assumption proves | ||||
* false, this code would need update. | * false, this code would need update. | ||||
*/ | */ | ||||
if (p == NULL) { /* no colon, add the disk */ | if (p == NULL) { /* no colon, add the disk */ | ||||
pd->pd_handle = disk_handle; | pd->pd_handle = disk_handle; | ||||
pd->pd_unit = unit; | pd->pd_unit = unit; | ||||
pd->pd_devpath = devpath; | pd->pd_devpath = devpath; | ||||
pd->pd_parent = NULL; | |||||
pd->pd_devsw = &efipart_hddev; | |||||
STAILQ_INSERT_TAIL(&hdinfo, pd, pd_link); | STAILQ_INSERT_TAIL(&hdinfo, pd, pd_link); | ||||
free(pathname); | free(pathname); | ||||
return (0); | return (0); | ||||
} | } | ||||
p++; /* skip the colon */ | p++; /* skip the colon */ | ||||
errno = 0; | errno = 0; | ||||
unit = (int)strtol(p, NULL, 0); | unit = (int)strtol(p, NULL, 0); | ||||
if (errno != 0) { | if (errno != 0) { | ||||
Show All 14 Lines | if (last == NULL) { | ||||
free(pathname); | free(pathname); | ||||
free(pd); | free(pd); | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
/* Add the partition. */ | /* Add the partition. */ | ||||
pd->pd_handle = disk_handle; | pd->pd_handle = disk_handle; | ||||
pd->pd_unit = unit; | pd->pd_unit = unit; | ||||
pd->pd_devpath = devpath; | pd->pd_devpath = devpath; | ||||
pd->pd_parent = last; | |||||
pd->pd_devsw = &efipart_hddev; | |||||
STAILQ_INSERT_TAIL(&last->pd_part, pd, pd_link); | STAILQ_INSERT_TAIL(&last->pd_part, pd, pd_link); | ||||
free(pathname); | free(pathname); | ||||
return (0); | return (0); | ||||
} | } | ||||
static void | static void | ||||
efipart_updatehd(void) | efipart_updatehd(void) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 119 Lines • ▼ Show 20 Lines | if (!EFI_ERROR(status)) { | ||||
printf(" (no media)"); | printf(" (no media)"); | ||||
} | } | ||||
if ((ret = pager_output("\n")) != 0) | if ((ret = pager_output("\n")) != 0) | ||||
break; | break; | ||||
if (!blkio->Media->MediaPresent) | if (!blkio->Media->MediaPresent) | ||||
continue; | continue; | ||||
pd->pd_blkio = blkio; | pd->pd_blkio = blkio; | ||||
pd_dev.d_dev = dev; | pd_dev.dd.d_dev = dev; | ||||
pd_dev.d_unit = pd->pd_unit; | pd_dev.dd.d_unit = pd->pd_unit; | ||||
pd_dev.d_slice = -1; | pd_dev.d_slice = -1; | ||||
pd_dev.d_partition = -1; | pd_dev.d_partition = -1; | ||||
pd_dev.d_opendata = blkio; | |||||
ret = disk_open(&pd_dev, blkio->Media->BlockSize * | ret = disk_open(&pd_dev, blkio->Media->BlockSize * | ||||
(blkio->Media->LastBlock + 1), | (blkio->Media->LastBlock + 1), | ||||
blkio->Media->BlockSize); | blkio->Media->BlockSize); | ||||
if (ret == 0) { | if (ret == 0) { | ||||
ret = disk_print(&pd_dev, line, verbose); | ret = disk_print(&pd_dev, line, verbose); | ||||
disk_close(&pd_dev); | disk_close(&pd_dev); | ||||
if (ret != 0) | if (ret != 0) | ||||
return (ret); | return (ret); | ||||
▲ Show 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | efipart_open(struct open_file *f, ...) | ||||
blkio = pd->pd_blkio; | blkio = pd->pd_blkio; | ||||
if (!blkio->Media->MediaPresent) | if (!blkio->Media->MediaPresent) | ||||
return (EAGAIN); | return (EAGAIN); | ||||
pd->pd_open++; | pd->pd_open++; | ||||
if (pd->pd_bcache == NULL) | if (pd->pd_bcache == NULL) | ||||
pd->pd_bcache = bcache_allocate(); | pd->pd_bcache = bcache_allocate(); | ||||
if (dev->d_dev->dv_type == DEVT_DISK) { | if (dev->dd.d_dev->dv_type == DEVT_DISK) { | ||||
int rc; | int rc; | ||||
rc = disk_open(dev, | rc = disk_open(dev, | ||||
blkio->Media->BlockSize * (blkio->Media->LastBlock + 1), | blkio->Media->BlockSize * (blkio->Media->LastBlock + 1), | ||||
blkio->Media->BlockSize); | blkio->Media->BlockSize); | ||||
if (rc != 0) { | if (rc != 0) { | ||||
pd->pd_open--; | pd->pd_open--; | ||||
if (pd->pd_open == 0) { | if (pd->pd_open == 0) { | ||||
Show All 22 Lines | if (pd == NULL) | ||||
return (EINVAL); | return (EINVAL); | ||||
pd->pd_open--; | pd->pd_open--; | ||||
if (pd->pd_open == 0) { | if (pd->pd_open == 0) { | ||||
pd->pd_blkio = NULL; | pd->pd_blkio = NULL; | ||||
bcache_free(pd->pd_bcache); | bcache_free(pd->pd_bcache); | ||||
pd->pd_bcache = NULL; | pd->pd_bcache = NULL; | ||||
} | } | ||||
if (dev->d_dev->dv_type == DEVT_DISK) | if (dev->dd.d_dev->dv_type == DEVT_DISK) | ||||
return (disk_close(dev)); | return (disk_close(dev)); | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
efipart_ioctl(struct open_file *f, u_long cmd, void *data) | efipart_ioctl(struct open_file *f, u_long cmd, void *data) | ||||
{ | { | ||||
struct disk_devdesc *dev; | struct disk_devdesc *dev; | ||||
pdinfo_t *pd; | pdinfo_t *pd; | ||||
int rc; | int rc; | ||||
dev = (struct disk_devdesc *)(f->f_devdata); | dev = (struct disk_devdesc *)(f->f_devdata); | ||||
if (dev == NULL) | if (dev == NULL) | ||||
return (EINVAL); | return (EINVAL); | ||||
pd = efiblk_get_pdinfo((struct devdesc *)dev); | pd = efiblk_get_pdinfo((struct devdesc *)dev); | ||||
if (pd == NULL) | if (pd == NULL) | ||||
return (EINVAL); | return (EINVAL); | ||||
if (dev->d_dev->dv_type == DEVT_DISK) { | if (dev->dd.d_dev->dv_type == DEVT_DISK) { | ||||
rc = disk_ioctl(dev, cmd, data); | rc = disk_ioctl(dev, cmd, data); | ||||
if (rc != ENOTTY) | if (rc != ENOTTY) | ||||
return (rc); | return (rc); | ||||
} | } | ||||
switch (cmd) { | switch (cmd) { | ||||
case DIOCGSECTORSIZE: | case DIOCGSECTORSIZE: | ||||
*(u_int *)data = pd->pd_blkio->Media->BlockSize; | *(u_int *)data = pd->pd_blkio->Media->BlockSize; | ||||
▲ Show 20 Lines • Show All 70 Lines • ▼ Show 20 Lines | efipart_strategy(void *devdata, int rw, daddr_t blk, size_t size, | ||||
if (pd->pd_blkio->Media->RemovableMedia && | if (pd->pd_blkio->Media->RemovableMedia && | ||||
!pd->pd_blkio->Media->MediaPresent) | !pd->pd_blkio->Media->MediaPresent) | ||||
return (ENXIO); | return (ENXIO); | ||||
bcd.dv_strategy = efipart_realstrategy; | bcd.dv_strategy = efipart_realstrategy; | ||||
bcd.dv_devdata = devdata; | bcd.dv_devdata = devdata; | ||||
bcd.dv_cache = pd->pd_bcache; | bcd.dv_cache = pd->pd_bcache; | ||||
if (dev->d_dev->dv_type == DEVT_DISK) { | if (dev->dd.d_dev->dv_type == DEVT_DISK) { | ||||
daddr_t offset; | daddr_t offset; | ||||
offset = dev->d_offset * pd->pd_blkio->Media->BlockSize; | offset = dev->d_offset * pd->pd_blkio->Media->BlockSize; | ||||
offset /= 512; | offset /= 512; | ||||
return (bcache_strategy(&bcd, rw, blk + offset, | return (bcache_strategy(&bcd, rw, blk + offset, | ||||
size, buf, rsize)); | size, buf, rsize)); | ||||
} | } | ||||
return (bcache_strategy(&bcd, rw, blk, size, buf, rsize)); | return (bcache_strategy(&bcd, rw, blk, size, buf, rsize)); | ||||
Show All 27 Lines | if (size == 0 || (size % 512) != 0) | ||||
return (EIO); | return (EIO); | ||||
off = blk * 512; | off = blk * 512; | ||||
/* | /* | ||||
* Get disk blocks, this value is either for whole disk or for | * Get disk blocks, this value is either for whole disk or for | ||||
* partition. | * partition. | ||||
*/ | */ | ||||
disk_blocks = 0; | disk_blocks = 0; | ||||
if (dev->d_dev->dv_type == DEVT_DISK) { | if (dev->dd.d_dev->dv_type == DEVT_DISK) { | ||||
if (disk_ioctl(dev, DIOCGMEDIASIZE, &disk_blocks) == 0) { | if (disk_ioctl(dev, DIOCGMEDIASIZE, &disk_blocks) == 0) { | ||||
/* DIOCGMEDIASIZE does return bytes. */ | /* DIOCGMEDIASIZE does return bytes. */ | ||||
disk_blocks /= blkio->Media->BlockSize; | disk_blocks /= blkio->Media->BlockSize; | ||||
} | } | ||||
d_offset = dev->d_offset; | d_offset = dev->d_offset; | ||||
} | } | ||||
if (disk_blocks == 0) | if (disk_blocks == 0) | ||||
disk_blocks = blkio->Media->LastBlock + 1 - d_offset; | disk_blocks = blkio->Media->LastBlock + 1 - d_offset; | ||||
▲ Show 20 Lines • Show All 53 Lines • Show Last 20 Lines |