diff options
Diffstat (limited to 'drivers/misc/genwqe')
-rw-r--r-- | drivers/misc/genwqe/card_base.c | 38 | ||||
-rw-r--r-- | drivers/misc/genwqe/card_base.h | 21 | ||||
-rw-r--r-- | drivers/misc/genwqe/card_ddcb.c | 77 | ||||
-rw-r--r-- | drivers/misc/genwqe/card_ddcb.h | 2 | ||||
-rw-r--r-- | drivers/misc/genwqe/card_debugfs.c | 10 | ||||
-rw-r--r-- | drivers/misc/genwqe/card_dev.c | 21 | ||||
-rw-r--r-- | drivers/misc/genwqe/card_sysfs.c | 11 | ||||
-rw-r--r-- | drivers/misc/genwqe/card_utils.c | 7 | ||||
-rw-r--r-- | drivers/misc/genwqe/genwqe_driver.h | 4 |
9 files changed, 112 insertions, 79 deletions
diff --git a/drivers/misc/genwqe/card_base.c b/drivers/misc/genwqe/card_base.c index 43bbabc96b6..4cf8f82cfca 100644 --- a/drivers/misc/genwqe/card_base.c +++ b/drivers/misc/genwqe/card_base.c @@ -5,7 +5,7 @@ * * Author: Frank Haverkamp <haver@linux.vnet.ibm.com> * Author: Joerg-Stephan Vogt <jsvogt@de.ibm.com> - * Author: Michael Jung <mijung@de.ibm.com> + * Author: Michael Jung <mijung@gmx.net> * Author: Michael Ruettger <michael@ibmra.de> * * This program is free software; you can redistribute it and/or modify @@ -45,10 +45,10 @@ MODULE_AUTHOR("Frank Haverkamp <haver@linux.vnet.ibm.com>"); MODULE_AUTHOR("Michael Ruettger <michael@ibmra.de>"); MODULE_AUTHOR("Joerg-Stephan Vogt <jsvogt@de.ibm.com>"); -MODULE_AUTHOR("Michal Jung <mijung@de.ibm.com>"); +MODULE_AUTHOR("Michael Jung <mijung@gmx.net>"); MODULE_DESCRIPTION("GenWQE Card"); -MODULE_VERSION(DRV_VERS_STRING); +MODULE_VERSION(DRV_VERSION); MODULE_LICENSE("GPL"); static char genwqe_driver_name[] = GENWQE_DEVNAME; @@ -346,8 +346,13 @@ static bool genwqe_setup_vf_jtimer(struct genwqe_dev *cd) unsigned int vf; u32 T = genwqe_T_psec(cd); u64 x; + int totalvfs; - for (vf = 0; vf < pci_sriov_get_totalvfs(pci_dev); vf++) { + totalvfs = pci_sriov_get_totalvfs(pci_dev); + if (totalvfs <= 0) + return false; + + for (vf = 0; vf < totalvfs; vf++) { if (cd->vf_jobtimeout_msec[vf] == 0) continue; @@ -383,8 +388,9 @@ static int genwqe_ffdc_buffs_alloc(struct genwqe_dev *cd) /* currently support only the debug units mentioned here */ cd->ffdc[type].entries = e; - cd->ffdc[type].regs = kmalloc(e * sizeof(struct genwqe_reg), - GFP_KERNEL); + cd->ffdc[type].regs = + kmalloc_array(e, sizeof(struct genwqe_reg), + GFP_KERNEL); /* * regs == NULL is ok, the using code treats this as no regs, * Printing warning is ok in this case. @@ -723,8 +729,8 @@ static u64 genwqe_fir_checking(struct genwqe_dev *cd) __genwqe_writeq(cd, sfir_addr, sfir); dev_dbg(&pci_dev->dev, - "[HM] Clearing 2ndary FIR 0x%08x " - "with 0x%016llx\n", sfir_addr, sfir); + "[HM] Clearing 2ndary FIR 0x%08x with 0x%016llx\n", + sfir_addr, sfir); /* * note, these cannot be error-Firs @@ -740,9 +746,8 @@ static u64 genwqe_fir_checking(struct genwqe_dev *cd) __genwqe_writeq(cd, fir_clr_addr, mask); dev_dbg(&pci_dev->dev, - "[HM] Clearing primary FIR 0x%08x " - "with 0x%016llx\n", fir_clr_addr, - mask); + "[HM] Clearing primary FIR 0x%08x with 0x%016llx\n", + fir_clr_addr, mask); } } } @@ -1125,6 +1130,8 @@ static int genwqe_pci_setup(struct genwqe_dev *cd) } cd->num_vfs = pci_sriov_get_totalvfs(pci_dev); + if (cd->num_vfs < 0) + cd->num_vfs = 0; err = genwqe_read_ids(cd); if (err) @@ -1202,8 +1209,8 @@ static int genwqe_probe(struct pci_dev *pci_dev, err = genwqe_health_check_start(cd); if (err < 0) { dev_err(&pci_dev->dev, - "err: cannot start health checking! " - "(err=%d)\n", err); + "err: cannot start health checking! (err=%d)\n", + err); goto out_stop_services; } } @@ -1313,11 +1320,14 @@ static void genwqe_err_resume(struct pci_dev *pci_dev) static int genwqe_sriov_configure(struct pci_dev *dev, int numvfs) { + int rc; struct genwqe_dev *cd = dev_get_drvdata(&dev->dev); if (numvfs > 0) { genwqe_setup_vf_jtimer(cd); - pci_enable_sriov(dev, numvfs); + rc = pci_enable_sriov(dev, numvfs); + if (rc < 0) + return rc; return numvfs; } if (numvfs == 0) { diff --git a/drivers/misc/genwqe/card_base.h b/drivers/misc/genwqe/card_base.h index 67abd8cb224..c64d7cad108 100644 --- a/drivers/misc/genwqe/card_base.h +++ b/drivers/misc/genwqe/card_base.h @@ -8,7 +8,7 @@ * * Author: Frank Haverkamp <haver@linux.vnet.ibm.com> * Author: Joerg-Stephan Vogt <jsvogt@de.ibm.com> - * Author: Michael Jung <mijung@de.ibm.com> + * Author: Michael Jung <mijung@gmx.net> * Author: Michael Ruettger <michael@ibmra.de> * * This program is free software; you can redistribute it and/or modify @@ -201,7 +201,8 @@ static inline void genwqe_mapping_init(struct dma_mapping *m, * @ddcb_seq: Sequence number of last DDCB * @ddcbs_in_flight: Currently enqueued DDCBs * @ddcbs_completed: Number of already completed DDCBs - * @busy: Number of -EBUSY returns + * @return_on_busy: Number of -EBUSY returns on full queue + * @wait_on_busy: Number of waits on full queue * @ddcb_daddr: DMA address of first DDCB in the queue * @ddcb_vaddr: Kernel virtual address of first DDCB in the queue * @ddcb_req: Associated requests (one per DDCB) @@ -218,7 +219,8 @@ struct ddcb_queue { unsigned int ddcbs_in_flight; /* number of ddcbs in processing */ unsigned int ddcbs_completed; unsigned int ddcbs_max_in_flight; - unsigned int busy; /* how many times -EBUSY? */ + unsigned int return_on_busy; /* how many times -EBUSY? */ + unsigned int wait_on_busy; dma_addr_t ddcb_daddr; /* DMA address */ struct ddcb *ddcb_vaddr; /* kernel virtual addr for DDCBs */ @@ -226,7 +228,7 @@ struct ddcb_queue { wait_queue_head_t *ddcb_waitqs; /* waitqueue per ddcb */ spinlock_t ddcb_lock; /* exclusive access to queue */ - wait_queue_head_t ddcb_waitq; /* wait for ddcb processing */ + wait_queue_head_t busy_waitq; /* wait for ddcb processing */ /* registers or the respective queue to be used */ u32 IO_QUEUE_CONFIG; @@ -306,7 +308,7 @@ struct genwqe_dev { struct pci_dev *pci_dev; /* PCI device */ void __iomem *mmio; /* BAR-0 MMIO start */ unsigned long mmio_len; - u16 num_vfs; + int num_vfs; u32 vf_jobtimeout_msec[GENWQE_MAX_VFS]; int is_privileged; /* access to all regs possible */ @@ -508,7 +510,7 @@ static inline bool dma_mapping_used(struct dma_mapping *m) * buildup and teardown. */ int __genwqe_execute_ddcb(struct genwqe_dev *cd, - struct genwqe_ddcb_cmd *cmd); + struct genwqe_ddcb_cmd *cmd, unsigned int f_flags); /** * __genwqe_execute_raw_ddcb() - Execute DDCB request without addr translation @@ -520,9 +522,12 @@ int __genwqe_execute_ddcb(struct genwqe_dev *cd, * modification. */ int __genwqe_execute_raw_ddcb(struct genwqe_dev *cd, - struct genwqe_ddcb_cmd *cmd); + struct genwqe_ddcb_cmd *cmd, + unsigned int f_flags); +int __genwqe_enqueue_ddcb(struct genwqe_dev *cd, + struct ddcb_requ *req, + unsigned int f_flags); -int __genwqe_enqueue_ddcb(struct genwqe_dev *cd, struct ddcb_requ *req); int __genwqe_wait_ddcb(struct genwqe_dev *cd, struct ddcb_requ *req); int __genwqe_purge_ddcb(struct genwqe_dev *cd, struct ddcb_requ *req); diff --git a/drivers/misc/genwqe/card_ddcb.c b/drivers/misc/genwqe/card_ddcb.c index dc9851a5540..6d51e5f0866 100644 --- a/drivers/misc/genwqe/card_ddcb.c +++ b/drivers/misc/genwqe/card_ddcb.c @@ -5,7 +5,7 @@ * * Author: Frank Haverkamp <haver@linux.vnet.ibm.com> * Author: Joerg-Stephan Vogt <jsvogt@de.ibm.com> - * Author: Michael Jung <mijung@de.ibm.com> + * Author: Michael Jung <mijung@gmx.net> * Author: Michael Ruettger <michael@ibmra.de> * * This program is free software; you can redistribute it and/or modify @@ -185,8 +185,7 @@ static void print_ddcb_info(struct genwqe_dev *cd, struct ddcb_queue *queue) pddcb = queue->ddcb_vaddr; for (i = 0; i < queue->ddcb_max; i++) { dev_err(&pci_dev->dev, - " %c %-3d: RETC=%03x SEQ=%04x " - "HSI=%02X SHI=%02x PRIV=%06llx CMD=%03x\n", + " %c %-3d: RETC=%03x SEQ=%04x HSI=%02X SHI=%02x PRIV=%06llx CMD=%03x\n", i == queue->ddcb_act ? '>' : ' ', i, be16_to_cpu(pddcb->retc_16), @@ -214,6 +213,7 @@ struct genwqe_ddcb_cmd *ddcb_requ_alloc(void) void ddcb_requ_free(struct genwqe_ddcb_cmd *cmd) { struct ddcb_requ *req = container_of(cmd, struct ddcb_requ, cmd); + kfree(req); } @@ -306,7 +306,7 @@ static int enqueue_ddcb(struct genwqe_dev *cd, struct ddcb_queue *queue, new = (old | DDCB_NEXT_BE32); - wmb(); + wmb(); /* need to ensure write ordering */ icrc_hsi_shi = cmpxchg(&prev_ddcb->icrc_hsi_shi_32, old, new); if (icrc_hsi_shi == old) @@ -317,7 +317,7 @@ static int enqueue_ddcb(struct genwqe_dev *cd, struct ddcb_queue *queue, ddcb_mark_tapped(pddcb); num = (u64)ddcb_no << 8; - wmb(); + wmb(); /* need to ensure write ordering */ __genwqe_writeq(cd, queue->IO_QUEUE_OFFSET, num); /* start queue */ return RET_DDCB_TAPPED; @@ -390,8 +390,9 @@ static int genwqe_check_ddcb_queue(struct genwqe_dev *cd, 0x00000000) goto go_home; /* not completed, continue waiting */ - /* Note: DDCB could be purged */ + wmb(); /* Add sync to decouple prev. read operations */ + /* Note: DDCB could be purged */ req = queue->ddcb_req[queue->ddcb_act]; if (req == NULL) { /* this occurs if DDCB is purged, not an error */ @@ -416,9 +417,7 @@ static int genwqe_check_ddcb_queue(struct genwqe_dev *cd, status = __genwqe_readq(cd, queue->IO_QUEUE_STATUS); dev_err(&pci_dev->dev, - "[%s] SEQN=%04x HSI=%02x RETC=%03x " - " Q_ERRCNTS=%016llx Q_STATUS=%016llx\n" - " DDCB_DMA_ADDR=%016llx\n", + "[%s] SEQN=%04x HSI=%02x RETC=%03x Q_ERRCNTS=%016llx Q_STATUS=%016llx DDCB_DMA_ADDR=%016llx\n", __func__, be16_to_cpu(pddcb->seqnum_16), pddcb->hsi, retc_16, errcnts, status, queue->ddcb_daddr + ddcb_offs); @@ -439,8 +438,7 @@ static int genwqe_check_ddcb_queue(struct genwqe_dev *cd, vcrc_16 = be16_to_cpu(pddcb->vcrc_16); if (vcrc != vcrc_16) { printk_ratelimited(KERN_ERR - "%s %s: err: wrong VCRC pre=%02x vcrc_len=%d " - "bytes vcrc_data=%04x is not vcrc_card=%04x\n", + "%s %s: err: wrong VCRC pre=%02x vcrc_len=%d bytes vcrc_data=%04x is not vcrc_card=%04x\n", GENWQE_DEVNAME, dev_name(&pci_dev->dev), pddcb->pre, VCRC_LENGTH(req->cmd.asv_length), vcrc, vcrc_16); @@ -450,8 +448,10 @@ static int genwqe_check_ddcb_queue(struct genwqe_dev *cd, queue->ddcbs_completed++; queue->ddcbs_in_flight--; - /* wake up process waiting for this DDCB */ + /* wake up process waiting for this DDCB, and + processes on the busy queue */ wake_up_interruptible(&queue->ddcb_waitqs[queue->ddcb_act]); + wake_up_interruptible(&queue->busy_waitq); pick_next_one: queue->ddcb_act = (queue->ddcb_act + 1) % queue->ddcb_max; @@ -717,8 +717,7 @@ go_home: genwqe_hexdump(pci_dev, pddcb, sizeof(*pddcb)); dev_err(&pci_dev->dev, - "[%s] err: DDCB#%d not purged and not completed " - "after %d seconds QSTAT=%016llx!!\n", + "[%s] err: DDCB#%d not purged and not completed after %d seconds QSTAT=%016llx!!\n", __func__, req->num, genwqe_ddcb_software_timeout, queue_status); @@ -740,7 +739,7 @@ int genwqe_init_debug_data(struct genwqe_dev *cd, struct genwqe_debug_data *d) } len = sizeof(d->driver_version); - snprintf(d->driver_version, len, "%s", DRV_VERS_STRING); + snprintf(d->driver_version, len, "%s", DRV_VERSION); d->slu_unitcfg = cd->slu_unitcfg; d->app_unitcfg = cd->app_unitcfg; return 0; @@ -748,14 +747,16 @@ int genwqe_init_debug_data(struct genwqe_dev *cd, struct genwqe_debug_data *d) /** * __genwqe_enqueue_ddcb() - Enqueue a DDCB - * @cd: pointer to genwqe device descriptor - * @req: pointer to DDCB execution request + * @cd: pointer to genwqe device descriptor + * @req: pointer to DDCB execution request + * @f_flags: file mode: blocking, non-blocking * * Return: 0 if enqueuing succeeded * -EIO if card is unusable/PCIe problems * -EBUSY if enqueuing failed */ -int __genwqe_enqueue_ddcb(struct genwqe_dev *cd, struct ddcb_requ *req) +int __genwqe_enqueue_ddcb(struct genwqe_dev *cd, struct ddcb_requ *req, + unsigned int f_flags) { struct ddcb *pddcb; unsigned long flags; @@ -763,6 +764,7 @@ int __genwqe_enqueue_ddcb(struct genwqe_dev *cd, struct ddcb_requ *req) struct pci_dev *pci_dev = cd->pci_dev; u16 icrc; + retry: if (cd->card_state != GENWQE_CARD_USED) { printk_ratelimited(KERN_ERR "%s %s: [%s] Card is unusable/PCIe problem Req#%d\n", @@ -788,9 +790,24 @@ int __genwqe_enqueue_ddcb(struct genwqe_dev *cd, struct ddcb_requ *req) pddcb = get_next_ddcb(cd, queue, &req->num); /* get ptr and num */ if (pddcb == NULL) { + int rc; + spin_unlock_irqrestore(&queue->ddcb_lock, flags); - queue->busy++; - return -EBUSY; + + if (f_flags & O_NONBLOCK) { + queue->return_on_busy++; + return -EBUSY; + } + + queue->wait_on_busy++; + rc = wait_event_interruptible(queue->busy_waitq, + queue_free_ddcbs(queue) != 0); + dev_dbg(&pci_dev->dev, "[%s] waiting for free DDCB: rc=%d\n", + __func__, rc); + if (rc == -ERESTARTSYS) + return rc; /* interrupted by a signal */ + + goto retry; } if (queue->ddcb_req[req->num] != NULL) { @@ -893,9 +910,11 @@ int __genwqe_enqueue_ddcb(struct genwqe_dev *cd, struct ddcb_requ *req) * __genwqe_execute_raw_ddcb() - Setup and execute DDCB * @cd: pointer to genwqe device descriptor * @req: user provided DDCB request + * @f_flags: file mode: blocking, non-blocking */ int __genwqe_execute_raw_ddcb(struct genwqe_dev *cd, - struct genwqe_ddcb_cmd *cmd) + struct genwqe_ddcb_cmd *cmd, + unsigned int f_flags) { int rc = 0; struct pci_dev *pci_dev = cd->pci_dev; @@ -911,7 +930,7 @@ int __genwqe_execute_raw_ddcb(struct genwqe_dev *cd, __func__, cmd->asiv_length); return -EINVAL; } - rc = __genwqe_enqueue_ddcb(cd, req); + rc = __genwqe_enqueue_ddcb(cd, req, f_flags); if (rc != 0) return rc; @@ -1017,7 +1036,8 @@ static int setup_ddcb_queue(struct genwqe_dev *cd, struct ddcb_queue *queue) queue->ddcbs_in_flight = 0; /* statistics */ queue->ddcbs_max_in_flight = 0; queue->ddcbs_completed = 0; - queue->busy = 0; + queue->return_on_busy = 0; + queue->wait_on_busy = 0; queue->ddcb_seq = 0x100; /* start sequence number */ queue->ddcb_max = genwqe_ddcb_max; /* module parameter */ @@ -1057,7 +1077,7 @@ static int setup_ddcb_queue(struct genwqe_dev *cd, struct ddcb_queue *queue) queue->ddcb_next = 0; /* queue is empty */ spin_lock_init(&queue->ddcb_lock); - init_waitqueue_head(&queue->ddcb_waitq); + init_waitqueue_head(&queue->busy_waitq); val64 = ((u64)(queue->ddcb_max - 1) << 8); /* lastptr */ __genwqe_writeq(cd, queue->IO_QUEUE_CONFIG, 0x07); /* iCRC/vCRC */ @@ -1251,10 +1271,8 @@ int genwqe_setup_service_layer(struct genwqe_dev *cd) } rc = genwqe_set_interrupt_capability(cd, GENWQE_MSI_IRQS); - if (rc) { - rc = -ENODEV; + if (rc) goto stop_kthread; - } /* * We must have all wait-queues initialized when we enable the @@ -1307,6 +1325,7 @@ static int queue_wake_up_all(struct genwqe_dev *cd) for (i = 0; i < queue->ddcb_max; i++) wake_up_interruptible(&queue->ddcb_waitqs[queue->ddcb_act]); + wake_up_interruptible(&queue->busy_waitq); spin_unlock_irqrestore(&queue->ddcb_lock, flags); return 0; @@ -1346,8 +1365,8 @@ int genwqe_finish_queue(struct genwqe_dev *cd) break; dev_dbg(&pci_dev->dev, - " DEBUG [%d/%d] waiting for queue to get empty: " - "%d requests!\n", i, waitmax, in_flight); + " DEBUG [%d/%d] waiting for queue to get empty: %d requests!\n", + i, waitmax, in_flight); /* * Severe severe error situation: The card itself has diff --git a/drivers/misc/genwqe/card_ddcb.h b/drivers/misc/genwqe/card_ddcb.h index c4f26720753..0361a68d79a 100644 --- a/drivers/misc/genwqe/card_ddcb.h +++ b/drivers/misc/genwqe/card_ddcb.h @@ -8,7 +8,7 @@ * * Author: Frank Haverkamp <haver@linux.vnet.ibm.com> * Author: Joerg-Stephan Vogt <jsvogt@de.ibm.com> - * Author: Michael Jung <mijung@de.ibm.com> + * Author: Michael Jung <mijung@gmx.net> * Author: Michael Ruettger <michael@ibmra.de> * * This program is free software; you can redistribute it and/or modify diff --git a/drivers/misc/genwqe/card_debugfs.c b/drivers/misc/genwqe/card_debugfs.c index c9b4d6d0eb9..c715534e7fe 100644 --- a/drivers/misc/genwqe/card_debugfs.c +++ b/drivers/misc/genwqe/card_debugfs.c @@ -5,7 +5,7 @@ * * Author: Frank Haverkamp <haver@linux.vnet.ibm.com> * Author: Joerg-Stephan Vogt <jsvogt@de.ibm.com> - * Author: Michael Jung <mijung@de.ibm.com> + * Author: Michael Jung <mijung@gmx.net> * Author: Michael Ruettger <michael@ibmra.de> * * This program is free software; you can redistribute it and/or modify @@ -244,14 +244,16 @@ static int genwqe_ddcb_info_show(struct seq_file *s, void *unused) " ddcbs_in_flight: %u\n" " ddcbs_max_in_flight: %u\n" " ddcbs_completed: %u\n" - " busy: %u\n" + " return_on_busy: %u\n" + " wait_on_busy: %u\n" " irqs_processed: %u\n", queue->ddcb_max, (long long)queue->ddcb_daddr, (long long)queue->ddcb_daddr + (queue->ddcb_max * DDCB_LENGTH), (long long)queue->ddcb_vaddr, queue->ddcbs_in_flight, queue->ddcbs_max_in_flight, queue->ddcbs_completed, - queue->busy, cd->irqs_processed); + queue->return_on_busy, queue->wait_on_busy, + cd->irqs_processed); /* Hardware State */ seq_printf(s, " 0x%08x 0x%016llx IO_QUEUE_CONFIG\n" @@ -323,7 +325,7 @@ static int genwqe_info_show(struct seq_file *s, void *unused) " Base Clock : %u MHz\n" " Arch/SVN Release: %u/%llx\n" " Bitstream : %llx\n", - GENWQE_DEVNAME, DRV_VERS_STRING, dev_name(&pci_dev->dev), + GENWQE_DEVNAME, DRV_VERSION, dev_name(&pci_dev->dev), genwqe_is_privileged(cd) ? "Physical" : "Virtual or no SR-IOV", cd->card_idx, slu_id, app_id, diff --git a/drivers/misc/genwqe/card_dev.c b/drivers/misc/genwqe/card_dev.c index aae42555e2c..5918586f2f7 100644 --- a/drivers/misc/genwqe/card_dev.c +++ b/drivers/misc/genwqe/card_dev.c @@ -5,7 +5,7 @@ * * Author: Frank Haverkamp <haver@linux.vnet.ibm.com> * Author: Joerg-Stephan Vogt <jsvogt@de.ibm.com> - * Author: Michael Jung <mijung@de.ibm.com> + * Author: Michael Jung <mijung@gmx.net> * Author: Michael Ruettger <michael@ibmra.de> * * This program is free software; you can redistribute it and/or modify @@ -213,9 +213,9 @@ static void genwqe_remove_mappings(struct genwqe_file *cfile) * GENWQE_MAPPING_SGL_TEMP should be removed by tidy up code. */ dev_err(&pci_dev->dev, - "[%s] %d. cleanup mapping: u_vaddr=%p " - "u_kaddr=%016lx dma_addr=%lx\n", __func__, i++, - dma_map->u_vaddr, (unsigned long)dma_map->k_vaddr, + "[%s] %d. cleanup mapping: u_vaddr=%p u_kaddr=%016lx dma_addr=%lx\n", + __func__, i++, dma_map->u_vaddr, + (unsigned long)dma_map->k_vaddr, (unsigned long)dma_map->dma_addr); if (dma_map->type == GENWQE_MAPPING_RAW) { @@ -346,6 +346,7 @@ static int genwqe_open(struct inode *inode, struct file *filp) static int genwqe_fasync(int fd, struct file *filp, int mode) { struct genwqe_file *cdev = (struct genwqe_file *)filp->private_data; + return fasync_helper(fd, filp, mode, &cdev->async_queue); } @@ -515,6 +516,7 @@ static int do_flash_update(struct genwqe_file *cfile, u32 crc; u8 cmdopts; struct genwqe_dev *cd = cfile->cd; + struct file *filp = cfile->filp; struct pci_dev *pci_dev = cd->pci_dev; if ((load->size & 0x3) != 0) @@ -609,7 +611,7 @@ static int do_flash_update(struct genwqe_file *cfile, /* For Genwqe5 we get back the calculated CRC */ *(u64 *)&req->asv[0] = 0ULL; /* 0x80 */ - rc = __genwqe_execute_raw_ddcb(cd, req); + rc = __genwqe_execute_raw_ddcb(cd, req, filp->f_flags); load->retc = req->retc; load->attn = req->attn; @@ -649,6 +651,7 @@ static int do_flash_read(struct genwqe_file *cfile, u8 *xbuf; u8 cmdopts; struct genwqe_dev *cd = cfile->cd; + struct file *filp = cfile->filp; struct pci_dev *pci_dev = cd->pci_dev; struct genwqe_ddcb_cmd *cmd; @@ -726,7 +729,7 @@ static int do_flash_read(struct genwqe_file *cfile, /* we only get back the calculated CRC */ *(u64 *)&cmd->asv[0] = 0ULL; /* 0x80 */ - rc = __genwqe_execute_raw_ddcb(cd, cmd); + rc = __genwqe_execute_raw_ddcb(cd, cmd, filp->f_flags); load->retc = cmd->retc; load->attn = cmd->attn; @@ -987,13 +990,14 @@ static int genwqe_execute_ddcb(struct genwqe_file *cfile, { int rc; struct genwqe_dev *cd = cfile->cd; + struct file *filp = cfile->filp; struct ddcb_requ *req = container_of(cmd, struct ddcb_requ, cmd); rc = ddcb_cmd_fixups(cfile, req); if (rc != 0) return rc; - rc = __genwqe_execute_raw_ddcb(cd, cmd); + rc = __genwqe_execute_raw_ddcb(cd, cmd, filp->f_flags); ddcb_cmd_cleanup(cfile, req); return rc; } @@ -1005,6 +1009,7 @@ static int do_execute_ddcb(struct genwqe_file *cfile, struct genwqe_ddcb_cmd *cmd; struct ddcb_requ *req; struct genwqe_dev *cd = cfile->cd; + struct file *filp = cfile->filp; cmd = ddcb_requ_alloc(); if (cmd == NULL) @@ -1020,7 +1025,7 @@ static int do_execute_ddcb(struct genwqe_file *cfile, if (!raw) rc = genwqe_execute_ddcb(cfile, cmd); else - rc = __genwqe_execute_raw_ddcb(cd, cmd); + rc = __genwqe_execute_raw_ddcb(cd, cmd, filp->f_flags); /* Copy back only the modifed fields. Do not copy ASIV back since the copy got modified by the driver. */ diff --git a/drivers/misc/genwqe/card_sysfs.c b/drivers/misc/genwqe/card_sysfs.c index 7232e40a3ad..2c33fbca922 100644 --- a/drivers/misc/genwqe/card_sysfs.c +++ b/drivers/misc/genwqe/card_sysfs.c @@ -5,7 +5,7 @@ * * Author: Frank Haverkamp <haver@linux.vnet.ibm.com> * Author: Joerg-Stephan Vogt <jsvogt@de.ibm.com> - * Author: Michael Jung <mijung@de.ibm.com> + * Author: Michael Jung <mijung@gmx.net> * Author: Michael Ruettger <michael@ibmra.de> * * This program is free software; you can redistribute it and/or modify @@ -91,13 +91,6 @@ static ssize_t type_show(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR_RO(type); -static ssize_t driver_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - return sprintf(buf, "%s\n", DRV_VERS_STRING); -} -static DEVICE_ATTR_RO(driver); - static ssize_t tempsens_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -256,7 +249,6 @@ static struct attribute *genwqe_attributes[] = { &dev_attr_next_bitstream.attr, &dev_attr_curr_bitstream.attr, &dev_attr_base_clock.attr, - &dev_attr_driver.attr, &dev_attr_type.attr, &dev_attr_version.attr, &dev_attr_appid.attr, @@ -268,7 +260,6 @@ static struct attribute *genwqe_attributes[] = { }; static struct attribute *genwqe_normal_attributes[] = { - &dev_attr_driver.attr, &dev_attr_type.attr, &dev_attr_version.attr, &dev_attr_appid.attr, diff --git a/drivers/misc/genwqe/card_utils.c b/drivers/misc/genwqe/card_utils.c index a6400f09229..7cb3b7e4173 100644 --- a/drivers/misc/genwqe/card_utils.c +++ b/drivers/misc/genwqe/card_utils.c @@ -5,7 +5,7 @@ * * Author: Frank Haverkamp <haver@linux.vnet.ibm.com> * Author: Joerg-Stephan Vogt <jsvogt@de.ibm.com> - * Author: Michael Jung <mijung@de.ibm.com> + * Author: Michael Jung <mijung@gmx.net> * Author: Michael Ruettger <michael@ibmra.de> * * This program is free software; you can redistribute it and/or modify @@ -150,6 +150,7 @@ int genwqe_read_app_id(struct genwqe_dev *cd, char *app_name, int len) memset(app_name, 0, len); for (i = 0, j = 0; j < min(len, 4); j++) { char ch = (char)((app_id >> (24 - j*8)) & 0xff); + if (ch == ' ') continue; app_name[i++] = isprint(ch) ? ch : 'X'; @@ -304,8 +305,7 @@ int genwqe_alloc_sync_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl, sgl->nr_pages = DIV_ROUND_UP(sgl->fpage_offs + user_size, PAGE_SIZE); sgl->lpage_size = (user_size - sgl->fpage_size) % PAGE_SIZE; - dev_dbg(&pci_dev->dev, "[%s] uaddr=%p usize=%8ld nr_pages=%ld " - "fpage_offs=%lx fpage_size=%ld lpage_size=%ld\n", + dev_dbg(&pci_dev->dev, "[%s] uaddr=%p usize=%8ld nr_pages=%ld fpage_offs=%lx fpage_size=%ld lpage_size=%ld\n", __func__, user_addr, user_size, sgl->nr_pages, sgl->fpage_offs, sgl->fpage_size, sgl->lpage_size); @@ -662,6 +662,7 @@ int genwqe_user_vunmap(struct genwqe_dev *cd, struct dma_mapping *m, u8 genwqe_card_type(struct genwqe_dev *cd) { u64 card_type = cd->slu_unitcfg; + return (u8)((card_type & IO_SLU_UNITCFG_TYPE_MASK) >> 20); } diff --git a/drivers/misc/genwqe/genwqe_driver.h b/drivers/misc/genwqe/genwqe_driver.h index a506e9aa2d5..15355350e07 100644 --- a/drivers/misc/genwqe/genwqe_driver.h +++ b/drivers/misc/genwqe/genwqe_driver.h @@ -8,7 +8,7 @@ * * Author: Frank Haverkamp <haver@linux.vnet.ibm.com> * Author: Joerg-Stephan Vogt <jsvogt@de.ibm.com> - * Author: Michael Jung <mijung@de.ibm.com> + * Author: Michael Jung <mijung@gmx.net> * Author: Michael Ruettger <michael@ibmra.de> * * This program is free software; you can redistribute it and/or modify @@ -36,7 +36,7 @@ #include <asm/byteorder.h> #include <linux/genwqe/genwqe_card.h> -#define DRV_VERS_STRING "2.0.21" +#define DRV_VERSION "2.0.25" /* * Static minor number assignement, until we decide/implement |