void ccw_free_request ( ccw_req_t * request ) { int size_needed; debug_text_event ( debug_area, 1, "FREE"); debug_int_event ( debug_area, 1, (long)request); /* Sanity checks */ if ( request == NULL || request->cache == NULL) BUG(); dechain ( request); /* Free memory allocated with kmalloc * make the same decisions as in ccw_alloc_requets */ size_needed = (sizeof (ccw_req_t) + 7) & -8; if (size_needed + request->datasize <= PAGE_SIZE) /* We kept the data with the request */ size_needed += (request->datasize + 7) & -8; else kfree(request->data); if (size_needed + request->cplength*sizeof(ccw1_t) > PAGE_SIZE) /* We kept the CCWs with request */ kfree(request->cpaddr); kmem_cache_free(request -> cache, request); }
void ctcm_dbf_longtext(enum ctcm_dbf_names dbf_nix, int level, char *fmt, ...) { char dbf_txt_buf[64]; va_list args; if (!debug_level_enabled(ctcm_dbf[dbf_nix].id, level)) return; va_start(args, fmt); vsnprintf(dbf_txt_buf, sizeof(dbf_txt_buf), fmt, args); va_end(args); debug_text_event(ctcm_dbf[dbf_nix].id, level, dbf_txt_buf); }
int ccwcache_init (void) { int rc = 0; int cachind; /* initialize variables */ spin_lock_init(&ccwchain_lock); /* allocate a debug area */ debug_area = debug_register( "ccwcache", 2, 4,sizeof(void*)); if ( debug_area == NULL ) BUG(); debug_register_view(debug_area,&debug_hex_ascii_view); debug_register_view(debug_area,&debug_raw_view); debug_text_event ( debug_area, 0, "INIT"); /* First allocate the kmem caches */ for ( cachind = 0; cachind < CCW_NUMBER_CACHES; cachind ++ ) { int slabsize = SMALLEST_SLAB << cachind; debug_text_event ( debug_area, 1, "allc"); debug_int_event ( debug_area, 1, slabsize); sprintf ( ccw_cache_name[cachind], "%s%d%c", ccw_name_template, slabsize, 0); ccw_cache[cachind] = kmem_cache_create( ccw_cache_name[cachind], slabsize, 0, CCW_CACHE_SLAB_TYPE, NULL, NULL ); debug_int_event ( debug_area, 1, (long)ccw_cache[cachind]); if (ccw_cache[cachind] == NULL) panic ("Allocation of CCW cache failed\n"); } return rc; }
static ssize_t vmcp_write(struct file *file, const char __user * buff, size_t count, loff_t * ppos) { char *cmd; struct vmcp_session *session; if (count > 240) return -EINVAL; cmd = kmalloc(count + 1, GFP_KERNEL); if (!cmd) return -ENOMEM; if (copy_from_user(cmd, buff, count)) { kfree(cmd); return -EFAULT; } cmd[count] = '\0'; session = (struct vmcp_session *)file->private_data; if (down_interruptible(&session->mutex)) { kfree(cmd); return -ERESTARTSYS; } if (!session->response) session->response = (char *)__get_free_pages(GFP_KERNEL | __GFP_REPEAT | GFP_DMA, get_order(session->bufsize)); if (!session->response) { up(&session->mutex); kfree(cmd); return -ENOMEM; } debug_text_event(vmcp_debug, 1, cmd); session->resp_size = cpcmd(cmd, session->response, session->bufsize, &session->resp_code); up(&session->mutex); kfree(cmd); *ppos = 0; /* reset the file pointer after a command */ return count; }
/* * function: zfcp_qdio_handler_error_check * * purpose: called by the response handler to determine error condition * * returns: error flag * */ static inline int zfcp_qdio_handler_error_check(struct zfcp_adapter *adapter, unsigned int status, unsigned int qdio_error, unsigned int siga_error) { int retval = 0; if (ZFCP_LOG_CHECK(ZFCP_LOG_LEVEL_TRACE)) { if (status & QDIO_STATUS_INBOUND_INT) { ZFCP_LOG_TRACE("status is" " QDIO_STATUS_INBOUND_INT \n"); } if (status & QDIO_STATUS_OUTBOUND_INT) { ZFCP_LOG_TRACE("status is" " QDIO_STATUS_OUTBOUND_INT \n"); } } // if (ZFCP_LOG_CHECK(ZFCP_LOG_LEVEL_TRACE)) if (unlikely(status & QDIO_STATUS_LOOK_FOR_ERROR)) { retval = -EIO; ZFCP_LOG_FLAGS(1, "QDIO_STATUS_LOOK_FOR_ERROR \n"); ZFCP_LOG_INFO("QDIO problem occurred (status=0x%x, " "qdio_error=0x%x, siga_error=0x%x)\n", status, qdio_error, siga_error); if (status & QDIO_STATUS_ACTIVATE_CHECK_CONDITION) { ZFCP_LOG_FLAGS(2, "QDIO_STATUS_ACTIVATE_CHECK_CONDITION\n"); } if (status & QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR) { ZFCP_LOG_FLAGS(2, "QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR\n"); } if (status & QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR) { ZFCP_LOG_FLAGS(2, "QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR\n"); } if (siga_error & QDIO_SIGA_ERROR_ACCESS_EXCEPTION) { ZFCP_LOG_FLAGS(2, "QDIO_SIGA_ERROR_ACCESS_EXCEPTION\n"); } if (siga_error & QDIO_SIGA_ERROR_B_BIT_SET) { ZFCP_LOG_FLAGS(2, "QDIO_SIGA_ERROR_B_BIT_SET\n"); } switch (qdio_error) { case 0: ZFCP_LOG_FLAGS(3, "QDIO_OK"); break; case SLSB_P_INPUT_ERROR: ZFCP_LOG_FLAGS(1, "SLSB_P_INPUT_ERROR\n"); break; case SLSB_P_OUTPUT_ERROR: ZFCP_LOG_FLAGS(1, "SLSB_P_OUTPUT_ERROR\n"); break; default: ZFCP_LOG_NORMAL("bug: unknown QDIO error 0x%x\n", qdio_error); break; } /* Restarting IO on the failed adapter from scratch */ debug_text_event(adapter->erp_dbf, 1, "qdio_err"); /* * Since we have been using this adapter, it is save to assume * that it is not failed but recoverable. The card seems to * report link-up events by self-initiated queue shutdown. * That is why we need to clear the the link-down flag * which is set again in case we have missed by a mile. */ zfcp_erp_adapter_reopen( adapter, ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED | ZFCP_STATUS_COMMON_ERP_FAILED); } return retval; }
/* * ccw_req_t *ccw_alloc_request ( int cplength, int datasize ) * allocates a ccw_req_t, that * - can hold a CP of cplength CCWS * - can hold additional data up to datasize */ ccw_req_t * ccw_alloc_request ( char *magic, int cplength, int datasize ) { ccw_req_t * request = NULL; int size_needed; int data_offset, ccw_offset; int cachind; /* Sanity checks */ if ( magic == NULL || datasize > PAGE_SIZE || cplength == 0 || (cplength*sizeof(ccw1_t)) > PAGE_SIZE) BUG(); debug_text_event ( debug_area, 1, "ALLC"); debug_text_event ( debug_area, 1, magic); debug_int_event ( debug_area, 1, cplength); debug_int_event ( debug_area, 1, datasize); /* We try to keep things together in memory */ size_needed = (sizeof (ccw_req_t) + 7) & -8; data_offset = ccw_offset = 0; if (size_needed + datasize <= PAGE_SIZE) { /* Keep data with the request */ data_offset = size_needed; size_needed += (datasize + 7) & -8; } if (size_needed + cplength*sizeof(ccw1_t) <= PAGE_SIZE) { /* Keep CCWs with request */ ccw_offset = size_needed; size_needed += cplength*sizeof(ccw1_t); } /* determine cache index for the requested size */ for (cachind = 0; cachind < CCW_NUMBER_CACHES; cachind ++ ) if ( size_needed < (SMALLEST_SLAB << cachind) ) break; /* Try to fulfill the request from a cache */ if ( ccw_cache[cachind] == NULL ) BUG(); request = kmem_cache_alloc ( ccw_cache[cachind], CCW_CACHE_TYPE ); if (request == NULL) return NULL; memset ( request, 0, (SMALLEST_SLAB << cachind)); request->cache = ccw_cache[cachind]; /* Allocate memory for the extra data */ if (data_offset == 0) { /* Allocated memory for extra data with kmalloc */ request->data = (void *) kmalloc(datasize, CCW_CACHE_TYPE ); if (request->data == NULL) { printk(KERN_WARNING PRINTK_HEADER "Couldn't allocate data area\n"); kmem_cache_free(request->cache, request); return NULL; } } else /* Extra data already allocated with the request */ request->data = (void *) ((addr_t) request + data_offset); /* Allocate memory for the channel program */ if (ccw_offset == 0) { /* Allocated memory for the channel program with kmalloc */ request->cpaddr = (ccw1_t *) kmalloc(cplength*sizeof(ccw1_t), CCW_CACHE_TYPE); if (request->cpaddr == NULL) { printk (KERN_DEBUG PRINTK_HEADER "Couldn't allocate ccw area\n"); if (data_offset == 0) kfree(request->data); kmem_cache_free(request->cache, request); return NULL; } } else /* Channel program already allocated with the request */ request->cpaddr = (ccw1_t *) ((addr_t) request + ccw_offset); memset ( request->data, 0, datasize ); memset ( request->cpaddr, 0, cplength*sizeof(ccw1_t) ); strncpy ( (char *)(&request->magic), magic, 4); ASCEBC((char *)(&request->magic),4); request -> cplength = cplength; request -> datasize = datasize; /* enqueue request to list of allocated requests */ enchain(request); debug_int_event ( debug_area, 1, (long)request); return request; }