···1014101410151015config SCSI_IPR10161016 tristate "IBM Power Linux RAID adapter support"10171017- depends on PCI && SCSI10171017+ depends on PCI && SCSI && ATA10181018 select FW_LOADER10191019 ---help---10201020 This driver supports the IBM Power Linux family RAID adapters.
+665-18
drivers/scsi/ipr.c
···7070#include <linux/firmware.h>7171#include <linux/module.h>7272#include <linux/moduleparam.h>7373+#include <linux/libata.h>7374#include <asm/io.h>7475#include <asm/irq.h>7576#include <asm/processor.h>···7978#include <scsi/scsi_tcq.h>8079#include <scsi/scsi_eh.h>8180#include <scsi/scsi_cmnd.h>8181+#include <scsi/scsi_transport.h>8282#include "ipr.h"83838484/*···201199 "FFFA: Undefined device response recovered by the IOA"},202200 {0x014A0000, 1, 1,203201 "FFF6: Device bus error, message or command phase"},202202+ {0x014A8000, 0, 1,203203+ "FFFE: Task Management Function failed"},204204 {0x015D0000, 0, 1,205205 "FFF6: Failure prediction threshold exceeded"},206206 {0x015D9200, 0, 1,···265261 "Device bus status error"},266262 {0x04448600, 0, 1,267263 "8157: IOA error requiring IOA reset to recover"},264264+ {0x04448700, 0, 0,265265+ "ATA device status error"},268266 {0x04490000, 0, 0,269267 "Message reject received from the device"},270268 {0x04449200, 0, 1,···279273 "9082: IOA detected device error"},280274 {0x044A0000, 1, 1,281275 "3110: Device bus error, message or command phase"},276276+ {0x044A8000, 1, 1,277277+ "3110: SAS Command / Task Management Function failed"},282278 {0x04670400, 0, 1,283279 "9091: Incorrect hardware configuration change has been detected"},284280 {0x04678000, 0, 1,···461453 trace_entry->time = jiffies;462454 trace_entry->op_code = ipr_cmd->ioarcb.cmd_pkt.cdb[0];463455 trace_entry->type = type;464464- trace_entry->cmd_index = ipr_cmd->cmd_index;456456+ trace_entry->ata_op_code = ipr_cmd->ioarcb.add_data.u.regs.command;457457+ trace_entry->cmd_index = ipr_cmd->cmd_index & 0xff;465458 trace_entry->res_handle = ipr_cmd->ioarcb.res_handle;466459 trace_entry->u.add_data = add_data;467460}···489480 ioarcb->read_ioadl_len = 0;490481 ioasa->ioasc = 0;491482 ioasa->residual_data_len = 0;483483+ ioasa->u.gata.status = 0;492484493485 ipr_cmd->scsi_cmd = NULL;486486+ ipr_cmd->qc = NULL;494487 ipr_cmd->sense_buffer[0] = 0;495488 ipr_cmd->dma_use_sg = 0;496489}···637626}638627639628/**629629+ * ipr_sata_eh_done - done function for aborted SATA commands630630+ * @ipr_cmd: ipr command struct631631+ *632632+ * This function is invoked for ops generated to SATA633633+ * devices which are being aborted.634634+ *635635+ * Return value:636636+ * none637637+ **/638638+static void ipr_sata_eh_done(struct ipr_cmnd *ipr_cmd)639639+{640640+ struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;641641+ struct ata_queued_cmd *qc = ipr_cmd->qc;642642+ struct ipr_sata_port *sata_port = qc->ap->private_data;643643+644644+ qc->err_mask |= AC_ERR_OTHER;645645+ sata_port->ioasa.status |= ATA_BUSY;646646+ list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);647647+ ata_qc_complete(qc);648648+}649649+650650+/**640651 * ipr_scsi_eh_done - mid-layer done function for aborted ops641652 * @ipr_cmd: ipr command struct642653 *···702669703670 if (ipr_cmd->scsi_cmd)704671 ipr_cmd->done = ipr_scsi_eh_done;672672+ else if (ipr_cmd->qc)673673+ ipr_cmd->done = ipr_sata_eh_done;705674706675 ipr_trc_hook(ipr_cmd, IPR_TRACE_FINISH, IPR_IOASC_IOA_WAS_RESET);707676 del_timer(&ipr_cmd->timer);···860825 res->del_from_ml = 0;861826 res->resetting_device = 0;862827 res->sdev = NULL;828828+ res->sata_port = NULL;863829}864830865831/**···13521316 int i;1353131713541318 for (i = 0; i < ARRAY_SIZE(ipr_error_table); i++)13551355- if (ipr_error_table[i].ioasc == ioasc)13191319+ if (ipr_error_table[i].ioasc == (ioasc & IPR_IOASC_IOASC_MASK))13561320 return i;1357132113581322 return 0;···30873051 **/30883052static int ipr_change_queue_depth(struct scsi_device *sdev, int qdepth)30893053{30543054+ struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)sdev->host->hostdata;30553055+ struct ipr_resource_entry *res;30563056+ unsigned long lock_flags = 0;30573057+30583058+ spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);30593059+ res = (struct ipr_resource_entry *)sdev->hostdata;30603060+30613061+ if (res && ipr_is_gata(res) && qdepth > IPR_MAX_CMD_PER_ATA_LUN)30623062+ qdepth = IPR_MAX_CMD_PER_ATA_LUN;30633063+ spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);30643064+30903065 scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);30913066 return sdev->queue_depth;30923067}···32133166}3214316732153168/**31693169+ * ipr_find_starget - Find target based on bus/target.31703170+ * @starget: scsi target struct31713171+ *31723172+ * Return value:31733173+ * resource entry pointer if found / NULL if not found31743174+ **/31753175+static struct ipr_resource_entry *ipr_find_starget(struct scsi_target *starget)31763176+{31773177+ struct Scsi_Host *shost = dev_to_shost(&starget->dev);31783178+ struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *) shost->hostdata;31793179+ struct ipr_resource_entry *res;31803180+31813181+ list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {31823182+ if ((res->cfgte.res_addr.bus == starget->channel) &&31833183+ (res->cfgte.res_addr.target == starget->id) &&31843184+ (res->cfgte.res_addr.lun == 0)) {31853185+ return res;31863186+ }31873187+ }31883188+31893189+ return NULL;31903190+}31913191+31923192+static struct ata_port_info sata_port_info;31933193+31943194+/**31953195+ * ipr_target_alloc - Prepare for commands to a SCSI target31963196+ * @starget: scsi target struct31973197+ *31983198+ * If the device is a SATA device, this function allocates an31993199+ * ATA port with libata, else it does nothing.32003200+ *32013201+ * Return value:32023202+ * 0 on success / non-0 on failure32033203+ **/32043204+static int ipr_target_alloc(struct scsi_target *starget)32053205+{32063206+ struct Scsi_Host *shost = dev_to_shost(&starget->dev);32073207+ struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *) shost->hostdata;32083208+ struct ipr_sata_port *sata_port;32093209+ struct ata_port *ap;32103210+ struct ipr_resource_entry *res;32113211+ unsigned long lock_flags;32123212+32133213+ spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);32143214+ res = ipr_find_starget(starget);32153215+ starget->hostdata = NULL;32163216+32173217+ if (res && ipr_is_gata(res)) {32183218+ spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);32193219+ sata_port = kzalloc(sizeof(*sata_port), GFP_KERNEL);32203220+ if (!sata_port)32213221+ return -ENOMEM;32223222+32233223+ ap = ata_sas_port_alloc(&ioa_cfg->ata_host, &sata_port_info, shost);32243224+ if (ap) {32253225+ spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);32263226+ sata_port->ioa_cfg = ioa_cfg;32273227+ sata_port->ap = ap;32283228+ sata_port->res = res;32293229+32303230+ res->sata_port = sata_port;32313231+ ap->private_data = sata_port;32323232+ starget->hostdata = sata_port;32333233+ } else {32343234+ kfree(sata_port);32353235+ return -ENOMEM;32363236+ }32373237+ }32383238+ spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);32393239+32403240+ return 0;32413241+}32423242+32433243+/**32443244+ * ipr_target_destroy - Destroy a SCSI target32453245+ * @starget: scsi target struct32463246+ *32473247+ * If the device was a SATA device, this function frees the libata32483248+ * ATA port, else it does nothing.32493249+ *32503250+ **/32513251+static void ipr_target_destroy(struct scsi_target *starget)32523252+{32533253+ struct ipr_sata_port *sata_port = starget->hostdata;32543254+32553255+ if (sata_port) {32563256+ starget->hostdata = NULL;32573257+ ata_sas_port_destroy(sata_port->ap);32583258+ kfree(sata_port);32593259+ }32603260+}32613261+32623262+/**32633263+ * ipr_find_sdev - Find device based on bus/target/lun.32643264+ * @sdev: scsi device struct32653265+ *32663266+ * Return value:32673267+ * resource entry pointer if found / NULL if not found32683268+ **/32693269+static struct ipr_resource_entry *ipr_find_sdev(struct scsi_device *sdev)32703270+{32713271+ struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *) sdev->host->hostdata;32723272+ struct ipr_resource_entry *res;32733273+32743274+ list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {32753275+ if ((res->cfgte.res_addr.bus == sdev->channel) &&32763276+ (res->cfgte.res_addr.target == sdev->id) &&32773277+ (res->cfgte.res_addr.lun == sdev->lun))32783278+ return res;32793279+ }32803280+32813281+ return NULL;32823282+}32833283+32843284+/**32163285 * ipr_slave_destroy - Unconfigure a SCSI device32173286 * @sdev: scsi device struct32183287 *···33463183 spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);33473184 res = (struct ipr_resource_entry *) sdev->hostdata;33483185 if (res) {31863186+ if (res->sata_port)31873187+ ata_port_disable(res->sata_port->ap);33493188 sdev->hostdata = NULL;33503189 res->sdev = NULL;31903190+ res->sata_port = NULL;33513191 }33523192 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);33533193}···33853219 }33863220 if (ipr_is_vset_device(res) || ipr_is_scsi_disk(res))33873221 sdev->allow_restart = 1;33883388- scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);32223222+ if (ipr_is_gata(res) && res->sata_port) {32233223+ scsi_adjust_queue_depth(sdev, 0, IPR_MAX_CMD_PER_ATA_LUN);32243224+ ata_sas_slave_configure(sdev, res->sata_port->ap);32253225+ } else {32263226+ scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);32273227+ }33893228 }33903229 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);33913230 return 0;32313231+}32323232+32333233+/**32343234+ * ipr_ata_slave_alloc - Prepare for commands to a SATA device32353235+ * @sdev: scsi device struct32363236+ *32373237+ * This function initializes an ATA port so that future commands32383238+ * sent through queuecommand will work.32393239+ *32403240+ * Return value:32413241+ * 0 on success32423242+ **/32433243+static int ipr_ata_slave_alloc(struct scsi_device *sdev)32443244+{32453245+ struct ipr_sata_port *sata_port = NULL;32463246+ int rc = -ENXIO;32473247+32483248+ ENTER;32493249+ if (sdev->sdev_target)32503250+ sata_port = sdev->sdev_target->hostdata;32513251+ if (sata_port)32523252+ rc = ata_sas_port_init(sata_port->ap);32533253+ if (rc)32543254+ ipr_slave_destroy(sdev);32553255+32563256+ LEAVE;32573257+ return rc;33923258}3393325933943260/**···3446324834473249 spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);3448325034493449- list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {34503450- if ((res->cfgte.res_addr.bus == sdev->channel) &&34513451- (res->cfgte.res_addr.target == sdev->id) &&34523452- (res->cfgte.res_addr.lun == sdev->lun)) {34533453- res->sdev = sdev;34543454- res->add_to_ml = 0;34553455- res->in_erp = 0;34563456- sdev->hostdata = res;34573457- if (!ipr_is_naca_model(res))34583458- res->needs_sync_complete = 1;34593459- rc = 0;34603460- break;32513251+ res = ipr_find_sdev(sdev);32523252+ if (res) {32533253+ res->sdev = sdev;32543254+ res->add_to_ml = 0;32553255+ res->in_erp = 0;32563256+ sdev->hostdata = res;32573257+ if (!ipr_is_naca_model(res))32583258+ res->needs_sync_complete = 1;32593259+ rc = 0;32603260+ if (ipr_is_gata(res)) {32613261+ spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);32623262+ return ipr_ata_slave_alloc(sdev);34613263 }34623264 }34633265···35123314 * This function issues a device reset to the affected device.35133315 * If the device is a SCSI device, a LUN reset will be sent35143316 * to the device first. If that does not work, a target reset35153515- * will be sent.33173317+ * will be sent. If the device is a SATA device, a PHY reset will33183318+ * be sent.35163319 *35173320 * Return value:35183321 * 0 on success / non-zero on failure···35243325 struct ipr_cmnd *ipr_cmd;35253326 struct ipr_ioarcb *ioarcb;35263327 struct ipr_cmd_pkt *cmd_pkt;33283328+ struct ipr_ioarcb_ata_regs *regs;35273329 u32 ioasc;3528333035293331 ENTER;35303332 ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);35313333 ioarcb = &ipr_cmd->ioarcb;35323334 cmd_pkt = &ioarcb->cmd_pkt;33353335+ regs = &ioarcb->add_data.u.regs;3533333635343337 ioarcb->res_handle = res->cfgte.res_handle;35353338 cmd_pkt->request_type = IPR_RQTYPE_IOACMD;35363339 cmd_pkt->cdb[0] = IPR_RESET_DEVICE;33403340+ if (ipr_is_gata(res)) {33413341+ cmd_pkt->cdb[2] = IPR_ATA_PHY_RESET;33423342+ ioarcb->add_cmd_parms_len = cpu_to_be32(sizeof(regs->flags));33433343+ regs->flags |= IPR_ATA_FLAG_STATUS_ON_GOOD_COMPLETION;33443344+ }3537334535383346 ipr_send_blocking_cmd(ipr_cmd, ipr_timeout, IPR_DEVICE_RESET_TIMEOUT);35393347 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);35403348 list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);33493349+ if (ipr_is_gata(res) && res->sata_port && ioasc != IPR_IOASC_IOA_WAS_RESET)33503350+ memcpy(&res->sata_port->ioasa, &ipr_cmd->ioasa.u.gata,33513351+ sizeof(struct ipr_ioasa_gata));3541335235423353 LEAVE;35433354 return (IPR_IOASC_SENSE_KEY(ioasc) ? -EIO : 0);33553355+}33563356+33573357+/**33583358+ * ipr_sata_reset - Reset the SATA port33593359+ * @ap: SATA port to reset33603360+ * @classes: class of the attached device33613361+ *33623362+ * This function issues a SATA phy reset to the affected ATA port.33633363+ *33643364+ * Return value:33653365+ * 0 on success / non-zero on failure33663366+ **/33673367+static int ipr_sata_reset(struct ata_port *ap, unsigned int *classes)33683368+{33693369+ struct ipr_sata_port *sata_port = ap->private_data;33703370+ struct ipr_ioa_cfg *ioa_cfg = sata_port->ioa_cfg;33713371+ struct ipr_resource_entry *res;33723372+ unsigned long lock_flags = 0;33733373+ int rc = -ENXIO;33743374+33753375+ ENTER;33763376+ spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);33773377+ res = sata_port->res;33783378+ if (res) {33793379+ rc = ipr_device_reset(ioa_cfg, res);33803380+ switch(res->cfgte.proto) {33813381+ case IPR_PROTO_SATA:33823382+ case IPR_PROTO_SAS_STP:33833383+ *classes = ATA_DEV_ATA;33843384+ break;33853385+ case IPR_PROTO_SATA_ATAPI:33863386+ case IPR_PROTO_SAS_STP_ATAPI:33873387+ *classes = ATA_DEV_ATAPI;33883388+ break;33893389+ default:33903390+ *classes = ATA_DEV_UNKNOWN;33913391+ break;33923392+ };33933393+ }33943394+33953395+ spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);33963396+ LEAVE;33973397+ return rc;35443398}3545339935463400/**···36123360 struct ipr_cmnd *ipr_cmd;36133361 struct ipr_ioa_cfg *ioa_cfg;36143362 struct ipr_resource_entry *res;36153615- int rc;33633363+ struct ata_port *ap;33643364+ int rc = 0;3616336536173366 ENTER;36183367 ioa_cfg = (struct ipr_ioa_cfg *) scsi_cmd->device->host->hostdata;···3641338836423389 res->resetting_device = 1;36433390 scmd_printk(KERN_ERR, scsi_cmd, "Resetting device\n");36443644- rc = ipr_device_reset(ioa_cfg, res);33913391+33923392+ if (ipr_is_gata(res) && res->sata_port) {33933393+ ap = res->sata_port->ap;33943394+ spin_unlock_irq(scsi_cmd->device->host->host_lock);33953395+ ata_do_eh(ap, NULL, NULL, ipr_sata_reset, NULL);33963396+ spin_lock_irq(scsi_cmd->device->host->host_lock);33973397+ } else33983398+ rc = ipr_device_reset(ioa_cfg, res);36453399 res->resetting_device = 0;3646340036473401 LEAVE;···45604300 return 0;45614301 }4562430243034303+ if (ipr_is_gata(res) && res->sata_port)43044304+ return ata_sas_queuecmd(scsi_cmd, done, res->sata_port->ap);43054305+45634306 ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);45644307 ioarcb = &ipr_cmd->ioarcb;45654308 list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q);···46084345}4609434646104347/**43484348+ * ipr_ioctl - IOCTL handler43494349+ * @sdev: scsi device struct43504350+ * @cmd: IOCTL cmd43514351+ * @arg: IOCTL arg43524352+ *43534353+ * Return value:43544354+ * 0 on success / other on failure43554355+ **/43564356+int ipr_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)43574357+{43584358+ struct ipr_resource_entry *res;43594359+43604360+ res = (struct ipr_resource_entry *)sdev->hostdata;43614361+ if (res && ipr_is_gata(res))43624362+ return ata_scsi_ioctl(sdev, cmd, arg);43634363+43644364+ return -EINVAL;43654365+}43664366+43674367+/**46114368 * ipr_info - Get information about the card/driver46124369 * @scsi_host: scsi host struct46134370 *···46494366 return buffer;46504367}4651436843694369+/**43704370+ * ipr_scsi_timed_out - Handle scsi command timeout43714371+ * @scsi_cmd: scsi command struct43724372+ *43734373+ * Return value:43744374+ * EH_NOT_HANDLED43754375+ **/43764376+enum scsi_eh_timer_return ipr_scsi_timed_out(struct scsi_cmnd *scsi_cmd)43774377+{43784378+ struct ipr_ioa_cfg *ioa_cfg;43794379+ struct ipr_cmnd *ipr_cmd;43804380+ unsigned long flags;43814381+43824382+ ENTER;43834383+ spin_lock_irqsave(scsi_cmd->device->host->host_lock, flags);43844384+ ioa_cfg = (struct ipr_ioa_cfg *)scsi_cmd->device->host->hostdata;43854385+43864386+ list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) {43874387+ if (ipr_cmd->qc && ipr_cmd->qc->scsicmd == scsi_cmd) {43884388+ ipr_cmd->qc->err_mask |= AC_ERR_TIMEOUT;43894389+ ipr_cmd->qc->flags |= ATA_QCFLAG_FAILED;43904390+ break;43914391+ }43924392+ }43934393+43944394+ spin_unlock_irqrestore(scsi_cmd->device->host->host_lock, flags);43954395+ LEAVE;43964396+ return EH_NOT_HANDLED;43974397+}43984398+43994399+static struct scsi_transport_template ipr_transport_template = {44004400+ .eh_timed_out = ipr_scsi_timed_out44014401+};44024402+46524403static struct scsi_host_template driver_template = {46534404 .module = THIS_MODULE,46544405 .name = "IPR",46554406 .info = ipr_ioa_info,44074407+ .ioctl = ipr_ioctl,46564408 .queuecommand = ipr_queuecommand,46574409 .eh_abort_handler = ipr_eh_abort,46584410 .eh_device_reset_handler = ipr_eh_dev_reset,···46954377 .slave_alloc = ipr_slave_alloc,46964378 .slave_configure = ipr_slave_configure,46974379 .slave_destroy = ipr_slave_destroy,43804380+ .target_alloc = ipr_target_alloc,43814381+ .target_destroy = ipr_target_destroy,46984382 .change_queue_depth = ipr_change_queue_depth,46994383 .change_queue_type = ipr_change_queue_type,47004384 .bios_param = ipr_biosparam,···47094389 .shost_attrs = ipr_ioa_attrs,47104390 .sdev_attrs = ipr_dev_attrs,47114391 .proc_name = IPR_NAME43924392+};43934393+43944394+/**43954395+ * ipr_ata_phy_reset - libata phy_reset handler43964396+ * @ap: ata port to reset43974397+ *43984398+ **/43994399+static void ipr_ata_phy_reset(struct ata_port *ap)44004400+{44014401+ unsigned long flags;44024402+ struct ipr_sata_port *sata_port = ap->private_data;44034403+ struct ipr_resource_entry *res = sata_port->res;44044404+ struct ipr_ioa_cfg *ioa_cfg = sata_port->ioa_cfg;44054405+ int rc;44064406+44074407+ ENTER;44084408+ spin_lock_irqsave(ioa_cfg->host->host_lock, flags);44094409+ while(ioa_cfg->in_reset_reload) {44104410+ spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags);44114411+ wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload);44124412+ spin_lock_irqsave(ioa_cfg->host->host_lock, flags);44134413+ }44144414+44154415+ if (!ioa_cfg->allow_cmds)44164416+ goto out_unlock;44174417+44184418+ rc = ipr_device_reset(ioa_cfg, res);44194419+44204420+ if (rc) {44214421+ ap->ops->port_disable(ap);44224422+ goto out_unlock;44234423+ }44244424+44254425+ switch(res->cfgte.proto) {44264426+ case IPR_PROTO_SATA:44274427+ case IPR_PROTO_SAS_STP:44284428+ ap->device[0].class = ATA_DEV_ATA;44294429+ break;44304430+ case IPR_PROTO_SATA_ATAPI:44314431+ case IPR_PROTO_SAS_STP_ATAPI:44324432+ ap->device[0].class = ATA_DEV_ATAPI;44334433+ break;44344434+ default:44354435+ ap->device[0].class = ATA_DEV_UNKNOWN;44364436+ ap->ops->port_disable(ap);44374437+ break;44384438+ };44394439+44404440+out_unlock:44414441+ spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags);44424442+ LEAVE;44434443+}44444444+44454445+/**44464446+ * ipr_ata_post_internal - Cleanup after an internal command44474447+ * @qc: ATA queued command44484448+ *44494449+ * Return value:44504450+ * none44514451+ **/44524452+static void ipr_ata_post_internal(struct ata_queued_cmd *qc)44534453+{44544454+ struct ipr_sata_port *sata_port = qc->ap->private_data;44554455+ struct ipr_ioa_cfg *ioa_cfg = sata_port->ioa_cfg;44564456+ struct ipr_cmnd *ipr_cmd;44574457+ unsigned long flags;44584458+44594459+ spin_lock_irqsave(ioa_cfg->host->host_lock, flags);44604460+ list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) {44614461+ if (ipr_cmd->qc == qc) {44624462+ ipr_device_reset(ioa_cfg, sata_port->res);44634463+ break;44644464+ }44654465+ }44664466+ spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags);44674467+}44684468+44694469+/**44704470+ * ipr_tf_read - Read the current ATA taskfile for the ATA port44714471+ * @ap: ATA port44724472+ * @tf: destination ATA taskfile44734473+ *44744474+ * Return value:44754475+ * none44764476+ **/44774477+static void ipr_tf_read(struct ata_port *ap, struct ata_taskfile *tf)44784478+{44794479+ struct ipr_sata_port *sata_port = ap->private_data;44804480+ struct ipr_ioasa_gata *g = &sata_port->ioasa;44814481+44824482+ tf->feature = g->error;44834483+ tf->nsect = g->nsect;44844484+ tf->lbal = g->lbal;44854485+ tf->lbam = g->lbam;44864486+ tf->lbah = g->lbah;44874487+ tf->device = g->device;44884488+ tf->command = g->status;44894489+ tf->hob_nsect = g->hob_nsect;44904490+ tf->hob_lbal = g->hob_lbal;44914491+ tf->hob_lbam = g->hob_lbam;44924492+ tf->hob_lbah = g->hob_lbah;44934493+ tf->ctl = g->alt_status;44944494+}44954495+44964496+/**44974497+ * ipr_copy_sata_tf - Copy a SATA taskfile to an IOA data structure44984498+ * @regs: destination44994499+ * @tf: source ATA taskfile45004500+ *45014501+ * Return value:45024502+ * none45034503+ **/45044504+static void ipr_copy_sata_tf(struct ipr_ioarcb_ata_regs *regs,45054505+ struct ata_taskfile *tf)45064506+{45074507+ regs->feature = tf->feature;45084508+ regs->nsect = tf->nsect;45094509+ regs->lbal = tf->lbal;45104510+ regs->lbam = tf->lbam;45114511+ regs->lbah = tf->lbah;45124512+ regs->device = tf->device;45134513+ regs->command = tf->command;45144514+ regs->hob_feature = tf->hob_feature;45154515+ regs->hob_nsect = tf->hob_nsect;45164516+ regs->hob_lbal = tf->hob_lbal;45174517+ regs->hob_lbam = tf->hob_lbam;45184518+ regs->hob_lbah = tf->hob_lbah;45194519+ regs->ctl = tf->ctl;45204520+}45214521+45224522+/**45234523+ * ipr_sata_done - done function for SATA commands45244524+ * @ipr_cmd: ipr command struct45254525+ *45264526+ * This function is invoked by the interrupt handler for45274527+ * ops generated by the SCSI mid-layer to SATA devices45284528+ *45294529+ * Return value:45304530+ * none45314531+ **/45324532+static void ipr_sata_done(struct ipr_cmnd *ipr_cmd)45334533+{45344534+ struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;45354535+ struct ata_queued_cmd *qc = ipr_cmd->qc;45364536+ struct ipr_sata_port *sata_port = qc->ap->private_data;45374537+ struct ipr_resource_entry *res = sata_port->res;45384538+ u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);45394539+45404540+ memcpy(&sata_port->ioasa, &ipr_cmd->ioasa.u.gata,45414541+ sizeof(struct ipr_ioasa_gata));45424542+ ipr_dump_ioasa(ioa_cfg, ipr_cmd, res);45434543+45444544+ if (be32_to_cpu(ipr_cmd->ioasa.ioasc_specific) & IPR_ATA_DEVICE_WAS_RESET)45454545+ scsi_report_device_reset(ioa_cfg->host, res->cfgte.res_addr.bus,45464546+ res->cfgte.res_addr.target);45474547+45484548+ if (IPR_IOASC_SENSE_KEY(ioasc) > RECOVERED_ERROR)45494549+ qc->err_mask |= __ac_err_mask(ipr_cmd->ioasa.u.gata.status);45504550+ else45514551+ qc->err_mask |= ac_err_mask(ipr_cmd->ioasa.u.gata.status);45524552+ list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);45534553+ ata_qc_complete(qc);45544554+}45554555+45564556+/**45574557+ * ipr_build_ata_ioadl - Build an ATA scatter/gather list45584558+ * @ipr_cmd: ipr command struct45594559+ * @qc: ATA queued command45604560+ *45614561+ **/45624562+static void ipr_build_ata_ioadl(struct ipr_cmnd *ipr_cmd,45634563+ struct ata_queued_cmd *qc)45644564+{45654565+ u32 ioadl_flags = 0;45664566+ struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;45674567+ struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;45684568+ int len = qc->nbytes + qc->pad_len;45694569+ struct scatterlist *sg;45704570+45714571+ if (len == 0)45724572+ return;45734573+45744574+ if (qc->dma_dir == DMA_TO_DEVICE) {45754575+ ioadl_flags = IPR_IOADL_FLAGS_WRITE;45764576+ ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;45774577+ ioarcb->write_data_transfer_length = cpu_to_be32(len);45784578+ ioarcb->write_ioadl_len =45794579+ cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg);45804580+ } else if (qc->dma_dir == DMA_FROM_DEVICE) {45814581+ ioadl_flags = IPR_IOADL_FLAGS_READ;45824582+ ioarcb->read_data_transfer_length = cpu_to_be32(len);45834583+ ioarcb->read_ioadl_len =45844584+ cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg);45854585+ }45864586+45874587+ ata_for_each_sg(sg, qc) {45884588+ ioadl->flags_and_data_len = cpu_to_be32(ioadl_flags | sg_dma_len(sg));45894589+ ioadl->address = cpu_to_be32(sg_dma_address(sg));45904590+ if (ata_sg_is_last(sg, qc))45914591+ ioadl->flags_and_data_len |= cpu_to_be32(IPR_IOADL_FLAGS_LAST);45924592+ else45934593+ ioadl++;45944594+ }45954595+}45964596+45974597+/**45984598+ * ipr_qc_issue - Issue a SATA qc to a device45994599+ * @qc: queued command46004600+ *46014601+ * Return value:46024602+ * 0 if success46034603+ **/46044604+static unsigned int ipr_qc_issue(struct ata_queued_cmd *qc)46054605+{46064606+ struct ata_port *ap = qc->ap;46074607+ struct ipr_sata_port *sata_port = ap->private_data;46084608+ struct ipr_resource_entry *res = sata_port->res;46094609+ struct ipr_ioa_cfg *ioa_cfg = sata_port->ioa_cfg;46104610+ struct ipr_cmnd *ipr_cmd;46114611+ struct ipr_ioarcb *ioarcb;46124612+ struct ipr_ioarcb_ata_regs *regs;46134613+46144614+ if (unlikely(!ioa_cfg->allow_cmds || ioa_cfg->ioa_is_dead))46154615+ return -EIO;46164616+46174617+ ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);46184618+ ioarcb = &ipr_cmd->ioarcb;46194619+ regs = &ioarcb->add_data.u.regs;46204620+46214621+ memset(&ioarcb->add_data, 0, sizeof(ioarcb->add_data));46224622+ ioarcb->add_cmd_parms_len = cpu_to_be32(sizeof(ioarcb->add_data.u.regs));46234623+46244624+ list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q);46254625+ ipr_cmd->qc = qc;46264626+ ipr_cmd->done = ipr_sata_done;46274627+ ipr_cmd->ioarcb.res_handle = res->cfgte.res_handle;46284628+ ioarcb->cmd_pkt.request_type = IPR_RQTYPE_ATA_PASSTHRU;46294629+ ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_LINK_DESC;46304630+ ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK;46314631+ ipr_cmd->dma_use_sg = qc->pad_len ? qc->n_elem + 1 : qc->n_elem;46324632+46334633+ ipr_build_ata_ioadl(ipr_cmd, qc);46344634+ regs->flags |= IPR_ATA_FLAG_STATUS_ON_GOOD_COMPLETION;46354635+ ipr_copy_sata_tf(regs, &qc->tf);46364636+ memcpy(ioarcb->cmd_pkt.cdb, qc->cdb, IPR_MAX_CDB_LEN);46374637+ ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_PHYS_LOC(res->cfgte.res_addr));46384638+46394639+ switch (qc->tf.protocol) {46404640+ case ATA_PROT_NODATA:46414641+ case ATA_PROT_PIO:46424642+ break;46434643+46444644+ case ATA_PROT_DMA:46454645+ regs->flags |= IPR_ATA_FLAG_XFER_TYPE_DMA;46464646+ break;46474647+46484648+ case ATA_PROT_ATAPI:46494649+ case ATA_PROT_ATAPI_NODATA:46504650+ regs->flags |= IPR_ATA_FLAG_PACKET_CMD;46514651+ break;46524652+46534653+ case ATA_PROT_ATAPI_DMA:46544654+ regs->flags |= IPR_ATA_FLAG_PACKET_CMD;46554655+ regs->flags |= IPR_ATA_FLAG_XFER_TYPE_DMA;46564656+ break;46574657+46584658+ default:46594659+ WARN_ON(1);46604660+ return -1;46614661+ }46624662+46634663+ mb();46644664+ writel(be32_to_cpu(ioarcb->ioarcb_host_pci_addr),46654665+ ioa_cfg->regs.ioarrin_reg);46664666+ return 0;46674667+}46684668+46694669+/**46704670+ * ipr_ata_check_status - Return last ATA status46714671+ * @ap: ATA port46724672+ *46734673+ * Return value:46744674+ * ATA status46754675+ **/46764676+static u8 ipr_ata_check_status(struct ata_port *ap)46774677+{46784678+ struct ipr_sata_port *sata_port = ap->private_data;46794679+ return sata_port->ioasa.status;46804680+}46814681+46824682+/**46834683+ * ipr_ata_check_altstatus - Return last ATA altstatus46844684+ * @ap: ATA port46854685+ *46864686+ * Return value:46874687+ * Alt ATA status46884688+ **/46894689+static u8 ipr_ata_check_altstatus(struct ata_port *ap)46904690+{46914691+ struct ipr_sata_port *sata_port = ap->private_data;46924692+ return sata_port->ioasa.alt_status;46934693+}46944694+46954695+static struct ata_port_operations ipr_sata_ops = {46964696+ .port_disable = ata_port_disable,46974697+ .check_status = ipr_ata_check_status,46984698+ .check_altstatus = ipr_ata_check_altstatus,46994699+ .dev_select = ata_noop_dev_select,47004700+ .phy_reset = ipr_ata_phy_reset,47014701+ .post_internal_cmd = ipr_ata_post_internal,47024702+ .tf_read = ipr_tf_read,47034703+ .qc_prep = ata_noop_qc_prep,47044704+ .qc_issue = ipr_qc_issue,47054705+ .port_start = ata_sas_port_start,47064706+ .port_stop = ata_sas_port_stop47074707+};47084708+47094709+static struct ata_port_info sata_port_info = {47104710+ .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_SATA_RESET |47114711+ ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA,47124712+ .pio_mask = 0x10, /* pio4 */47134713+ .mwdma_mask = 0x07,47144714+ .udma_mask = 0x7f, /* udma0-6 */47154715+ .port_ops = &ipr_sata_ops47124716};4713471747144718#ifdef CONFIG_PPC_PSERIES···7018637470196375 ioa_cfg = (struct ipr_ioa_cfg *)host->hostdata;70206376 memset(ioa_cfg, 0, sizeof(struct ipr_ioa_cfg));63776377+ host->transportt = &ipr_transport_template;63786378+ ata_host_init(&ioa_cfg->ata_host, &pdev->dev,63796379+ sata_port_info.flags, &ipr_sata_ops);7021638070226381 ioa_cfg->chip_cfg = ipr_get_chip_cfg(dev_id);70236382