📄 aachba.c
字号:
* Would be nice if we could tell the SCSI layer what * the maximum SG element size can be. Worst case is * (sg_tablesize-1) 4KB elements with one 64KB * element. * 32bit -> 468 or 238KB 64bit -> 424 or 212KB */ dev->scsi_host_ptr->max_sectors = (dev->scsi_host_ptr->sg_tablesize * 8) + 112; } } fib_complete(fibptr); fib_free(fibptr); return rcode;}static void io_callback(void *context, struct fib * fibptr){ struct aac_dev *dev; struct aac_read_reply *readreply; struct scsi_cmnd *scsicmd; u32 cid; scsicmd = (struct scsi_cmnd *) context; dev = (struct aac_dev *)scsicmd->device->host->hostdata; cid = ID_LUN_TO_CONTAINER(scsicmd->device->id, scsicmd->device->lun); if (nblank(dprintk(x))) { u64 lba; switch (scsicmd->cmnd[0]) { case WRITE_6: case READ_6: lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3]; break; case WRITE_16: case READ_16: lba = ((u64)scsicmd->cmnd[2] << 56) | ((u64)scsicmd->cmnd[3] << 48) | ((u64)scsicmd->cmnd[4] << 40) | ((u64)scsicmd->cmnd[5] << 32) | ((u64)scsicmd->cmnd[6] << 24) | (scsicmd->cmnd[7] << 16) | (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9]; break; case WRITE_12: case READ_12: lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; break; default: lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; break; } printk(KERN_DEBUG "io_callback[cpu %d]: lba = %llu, t = %ld.\n", smp_processor_id(), (unsigned long long)lba, jiffies); } if (fibptr == NULL) BUG(); if(scsicmd->use_sg) pci_unmap_sg(dev->pdev, (struct scatterlist *)scsicmd->buffer, scsicmd->use_sg, scsicmd->sc_data_direction); else if(scsicmd->request_bufflen) pci_unmap_single(dev->pdev, scsicmd->SCp.dma_handle, scsicmd->request_bufflen, scsicmd->sc_data_direction); readreply = (struct aac_read_reply *)fib_data(fibptr); if (le32_to_cpu(readreply->status) == ST_OK) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; else {#ifdef AAC_DETAILED_STATUS_INFO printk(KERN_WARNING "io_callback: io failed, status = %d\n", le32_to_cpu(readreply->status));#endif scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION; set_sense((u8 *) &dev->fsa_dev[cid].sense_data, HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0, 0, 0); memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data, (sizeof(dev->fsa_dev[cid].sense_data) > sizeof(scsicmd->sense_buffer)) ? sizeof(scsicmd->sense_buffer) : sizeof(dev->fsa_dev[cid].sense_data)); } fib_complete(fibptr); fib_free(fibptr); scsicmd->scsi_done(scsicmd);}static int aac_read(struct scsi_cmnd * scsicmd, int cid){ u64 lba; u32 count; int status; u16 fibsize; struct aac_dev *dev; struct fib * cmd_fibcontext; dev = (struct aac_dev *)scsicmd->device->host->hostdata; /* * Get block address and transfer length */ switch (scsicmd->cmnd[0]) { case READ_6: dprintk((KERN_DEBUG "aachba: received a read(6) command on id %d.\n", cid)); lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3]; count = scsicmd->cmnd[4]; if (count == 0) count = 256; break; case READ_16: dprintk((KERN_DEBUG "aachba: received a read(16) command on id %d.\n", cid)); lba = ((u64)scsicmd->cmnd[2] << 56) | ((u64)scsicmd->cmnd[3] << 48) | ((u64)scsicmd->cmnd[4] << 40) | ((u64)scsicmd->cmnd[5] << 32) | ((u64)scsicmd->cmnd[6] << 24) | (scsicmd->cmnd[7] << 16) | (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9]; count = (scsicmd->cmnd[10] << 24) | (scsicmd->cmnd[11] << 16) | (scsicmd->cmnd[12] << 8) | scsicmd->cmnd[13]; break; case READ_12: dprintk((KERN_DEBUG "aachba: received a read(12) command on id %d.\n", cid)); lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; count = (scsicmd->cmnd[6] << 24) | (scsicmd->cmnd[7] << 16) | (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9]; break; default: dprintk((KERN_DEBUG "aachba: received a read(10) command on id %d.\n", cid)); lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8]; break; } dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %llu, t = %ld.\n", smp_processor_id(), (unsigned long long)lba, jiffies)); if ((!(dev->raw_io_interface) || !(dev->raw_io_64)) && (lba & 0xffffffff00000000LL)) { dprintk((KERN_DEBUG "aac_read: Illegal lba\n")); scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION; set_sense((u8 *) &dev->fsa_dev[cid].sense_data, HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0, 0, 0); memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data, (sizeof(dev->fsa_dev[cid].sense_data) > sizeof(scsicmd->sense_buffer)) ? sizeof(scsicmd->sense_buffer) : sizeof(dev->fsa_dev[cid].sense_data)); scsicmd->scsi_done(scsicmd); return 0; } /* * Alocate and initialize a Fib */ if (!(cmd_fibcontext = fib_alloc(dev))) { return -1; } fib_init(cmd_fibcontext); if (dev->raw_io_interface) { struct aac_raw_io *readcmd; readcmd = (struct aac_raw_io *) fib_data(cmd_fibcontext); readcmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff)); readcmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32)); readcmd->count = cpu_to_le32(count<<9); readcmd->cid = cpu_to_le16(cid); readcmd->flags = cpu_to_le16(1); readcmd->bpTotal = 0; readcmd->bpComplete = 0; aac_build_sgraw(scsicmd, &readcmd->sg); fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(readcmd->sg.count) - 1) * sizeof (struct sgentryraw)); if (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr))) BUG(); /* * Now send the Fib to the adapter */ status = fib_send(ContainerRawIo, cmd_fibcontext, fibsize, FsaNormal, 0, 1, (fib_callback) io_callback, (void *) scsicmd); } else if (dev->dac_support == 1) { struct aac_read64 *readcmd; readcmd = (struct aac_read64 *) fib_data(cmd_fibcontext); readcmd->command = cpu_to_le32(VM_CtHostRead64); readcmd->cid = cpu_to_le16(cid); readcmd->sector_count = cpu_to_le16(count); readcmd->block = cpu_to_le32((u32)(lba&0xffffffff)); readcmd->pad = 0; readcmd->flags = 0; aac_build_sg64(scsicmd, &readcmd->sg); fibsize = sizeof(struct aac_read64) + ((le32_to_cpu(readcmd->sg.count) - 1) * sizeof (struct sgentry64)); BUG_ON (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr))); /* * Now send the Fib to the adapter */ status = fib_send(ContainerCommand64, cmd_fibcontext, fibsize, FsaNormal, 0, 1, (fib_callback) io_callback, (void *) scsicmd); } else { struct aac_read *readcmd; readcmd = (struct aac_read *) fib_data(cmd_fibcontext); readcmd->command = cpu_to_le32(VM_CtBlockRead); readcmd->cid = cpu_to_le32(cid); readcmd->block = cpu_to_le32((u32)(lba&0xffffffff)); readcmd->count = cpu_to_le32(count * 512); aac_build_sg(scsicmd, &readcmd->sg); fibsize = sizeof(struct aac_read) + ((le32_to_cpu(readcmd->sg.count) - 1) * sizeof (struct sgentry)); BUG_ON (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr))); /* * Now send the Fib to the adapter */ status = fib_send(ContainerCommand, cmd_fibcontext, fibsize, FsaNormal, 0, 1, (fib_callback) io_callback, (void *) scsicmd); } /* * Check that the command queued to the controller */ if (status == -EINPROGRESS) return 0; printk(KERN_WARNING "aac_read: fib_send failed with status: %d.\n", status); /* * For some reason, the Fib didn't queue, return QUEUE_FULL */ scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_TASK_SET_FULL; scsicmd->scsi_done(scsicmd); fib_complete(cmd_fibcontext); fib_free(cmd_fibcontext); return 0;}static int aac_write(struct scsi_cmnd * scsicmd, int cid){ u64 lba; u32 count; int status; u16 fibsize; struct aac_dev *dev; struct fib * cmd_fibcontext; dev = (struct aac_dev *)scsicmd->device->host->hostdata; /* * Get block address and transfer length */ if (scsicmd->cmnd[0] == WRITE_6) /* 6 byte command */ { lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3]; count = scsicmd->cmnd[4]; if (count == 0) count = 256; } else if (scsicmd->cmnd[0] == WRITE_16) { /* 16 byte command */ dprintk((KERN_DEBUG "aachba: received a write(16) command on id %d.\n", cid)); lba = ((u64)scsicmd->cmnd[2] << 56) | ((u64)scsicmd->cmnd[3] << 48) | ((u64)scsicmd->cmnd[4] << 40) | ((u64)scsicmd->cmnd[5] << 32) | ((u64)scsicmd->cmnd[6] << 24) | (scsicmd->cmnd[7] << 16) | (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9]; count = (scsicmd->cmnd[10] << 24) | (scsicmd->cmnd[11] << 16) | (scsicmd->cmnd[12] << 8) | scsicmd->cmnd[13]; } else if (scsicmd->cmnd[0] == WRITE_12) { /* 12 byte command */ dprintk((KERN_DEBUG "aachba: received a write(12) command on id %d.\n", cid)); lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; count = (scsicmd->cmnd[6] << 24) | (scsicmd->cmnd[7] << 16) | (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9]; } else { dprintk((KERN_DEBUG "aachba: received a write(10) command on id %d.\n", cid)); lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8]; } dprintk((KERN_DEBUG "aac_write[cpu %d]: lba = %llu, t = %ld.\n", smp_processor_id(), (unsigned long long)lba, jiffies)); if ((!(dev->raw_io_interface) || !(dev->raw_io_64)) && (lba & 0xffffffff00000000LL)) { dprintk((KERN_DEBUG "aac_write: Illegal lba\n")); scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION; set_sense((u8 *) &dev->fsa_dev[cid].sense_data, HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0, 0, 0); memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data, (sizeof(dev->fsa_dev[cid].sense_data) > sizeof(scsicmd->sense_buffer)) ? sizeof(scsicmd->sense_buffer) : sizeof(dev->fsa_dev[cid].sense_data)); scsicmd->scsi_done(scsicmd); return 0; } /* * Allocate and initialize a Fib then setup a BlockWrite command */ if (!(cmd_fibcontext = fib_alloc(dev))) { scsicmd->result = DID_ERROR << 16; scsicmd->scsi_done(scsicmd); return 0; } fib_init(cmd_fibcontext); if (dev->raw_io_interface) { struct aac_raw_io *writecmd; writecmd = (struct aac_raw_io *) fib_data(cmd_fibcontext); writecmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff)); writecmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32)); writecmd->count = cpu_to_le32(count<<9); writecmd->cid = cpu_to_le16(cid); writecmd->flags = 0; writecmd->bpTotal = 0; writecmd->bpComplete = 0; aac_build_sgraw(scsicmd, &writecmd->sg); fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(writecmd->sg.count) - 1) * sizeof (struct sgentryraw)); if (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr))) BUG(); /* * Now send the Fib to the adapter */ status = fib_send(ContainerRawIo, cmd_fibcontext, fibsize, FsaNormal, 0, 1, (fib_callback) io_callback, (void *) scsicmd); } else if (dev->dac_support == 1) { struct aac_write64 *writecmd; writecmd = (struct aac_write64 *) fib_data(cmd_fibcontext); writecmd->command = cpu_to_le32(VM_CtHostWrite64); writecmd->cid = cpu_to_le16(cid); writecmd->sector_count = cpu_to_le16(count); writecmd->block = cpu_to_le32((u32)(lba&0xffffffff)); writecmd->pad = 0; writecmd->flags = 0; aac_build_sg64(scsicmd, &writecmd->sg); fibsize = sizeof(struct aac_write64) + ((le32_to_cpu(writecmd->sg.count) - 1) * sizeof (struct sgentry64)); BUG_ON (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr))); /* * Now send the Fib to the adapter */ status = fib_send(ContainerCommand64, cmd_fibcontext, fibsize, FsaNormal, 0, 1, (fib_callback) io_callback, (void *) scsicmd); } else { struct aac_write *writecmd; writecmd = (struct aac_write *) fib_data(cmd_fibcontext); writecmd->command = cpu_to_le32(VM_CtBlockWrite); writecmd->cid = cpu_to_le32(cid); writecmd->block = cpu_to_le32((u32)(lba&0xffffffff)); writecmd->count = cpu_to_le32(count * 512); writecmd->sg.count = cpu_to_le32(1); /* ->stable is not used - it did mean which type of write */ aac_build_sg(scsicmd, &writecmd->sg); fibsize = sizeof(struct aac_write) + ((le32_to_cpu(writecmd->sg.count) - 1) * sizeof (struct sgentry)); BUG_ON (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr))); /* * Now send the Fib to the adapter */ status = fib_send(ContainerCommand, cmd_fibcontext, fibsize, FsaNormal, 0, 1, (fib_callback) io_callback, (void *) scsicmd); } /* * Check that the command queued to the controller */ if (status == -EINPROGRESS) { return 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -