aachba.c
来自「linux 内核源代码」· C语言 代码 · 共 2,197 行 · 第 1/5 页
C
2,197 行
/* * If the firmware supports ROMB RAID/SCSI mode and we are currently * in RAID/SCSI mode, set the flag. For now if in this mode we will * force nondasd support on. If we decide to allow the non-dasd flag * additional changes changes will have to be made to support * RAID/SCSI. the function aac_scsi_cmd in this module will have to be * changed to support the new dev->raid_scsi_mode flag instead of * leaching off of the dev->nondasd_support flag. Also in linit.c the * function aac_detect will have to be modified where it sets up the * max number of channels based on the aac->nondasd_support flag only. */ if ((dev->adapter_info.options & AAC_OPT_SCSI_MANAGED) && (dev->adapter_info.options & AAC_OPT_RAID_SCSI_MODE)) { dev->nondasd_support = 1; dev->raid_scsi_mode = 1; } if (dev->raid_scsi_mode != 0) printk(KERN_INFO "%s%d: ROMB RAID/SCSI mode enabled\n", dev->name, dev->id); if(nondasd != -1) { dev->nondasd_support = (nondasd!=0); } if(dev->nondasd_support != 0){ printk(KERN_INFO "%s%d: Non-DASD support enabled.\n",dev->name, dev->id); } dev->dac_support = 0; if( (sizeof(dma_addr_t) > 4) && (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)){ printk(KERN_INFO "%s%d: 64bit support enabled.\n", dev->name, dev->id); dev->dac_support = 1; } if(dacmode != -1) { dev->dac_support = (dacmode!=0); } if(dev->dac_support != 0) { if (!pci_set_dma_mask(dev->pdev, DMA_64BIT_MASK) && !pci_set_consistent_dma_mask(dev->pdev, DMA_64BIT_MASK)) { printk(KERN_INFO"%s%d: 64 Bit DAC enabled\n", dev->name, dev->id); } else if (!pci_set_dma_mask(dev->pdev, DMA_32BIT_MASK) && !pci_set_consistent_dma_mask(dev->pdev, DMA_32BIT_MASK)) { printk(KERN_INFO"%s%d: DMA mask set failed, 64 Bit DAC disabled\n", dev->name, dev->id); dev->dac_support = 0; } else { printk(KERN_WARNING"%s%d: No suitable DMA available.\n", dev->name, dev->id); rcode = -ENOMEM; } } /* * Deal with configuring for the individualized limits of each packet * interface. */ dev->a_ops.adapter_scsi = (dev->dac_support) ? aac_scsi_64 : aac_scsi_32; if (dev->raw_io_interface) { dev->a_ops.adapter_bounds = (dev->raw_io_64) ? aac_bounds_64 : aac_bounds_32; dev->a_ops.adapter_read = aac_read_raw_io; dev->a_ops.adapter_write = aac_write_raw_io; } else { dev->a_ops.adapter_bounds = aac_bounds_32; dev->scsi_host_ptr->sg_tablesize = (dev->max_fib_size - sizeof(struct aac_fibhdr) - sizeof(struct aac_write) + sizeof(struct sgentry)) / sizeof(struct sgentry); if (dev->dac_support) { dev->a_ops.adapter_read = aac_read_block64; dev->a_ops.adapter_write = aac_write_block64; /* * 38 scatter gather elements */ dev->scsi_host_ptr->sg_tablesize = (dev->max_fib_size - sizeof(struct aac_fibhdr) - sizeof(struct aac_write64) + sizeof(struct sgentry64)) / sizeof(struct sgentry64); } else { dev->a_ops.adapter_read = aac_read_block; dev->a_ops.adapter_write = aac_write_block; } dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT; if(!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) { /* * Worst case size that could cause sg overflow when * we break up SG elements that are larger than 64KB. * 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; } } aac_fib_complete(fibptr); aac_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; if (!aac_valid_context(scsicmd, fibptr)) return; dev = fibptr->dev; cid = scmd_id(scsicmd); 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); } BUG_ON(fibptr == NULL); scsi_dma_unmap(scsicmd); 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)); } aac_fib_complete(fibptr); aac_fib_free(fibptr); scsicmd->scsi_done(scsicmd);}static int aac_read(struct scsi_cmnd * scsicmd){ u64 lba; u32 count; int status; 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", scmd_id(scsicmd))); 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", scmd_id(scsicmd))); 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", scmd_id(scsicmd))); 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", scmd_id(scsicmd))); 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 (aac_adapter_bounds(dev,scsicmd,lba)) return 0; /* * Alocate and initialize a Fib */ if (!(cmd_fibcontext = aac_fib_alloc(dev))) { return -1; } status = aac_adapter_read(cmd_fibcontext, scsicmd, lba, count); /* * Check that the command queued to the controller */ if (status == -EINPROGRESS) { scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; return 0; } printk(KERN_WARNING "aac_read: aac_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); aac_fib_complete(cmd_fibcontext); aac_fib_free(cmd_fibcontext); return 0;}static int aac_write(struct scsi_cmnd * scsicmd){ u64 lba; u32 count; int fua; int status; 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; fua = 0; } else if (scsicmd->cmnd[0] == WRITE_16) { /* 16 byte command */ dprintk((KERN_DEBUG "aachba: received a write(16) command on id %d.\n", scmd_id(scsicmd))); 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]; fua = scsicmd->cmnd[1] & 0x8; } else if (scsicmd->cmnd[0] == WRITE_12) { /* 12 byte command */ dprintk((KERN_DEBUG "aachba: received a write(12) command on id %d.\n", scmd_id(scsicmd))); 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]; fua = scsicmd->cmnd[1] & 0x8; } else { dprintk((KERN_DEBUG "aachba: received a write(10) command on id %d.\n", scmd_id(scsicmd))); 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]; fua = scsicmd->cmnd[1] & 0x8; } dprintk((KERN_DEBUG "aac_write[cpu %d]: lba = %llu, t = %ld.\n", smp_processor_id(), (unsigned long long)lba, jiffies)); if (aac_adapter_bounds(dev,scsicmd,lba)) return 0; /* * Allocate and initialize a Fib then setup a BlockWrite command */ if (!(cmd_fibcontext = aac_fib_alloc(dev))) { scsicmd->result = DID_ERROR << 16; scsicmd->scsi_done(scsicmd); return 0; } status = aac_adapter_write(cmd_fibcontext, scsicmd, lba, count, fua); /* * Check that the command queued to the controller */ if (status == -EINPROGRESS) { scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; return 0; } printk(KERN_WARNING "aac_write: aac_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); aac_fib_complete(cmd_fibcontext); aac_fib_free(cmd_fibcontext); return 0;}static void synchronize_callback(void *context, struct fib *fibptr){ struct aac_synchronize_reply *synchronizereply; struct scsi_cmnd *cmd; cmd = context; if (!aac_valid_context(cmd, fibptr)) return; dprintk((KERN_DEBUG "synchronize_callback[cpu %d]: t = %ld.\n", smp_processor_id(), jiffies)); BUG_ON(fibptr == NULL); synchronizereply = fib_data(fibptr); if (le32_to_cpu(synchronizereply->status) == CT_OK) cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; else { struct scsi_device *sdev = cmd->device; struct aac_dev *dev = fibptr->dev; u32 cid = sdev_id(sdev); printk(KERN_WARNING "synchronize_callback: synchronize failed, status = %d\n", le32_to_cpu(synchronizereply->status)); cmd->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(cmd->sense_buffer, &dev->fsa_dev[cid].sense_data, min(sizeof(dev->fsa_dev[cid].sense_data), sizeof(cmd->sense_buffer))); } aac_fib_complete(fibptr); aac_fib_free(fibptr); cmd->scsi_done(cmd);}static int aac_synchronize(struct scsi_cmnd *scsicmd){ int status; struct fib *cmd_fibcontext; struct aac_synchronize *synchronizecmd; struct scsi_cmnd *cmd; struct scsi_device *sdev = scsicmd->device; int active = 0; struct aac_dev *aac; u64 lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; u32 count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8]; unsigned long flags; /* * Wait for all outstanding queued commands to complete to this * specific target (block). */ spin_lock_irqsave(&sdev->list_lock, flags); list_for_each_entry(cmd, &sdev->cmd_list, list) if (cmd->SCp.phase == AAC_OWNER_FIRMWARE) { u64 cmnd_lba; u32 cmnd_count; if (cmd->cmnd[0] == WRITE_6) { cmnd_lba = ((cmd->cmnd[1] & 0x1F) << 16) | (cmd->cmnd[2] << 8) | cmd->cmnd[3]; cmnd_count = cmd->cmnd[4]; if (cmnd_count == 0) cmnd_count = 256; } else if (cmd->cmnd[0] == WRITE_16) { cmnd_lba = ((u64)cmd->cmnd[2] << 56) | ((u64)cmd->cmnd[3] << 48) | ((u64)cmd->cmnd[4] << 40) | ((u64)cmd->cmnd[5] << 32) | ((u64)cmd->cmnd[6] << 24) |
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?