static ssize_t ilo_write(struct file *fp, const char __user *buf, size_t len, loff_t *off) { int err, pkt_id, pkt_len; struct ccb_data *data = fp->private_data; struct ccb *driver_ccb = &data->driver_ccb; struct ilo_hwinfo *hw = data->ilo_hw; void *pkt; if (is_channel_reset(driver_ccb)) return -ENODEV; /* get a packet to send the user command */ if (!ilo_pkt_dequeue(hw, driver_ccb, SENDQ, &pkt_id, &pkt_len, &pkt)) return -EBUSY; /* limit the length to the length of the packet */ if (pkt_len < len) len = pkt_len; /* on failure, set the len to 0 to return empty packet to the device */ err = copy_from_user(pkt, buf, len); if (err) len = 0; /* send the packet */ ilo_pkt_enqueue(hw, driver_ccb, SENDQ, pkt_id, len); doorbell_set(driver_ccb); return err ? -EFAULT : len; }
static ssize_t ilo_write(struct file *fp, const char __user *buf, size_t len, loff_t *off) { int err, pkt_id, pkt_len; struct ccb_data *data = fp->private_data; struct ccb *driver_ccb = &data->driver_ccb; struct ilo_hwinfo *hw = data->ilo_hw; void *pkt; if (is_channel_reset(driver_ccb)) return -ENODEV; /* */ if (!ilo_pkt_dequeue(hw, driver_ccb, SENDQ, &pkt_id, &pkt_len, &pkt)) return -EBUSY; /* */ if (pkt_len < len) len = pkt_len; /* */ err = copy_from_user(pkt, buf, len); if (err) len = 0; /* */ ilo_pkt_enqueue(hw, driver_ccb, SENDQ, pkt_id, len); doorbell_set(driver_ccb); return err ? -EFAULT : len; }
static ssize_t ilo_read(struct file *fp, char __user *buf, size_t len, loff_t *off) { int err, found, cnt, pkt_id, pkt_len; struct ccb_data *data = fp->private_data; struct ccb *driver_ccb = &data->driver_ccb; struct ilo_hwinfo *hw = data->ilo_hw; void *pkt; if (is_channel_reset(driver_ccb)) { /* * If the device has been reset, applications * need to close and reopen all ccbs. */ return -ENODEV; } /* * This function is to be called when data is expected * in the channel, and will return an error if no packet is found * during the loop below. The sleep/retry logic is to allow * applications to call read() immediately post write(), * and give iLO some time to process the sent packet. */ cnt = 20; do { /* look for a received packet */ found = ilo_pkt_dequeue(hw, driver_ccb, RECVQ, &pkt_id, &pkt_len, &pkt); if (found) break; cnt--; msleep(100); } while (!found && cnt); if (!found) return -EAGAIN; /* only copy the length of the received packet */ if (pkt_len < len) len = pkt_len; 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)); return err ? -EFAULT : len; }
static ssize_t ilo_read(struct file *fp, char __user *buf, size_t len, loff_t *off) { int err, found, cnt, pkt_id, pkt_len; struct ccb_data *data = fp->private_data; struct ccb *driver_ccb = &data->driver_ccb; struct ilo_hwinfo *hw = data->ilo_hw; void *pkt; if (is_channel_reset(driver_ccb)) { /* */ return -ENODEV; } /* */ cnt = 20; do { /* */ found = ilo_pkt_dequeue(hw, driver_ccb, RECVQ, &pkt_id, &pkt_len, &pkt); if (found) break; cnt--; msleep(100); } while (!found && cnt); if (!found) return -EAGAIN; /* */ if (pkt_len < len) len = pkt_len; err = copy_to_user(buf, pkt, len); /* */ ilo_pkt_enqueue(hw, driver_ccb, RECVQ, pkt_id, desc_mem_sz(1)); return err ? -EFAULT : len; }
static int ilo_ccb_verify(struct ilo_hwinfo *hw, struct ccb_data *data) { int pkt_id, i; struct ccb *driver_ccb = &data->driver_ccb; /* make sure iLO is really handling requests */ for (i = MAX_WAIT; i > 0; i--) { if (ilo_pkt_dequeue(hw, driver_ccb, SENDQ, &pkt_id, NULL, NULL)) break; udelay(WAIT_TIME); } if (i == 0) { dev_err(&hw->ilo_dev->dev, "Open could not dequeue a packet\n"); return -EBUSY; } ilo_pkt_enqueue(hw, driver_ccb, SENDQ, pkt_id, 0); doorbell_set(driver_ccb); return 0; }