⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 3w-xxxx.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
				if (tw_dev->state[request_id] != TW_S_PENDING) {					printk(KERN_WARNING "3w-xxxx: scsi%d: Found request id that wasn't pending.\n", tw_dev->host->host_no);					break;				}				if (tw_post_command_packet(tw_dev, request_id)==0) {					if (tw_dev->pending_head == TW_Q_LENGTH-1) {						tw_dev->pending_head = TW_Q_START;					} else {						tw_dev->pending_head = tw_dev->pending_head + 1;					}					tw_dev->pending_request_count--;				} else {					break;				}			}			/* If there are no more pending requests, we mask command interrupt */			if (tw_dev->pending_request_count == 0) 				tw_mask_command_interrupt(tw_dev);		}		/* Handle response interrupt */		if (do_response_interrupt) {			/* Drain the response queue from the board */			while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {				response_que.value = inl(response_que_addr);				request_id = response_que.u.response_id;				command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];				error = 0;				if (command_packet->status != 0) {					dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Bad response, status = 0x%x, flags = 0x%x, unit = 0x%x.\n", command_packet->status, command_packet->flags, command_packet->byte3.unit);					tw_decode_error(tw_dev, command_packet->status, command_packet->flags, command_packet->byte3.unit);					error = 1;				}				if (tw_dev->state[request_id] != TW_S_POSTED) {					printk(KERN_WARNING "3w-xxxx: scsi%d: Received a request id (%d) (opcode = 0x%x) that wasn't posted.\n", tw_dev->host->host_no, request_id, command_packet->byte0.opcode);					error = 1;				}				if (TW_STATUS_ERRORS(status_reg_value)) {				  tw_decode_bits(tw_dev, status_reg_value);				  error = 1;				}				dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Response queue request id: %d.\n", request_id);				/* Check for internal command */				if (tw_dev->srb[request_id] == 0) {					dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Found internally posted command.\n");					error = tw_aen_complete(tw_dev, request_id);					if (error) {						printk(KERN_WARNING "3w-xxxx: scsi%d: Error completing aen.\n", tw_dev->host->host_no);					}					status_reg_value = inl(status_reg_addr);					if (tw_check_bits(status_reg_value)) {						dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");						tw_decode_bits(tw_dev, status_reg_value);					}		} else {				switch (tw_dev->srb[request_id]->cmnd[0]) {					case READ_10:					case READ_6:						dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_10/READ_6\n");						break;					case WRITE_10:					case WRITE_6:						dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught WRITE_10/WRITE_6\n");						break;					case INQUIRY:						dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught INQUIRY\n");						error = tw_scsiop_inquiry_complete(tw_dev, request_id);						break;					case READ_CAPACITY:						dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_CAPACITY\n");						error = tw_scsiop_read_capacity_complete(tw_dev, request_id);						break;					case TW_IOCTL:						dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught TW_IOCTL\n");						error = tw_ioctl_complete(tw_dev, request_id);						break;					default:						printk(KERN_WARNING "3w-xxxx: scsi%d: Unknown scsi opcode: 0x%x.\n", tw_dev->host->host_no, tw_dev->srb[request_id]->cmnd[0]);						tw_dev->srb[request_id]->result = (DID_BAD_TARGET << 16);						tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);					}					if (error == 1) {						/* Tell scsi layer there was an error */						dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Scsi Error.\n");						tw_dev->srb[request_id]->result = (DID_RESET << 16);					}					if (error == 0) {						/* Tell scsi layer command was a success */						tw_dev->srb[request_id]->result = (DID_OK << 16);					}					if (error != 2) {						tw_dev->state[request_id] = TW_S_COMPLETED;						tw_state_request_finish(tw_dev, request_id);						tw_dev->posted_request_count--;						tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);					}					status_reg_value = inl(status_reg_addr);					if (tw_check_bits(status_reg_value)) {						dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");						tw_decode_bits(tw_dev, status_reg_value);					}				}			}		}		spin_unlock(&tw_dev->tw_lock);	}	spin_unlock_irqrestore(&io_request_lock, flags);	clear_bit(TW_IN_INTR, &tw_dev->flags);} /* End tw_interrupt() *//* This function handles ioctls from userspace to the driver */int tw_ioctl(TW_Device_Extension *tw_dev, int request_id){	unsigned char opcode;	int bufflen, error = 0;	TW_Param *param;	TW_Command *command_packet, *command_save;	u32 param_value;	TW_Ioctl *ioctl = NULL;	TW_Passthru *passthru = NULL;	int tw_aen_code, i, use_sg;	char *data_ptr;	int total_bytes = 0;	ioctl = (TW_Ioctl *)tw_dev->srb[request_id]->request_buffer;	if (ioctl == NULL) {		printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Request buffer NULL.\n");		tw_dev->state[request_id] = TW_S_COMPLETED;		tw_state_request_finish(tw_dev, request_id);		tw_dev->srb[request_id]->result = (DID_OK << 16);		tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);		return 0;	}	bufflen = tw_dev->srb[request_id]->request_bufflen;	/* Initialize command packet */	command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];	if (command_packet == NULL) {		printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad command packet virtual address.\n");		tw_dev->state[request_id] = TW_S_COMPLETED;		tw_state_request_finish(tw_dev, request_id);		tw_dev->srb[request_id]->result = (DID_OK << 16);		tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);		return 0;	}	memset(command_packet, 0, sizeof(TW_Sector));	/* Initialize param */	if (tw_dev->alignment_virtual_address[request_id] == NULL) {		printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad alignment virtual address.\n");		tw_dev->state[request_id] = TW_S_COMPLETED;		tw_state_request_finish(tw_dev, request_id);		tw_dev->srb[request_id]->result = (DID_OK << 16);		tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);		return 0;	}	param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];	memset(param, 0, sizeof(TW_Sector));	dprintk(KERN_NOTICE "opcode = %d table_id = %d parameter_id = %d parameter_size_bytes = %d\n", ioctl->opcode, ioctl->table_id, ioctl->parameter_id, ioctl->parameter_size_bytes);	opcode = ioctl->opcode;	switch (opcode) {		case TW_OP_NOP:			dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_NOP.\n");			command_packet->byte0.opcode = TW_OP_NOP;			break;		case TW_OP_GET_PARAM:			dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_GET_PARAM.\n");			command_packet->byte0.opcode = TW_OP_GET_PARAM;			command_packet->byte3.unit = ioctl->unit_index;			param->table_id = ioctl->table_id;			param->parameter_id = ioctl->parameter_id;			param->parameter_size_bytes = ioctl->parameter_size_bytes;			tw_dev->ioctl_size[request_id] = ioctl->parameter_size_bytes;			dprintk(KERN_NOTICE "table_id = %d parameter_id = %d parameter_size_bytes %d\n", param->table_id, param->parameter_id, param->parameter_size_bytes);			break;		case TW_OP_SET_PARAM:			dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_SET_PARAM: table_id = %d, parameter_id = %d, parameter_size_bytes = %d.\n",			ioctl->table_id, ioctl->parameter_id, ioctl->parameter_size_bytes);			if (ioctl->data != NULL) {				command_packet->byte0.opcode = TW_OP_SET_PARAM;				param->table_id = ioctl->table_id;				param->parameter_id = ioctl->parameter_id;				param->parameter_size_bytes = ioctl->parameter_size_bytes;				memcpy(param->data, ioctl->data, ioctl->parameter_size_bytes);				break;			} else {				printk(KERN_WARNING "3w-xxxx: tw_ioctl(): ioctl->data NULL.\n");				return 1;			}		case TW_OP_AEN_LISTEN:			dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_AEN_LISTEN.\n");			if (tw_dev->aen_head == tw_dev->aen_tail) {				/* aen queue empty */				dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): Aen queue empty.\n");				tw_aen_code = TW_AEN_QUEUE_EMPTY;				memcpy(tw_dev->srb[request_id]->request_buffer, &tw_aen_code, ioctl->parameter_size_bytes);			} else {				/* Copy aen queue entry to request buffer */				dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): Returning aen 0x%x\n", tw_dev->aen_queue[tw_dev->aen_head]);				tw_aen_code = tw_dev->aen_queue[tw_dev->aen_head];				memcpy(tw_dev->srb[request_id]->request_buffer, &tw_aen_code, ioctl->parameter_size_bytes);				if (tw_dev->aen_head == TW_Q_LENGTH - 1) {					tw_dev->aen_head = TW_Q_START;				} else {					tw_dev->aen_head = tw_dev->aen_head + 1;				}			}			tw_dev->state[request_id] = TW_S_COMPLETED;			tw_state_request_finish(tw_dev, request_id);			tw_dev->srb[request_id]->result = (DID_OK << 16);			tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);			return 0;		case TW_ATA_PASSTHRU:			if (ioctl->data != NULL) {				memcpy(command_packet, ioctl->data, sizeof(TW_Command));				command_packet->request_id = request_id;			} else {				printk(KERN_WARNING "3w-xxxx: tw_ioctl(): ioctl->data NULL.\n");				return 1;			}			passthru = (TW_Passthru *)tw_dev->command_packet_virtual_address[request_id];			passthru->sg_list[0].length = passthru->sector_count*512;			if (passthru->sg_list[0].length > TW_MAX_PASSTHRU_BYTES) {				printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Passthru size (%ld) too big.\n", passthru->sg_list[0].length);				return 1;			}			passthru->sg_list[0].address = virt_to_bus(tw_dev->alignment_virtual_address[request_id]);			tw_post_command_packet(tw_dev, request_id);			return 0;		case TW_CMD_PACKET:			dprintk(KERN_WARNING "3w-xxxx: tw_ioctl(): caught TW_CMD_PACKET.\n");			if (ioctl->data != NULL) {				memcpy(command_packet, ioctl->data, sizeof(TW_Command));				command_packet->request_id = request_id;				tw_post_command_packet(tw_dev, request_id);				return 0;			} else {				printk(KERN_WARNING "3w-xxxx: tw_ioctl(): ioctl->data NULL.\n");				return 1;			}		case TW_CMD_PACKET_WITH_DATA:			dprintk(KERN_WARNING "3w-xxxx: tw_ioctl(): caught TW_CMD_PACKET_WITH_DATA.\n");			command_save = (TW_Command *)tw_dev->alignment_virtual_address[request_id];			if (command_save == NULL) {				printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): Bad alignment virtual address.\n", tw_dev->host->host_no);				return 1;			}			if (ioctl->data != NULL) {				/* Copy down the command packet */				memcpy(command_packet, ioctl->data, sizeof(TW_Command));				memcpy(command_save, ioctl->data, sizeof(TW_Command));				command_packet->request_id = request_id;				/* Now deal with the two possible sglists */				if (command_packet->byte0.sgl_offset == 2) {					use_sg = command_packet->size - 3;					for (i=0;i<use_sg;i++)						total_bytes+=command_packet->byte8.param.sgl[i].length;					tw_dev->ioctl_data[request_id] = kmalloc(total_bytes, GFP_ATOMIC);					if (!tw_dev->ioctl_data[request_id]) {						printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): kmalloc failed for request_id %d.\n", tw_dev->host->host_no, request_id);						return 1;					}					/* Copy param sglist into the kernel */					data_ptr = tw_dev->ioctl_data[request_id];					for (i=0;i<use_sg;i++) {						if ((u32 *)command_packet->byte8.param.sgl[i].address != NULL) {							error = copy_from_user(data_ptr, (u32 *)command_packet->byte8.param.sgl[i].address, command_packet->byte8.param.sgl[i].length);							if (error) {								printk(KERN_WARNING "3w-xxxx: scsi%d: Error copying param sglist from userspace.\n", tw_dev->host->host_no);								goto tw_ioctl_bail;							}						} else {							printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): Bad param sgl address.\n", tw_dev->host->host_no);							tw_dev->srb[request_id]->result = (DID_RESET << 16);							goto tw_ioctl_bail;						}						data_ptr+=command_packet->byte8.param.sgl[i].length;					}					command_packet->size = 4;					command_packet->byte8.param.sgl[0].address = virt_to_bus(tw_dev->ioctl_data[request_id]);					command_packet->byte8.param.sgl[0].length = total_bytes;				}				if (command_packet->byte0.sgl_offset == 3) {					use_sg = command_packet->size - 4;					for (i=0;i<use_sg;i++)						total_bytes+=command_packet->byte8.io.sgl[i].length;					tw_dev->ioctl_data[request_id] = kmalloc(total_bytes, GFP_ATOMIC);					if (!tw_dev->ioctl_data[request_id]) {						printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): kmalloc failed for request_id %d.\n", tw_dev->host->host_no, request_id);						return 1;					}					if (command_packet->byte0.opcode == TW_OP_WRITE) {						/* Copy io sglist into the kernel */						data_ptr = tw_dev->ioctl_data[request_id];						for (i=0;i<use_sg;i++) {							if ((u32 *)command_packet->byte8.io.sgl[i].address != NULL) {								error = copy_from_user(data_ptr, (u32 *)command_packet->byte8.io.sgl[i].address, command_packet->byte8.io.sgl[i].length);								if (error) {									printk(KERN_WARNING "3w-xxxx: scsi%d: Error copying io sglist from userspace.\n", tw_dev->host->host_no);									goto tw_ioctl_bail;								}							} else {								printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): Bad io sgl address.\n", tw_dev->host->host_no);								tw_dev->srb[request_id]->result = (DID_RESET << 16);								goto tw_ioctl_bail;							}							data_ptr+=command_packet->byte8.io.sgl[i].length;						}					}					command_packet->size = 5;					command_packet->byte8.io.sgl[0].address = virt_to_bus(tw_dev->ioctl_data[request_id]);					command_packet->byte8.io.sgl[0].length = total_bytes;				}				spin_unlock_irq(&io_request_lock);				spin_unlock_irq(&tw_dev->tw_lock);				/* Finally post the command packet */				tw_post_command_packet(tw_dev, request_id);				mdelay(TW_IOCTL_WAIT_TIME);				spin_lock_irq(&tw_dev->tw_lock);				spin_lock_irq(&io_request_lock);				if (signal_pending(current)) {					dprintk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): Signal pending, aborting ioctl().\n", tw_dev->host->host_no);					tw_dev->srb[request_id]->result = (DID_OK << 16);					goto tw_ioctl_bail;				}				tw_dev->srb[request_id]->result = (DID_OK << 16);				/* Now copy up the param or io sglist to userspace */				if (command_packet->byte0.sgl_offset == 2) {					use_sg = command_save->size - 3;					data_ptr = phys_to_virt(command_packet->byte8.param.sgl[0].address);					for (i=0;i<use_sg;i++) {						if ((u32 *)command_save->byte8.param.sgl[i].address != NULL) {							error = copy_to_user((u32 *)command_save->byte8.param.sgl[i].address, data_ptr, command_save->byte8.param.sgl[i].length);							if (error) {								printk(KERN_WARNING "3w-xxxx: scsi%d: Error copying param sglist to userspace.\n", tw_dev->host->host_no);								goto tw_ioctl_bail;							}							dprintk(KERN_WARNING "3w-xxxx: scsi%d: Copied %ld by

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -