Changeset View
Changeset View
Standalone View
Standalone View
head/sys/boot/efi/libefi/efipart.c
Show First 20 Lines • Show All 95 Lines • ▼ Show 20 Lines | |||||
static pdinfo_list_t fdinfo; | static pdinfo_list_t fdinfo; | ||||
static pdinfo_list_t cdinfo; | static pdinfo_list_t cdinfo; | ||||
static pdinfo_list_t hdinfo; | static pdinfo_list_t hdinfo; | ||||
static EFI_HANDLE *efipart_handles = NULL; | static EFI_HANDLE *efipart_handles = NULL; | ||||
static UINTN efipart_nhandles = 0; | static UINTN efipart_nhandles = 0; | ||||
static pdinfo_t * | pdinfo_list_t * | ||||
efiblk_get_pdinfo(pdinfo_list_t *pdi, int unit) | efiblk_get_pdinfo_list(struct devsw *dev) | ||||
{ | { | ||||
pdinfo_t *pd; | if (dev->dv_type == DEVT_DISK) | ||||
return (&hdinfo); | |||||
if (dev->dv_type == DEVT_CD) | |||||
return (&cdinfo); | |||||
if (dev->dv_type == DEVT_FD) | |||||
return (&fdinfo); | |||||
return (NULL); | |||||
} | |||||
pdinfo_t * | |||||
efiblk_get_pdinfo(struct devdesc *dev) | |||||
{ | |||||
pdinfo_list_t *pdi; | |||||
pdinfo_t *pd = NULL; | |||||
pdi = efiblk_get_pdinfo_list(dev->d_dev); | |||||
if (pdi == NULL) | |||||
return (pd); | |||||
STAILQ_FOREACH(pd, pdi, pd_link) { | STAILQ_FOREACH(pd, pdi, pd_link) { | ||||
if (pd->pd_unit == unit) | if (pd->pd_unit == dev->d_unit) | ||||
return (pd); | return (pd); | ||||
} | } | ||||
return (NULL); | return (pd); | ||||
} | } | ||||
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; | ||||
▲ Show 20 Lines • Show All 544 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
static int | static int | ||||
efipart_printhd(int verbose) | efipart_printhd(int verbose) | ||||
{ | { | ||||
return (efipart_print_common(&efipart_hddev, &hdinfo, verbose)); | return (efipart_print_common(&efipart_hddev, &hdinfo, verbose)); | ||||
} | } | ||||
pdinfo_list_t * | |||||
efiblk_get_pdinfo_list(struct devsw *dev) | |||||
{ | |||||
if (dev->dv_type == DEVT_DISK) | |||||
return (&hdinfo); | |||||
if (dev->dv_type == DEVT_CD) | |||||
return (&cdinfo); | |||||
if (dev->dv_type == DEVT_FD) | |||||
return (&fdinfo); | |||||
return (NULL); | |||||
} | |||||
static int | static int | ||||
efipart_open(struct open_file *f, ...) | efipart_open(struct open_file *f, ...) | ||||
{ | { | ||||
va_list args; | va_list args; | ||||
struct disk_devdesc *dev; | struct disk_devdesc *dev; | ||||
pdinfo_list_t *pdi; | |||||
pdinfo_t *pd; | pdinfo_t *pd; | ||||
EFI_BLOCK_IO *blkio; | EFI_BLOCK_IO *blkio; | ||||
EFI_STATUS status; | EFI_STATUS status; | ||||
va_start(args, f); | va_start(args, f); | ||||
dev = va_arg(args, struct disk_devdesc*); | dev = va_arg(args, struct disk_devdesc*); | ||||
va_end(args); | va_end(args); | ||||
if (dev == NULL) | if (dev == NULL) | ||||
return (EINVAL); | return (EINVAL); | ||||
pdi = efiblk_get_pdinfo_list(dev->d_dev); | pd = efiblk_get_pdinfo((struct devdesc *)dev); | ||||
if (pdi == NULL) | |||||
return (EINVAL); | |||||
pd = efiblk_get_pdinfo(pdi, dev->d_unit); | |||||
if (pd == NULL) | if (pd == NULL) | ||||
return (EIO); | return (EIO); | ||||
if (pd->pd_blkio == NULL) { | if (pd->pd_blkio == NULL) { | ||||
status = BS->HandleProtocol(pd->pd_handle, &blkio_guid, | status = BS->HandleProtocol(pd->pd_handle, &blkio_guid, | ||||
(void **)&pd->pd_blkio); | (void **)&pd->pd_blkio); | ||||
if (EFI_ERROR(status)) | if (EFI_ERROR(status)) | ||||
return (efi_status_to_errno(status)); | return (efi_status_to_errno(status)); | ||||
Show All 14 Lines | efipart_open(struct open_file *f, ...) | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
efipart_close(struct open_file *f) | efipart_close(struct open_file *f) | ||||
{ | { | ||||
struct disk_devdesc *dev; | struct disk_devdesc *dev; | ||||
pdinfo_list_t *pdi; | |||||
pdinfo_t *pd; | pdinfo_t *pd; | ||||
dev = (struct disk_devdesc *)(f->f_devdata); | dev = (struct disk_devdesc *)(f->f_devdata); | ||||
if (dev == NULL) | if (dev == NULL) | ||||
return (EINVAL); | return (EINVAL); | ||||
pdi = efiblk_get_pdinfo_list(dev->d_dev); | |||||
if (pdi == NULL) | |||||
return (EINVAL); | |||||
pd = efiblk_get_pdinfo(pdi, dev->d_unit); | pd = efiblk_get_pdinfo((struct devdesc *)dev); | ||||
if (pd == NULL) | 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->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_list_t *pdi; | |||||
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); | ||||
pdi = efiblk_get_pdinfo_list(dev->d_dev); | |||||
if (pdi == NULL) | |||||
return (EINVAL); | |||||
pd = efiblk_get_pdinfo(pdi, dev->d_unit); | 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->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); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
static int | static int | ||||
efipart_strategy(void *devdata, int rw, daddr_t blk, size_t size, | efipart_strategy(void *devdata, int rw, daddr_t blk, size_t size, | ||||
char *buf, size_t *rsize) | char *buf, size_t *rsize) | ||||
{ | { | ||||
struct bcache_devdata bcd; | struct bcache_devdata bcd; | ||||
struct disk_devdesc *dev; | struct disk_devdesc *dev; | ||||
pdinfo_list_t *pdi; | |||||
pdinfo_t *pd; | pdinfo_t *pd; | ||||
dev = (struct disk_devdesc *)devdata; | dev = (struct disk_devdesc *)devdata; | ||||
if (dev == NULL) | if (dev == NULL) | ||||
return (EINVAL); | return (EINVAL); | ||||
pdi = efiblk_get_pdinfo_list(dev->d_dev); | |||||
if (pdi == NULL) | |||||
return (EINVAL); | |||||
pd = efiblk_get_pdinfo(pdi, dev->d_unit); | pd = efiblk_get_pdinfo((struct devdesc *)dev); | ||||
if (pd == NULL) | if (pd == NULL) | ||||
return (EINVAL); | return (EINVAL); | ||||
if (pd->pd_blkio->Media->RemovableMedia && | if (pd->pd_blkio->Media->RemovableMedia && | ||||
!pd->pd_blkio->Media->MediaPresent) | !pd->pd_blkio->Media->MediaPresent) | ||||
return (EIO); | return (EIO); | ||||
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->d_dev->dv_type == DEVT_DISK) { | ||||
return (bcache_strategy(&bcd, rw, blk + dev->d_offset, | return (bcache_strategy(&bcd, rw, blk + dev->d_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)); | ||||
} | } | ||||
static int | static int | ||||
efipart_realstrategy(void *devdata, int rw, daddr_t blk, size_t size, | efipart_realstrategy(void *devdata, int rw, daddr_t blk, size_t size, | ||||
char *buf, size_t *rsize) | char *buf, size_t *rsize) | ||||
{ | { | ||||
struct disk_devdesc *dev = (struct disk_devdesc *)devdata; | struct disk_devdesc *dev = (struct disk_devdesc *)devdata; | ||||
pdinfo_list_t *pdi; | |||||
pdinfo_t *pd; | pdinfo_t *pd; | ||||
EFI_BLOCK_IO *blkio; | EFI_BLOCK_IO *blkio; | ||||
uint64_t off, disk_blocks, d_offset = 0; | uint64_t off, disk_blocks, d_offset = 0; | ||||
char *blkbuf; | char *blkbuf; | ||||
size_t blkoff, blksz; | size_t blkoff, blksz; | ||||
int error; | int error; | ||||
size_t diskend, readstart; | size_t diskend, readstart; | ||||
if (dev == NULL || blk < 0) | if (dev == NULL || blk < 0) | ||||
return (EINVAL); | return (EINVAL); | ||||
pdi = efiblk_get_pdinfo_list(dev->d_dev); | pd = efiblk_get_pdinfo((struct devdesc *)dev); | ||||
if (pdi == NULL) | |||||
return (EINVAL); | |||||
pd = efiblk_get_pdinfo(pdi, dev->d_unit); | |||||
if (pd == NULL) | if (pd == NULL) | ||||
return (EINVAL); | return (EINVAL); | ||||
blkio = pd->pd_blkio; | blkio = pd->pd_blkio; | ||||
if (blkio == NULL) | if (blkio == NULL) | ||||
return (ENXIO); | return (ENXIO); | ||||
if (size == 0 || (size % 512) != 0) | if (size == 0 || (size % 512) != 0) | ||||
▲ Show 20 Lines • Show All 69 Lines • Show Last 20 Lines |