From: tcamuso@redhat.com <tcamuso@redhat.com> Date: Thu, 28 Aug 2008 17:43:37 -0400 Subject: [misc] hpilo: update driver to 0.5 Message-id: 20080828214410.7055.51043.sendpatchset@dhcp-100-2-186.bos.redhat.com O-Subject: [PATCH 2/3]hpilo driver - backport changes from upstream 2.6.27 Bugzilla: 437212 Patch 2 of 3 ============ A patch set to update hpilo driver from version 0.2 to version 0.5, which is the version in upstream 2.6.27. Patch Description ================= This patch actually updates the hpilo driver from Version 0.2 to Version 0.5. Bugzilla ======== https://bugzilla.redhat.com/show_bug.cgi?id=437212 Upstream Status =============== commit f38954c93c4a548f55d73ac5c1cf5e7f4023bb6c Test Status =========== David Altobelli built and tested this patch set against 2.6.18-105 for functionality and regression, and the driver performed as expected with no regressions. Summary ======= drivers/misc/hpilo.c | 249 ++++++++++++++++++++++++++++++++------------------ drivers/misc/hpilo.h | 35 +------- 2 files changed, 164 insertions(+), 120 deletions(-) Signed-off-by: Tony Camuso Signed-off-by: David Altobelli diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c index 0e4e46b..05e2982 100644 --- a/drivers/misc/hpilo.c +++ b/drivers/misc/hpilo.c @@ -27,6 +27,27 @@ static struct class *ilo_class; static unsigned int ilo_major; static char ilo_hwdev[MAX_ILO_DEV]; +static inline int get_entry_id(int entry) +{ + return (entry & ENTRY_MASK_DESCRIPTOR) >> ENTRY_BITPOS_DESCRIPTOR; +} + +static inline int get_entry_len(int entry) +{ + return ((entry & ENTRY_MASK_QWORDS) >> ENTRY_BITPOS_QWORDS) << 3; +} + +static inline int mk_entry(int id, int len) +{ + int qlen = len & 7 ? (len >> 3) + 1 : len >> 3; + return id << ENTRY_BITPOS_DESCRIPTOR | qlen << ENTRY_BITPOS_QWORDS; +} + +static inline int desc_mem_sz(int nr_entry) +{ + return nr_entry << L2_QENTRY_SZ; +} + /* * FIFO queues, shared with hardware. * @@ -39,14 +60,15 @@ static char ilo_hwdev[MAX_ILO_DEV]; */ static int fifo_enqueue(struct ilo_hwinfo *hw, char *fifobar, int entry) { - struct fifo *Q = FIFOBARTOHANDLE(fifobar); + struct fifo *fifo_q = FIFOBARTOHANDLE(fifobar); int ret = 0; spin_lock(&hw->fifo_lock); - if (!(Q->fifobar[(Q->tail + 1) & Q->imask] & ENTRY_MASK_O)) { - Q->fifobar[Q->tail & Q->imask] |= - ((entry & ENTRY_MASK_NOSTATE) | Q->merge); - Q->tail += 1; + if (!(fifo_q->fifobar[(fifo_q->tail + 1) & fifo_q->imask] + & ENTRY_MASK_O)) { + fifo_q->fifobar[fifo_q->tail & fifo_q->imask] |= + (entry & ENTRY_MASK_NOSTATE) | fifo_q->merge; + fifo_q->tail += 1; ret = 1; } spin_unlock(&hw->fifo_lock); @@ -56,18 +78,19 @@ static int fifo_enqueue(struct ilo_hwinfo *hw, char *fifobar, int entry) static int fifo_dequeue(struct ilo_hwinfo *hw, char *fifobar, int *entry) { - struct fifo *Q = FIFOBARTOHANDLE(fifobar); + struct fifo *fifo_q = FIFOBARTOHANDLE(fifobar); int ret = 0; u64 c; spin_lock(&hw->fifo_lock); - c = Q->fifobar[Q->head & Q->imask]; + c = fifo_q->fifobar[fifo_q->head & fifo_q->imask]; if (c & ENTRY_MASK_C) { if (entry) *entry = c & ENTRY_MASK_NOSTATE; - Q->fifobar[Q->head & Q->imask] = ((c | ENTRY_MASK) + 1); - Q->head += 1; + fifo_q->fifobar[fifo_q->head & fifo_q->imask] = + (c | ENTRY_MASK) + 1; + fifo_q->head += 1; ret = 1; } spin_unlock(&hw->fifo_lock); @@ -86,9 +109,7 @@ static int ilo_pkt_enqueue(struct ilo_hwinfo *hw, struct ccb *ccb, else fifobar = ccb->ccb_u3.recv_fifobar; - entry = id << ENTRY_BITPOS_DESCRIPTOR | - QWORDS(len) << ENTRY_BITPOS_QWORDS; - + entry = mk_entry(id, len); return fifo_enqueue(hw, fifobar, entry); } @@ -109,40 +130,64 @@ static int ilo_pkt_dequeue(struct ilo_hwinfo *hw, struct ccb *ccb, ret = fifo_dequeue(hw, fifobar, &entry); if (ret) { - pkt_id = GETDESC(entry); + pkt_id = get_entry_id(entry); if (id) *id = pkt_id; if (len) - *len = GETQWORDS(entry) << 3; + *len = get_entry_len(entry); if (pkt) - *pkt = (void *)(desc + DESC_MEM_SZ(pkt_id)); + *pkt = (void *)(desc + desc_mem_sz(pkt_id)); } return ret; } +static inline void doorbell_set(struct ccb *ccb) +{ + iowrite8(1, ccb->ccb_u5.db_base); +} + +static inline void doorbell_clr(struct ccb *ccb) +{ + iowrite8(2, ccb->ccb_u5.db_base); +} +static inline int ctrl_set(int l2sz, int idxmask, int desclim) +{ + int active = 0, go = 1; + return l2sz << CTRL_BITPOS_L2SZ | + idxmask << CTRL_BITPOS_FIFOINDEXMASK | + desclim << CTRL_BITPOS_DESCLIMIT | + active << CTRL_BITPOS_A | + go << CTRL_BITPOS_G; +} static void ctrl_setup(struct ccb *ccb, int nr_desc, int l2desc_sz) { /* for simplicity, use the same parameters for send and recv ctrls */ - CTRL_SET(ccb->send_ctrl, l2desc_sz, nr_desc-1, nr_desc-1, 0, 1); - CTRL_SET(ccb->recv_ctrl, l2desc_sz, nr_desc-1, nr_desc-1, 0, 1); + ccb->send_ctrl = ctrl_set(l2desc_sz, nr_desc-1, nr_desc-1); + ccb->recv_ctrl = ctrl_set(l2desc_sz, nr_desc-1, nr_desc-1); +} + +static inline int fifo_sz(int nr_entry) +{ + /* size of a fifo is determined by the number of entries it contains */ + return (nr_entry * sizeof(u64)) + FIFOHANDLESIZE; } static void fifo_setup(void *base_addr, int nr_entry) { - struct fifo *Q = base_addr; + struct fifo *fifo_q = base_addr; int i; /* set up an empty fifo */ - Q->head = 0; - Q->tail = 0; - Q->reset = 0; - Q->nrents = nr_entry; - Q->imask = nr_entry - 1; - Q->merge = ENTRY_MASK_O; + fifo_q->head = 0; + fifo_q->tail = 0; + fifo_q->reset = 0; + fifo_q->nrents = nr_entry; + fifo_q->imask = nr_entry - 1; + fifo_q->merge = ENTRY_MASK_O; for (i = 0; i < nr_entry; i++) - Q->fifobar[i] = 0; + fifo_q->fifobar[i] = 0; } static void ilo_ccb_close(struct pci_dev *pdev, struct ccb_data *data) @@ -155,7 +200,7 @@ static void ilo_ccb_close(struct pci_dev *pdev, struct ccb_data *data) device_ccb = data->mapped_ccb; /* complicated dance to tell the hw we are stopping */ - DOORBELL_CLR(driver_ccb); + doorbell_clr(driver_ccb); iowrite32(ioread32(&device_ccb->send_ctrl) & ~(1 << CTRL_BITPOS_G), &device_ccb->send_ctrl); iowrite32(ioread32(&device_ccb->recv_ctrl) & ~(1 << CTRL_BITPOS_G), @@ -163,7 +208,7 @@ static void ilo_ccb_close(struct pci_dev *pdev, struct ccb_data *data) /* give iLO some time to process stop request */ for (retries = 1000; retries > 0; retries--) { - DOORBELL_SET(driver_ccb); + doorbell_set(driver_ccb); udelay(1); if (!(ioread32(&device_ccb->send_ctrl) & (1 << CTRL_BITPOS_A)) && @@ -191,8 +236,8 @@ static int ilo_ccb_open(struct ilo_hwinfo *hw, struct ccb_data *data, int slot) ilo_ccb = &data->ilo_ccb; pdev = hw->ilo_dev; - data->dma_size = 2 * FIFO_SZ(NR_QENTRY) + - 2 * DESC_MEM_SZ(NR_QENTRY) + + data->dma_size = 2 * fifo_sz(NR_QENTRY) + + 2 * desc_mem_sz(NR_QENTRY) + ILO_START_ALIGN + ILO_CACHE_SZ; error = -ENOMEM; @@ -217,24 +262,24 @@ static int ilo_ccb_open(struct ilo_hwinfo *hw, struct ccb_data *data, int slot) ctrl_setup(ilo_ccb, NR_QENTRY, L2_QENTRY_SZ); fifo_setup(dma_va, NR_QENTRY); - driver_ccb->ccb_u1.send_fifobar = (dma_va + FIFOHANDLESIZE); - ilo_ccb->ccb_u1.send_fifobar = (dma_pa + FIFOHANDLESIZE); - dma_va += FIFO_SZ(NR_QENTRY); - dma_pa += FIFO_SZ(NR_QENTRY); + driver_ccb->ccb_u1.send_fifobar = dma_va + FIFOHANDLESIZE; + ilo_ccb->ccb_u1.send_fifobar = dma_pa + FIFOHANDLESIZE; + dma_va += fifo_sz(NR_QENTRY); + dma_pa += fifo_sz(NR_QENTRY); dma_va = (char *)roundup((unsigned long)dma_va, ILO_CACHE_SZ); dma_pa = (char *)roundup((unsigned long)dma_pa, ILO_CACHE_SZ); fifo_setup(dma_va, NR_QENTRY); - driver_ccb->ccb_u3.recv_fifobar = (dma_va + FIFOHANDLESIZE); - ilo_ccb->ccb_u3.recv_fifobar = (dma_pa + FIFOHANDLESIZE); - dma_va += FIFO_SZ(NR_QENTRY); - dma_pa += FIFO_SZ(NR_QENTRY); + driver_ccb->ccb_u3.recv_fifobar = dma_va + FIFOHANDLESIZE; + ilo_ccb->ccb_u3.recv_fifobar = dma_pa + FIFOHANDLESIZE; + dma_va += fifo_sz(NR_QENTRY); + dma_pa += fifo_sz(NR_QENTRY); driver_ccb->ccb_u2.send_desc = dma_va; ilo_ccb->ccb_u2.send_desc = dma_pa; - dma_pa += DESC_MEM_SZ(NR_QENTRY); - dma_va += DESC_MEM_SZ(NR_QENTRY); + dma_pa += desc_mem_sz(NR_QENTRY); + dma_va += desc_mem_sz(NR_QENTRY); driver_ccb->ccb_u4.recv_desc = dma_va; ilo_ccb->ccb_u4.recv_desc = dma_pa; @@ -254,14 +299,14 @@ static int ilo_ccb_open(struct ilo_hwinfo *hw, struct ccb_data *data, int slot) pkt_sz = 0; for (pkt_id = 0; pkt_id < NR_QENTRY; pkt_id++) { ilo_pkt_enqueue(hw, driver_ccb, SENDQ, pkt_id, pkt_sz); - DOORBELL_SET(driver_ccb); + doorbell_set(driver_ccb); } - pkt_sz = DESC_MEM_SZ(1); + pkt_sz = desc_mem_sz(1); for (pkt_id = 0; pkt_id < NR_QENTRY; pkt_id++) ilo_pkt_enqueue(hw, driver_ccb, RECVQ, pkt_id, pkt_sz); - DOORBELL_CLR(driver_ccb); + doorbell_clr(driver_ccb); /* make sure iLO is really handling requests */ for (i = 1000; i > 0; i--) { @@ -272,7 +317,7 @@ static int ilo_ccb_open(struct ilo_hwinfo *hw, struct ccb_data *data, int slot) if (i) { ilo_pkt_enqueue(hw, driver_ccb, SENDQ, pkt_id, 0); - DOORBELL_SET(driver_ccb); + doorbell_set(driver_ccb); } else { dev_err(&pdev->dev, "Open could not dequeue a packet\n"); error = -EBUSY; @@ -286,6 +331,30 @@ out: return error; } +static inline int is_channel_reset(struct ccb *ccb) +{ + /* check for this particular channel needing a reset */ + return FIFOBARTOHANDLE(ccb->ccb_u1.send_fifobar)->reset; +} + +static inline void set_channel_reset(struct ccb *ccb) +{ + /* set a flag indicating this channel needs a reset */ + FIFOBARTOHANDLE(ccb->ccb_u1.send_fifobar)->reset = 1; +} + +static inline int is_device_reset(struct ilo_hwinfo *hw) +{ + /* check for global reset condition */ + return ioread32(&hw->mmio_vaddr[DB_OUT]) & (1 << DB_RESET); +} + +static inline void clear_device(struct ilo_hwinfo *hw) +{ + /* clear the device (reset bits, pending channel entries) */ + iowrite32(-1, &hw->mmio_vaddr[DB_OUT]); +} + static void ilo_locked_reset(struct ilo_hwinfo *hw) { int slot; @@ -297,10 +366,10 @@ static void ilo_locked_reset(struct ilo_hwinfo *hw) for (slot = 0; slot < MAX_CCB; slot++) { if (!hw->ccb_alloc[slot]) continue; - SET_CHANNEL_RESET(&hw->ccb_alloc[slot]->driver_ccb); + set_channel_reset(&hw->ccb_alloc[slot]->driver_ccb); } - CLEAR_DEVICE(hw); + clear_device(hw); } static void ilo_reset(struct ilo_hwinfo *hw) @@ -308,7 +377,7 @@ static void ilo_reset(struct ilo_hwinfo *hw) spin_lock(&hw->alloc_lock); /* reset might have been handled after lock was taken */ - if (IS_DEVICE_RESET(hw)) + if (is_device_reset(hw)) ilo_locked_reset(hw); spin_unlock(&hw->alloc_lock); @@ -327,7 +396,7 @@ static ssize_t ilo_read(struct file *fp, char __user *buf, driver_ccb = &data->driver_ccb; hw = data->ilo_hw; - if (IS_DEVICE_RESET(hw) || IS_CHANNEL_RESET(driver_ccb)) { + if (is_device_reset(hw) || is_channel_reset(driver_ccb)) { /* * If the device has been reset, applications * need to close and reopen all ccbs. @@ -364,9 +433,9 @@ static ssize_t ilo_read(struct file *fp, char __user *buf, err = copy_to_user(buf, pkt, len); /* return the received packet to the queue */ - ilo_pkt_enqueue(hw, driver_ccb, RECVQ, pkt_id, DESC_MEM_SZ(1)); + ilo_pkt_enqueue(hw, driver_ccb, RECVQ, pkt_id, desc_mem_sz(1)); - return (err ? -EFAULT : len); + return err ? -EFAULT : len; } static ssize_t ilo_write(struct file *fp, const char __user *buf, @@ -382,7 +451,7 @@ static ssize_t ilo_write(struct file *fp, const char __user *buf, driver_ccb = &data->driver_ccb; hw = data->ilo_hw; - if (IS_DEVICE_RESET(hw) || IS_CHANNEL_RESET(driver_ccb)) { + if (is_device_reset(hw) || is_channel_reset(driver_ccb)) { /* * If the device has been reset, applications * need to close and reopen all ccbs. @@ -406,9 +475,9 @@ static ssize_t ilo_write(struct file *fp, const char __user *buf, /* send the packet */ ilo_pkt_enqueue(hw, driver_ccb, SENDQ, pkt_id, len); - DOORBELL_SET(driver_ccb); + doorbell_set(driver_ccb); - return (err ? -EFAULT : len); + return err ? -EFAULT : len; } static int ilo_close(struct inode *ip, struct file *fp) @@ -422,7 +491,7 @@ static int ilo_close(struct inode *ip, struct file *fp) spin_lock(&hw->alloc_lock); - if (IS_DEVICE_RESET(hw)) + if (is_device_reset(hw)) ilo_locked_reset(hw); if (hw->ccb_alloc[slot]->ccb_cnt == 1) { @@ -450,49 +519,51 @@ static int ilo_open(struct inode *ip, struct file *fp) slot = iminor(ip) % MAX_CCB; hw = container_of(ip->i_cdev, struct ilo_hwinfo, cdev); + /* new ccb allocation */ + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + spin_lock(&hw->alloc_lock); - if (IS_DEVICE_RESET(hw)) + if (is_device_reset(hw)) ilo_locked_reset(hw); /* each fd private_data holds sw/hw view of ccb */ if (hw->ccb_alloc[slot] == NULL) { - /* new ccb allocation */ - error = -ENOMEM; - data = kzalloc(sizeof(struct ccb_data), GFP_KERNEL); - if (!data) - goto out; - /* create a channel control block for this minor */ error = ilo_ccb_open(hw, data, slot); - if (error) - goto free; - - hw->ccb_alloc[slot] = data; - hw->ccb_alloc[slot]->ccb_cnt = 1; - hw->ccb_alloc[slot]->ccb_excl = fp->f_flags & O_EXCL; - hw->ccb_alloc[slot]->ilo_hw = hw; - } else if (fp->f_flags & O_EXCL || hw->ccb_alloc[slot]->ccb_excl) { - /* either this open or a previous open wants exclusive access */ - error = -EBUSY; - goto out; - } else - hw->ccb_alloc[slot]->ccb_cnt++; - + if (!error) { + hw->ccb_alloc[slot] = data; + hw->ccb_alloc[slot]->ccb_cnt = 1; + hw->ccb_alloc[slot]->ccb_excl = fp->f_flags & O_EXCL; + hw->ccb_alloc[slot]->ilo_hw = hw; + } else + kfree(data); + } else { + kfree(data); + if (fp->f_flags & O_EXCL || hw->ccb_alloc[slot]->ccb_excl) { + /* + * The channel exists, and either this open + * or a previous open of this channel wants + * exclusive access. + */ + error = -EBUSY; + } else { + hw->ccb_alloc[slot]->ccb_cnt++; + error = 0; + } + } spin_unlock(&hw->alloc_lock); - fp->private_data = hw->ccb_alloc[slot]; + if (!error) + fp->private_data = hw->ccb_alloc[slot]; - return 0; -free: - kfree(data); -out: - spin_unlock(&hw->alloc_lock); return error; } static const struct file_operations ilo_fops = { - THIS_MODULE, + .owner = THIS_MODULE, .read = ilo_read, .write = ilo_write, .open = ilo_open, @@ -545,7 +616,7 @@ static void ilo_remove(struct pci_dev *pdev) int i, minor; struct ilo_hwinfo *ilo_hw = pci_get_drvdata(pdev); - CLEAR_DEVICE(ilo_hw); + clear_device(ilo_hw); minor = MINOR(ilo_hw->cdev.dev); for (i = minor; i < minor + MAX_CCB; i++) @@ -580,7 +651,7 @@ static int __devinit ilo_probe(struct pci_dev *pdev, /* track global allocations for this device */ error = -ENOMEM; - ilo_hw = kzalloc(sizeof(struct ilo_hwinfo), GFP_KERNEL); + ilo_hw = kzalloc(sizeof(*ilo_hw), GFP_KERNEL); if (!ilo_hw) goto out; @@ -603,7 +674,7 @@ static int __devinit ilo_probe(struct pci_dev *pdev, goto free_regions; pci_set_drvdata(pdev, ilo_hw); - CLEAR_DEVICE(ilo_hw); + clear_device(ilo_hw); cdev_init(&ilo_hw->cdev, &ilo_fops); ilo_hw->cdev.owner = THIS_MODULE; @@ -615,9 +686,11 @@ static int __devinit ilo_probe(struct pci_dev *pdev, } for (minor = 0 ; minor < MAX_CCB; minor++) { - if (IS_ERR(device_create(ilo_class, &pdev->dev, - MKDEV(ilo_major, minor), - "hpilo!d%dccb%d", devnum, minor))) + struct device *dev; + dev = device_create(ilo_class, &pdev->dev, + MKDEV(ilo_major, minor), NULL, + "hpilo!d%dccb%d", devnum, minor); + if (IS_ERR(dev)) dev_err(&pdev->dev, "Could not create files\n"); } @@ -685,7 +758,7 @@ static void __exit ilo_exit(void) class_destroy(ilo_class); } -MODULE_VERSION("0.02"); +MODULE_VERSION("0.05"); MODULE_ALIAS(ILO_NAME); MODULE_DESCRIPTION(ILO_NAME); MODULE_AUTHOR("David Altobelli <david.altobelli@hp.com>"); diff --git a/drivers/misc/hpilo.h b/drivers/misc/hpilo.h index cc10c91..a281207 100644 --- a/drivers/misc/hpilo.h +++ b/drivers/misc/hpilo.h @@ -18,7 +18,7 @@ /* max number of supported devices */ #define MAX_ILO_DEV 1 /* max number of files */ -#define MAX_OPEN MAX_CCB * MAX_ILO_DEV +#define MAX_OPEN (MAX_CCB * MAX_ILO_DEV) /* * Per device, used to track global memory allocations. @@ -46,10 +46,8 @@ struct ilo_hwinfo { /* offset from mmio_vaddr */ #define DB_OUT 0xD4 -/* check for global reset condition */ -#define IS_DEVICE_RESET(hw) (ioread32(&(hw)->mmio_vaddr[DB_OUT]) & (1 << 26)) -/* clear the device (reset bits, pending channel entries) */ -#define CLEAR_DEVICE(hw) (iowrite32(-1, &(hw)->mmio_vaddr[DB_OUT])) +/* DB_OUT reset bit */ +#define DB_RESET 26 /* * Channel control block. Used to manage hardware queues. @@ -94,7 +92,6 @@ struct ccb { #define RECVQ 2 #define NR_QENTRY 4 #define L2_QENTRY_SZ 12 -#define DESC_MEM_SZ(_descs) ((_descs) << L2_QENTRY_SZ) /* ccb ctrl bitfields */ #define CTRL_BITPOS_L2SZ 0 @@ -103,19 +100,9 @@ struct ccb { #define CTRL_BITPOS_A 30 #define CTRL_BITPOS_G 31 -#define CTRL_SET(_c, _l, _f, _d, _a, _g) \ - ((_c) = \ - (((_l) << CTRL_BITPOS_L2SZ) |\ - ((_f) << CTRL_BITPOS_FIFOINDEXMASK) |\ - ((_d) << CTRL_BITPOS_DESCLIMIT) |\ - ((_a) << CTRL_BITPOS_A) |\ - ((_g) << CTRL_BITPOS_G))) - /* ccb doorbell macros */ #define L2_DB_SIZE 14 #define ONE_DB_SIZE (1 << L2_DB_SIZE) -#define DOORBELL_SET(_ccb) (iowrite8(1, (_ccb)->ccb_u5.db_base)) -#define DOORBELL_CLR(_ccb) (iowrite8(2, (_ccb)->ccb_u5.db_base)) /* * Per fd structure used to track the ccb allocated to that dev file. @@ -171,17 +158,6 @@ struct fifo { #define FIFOBARTOHANDLE(_fifo) \ ((struct fifo *)(((char *)(_fifo)) - FIFOHANDLESIZE)) -/* set a flag indicating this channel needs a reset */ -#define SET_CHANNEL_RESET(_ccb) \ - (FIFOBARTOHANDLE((_ccb)->ccb_u1.send_fifobar)->reset = 1) - -/* check for this particular channel needing a reset */ -#define IS_CHANNEL_RESET(_ccb) \ - (FIFOBARTOHANDLE((_ccb)->ccb_u1.send_fifobar)->reset) - -/* overall size of a fifo is determined by the number of entries it contains */ -#define FIFO_SZ(_num) (((_num)*sizeof(u64)) + FIFOHANDLESIZE) - /* the number of qwords to consume from the entry descriptor */ #define ENTRY_BITPOS_QWORDS 0 /* descriptor index number (within a specified queue) */ @@ -210,9 +186,4 @@ struct fifo { #define ENTRY_MASK_NOSTATE (ENTRY_MASK >> (ENTRY_BITS_C + ENTRY_BITS_O)) -#define GETQWORDS(_e) (((_e) & ENTRY_MASK_QWORDS) >> ENTRY_BITPOS_QWORDS) -#define GETDESC(_e) (((_e) & ENTRY_MASK_DESCRIPTOR) >> ENTRY_BITPOS_DESCRIPTOR) - -#define QWORDS(_B) (((_B) & 7) ? (((_B) >> 3) + 1) : ((_B) >> 3)) - #endif /* __HPILO_H */